// 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.Seek(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, r.expr(), nil)
		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
}
