// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Indexed package import.
// See iexport.go for the export data format.

package gc

import (
	"cmd/compile/internal/types"
	"cmd/internal/bio"
	"cmd/internal/src"
	"encoding/binary"
	"fmt"
	"math/big"
	"os"
	"strings"
)

// An iimporterAndOffset identifies an importer and an offset within
// its data section.
type iimporterAndOffset struct {
	p   *iimporter
	off uint64
}

var (
	// declImporter maps from imported identifiers to an importer
	// and offset where that identifier's declaration can be read.
	declImporter = map[*types.Sym]iimporterAndOffset{}

	// inlineImporter is like declImporter, but for inline bodies
	// for function and method symbols.
	inlineImporter = map[*types.Sym]iimporterAndOffset{}
)

func expandDecl(n *Node) {
	if n.Op != ONONAME {
		return
	}

	r := importReaderFor(n, declImporter)
	if r == nil {
		// Can happen if user tries to reference an undeclared name.
		return
	}

	r.doDecl(n)
}

func expandInline(fn *Node) {
	if fn.Func.Inl.Body != nil {
		return
	}

	r := importReaderFor(fn, inlineImporter)
	if r == nil {
		Fatalf("missing import reader for %v", fn)
	}

	r.doInline(fn)
}

func importReaderFor(n *Node, importers map[*types.Sym]iimporterAndOffset) *importReader {
	x, ok := importers[n.Sym]
	if !ok {
		return nil
	}

	return x.p.newReader(x.off, n.Sym.Pkg)
}

type intReader struct {
	*bio.Reader
	pkg *types.Pkg
}

func (r *intReader) int64() int64 {
	i, err := binary.ReadVarint(r.Reader)
	if err != nil {
		yyerror("import %q: read error: %v", r.pkg.Path, err)
		errorexit()
	}
	return i
}

func (r *intReader) uint64() uint64 {
	i, err := binary.ReadUvarint(r.Reader)
	if err != nil {
		yyerror("import %q: read error: %v", r.pkg.Path, err)
		errorexit()
	}
	return i
}

func iimport(pkg *types.Pkg, in *bio.Reader) {
	ir := &intReader{in, pkg}

	version := ir.uint64()
	if version != iexportVersion {
		yyerror("import %q: unknown export format version %d", pkg.Path, version)
		errorexit()
	}

	sLen := ir.uint64()
	dLen := ir.uint64()

	// Map string (and data) section into memory as a single large
	// string. This reduces heap fragmentation and allows
	// returning individual substrings very efficiently.
	data, err := mapFile(in.File(), in.Offset(), int64(sLen+dLen))
	if err != nil {
		yyerror("import %q: mapping input: %v", pkg.Path, err)
		errorexit()
	}
	stringData := data[:sLen]
	declData := data[sLen:]

	in.MustSeek(int64(sLen+dLen), os.SEEK_CUR)

	p := &iimporter{
		ipkg: pkg,

		pkgCache:     map[uint64]*types.Pkg{},
		posBaseCache: map[uint64]*src.PosBase{},
		typCache:     map[uint64]*types.Type{},

		stringData: stringData,
		declData:   declData,
	}

	for i, pt := range predeclared() {
		p.typCache[uint64(i)] = pt
	}

	// Declaration index.
	for nPkgs := ir.uint64(); nPkgs > 0; nPkgs-- {
		pkg := p.pkgAt(ir.uint64())
		pkgName := p.stringAt(ir.uint64())
		pkgHeight := int(ir.uint64())
		if pkg.Name == "" {
			pkg.Name = pkgName
			pkg.Height = pkgHeight
			numImport[pkgName]++

			// TODO(mdempsky): This belongs somewhere else.
			pkg.Lookup("_").Def = asTypesNode(nblank)
		} else {
			if pkg.Name != pkgName {
				Fatalf("conflicting package names %v and %v for path %q", pkg.Name, pkgName, pkg.Path)
			}
			if pkg.Height != pkgHeight {
				Fatalf("conflicting package heights %v and %v for path %q", pkg.Height, pkgHeight, pkg.Path)
			}
		}

		for nSyms := ir.uint64(); nSyms > 0; nSyms-- {
			s := pkg.Lookup(p.stringAt(ir.uint64()))
			off := ir.uint64()

			if _, ok := declImporter[s]; ok {
				continue
			}
			declImporter[s] = iimporterAndOffset{p, off}

			// Create stub declaration. If used, this will
			// be overwritten by expandDecl.
			if s.Def != nil {
				Fatalf("unexpected definition for %v: %v", s, asNode(s.Def))
			}
			s.Def = asTypesNode(npos(src.NoXPos, dclname(s)))
		}
	}

	// Inline body index.
	for nPkgs := ir.uint64(); nPkgs > 0; nPkgs-- {
		pkg := p.pkgAt(ir.uint64())

		for nSyms := ir.uint64(); nSyms > 0; nSyms-- {
			s := pkg.Lookup(p.stringAt(ir.uint64()))
			off := ir.uint64()

			if _, ok := inlineImporter[s]; ok {
				continue
			}
			inlineImporter[s] = iimporterAndOffset{p, off}
		}
	}
}

type iimporter struct {
	ipkg *types.Pkg

	pkgCache     map[uint64]*types.Pkg
	posBaseCache map[uint64]*src.PosBase
	typCache     map[uint64]*types.Type

	stringData string
	declData   string
}

func (p *iimporter) stringAt(off uint64) string {
	var x [binary.MaxVarintLen64]byte
	n := copy(x[:], p.stringData[off:])

	slen, n := binary.Uvarint(x[:n])
	if n <= 0 {
		Fatalf("varint failed")
	}
	spos := off + uint64(n)
	return p.stringData[spos : spos+slen]
}

func (p *iimporter) posBaseAt(off uint64) *src.PosBase {
	if posBase, ok := p.posBaseCache[off]; ok {
		return posBase
	}

	file := p.stringAt(off)
	posBase := src.NewFileBase(file, file)
	p.posBaseCache[off] = posBase
	return posBase
}

func (p *iimporter) pkgAt(off uint64) *types.Pkg {
	if pkg, ok := p.pkgCache[off]; ok {
		return pkg
	}

	pkg := p.ipkg
	if pkgPath := p.stringAt(off); pkgPath != "" {
		pkg = types.NewPkg(pkgPath, "")
	}
	p.pkgCache[off] = pkg
	return pkg
}

// An importReader keeps state for reading an individual imported
// object (declaration or inline body).
type importReader struct {
	strings.Reader
	p *iimporter

	currPkg  *types.Pkg
	prevBase *src.PosBase
	prevLine int64
}

func (p *iimporter) newReader(off uint64, pkg *types.Pkg) *importReader {
	r := &importReader{
		p:       p,
		currPkg: pkg,
	}
	// (*strings.Reader).Reset wasn't added until Go 1.7, and we
	// need to build with Go 1.4.
	r.Reader = *strings.NewReader(p.declData[off:])
	return r
}

func (r *importReader) string() string        { return r.p.stringAt(r.uint64()) }
func (r *importReader) posBase() *src.PosBase { return r.p.posBaseAt(r.uint64()) }
func (r *importReader) pkg() *types.Pkg       { return r.p.pkgAt(r.uint64()) }

func (r *importReader) setPkg() {
	r.currPkg = r.pkg()
}

func (r *importReader) doDecl(n *Node) {
	if n.Op != ONONAME {
		Fatalf("doDecl: unexpected Op for %v: %v", n.Sym, n.Op)
	}

	tag := r.byte()
	pos := r.pos()

	switch tag {
	case 'A':
		typ := r.typ()

		importalias(r.p.ipkg, pos, n.Sym, typ)

	case 'C':
		typ, val := r.value()

		importconst(r.p.ipkg, pos, n.Sym, typ, val)

	case 'F':
		typ := r.signature(nil)

		importfunc(r.p.ipkg, pos, n.Sym, typ)
		r.funcExt(n)

	case 'T':
		// Types can be recursive. We need to setup a stub
		// declaration before recursing.
		t := importtype(r.p.ipkg, pos, n.Sym)

		// We also need to defer width calculations until
		// after the underlying type has been assigned.
		//
		// TODO(mdempsky): Add nesting support directly to
		// {defer,resume}checkwidth? Width calculations are
		// already deferred during initial typechecking, but
		// not when we're expanding inline function bodies, so
		// we currently need to handle both cases here.
		deferring := defercalc != 0
		if !deferring {
			defercheckwidth()
		}
		underlying := r.typ()
		copytype(typenod(t), underlying)
		if !deferring {
			resumecheckwidth()
		}

		if underlying.IsInterface() {
			break
		}

		ms := make([]*types.Field, r.uint64())
		for i := range ms {
			mpos := r.pos()
			msym := r.ident()
			recv := r.param()
			mtyp := r.signature(recv)

			f := types.NewField()
			f.Pos = mpos
			f.Sym = msym
			f.Type = mtyp
			ms[i] = f

			m := newfuncnamel(mpos, methodSym(recv.Type, msym))
			m.Type = mtyp
			m.SetClass(PFUNC)
			// methodSym already marked m.Sym as a function.

			// (comment from parser.go)
			// inl.C's inlnode in on a dotmeth node expects to find the inlineable body as
			// (dotmeth's type).Nname.Inl, and dotmeth's type has been pulled
			// out by typecheck's lookdot as this $$.ttype. So by providing
			// this back link here we avoid special casing there.
			mtyp.SetNname(asTypesNode(m))
		}
		t.Methods().Set(ms)

		for _, m := range ms {
			r.methExt(m)
		}

	case 'V':
		typ := r.typ()

		importvar(r.p.ipkg, pos, n.Sym, typ)
		r.varExt(n)

	default:
		Fatalf("unexpected tag: %v", tag)
	}
}

func (p *importReader) value() (typ *types.Type, v Val) {
	typ = p.typ()

	switch constTypeOf(typ) {
	case CTNIL:
		v.U = &NilVal{}
	case CTBOOL:
		v.U = p.bool()
	case CTSTR:
		v.U = p.string()
	case CTINT:
		x := new(Mpint)
		x.Rune = typ == types.Idealrune
		p.mpint(&x.Val, typ)
		v.U = x
	case CTFLT:
		x := newMpflt()
		p.float(x, typ)
		v.U = x
	case CTCPLX:
		x := newMpcmplx()
		p.float(&x.Real, typ)
		p.float(&x.Imag, typ)
		v.U = x
	}

	typ = idealType(typ)
	return
}

func (p *importReader) mpint(x *big.Int, typ *types.Type) {
	signed, maxBytes := intSize(typ)

	maxSmall := 256 - maxBytes
	if signed {
		maxSmall = 256 - 2*maxBytes
	}
	if maxBytes == 1 {
		maxSmall = 256
	}

	n, _ := p.ReadByte()
	if uint(n) < maxSmall {
		v := int64(n)
		if signed {
			v >>= 1
			if n&1 != 0 {
				v = ^v
			}
		}
		x.SetInt64(v)
		return
	}

	v := -n
	if signed {
		v = -(n &^ 1) >> 1
	}
	if v < 1 || uint(v) > maxBytes {
		Fatalf("weird decoding: %v, %v => %v", n, signed, v)
	}
	b := make([]byte, v)
	p.Read(b)
	x.SetBytes(b)
	if signed && n&1 != 0 {
		x.Neg(x)
	}
}

func (p *importReader) float(x *Mpflt, typ *types.Type) {
	var mant big.Int
	p.mpint(&mant, typ)
	m := x.Val.SetInt(&mant)
	if m.Sign() == 0 {
		return
	}
	m.SetMantExp(m, int(p.int64()))
}

func (r *importReader) ident() *types.Sym {
	name := r.string()
	if name == "" {
		return nil
	}
	pkg := r.currPkg
	if types.IsExported(name) {
		pkg = localpkg
	}
	return pkg.Lookup(name)
}

func (r *importReader) qualifiedIdent() *types.Sym {
	name := r.string()
	pkg := r.pkg()
	return pkg.Lookup(name)
}

func (r *importReader) pos() src.XPos {
	delta := r.int64()
	if delta != deltaNewFile {
		r.prevLine += delta
	} else if l := r.int64(); l == -1 {
		r.prevLine += deltaNewFile
	} else {
		r.prevBase = r.posBase()
		r.prevLine = l
	}

	if (r.prevBase == nil || r.prevBase.AbsFilename() == "") && r.prevLine == 0 {
		// TODO(mdempsky): Remove once we reliably write
		// position information for all nodes.
		return src.NoXPos
	}

	if r.prevBase == nil {
		Fatalf("missing posbase")
	}
	pos := src.MakePos(r.prevBase, uint(r.prevLine), 0)
	return Ctxt.PosTable.XPos(pos)
}

func (r *importReader) typ() *types.Type {
	return r.p.typAt(r.uint64())
}

func (p *iimporter) typAt(off uint64) *types.Type {
	t, ok := p.typCache[off]
	if !ok {
		if off < predeclReserved {
			Fatalf("predeclared type missing from cache: %d", off)
		}
		t = p.newReader(off-predeclReserved, nil).typ1()
		p.typCache[off] = t
	}
	return t
}

func (r *importReader) typ1() *types.Type {
	switch k := r.kind(); k {
	default:
		Fatalf("unexpected kind tag in %q: %v", r.p.ipkg.Path, k)
		return nil

	case definedType:
		// We might be called from within doInline, in which
		// case Sym.Def can point to declared parameters
		// instead of the top-level types. Also, we don't
		// support inlining functions with local defined
		// types. Therefore, this must be a package-scope
		// type.
		n := asNode(r.qualifiedIdent().PkgDef())
		if n.Op == ONONAME {
			expandDecl(n)
		}
		if n.Op != OTYPE {
			Fatalf("expected OTYPE, got %v: %v, %v", n.Op, n.Sym, n)
		}
		return n.Type
	case pointerType:
		return types.NewPtr(r.typ())
	case sliceType:
		return types.NewSlice(r.typ())
	case arrayType:
		n := r.uint64()
		return types.NewArray(r.typ(), int64(n))
	case chanType:
		dir := types.ChanDir(r.uint64())
		return types.NewChan(r.typ(), dir)
	case mapType:
		return types.NewMap(r.typ(), r.typ())

	case signatureType:
		r.setPkg()
		return r.signature(nil)

	case structType:
		r.setPkg()

		fs := make([]*types.Field, r.uint64())
		for i := range fs {
			pos := r.pos()
			sym := r.ident()
			typ := r.typ()
			emb := r.bool()
			note := r.string()

			f := types.NewField()
			f.Pos = pos
			f.Sym = sym
			f.Type = typ
			if emb {
				f.Embedded = 1
			}
			f.Note = note
			fs[i] = f
		}

		t := types.New(TSTRUCT)
		t.SetPkg(r.currPkg)
		t.SetFields(fs)
		return t

	case interfaceType:
		r.setPkg()

		embeddeds := make([]*types.Field, r.uint64())
		for i := range embeddeds {
			pos := r.pos()
			typ := r.typ()

			f := types.NewField()
			f.Pos = pos
			f.Type = typ
			embeddeds[i] = f
		}

		methods := make([]*types.Field, r.uint64())
		for i := range methods {
			pos := r.pos()
			sym := r.ident()
			typ := r.signature(fakeRecvField())

			f := types.NewField()
			f.Pos = pos
			f.Sym = sym
			f.Type = typ
			methods[i] = f
		}

		t := types.New(TINTER)
		t.SetPkg(r.currPkg)
		t.SetInterface(append(embeddeds, methods...))

		// Ensure we expand the interface in the frontend (#25055).
		checkwidth(t)

		return t
	}
}

func (r *importReader) kind() itag {
	return itag(r.uint64())
}

func (r *importReader) signature(recv *types.Field) *types.Type {
	params := r.paramList()
	results := r.paramList()
	if n := len(params); n > 0 {
		params[n-1].SetIsDDD(r.bool())
	}
	t := functypefield(recv, params, results)
	t.SetPkg(r.currPkg)
	return t
}

func (r *importReader) paramList() []*types.Field {
	fs := make([]*types.Field, r.uint64())
	for i := range fs {
		fs[i] = r.param()
	}
	return fs
}

func (r *importReader) param() *types.Field {
	f := types.NewField()
	f.Pos = r.pos()
	f.Sym = r.ident()
	f.Type = r.typ()
	return f
}

func (r *importReader) bool() bool {
	return r.uint64() != 0
}

func (r *importReader) int64() int64 {
	n, err := binary.ReadVarint(r)
	if err != nil {
		Fatalf("readVarint: %v", err)
	}
	return n
}

func (r *importReader) uint64() uint64 {
	n, err := binary.ReadUvarint(r)
	if err != nil {
		Fatalf("readVarint: %v", err)
	}
	return n
}

func (r *importReader) byte() byte {
	x, err := r.ReadByte()
	if err != nil {
		Fatalf("declReader.ReadByte: %v", err)
	}
	return x
}

// Compiler-specific extensions.

func (r *importReader) varExt(n *Node) {
	r.linkname(n.Sym)
}

func (r *importReader) funcExt(n *Node) {
	r.linkname(n.Sym)

	// Escape analysis.
	for _, fs := range types.RecvsParams {
		for _, f := range fs(n.Type).FieldSlice() {
			f.Note = r.string()
		}
	}

	// Inline body.
	if u := r.uint64(); u > 0 {
		n.Func.Inl = &Inline{
			Cost: int32(u - 1),
		}
		n.Func.Endlineno = r.pos()
	}
}

func (r *importReader) methExt(m *types.Field) {
	if r.bool() {
		m.SetNointerface(true)
	}
	r.funcExt(asNode(m.Type.Nname()))
}

func (r *importReader) linkname(s *types.Sym) {
	s.Linkname = r.string()
}

func (r *importReader) doInline(n *Node) {
	if len(n.Func.Inl.Body) != 0 {
		Fatalf("%v already has inline body", n)
	}

	funchdr(n)
	body := r.stmtList()
	funcbody()
	if body == nil {
		//
		// Make sure empty body is not interpreted as
		// no inlineable body (see also parser.fnbody)
		// (not doing so can cause significant performance
		// degradation due to unnecessary calls to empty
		// functions).
		body = []*Node{}
	}
	n.Func.Inl.Body = body

	importlist = append(importlist, n)

	if Debug['E'] > 0 && Debug['m'] > 2 {
		if Debug['m'] > 3 {
			fmt.Printf("inl body for %v %#v: %+v\n", n, n.Type, asNodes(n.Func.Inl.Body))
		} else {
			fmt.Printf("inl body for %v %#v: %v\n", n, n.Type, asNodes(n.Func.Inl.Body))
		}
	}
}

// ----------------------------------------------------------------------------
// Inlined function bodies

// Approach: Read nodes and use them to create/declare the same data structures
// as done originally by the (hidden) parser by closely following the parser's
// original code. In other words, "parsing" the import data (which happens to
// be encoded in binary rather textual form) is the best way at the moment to
// re-establish the syntax tree's invariants. At some future point we might be
// able to avoid this round-about way and create the rewritten nodes directly,
// possibly avoiding a lot of duplicate work (name resolution, type checking).
//
// Refined nodes (e.g., ODOTPTR as a refinement of OXDOT) are exported as their
// unrefined nodes (since this is what the importer uses). The respective case
// entries are unreachable in the importer.

func (r *importReader) stmtList() []*Node {
	var list []*Node
	for {
		n := r.node()
		if n == nil {
			break
		}
		// OBLOCK nodes may be created when importing ODCL nodes - unpack them
		if n.Op == OBLOCK {
			list = append(list, n.List.Slice()...)
		} else {
			list = append(list, n)
		}

	}
	return list
}

func (r *importReader) exprList() []*Node {
	var list []*Node
	for {
		n := r.expr()
		if n == nil {
			break
		}
		list = append(list, n)
	}
	return list
}

func (r *importReader) expr() *Node {
	n := r.node()
	if n != nil && n.Op == OBLOCK {
		Fatalf("unexpected block node: %v", n)
	}
	return n
}

// TODO(gri) split into expr and stmt
func (r *importReader) node() *Node {
	switch op := r.op(); op {
	// expressions
	// case OPAREN:
	// 	unreachable - unpacked by exporter

	// case ODDDARG:
	//	unimplemented

	case OLITERAL:
		pos := r.pos()
		typ, val := r.value()

		n := npos(pos, nodlit(val))
		n.Type = typ
		return n

	case ONONAME:
		return mkname(r.qualifiedIdent())

	case ONAME:
		return mkname(r.ident())

	// case OPACK, ONONAME:
	// 	unreachable - should have been resolved by typechecking

	case OTYPE:
		return typenod(r.typ())

	// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
	//      unreachable - should have been resolved by typechecking

	// case OCLOSURE:
	//	unimplemented

	case OPTRLIT:
		pos := r.pos()
		n := npos(pos, r.expr())
		if !r.bool() /* !implicit, i.e. '&' operator */ {
			if n.Op == OCOMPLIT {
				// Special case for &T{...}: turn into (*T){...}.
				n.Right = nodl(pos, ODEREF, n.Right, nil)
				n.Right.SetImplicit(true)
			} else {
				n = nodl(pos, OADDR, n, nil)
			}
		}
		return n

	case OSTRUCTLIT:
		// TODO(mdempsky): Export position information for OSTRUCTKEY nodes.
		savedlineno := lineno
		lineno = r.pos()
		n := nodl(lineno, OCOMPLIT, nil, typenod(r.typ()))
		n.List.Set(r.elemList()) // special handling of field names
		lineno = savedlineno
		return n

	// case OARRAYLIT, OSLICELIT, OMAPLIT:
	// 	unreachable - mapped to case OCOMPLIT below by exporter

	case OCOMPLIT:
		n := nodl(r.pos(), OCOMPLIT, nil, typenod(r.typ()))
		n.List.Set(r.exprList())
		return n

	case OKEY:
		pos := r.pos()
		left, right := r.exprsOrNil()
		return nodl(pos, OKEY, left, right)

	// case OSTRUCTKEY:
	//	unreachable - handled in case OSTRUCTLIT by elemList

	// case OCALLPART:
	//	unimplemented

	// case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
	// 	unreachable - mapped to case OXDOT below by exporter

	case OXDOT:
		// see parser.new_dotname
		return npos(r.pos(), nodSym(OXDOT, r.expr(), r.ident()))

	// case ODOTTYPE, ODOTTYPE2:
	// 	unreachable - mapped to case ODOTTYPE below by exporter

	case ODOTTYPE:
		n := nodl(r.pos(), ODOTTYPE, r.expr(), nil)
		n.Type = r.typ()
		return n

	// case OINDEX, OINDEXMAP, OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
	// 	unreachable - mapped to cases below by exporter

	case OINDEX:
		return nodl(r.pos(), op, r.expr(), r.expr())

	case OSLICE, OSLICE3:
		n := nodl(r.pos(), op, r.expr(), nil)
		low, high := r.exprsOrNil()
		var max *Node
		if n.Op.IsSlice3() {
			max = r.expr()
		}
		n.SetSliceBounds(low, high, max)
		return n

	// case OCONV, OCONVIFACE, OCONVNOP, OBYTES2STR, ORUNES2STR, OSTR2BYTES, OSTR2RUNES, ORUNESTR:
	// 	unreachable - mapped to OCONV case below by exporter

	case OCONV:
		n := nodl(r.pos(), OCONV, r.expr(), nil)
		n.Type = r.typ()
		return n

	case OCOPY, OCOMPLEX, OREAL, OIMAG, OAPPEND, OCAP, OCLOSE, ODELETE, OLEN, OMAKE, ONEW, OPANIC, ORECOVER, OPRINT, OPRINTN:
		n := npos(r.pos(), builtinCall(op))
		n.List.Set(r.exprList())
		if op == OAPPEND {
			n.SetIsDDD(r.bool())
		}
		return n

	// case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
	// 	unreachable - mapped to OCALL case below by exporter

	case OCALL:
		n := nodl(r.pos(), OCALL, nil, nil)
		n.Ninit.Set(r.stmtList())
		n.Left = r.expr()
		n.List.Set(r.exprList())
		n.SetIsDDD(r.bool())
		return n

	case OMAKEMAP, OMAKECHAN, OMAKESLICE:
		n := npos(r.pos(), builtinCall(OMAKE))
		n.List.Append(typenod(r.typ()))
		n.List.Append(r.exprList()...)
		return n

	// unary expressions
	case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
		return nodl(r.pos(), op, r.expr(), nil)

	// binary expressions
	case OADD, OAND, OANDAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE, OLT,
		OLSH, OMOD, OMUL, ONE, OOR, OOROR, ORSH, OSEND, OSUB, OXOR:
		return nodl(r.pos(), op, r.expr(), r.expr())

	case OADDSTR:
		pos := r.pos()
		list := r.exprList()
		x := npos(pos, list[0])
		for _, y := range list[1:] {
			x = nodl(pos, OADD, x, y)
		}
		return x

	// --------------------------------------------------------------------
	// statements
	case ODCL:
		pos := r.pos()
		lhs := npos(pos, dclname(r.ident()))
		typ := typenod(r.typ())
		return npos(pos, liststmt(variter([]*Node{lhs}, typ, nil))) // TODO(gri) avoid list creation

	// case ODCLFIELD:
	//	unimplemented

	// case OAS, OASWB:
	// 	unreachable - mapped to OAS case below by exporter

	case OAS:
		return nodl(r.pos(), OAS, r.expr(), r.expr())

	case OASOP:
		n := nodl(r.pos(), OASOP, nil, nil)
		n.SetSubOp(r.op())
		n.Left = r.expr()
		if !r.bool() {
			n.Right = nodintconst(1)
			n.SetImplicit(true)
		} else {
			n.Right = r.expr()
		}
		return n

	// case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
	// 	unreachable - mapped to OAS2 case below by exporter

	case OAS2:
		n := nodl(r.pos(), OAS2, nil, nil)
		n.List.Set(r.exprList())
		n.Rlist.Set(r.exprList())
		return n

	case ORETURN:
		n := nodl(r.pos(), ORETURN, nil, nil)
		n.List.Set(r.exprList())
		return n

	// case ORETJMP:
	// 	unreachable - generated by compiler for trampolin routines (not exported)

	case OGO, ODEFER:
		return nodl(r.pos(), op, r.expr(), nil)

	case OIF:
		n := nodl(r.pos(), OIF, nil, nil)
		n.Ninit.Set(r.stmtList())
		n.Left = r.expr()
		n.Nbody.Set(r.stmtList())
		n.Rlist.Set(r.stmtList())
		return n

	case OFOR:
		n := nodl(r.pos(), OFOR, nil, nil)
		n.Ninit.Set(r.stmtList())
		n.Left, n.Right = r.exprsOrNil()
		n.Nbody.Set(r.stmtList())
		return n

	case ORANGE:
		n := nodl(r.pos(), ORANGE, nil, nil)
		n.List.Set(r.stmtList())
		n.Right = r.expr()
		n.Nbody.Set(r.stmtList())
		return n

	case OSELECT, OSWITCH:
		n := nodl(r.pos(), op, nil, nil)
		n.Ninit.Set(r.stmtList())
		n.Left, _ = r.exprsOrNil()
		n.List.Set(r.stmtList())
		return n

	// case OCASE, OXCASE:
	// 	unreachable - mapped to OXCASE case below by exporter

	case OXCASE:
		n := nodl(r.pos(), OXCASE, nil, nil)
		n.List.Set(r.exprList())
		// TODO(gri) eventually we must declare variables for type switch
		// statements (type switch statements are not yet exported)
		n.Nbody.Set(r.stmtList())
		return n

	// case OFALL:
	// 	unreachable - mapped to OXFALL case below by exporter

	case OFALL:
		n := nodl(r.pos(), OFALL, nil, nil)
		return n

	case OBREAK, OCONTINUE:
		pos := r.pos()
		left, _ := r.exprsOrNil()
		if left != nil {
			left = newname(left.Sym)
		}
		return nodl(pos, op, left, nil)

	// case OEMPTY:
	// 	unreachable - not emitted by exporter

	case OGOTO, OLABEL:
		n := nodl(r.pos(), op, nil, nil)
		n.Sym = lookup(r.string())
		return n

	case OEND:
		return nil

	default:
		Fatalf("cannot import %v (%d) node\n"+
			"\t==> please file an issue and assign to gri@", op, int(op))
		panic("unreachable") // satisfy compiler
	}
}

func (r *importReader) op() Op {
	return Op(r.uint64())
}

func (r *importReader) elemList() []*Node {
	c := r.uint64()
	list := make([]*Node, c)
	for i := range list {
		s := r.ident()
		list[i] = nodSym(OSTRUCTKEY, r.expr(), s)
	}
	return list
}

func (r *importReader) exprsOrNil() (a, b *Node) {
	ab := r.uint64()
	if ab&1 != 0 {
		a = r.expr()
	}
	if ab&2 != 0 {
		b = r.node()
	}
	return
}
