github.com/cockroachdb/tools@v0.0.0-20230222021103-a6d27438930d/internal/gcimporter/iimport.go (about)

     1  // Copyright 2018 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Indexed package import.
     6  // See cmd/compile/internal/gc/iexport.go for the export data format.
     7  
     8  // This file is a copy of $GOROOT/src/go/internal/gcimporter/iimport.go.
     9  
    10  package gcimporter
    11  
    12  import (
    13  	"bytes"
    14  	"encoding/binary"
    15  	"fmt"
    16  	"go/constant"
    17  	"go/token"
    18  	"go/types"
    19  	"io"
    20  	"math/big"
    21  	"sort"
    22  	"strings"
    23  
    24  	"golang.org/x/tools/internal/typeparams"
    25  )
    26  
    27  type intReader struct {
    28  	*bytes.Reader
    29  	path string
    30  }
    31  
    32  func (r *intReader) int64() int64 {
    33  	i, err := binary.ReadVarint(r.Reader)
    34  	if err != nil {
    35  		errorf("import %q: read varint error: %v", r.path, err)
    36  	}
    37  	return i
    38  }
    39  
    40  func (r *intReader) uint64() uint64 {
    41  	i, err := binary.ReadUvarint(r.Reader)
    42  	if err != nil {
    43  		errorf("import %q: read varint error: %v", r.path, err)
    44  	}
    45  	return i
    46  }
    47  
    48  // Keep this in sync with constants in iexport.go.
    49  const (
    50  	iexportVersionGo1_11   = 0
    51  	iexportVersionPosCol   = 1
    52  	iexportVersionGo1_18   = 2
    53  	iexportVersionGenerics = 2
    54  
    55  	iexportVersionCurrent = 2
    56  )
    57  
    58  type ident struct {
    59  	pkg  *types.Package
    60  	name string
    61  }
    62  
    63  const predeclReserved = 32
    64  
    65  type itag uint64
    66  
    67  const (
    68  	// Types
    69  	definedType itag = iota
    70  	pointerType
    71  	sliceType
    72  	arrayType
    73  	chanType
    74  	mapType
    75  	signatureType
    76  	structType
    77  	interfaceType
    78  	typeParamType
    79  	instanceType
    80  	unionType
    81  )
    82  
    83  // IImportData imports a package from the serialized package data
    84  // and returns 0 and a reference to the package.
    85  // If the export data version is not recognized or the format is otherwise
    86  // compromised, an error is returned.
    87  func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (int, *types.Package, error) {
    88  	pkgs, err := iimportCommon(fset, imports, data, false, path, nil)
    89  	if err != nil {
    90  		return 0, nil, err
    91  	}
    92  	return 0, pkgs[0], nil
    93  }
    94  
    95  // IImportBundle imports a set of packages from the serialized package bundle.
    96  func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data []byte) ([]*types.Package, error) {
    97  	return iimportCommon(fset, imports, data, true, "", nil)
    98  }
    99  
   100  func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data []byte, bundle bool, path string, insert InsertType) (pkgs []*types.Package, err error) {
   101  	const currentVersion = iexportVersionCurrent
   102  	version := int64(-1)
   103  	if !debug {
   104  		defer func() {
   105  			if e := recover(); e != nil {
   106  				if bundle {
   107  					err = fmt.Errorf("%v", e)
   108  				} else if version > currentVersion {
   109  					err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
   110  				} else {
   111  					err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
   112  				}
   113  			}
   114  		}()
   115  	}
   116  
   117  	r := &intReader{bytes.NewReader(data), path}
   118  
   119  	if bundle {
   120  		bundleVersion := r.uint64()
   121  		switch bundleVersion {
   122  		case bundleVersion:
   123  		default:
   124  			errorf("unknown bundle format version %d", bundleVersion)
   125  		}
   126  	}
   127  
   128  	version = int64(r.uint64())
   129  	switch version {
   130  	case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11:
   131  	default:
   132  		if version > iexportVersionGo1_18 {
   133  			errorf("unstable iexport format version %d, just rebuild compiler and std library", version)
   134  		} else {
   135  			errorf("unknown iexport format version %d", version)
   136  		}
   137  	}
   138  
   139  	sLen := int64(r.uint64())
   140  	var fLen int64
   141  	var fileOffset []uint64
   142  	if insert != nil {
   143  		// Shallow mode uses a different position encoding.
   144  		fLen = int64(r.uint64())
   145  		fileOffset = make([]uint64, r.uint64())
   146  		for i := range fileOffset {
   147  			fileOffset[i] = r.uint64()
   148  		}
   149  	}
   150  	dLen := int64(r.uint64())
   151  
   152  	whence, _ := r.Seek(0, io.SeekCurrent)
   153  	stringData := data[whence : whence+sLen]
   154  	fileData := data[whence+sLen : whence+sLen+fLen]
   155  	declData := data[whence+sLen+fLen : whence+sLen+fLen+dLen]
   156  	r.Seek(sLen+fLen+dLen, io.SeekCurrent)
   157  
   158  	p := iimporter{
   159  		version: int(version),
   160  		ipath:   path,
   161  		insert:  insert,
   162  
   163  		stringData:  stringData,
   164  		stringCache: make(map[uint64]string),
   165  		fileOffset:  fileOffset,
   166  		fileData:    fileData,
   167  		fileCache:   make([]*token.File, len(fileOffset)),
   168  		pkgCache:    make(map[uint64]*types.Package),
   169  
   170  		declData: declData,
   171  		pkgIndex: make(map[*types.Package]map[string]uint64),
   172  		typCache: make(map[uint64]types.Type),
   173  		// Separate map for typeparams, keyed by their package and unique
   174  		// name.
   175  		tparamIndex: make(map[ident]types.Type),
   176  
   177  		fake: fakeFileSet{
   178  			fset:  fset,
   179  			files: make(map[string]*fileInfo),
   180  		},
   181  	}
   182  	defer p.fake.setLines() // set lines for files in fset
   183  
   184  	for i, pt := range predeclared() {
   185  		p.typCache[uint64(i)] = pt
   186  	}
   187  
   188  	pkgList := make([]*types.Package, r.uint64())
   189  	for i := range pkgList {
   190  		pkgPathOff := r.uint64()
   191  		pkgPath := p.stringAt(pkgPathOff)
   192  		pkgName := p.stringAt(r.uint64())
   193  		_ = r.uint64() // package height; unused by go/types
   194  
   195  		if pkgPath == "" {
   196  			pkgPath = path
   197  		}
   198  		pkg := imports[pkgPath]
   199  		if pkg == nil {
   200  			pkg = types.NewPackage(pkgPath, pkgName)
   201  			imports[pkgPath] = pkg
   202  		} else if pkg.Name() != pkgName {
   203  			errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path)
   204  		}
   205  		if i == 0 && !bundle {
   206  			p.localpkg = pkg
   207  		}
   208  
   209  		p.pkgCache[pkgPathOff] = pkg
   210  
   211  		// Read index for package.
   212  		nameIndex := make(map[string]uint64)
   213  		nSyms := r.uint64()
   214  		// In shallow mode we don't expect an index for other packages.
   215  		assert(nSyms == 0 || p.localpkg == pkg || p.insert == nil)
   216  		for ; nSyms > 0; nSyms-- {
   217  			name := p.stringAt(r.uint64())
   218  			nameIndex[name] = r.uint64()
   219  		}
   220  
   221  		p.pkgIndex[pkg] = nameIndex
   222  		pkgList[i] = pkg
   223  	}
   224  
   225  	if bundle {
   226  		pkgs = make([]*types.Package, r.uint64())
   227  		for i := range pkgs {
   228  			pkg := p.pkgAt(r.uint64())
   229  			imps := make([]*types.Package, r.uint64())
   230  			for j := range imps {
   231  				imps[j] = p.pkgAt(r.uint64())
   232  			}
   233  			pkg.SetImports(imps)
   234  			pkgs[i] = pkg
   235  		}
   236  	} else {
   237  		if len(pkgList) == 0 {
   238  			errorf("no packages found for %s", path)
   239  			panic("unreachable")
   240  		}
   241  		pkgs = pkgList[:1]
   242  
   243  		// record all referenced packages as imports
   244  		list := append(([]*types.Package)(nil), pkgList[1:]...)
   245  		sort.Sort(byPath(list))
   246  		pkgs[0].SetImports(list)
   247  	}
   248  
   249  	for _, pkg := range pkgs {
   250  		if pkg.Complete() {
   251  			continue
   252  		}
   253  
   254  		names := make([]string, 0, len(p.pkgIndex[pkg]))
   255  		for name := range p.pkgIndex[pkg] {
   256  			names = append(names, name)
   257  		}
   258  		sort.Strings(names)
   259  		for _, name := range names {
   260  			p.doDecl(pkg, name)
   261  		}
   262  
   263  		// package was imported completely and without errors
   264  		pkg.MarkComplete()
   265  	}
   266  
   267  	// SetConstraint can't be called if the constraint type is not yet complete.
   268  	// When type params are created in the 'P' case of (*importReader).obj(),
   269  	// the associated constraint type may not be complete due to recursion.
   270  	// Therefore, we defer calling SetConstraint there, and call it here instead
   271  	// after all types are complete.
   272  	for _, d := range p.later {
   273  		typeparams.SetTypeParamConstraint(d.t, d.constraint)
   274  	}
   275  
   276  	for _, typ := range p.interfaceList {
   277  		typ.Complete()
   278  	}
   279  
   280  	return pkgs, nil
   281  }
   282  
   283  type setConstraintArgs struct {
   284  	t          *typeparams.TypeParam
   285  	constraint types.Type
   286  }
   287  
   288  type iimporter struct {
   289  	version int
   290  	ipath   string
   291  
   292  	localpkg *types.Package
   293  	insert   func(pkg *types.Package, name string) // "shallow" mode only
   294  
   295  	stringData  []byte
   296  	stringCache map[uint64]string
   297  	fileOffset  []uint64 // fileOffset[i] is offset in fileData for info about file encoded as i
   298  	fileData    []byte
   299  	fileCache   []*token.File // memoized decoding of file encoded as i
   300  	pkgCache    map[uint64]*types.Package
   301  
   302  	declData    []byte
   303  	pkgIndex    map[*types.Package]map[string]uint64
   304  	typCache    map[uint64]types.Type
   305  	tparamIndex map[ident]types.Type
   306  
   307  	fake          fakeFileSet
   308  	interfaceList []*types.Interface
   309  
   310  	// Arguments for calls to SetConstraint that are deferred due to recursive types
   311  	later []setConstraintArgs
   312  
   313  	indent int // for tracing support
   314  }
   315  
   316  func (p *iimporter) trace(format string, args ...interface{}) {
   317  	if !trace {
   318  		// Call sites should also be guarded, but having this check here allows
   319  		// easily enabling/disabling debug trace statements.
   320  		return
   321  	}
   322  	fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...)
   323  }
   324  
   325  func (p *iimporter) doDecl(pkg *types.Package, name string) {
   326  	if debug {
   327  		p.trace("import decl %s", name)
   328  		p.indent++
   329  		defer func() {
   330  			p.indent--
   331  			p.trace("=> %s", name)
   332  		}()
   333  	}
   334  	// See if we've already imported this declaration.
   335  	if obj := pkg.Scope().Lookup(name); obj != nil {
   336  		return
   337  	}
   338  
   339  	off, ok := p.pkgIndex[pkg][name]
   340  	if !ok {
   341  		// In "shallow" mode, call back to the application to
   342  		// find the object and insert it into the package scope.
   343  		if p.insert != nil {
   344  			assert(pkg != p.localpkg)
   345  			p.insert(pkg, name) // "can't fail"
   346  			return
   347  		}
   348  		errorf("%v.%v not in index", pkg, name)
   349  	}
   350  
   351  	r := &importReader{p: p, currPkg: pkg}
   352  	r.declReader.Reset(p.declData[off:])
   353  
   354  	r.obj(name)
   355  }
   356  
   357  func (p *iimporter) stringAt(off uint64) string {
   358  	if s, ok := p.stringCache[off]; ok {
   359  		return s
   360  	}
   361  
   362  	slen, n := binary.Uvarint(p.stringData[off:])
   363  	if n <= 0 {
   364  		errorf("varint failed")
   365  	}
   366  	spos := off + uint64(n)
   367  	s := string(p.stringData[spos : spos+slen])
   368  	p.stringCache[off] = s
   369  	return s
   370  }
   371  
   372  func (p *iimporter) fileAt(index uint64) *token.File {
   373  	file := p.fileCache[index]
   374  	if file == nil {
   375  		off := p.fileOffset[index]
   376  		file = p.decodeFile(intReader{bytes.NewReader(p.fileData[off:]), p.ipath})
   377  		p.fileCache[index] = file
   378  	}
   379  	return file
   380  }
   381  
   382  func (p *iimporter) decodeFile(rd intReader) *token.File {
   383  	filename := p.stringAt(rd.uint64())
   384  	size := int(rd.uint64())
   385  	file := p.fake.fset.AddFile(filename, -1, size)
   386  
   387  	// SetLines requires a nondecreasing sequence.
   388  	// Because it is common for clients to derive the interval
   389  	// [start, start+len(name)] from a start position, and we
   390  	// want to ensure that the end offset is on the same line,
   391  	// we fill in the gaps of the sparse encoding with values
   392  	// that strictly increase by the largest possible amount.
   393  	// This allows us to avoid having to record the actual end
   394  	// offset of each needed line.
   395  
   396  	lines := make([]int, int(rd.uint64()))
   397  	var index, offset int
   398  	for i, n := 0, int(rd.uint64()); i < n; i++ {
   399  		index += int(rd.uint64())
   400  		offset += int(rd.uint64())
   401  		lines[index] = offset
   402  
   403  		// Ensure monotonicity between points.
   404  		for j := index - 1; j > 0 && lines[j] == 0; j-- {
   405  			lines[j] = lines[j+1] - 1
   406  		}
   407  	}
   408  
   409  	// Ensure monotonicity after last point.
   410  	for j := len(lines) - 1; j > 0 && lines[j] == 0; j-- {
   411  		size--
   412  		lines[j] = size
   413  	}
   414  
   415  	if !file.SetLines(lines) {
   416  		errorf("SetLines failed: %d", lines) // can't happen
   417  	}
   418  	return file
   419  }
   420  
   421  func (p *iimporter) pkgAt(off uint64) *types.Package {
   422  	if pkg, ok := p.pkgCache[off]; ok {
   423  		return pkg
   424  	}
   425  	path := p.stringAt(off)
   426  	errorf("missing package %q in %q", path, p.ipath)
   427  	return nil
   428  }
   429  
   430  func (p *iimporter) typAt(off uint64, base *types.Named) types.Type {
   431  	if t, ok := p.typCache[off]; ok && canReuse(base, t) {
   432  		return t
   433  	}
   434  
   435  	if off < predeclReserved {
   436  		errorf("predeclared type missing from cache: %v", off)
   437  	}
   438  
   439  	r := &importReader{p: p}
   440  	r.declReader.Reset(p.declData[off-predeclReserved:])
   441  	t := r.doType(base)
   442  
   443  	if canReuse(base, t) {
   444  		p.typCache[off] = t
   445  	}
   446  	return t
   447  }
   448  
   449  // canReuse reports whether the type rhs on the RHS of the declaration for def
   450  // may be re-used.
   451  //
   452  // Specifically, if def is non-nil and rhs is an interface type with methods, it
   453  // may not be re-used because we have a convention of setting the receiver type
   454  // for interface methods to def.
   455  func canReuse(def *types.Named, rhs types.Type) bool {
   456  	if def == nil {
   457  		return true
   458  	}
   459  	iface, _ := rhs.(*types.Interface)
   460  	if iface == nil {
   461  		return true
   462  	}
   463  	// Don't use iface.Empty() here as iface may not be complete.
   464  	return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0
   465  }
   466  
   467  type importReader struct {
   468  	p          *iimporter
   469  	declReader bytes.Reader
   470  	currPkg    *types.Package
   471  	prevFile   string
   472  	prevLine   int64
   473  	prevColumn int64
   474  }
   475  
   476  func (r *importReader) obj(name string) {
   477  	tag := r.byte()
   478  	pos := r.pos()
   479  
   480  	switch tag {
   481  	case 'A':
   482  		typ := r.typ()
   483  
   484  		r.declare(types.NewTypeName(pos, r.currPkg, name, typ))
   485  
   486  	case 'C':
   487  		typ, val := r.value()
   488  
   489  		r.declare(types.NewConst(pos, r.currPkg, name, typ, val))
   490  
   491  	case 'F', 'G':
   492  		var tparams []*typeparams.TypeParam
   493  		if tag == 'G' {
   494  			tparams = r.tparamList()
   495  		}
   496  		sig := r.signature(nil, nil, tparams)
   497  		r.declare(types.NewFunc(pos, r.currPkg, name, sig))
   498  
   499  	case 'T', 'U':
   500  		// Types can be recursive. We need to setup a stub
   501  		// declaration before recursing.
   502  		obj := types.NewTypeName(pos, r.currPkg, name, nil)
   503  		named := types.NewNamed(obj, nil, nil)
   504  		// Declare obj before calling r.tparamList, so the new type name is recognized
   505  		// if used in the constraint of one of its own typeparams (see #48280).
   506  		r.declare(obj)
   507  		if tag == 'U' {
   508  			tparams := r.tparamList()
   509  			typeparams.SetForNamed(named, tparams)
   510  		}
   511  
   512  		underlying := r.p.typAt(r.uint64(), named).Underlying()
   513  		named.SetUnderlying(underlying)
   514  
   515  		if !isInterface(underlying) {
   516  			for n := r.uint64(); n > 0; n-- {
   517  				mpos := r.pos()
   518  				mname := r.ident()
   519  				recv := r.param()
   520  
   521  				// If the receiver has any targs, set those as the
   522  				// rparams of the method (since those are the
   523  				// typeparams being used in the method sig/body).
   524  				base := baseType(recv.Type())
   525  				assert(base != nil)
   526  				targs := typeparams.NamedTypeArgs(base)
   527  				var rparams []*typeparams.TypeParam
   528  				if targs.Len() > 0 {
   529  					rparams = make([]*typeparams.TypeParam, targs.Len())
   530  					for i := range rparams {
   531  						rparams[i] = targs.At(i).(*typeparams.TypeParam)
   532  					}
   533  				}
   534  				msig := r.signature(recv, rparams, nil)
   535  
   536  				named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig))
   537  			}
   538  		}
   539  
   540  	case 'P':
   541  		// We need to "declare" a typeparam in order to have a name that
   542  		// can be referenced recursively (if needed) in the type param's
   543  		// bound.
   544  		if r.p.version < iexportVersionGenerics {
   545  			errorf("unexpected type param type")
   546  		}
   547  		name0 := tparamName(name)
   548  		tn := types.NewTypeName(pos, r.currPkg, name0, nil)
   549  		t := typeparams.NewTypeParam(tn, nil)
   550  
   551  		// To handle recursive references to the typeparam within its
   552  		// bound, save the partial type in tparamIndex before reading the bounds.
   553  		id := ident{r.currPkg, name}
   554  		r.p.tparamIndex[id] = t
   555  		var implicit bool
   556  		if r.p.version >= iexportVersionGo1_18 {
   557  			implicit = r.bool()
   558  		}
   559  		constraint := r.typ()
   560  		if implicit {
   561  			iface, _ := constraint.(*types.Interface)
   562  			if iface == nil {
   563  				errorf("non-interface constraint marked implicit")
   564  			}
   565  			typeparams.MarkImplicit(iface)
   566  		}
   567  		// The constraint type may not be complete, if we
   568  		// are in the middle of a type recursion involving type
   569  		// constraints. So, we defer SetConstraint until we have
   570  		// completely set up all types in ImportData.
   571  		r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint})
   572  
   573  	case 'V':
   574  		typ := r.typ()
   575  
   576  		r.declare(types.NewVar(pos, r.currPkg, name, typ))
   577  
   578  	default:
   579  		errorf("unexpected tag: %v", tag)
   580  	}
   581  }
   582  
   583  func (r *importReader) declare(obj types.Object) {
   584  	obj.Pkg().Scope().Insert(obj)
   585  }
   586  
   587  func (r *importReader) value() (typ types.Type, val constant.Value) {
   588  	typ = r.typ()
   589  	if r.p.version >= iexportVersionGo1_18 {
   590  		// TODO: add support for using the kind.
   591  		_ = constant.Kind(r.int64())
   592  	}
   593  
   594  	switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
   595  	case types.IsBoolean:
   596  		val = constant.MakeBool(r.bool())
   597  
   598  	case types.IsString:
   599  		val = constant.MakeString(r.string())
   600  
   601  	case types.IsInteger:
   602  		var x big.Int
   603  		r.mpint(&x, b)
   604  		val = constant.Make(&x)
   605  
   606  	case types.IsFloat:
   607  		val = r.mpfloat(b)
   608  
   609  	case types.IsComplex:
   610  		re := r.mpfloat(b)
   611  		im := r.mpfloat(b)
   612  		val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
   613  
   614  	default:
   615  		if b.Kind() == types.Invalid {
   616  			val = constant.MakeUnknown()
   617  			return
   618  		}
   619  		errorf("unexpected type %v", typ) // panics
   620  		panic("unreachable")
   621  	}
   622  
   623  	return
   624  }
   625  
   626  func intSize(b *types.Basic) (signed bool, maxBytes uint) {
   627  	if (b.Info() & types.IsUntyped) != 0 {
   628  		return true, 64
   629  	}
   630  
   631  	switch b.Kind() {
   632  	case types.Float32, types.Complex64:
   633  		return true, 3
   634  	case types.Float64, types.Complex128:
   635  		return true, 7
   636  	}
   637  
   638  	signed = (b.Info() & types.IsUnsigned) == 0
   639  	switch b.Kind() {
   640  	case types.Int8, types.Uint8:
   641  		maxBytes = 1
   642  	case types.Int16, types.Uint16:
   643  		maxBytes = 2
   644  	case types.Int32, types.Uint32:
   645  		maxBytes = 4
   646  	default:
   647  		maxBytes = 8
   648  	}
   649  
   650  	return
   651  }
   652  
   653  func (r *importReader) mpint(x *big.Int, typ *types.Basic) {
   654  	signed, maxBytes := intSize(typ)
   655  
   656  	maxSmall := 256 - maxBytes
   657  	if signed {
   658  		maxSmall = 256 - 2*maxBytes
   659  	}
   660  	if maxBytes == 1 {
   661  		maxSmall = 256
   662  	}
   663  
   664  	n, _ := r.declReader.ReadByte()
   665  	if uint(n) < maxSmall {
   666  		v := int64(n)
   667  		if signed {
   668  			v >>= 1
   669  			if n&1 != 0 {
   670  				v = ^v
   671  			}
   672  		}
   673  		x.SetInt64(v)
   674  		return
   675  	}
   676  
   677  	v := -n
   678  	if signed {
   679  		v = -(n &^ 1) >> 1
   680  	}
   681  	if v < 1 || uint(v) > maxBytes {
   682  		errorf("weird decoding: %v, %v => %v", n, signed, v)
   683  	}
   684  	b := make([]byte, v)
   685  	io.ReadFull(&r.declReader, b)
   686  	x.SetBytes(b)
   687  	if signed && n&1 != 0 {
   688  		x.Neg(x)
   689  	}
   690  }
   691  
   692  func (r *importReader) mpfloat(typ *types.Basic) constant.Value {
   693  	var mant big.Int
   694  	r.mpint(&mant, typ)
   695  	var f big.Float
   696  	f.SetInt(&mant)
   697  	if f.Sign() != 0 {
   698  		f.SetMantExp(&f, int(r.int64()))
   699  	}
   700  	return constant.Make(&f)
   701  }
   702  
   703  func (r *importReader) ident() string {
   704  	return r.string()
   705  }
   706  
   707  func (r *importReader) qualifiedIdent() (*types.Package, string) {
   708  	name := r.string()
   709  	pkg := r.pkg()
   710  	return pkg, name
   711  }
   712  
   713  func (r *importReader) pos() token.Pos {
   714  	if r.p.insert != nil { // shallow mode
   715  		return r.posv2()
   716  	}
   717  	if r.p.version >= iexportVersionPosCol {
   718  		r.posv1()
   719  	} else {
   720  		r.posv0()
   721  	}
   722  
   723  	if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 {
   724  		return token.NoPos
   725  	}
   726  	return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn))
   727  }
   728  
   729  func (r *importReader) posv0() {
   730  	delta := r.int64()
   731  	if delta != deltaNewFile {
   732  		r.prevLine += delta
   733  	} else if l := r.int64(); l == -1 {
   734  		r.prevLine += deltaNewFile
   735  	} else {
   736  		r.prevFile = r.string()
   737  		r.prevLine = l
   738  	}
   739  }
   740  
   741  func (r *importReader) posv1() {
   742  	delta := r.int64()
   743  	r.prevColumn += delta >> 1
   744  	if delta&1 != 0 {
   745  		delta = r.int64()
   746  		r.prevLine += delta >> 1
   747  		if delta&1 != 0 {
   748  			r.prevFile = r.string()
   749  		}
   750  	}
   751  }
   752  
   753  func (r *importReader) posv2() token.Pos {
   754  	file := r.uint64()
   755  	if file == 0 {
   756  		return token.NoPos
   757  	}
   758  	tf := r.p.fileAt(file - 1)
   759  	return tf.Pos(int(r.uint64()))
   760  }
   761  
   762  func (r *importReader) typ() types.Type {
   763  	return r.p.typAt(r.uint64(), nil)
   764  }
   765  
   766  func isInterface(t types.Type) bool {
   767  	_, ok := t.(*types.Interface)
   768  	return ok
   769  }
   770  
   771  func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) }
   772  func (r *importReader) string() string      { return r.p.stringAt(r.uint64()) }
   773  
   774  func (r *importReader) doType(base *types.Named) (res types.Type) {
   775  	k := r.kind()
   776  	if debug {
   777  		r.p.trace("importing type %d (base: %s)", k, base)
   778  		r.p.indent++
   779  		defer func() {
   780  			r.p.indent--
   781  			r.p.trace("=> %s", res)
   782  		}()
   783  	}
   784  	switch k {
   785  	default:
   786  		errorf("unexpected kind tag in %q: %v", r.p.ipath, k)
   787  		return nil
   788  
   789  	case definedType:
   790  		pkg, name := r.qualifiedIdent()
   791  		r.p.doDecl(pkg, name)
   792  		return pkg.Scope().Lookup(name).(*types.TypeName).Type()
   793  	case pointerType:
   794  		return types.NewPointer(r.typ())
   795  	case sliceType:
   796  		return types.NewSlice(r.typ())
   797  	case arrayType:
   798  		n := r.uint64()
   799  		return types.NewArray(r.typ(), int64(n))
   800  	case chanType:
   801  		dir := chanDir(int(r.uint64()))
   802  		return types.NewChan(dir, r.typ())
   803  	case mapType:
   804  		return types.NewMap(r.typ(), r.typ())
   805  	case signatureType:
   806  		r.currPkg = r.pkg()
   807  		return r.signature(nil, nil, nil)
   808  
   809  	case structType:
   810  		r.currPkg = r.pkg()
   811  
   812  		fields := make([]*types.Var, r.uint64())
   813  		tags := make([]string, len(fields))
   814  		for i := range fields {
   815  			fpos := r.pos()
   816  			fname := r.ident()
   817  			ftyp := r.typ()
   818  			emb := r.bool()
   819  			tag := r.string()
   820  
   821  			fields[i] = types.NewField(fpos, r.currPkg, fname, ftyp, emb)
   822  			tags[i] = tag
   823  		}
   824  		return types.NewStruct(fields, tags)
   825  
   826  	case interfaceType:
   827  		r.currPkg = r.pkg()
   828  
   829  		embeddeds := make([]types.Type, r.uint64())
   830  		for i := range embeddeds {
   831  			_ = r.pos()
   832  			embeddeds[i] = r.typ()
   833  		}
   834  
   835  		methods := make([]*types.Func, r.uint64())
   836  		for i := range methods {
   837  			mpos := r.pos()
   838  			mname := r.ident()
   839  
   840  			// TODO(mdempsky): Matches bimport.go, but I
   841  			// don't agree with this.
   842  			var recv *types.Var
   843  			if base != nil {
   844  				recv = types.NewVar(token.NoPos, r.currPkg, "", base)
   845  			}
   846  
   847  			msig := r.signature(recv, nil, nil)
   848  			methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig)
   849  		}
   850  
   851  		typ := newInterface(methods, embeddeds)
   852  		r.p.interfaceList = append(r.p.interfaceList, typ)
   853  		return typ
   854  
   855  	case typeParamType:
   856  		if r.p.version < iexportVersionGenerics {
   857  			errorf("unexpected type param type")
   858  		}
   859  		pkg, name := r.qualifiedIdent()
   860  		id := ident{pkg, name}
   861  		if t, ok := r.p.tparamIndex[id]; ok {
   862  			// We're already in the process of importing this typeparam.
   863  			return t
   864  		}
   865  		// Otherwise, import the definition of the typeparam now.
   866  		r.p.doDecl(pkg, name)
   867  		return r.p.tparamIndex[id]
   868  
   869  	case instanceType:
   870  		if r.p.version < iexportVersionGenerics {
   871  			errorf("unexpected instantiation type")
   872  		}
   873  		// pos does not matter for instances: they are positioned on the original
   874  		// type.
   875  		_ = r.pos()
   876  		len := r.uint64()
   877  		targs := make([]types.Type, len)
   878  		for i := range targs {
   879  			targs[i] = r.typ()
   880  		}
   881  		baseType := r.typ()
   882  		// The imported instantiated type doesn't include any methods, so
   883  		// we must always use the methods of the base (orig) type.
   884  		// TODO provide a non-nil *Environment
   885  		t, _ := typeparams.Instantiate(nil, baseType, targs, false)
   886  		return t
   887  
   888  	case unionType:
   889  		if r.p.version < iexportVersionGenerics {
   890  			errorf("unexpected instantiation type")
   891  		}
   892  		terms := make([]*typeparams.Term, r.uint64())
   893  		for i := range terms {
   894  			terms[i] = typeparams.NewTerm(r.bool(), r.typ())
   895  		}
   896  		return typeparams.NewUnion(terms)
   897  	}
   898  }
   899  
   900  func (r *importReader) kind() itag {
   901  	return itag(r.uint64())
   902  }
   903  
   904  func (r *importReader) signature(recv *types.Var, rparams []*typeparams.TypeParam, tparams []*typeparams.TypeParam) *types.Signature {
   905  	params := r.paramList()
   906  	results := r.paramList()
   907  	variadic := params.Len() > 0 && r.bool()
   908  	return typeparams.NewSignatureType(recv, rparams, tparams, params, results, variadic)
   909  }
   910  
   911  func (r *importReader) tparamList() []*typeparams.TypeParam {
   912  	n := r.uint64()
   913  	if n == 0 {
   914  		return nil
   915  	}
   916  	xs := make([]*typeparams.TypeParam, n)
   917  	for i := range xs {
   918  		// Note: the standard library importer is tolerant of nil types here,
   919  		// though would panic in SetTypeParams.
   920  		xs[i] = r.typ().(*typeparams.TypeParam)
   921  	}
   922  	return xs
   923  }
   924  
   925  func (r *importReader) paramList() *types.Tuple {
   926  	xs := make([]*types.Var, r.uint64())
   927  	for i := range xs {
   928  		xs[i] = r.param()
   929  	}
   930  	return types.NewTuple(xs...)
   931  }
   932  
   933  func (r *importReader) param() *types.Var {
   934  	pos := r.pos()
   935  	name := r.ident()
   936  	typ := r.typ()
   937  	return types.NewParam(pos, r.currPkg, name, typ)
   938  }
   939  
   940  func (r *importReader) bool() bool {
   941  	return r.uint64() != 0
   942  }
   943  
   944  func (r *importReader) int64() int64 {
   945  	n, err := binary.ReadVarint(&r.declReader)
   946  	if err != nil {
   947  		errorf("readVarint: %v", err)
   948  	}
   949  	return n
   950  }
   951  
   952  func (r *importReader) uint64() uint64 {
   953  	n, err := binary.ReadUvarint(&r.declReader)
   954  	if err != nil {
   955  		errorf("readUvarint: %v", err)
   956  	}
   957  	return n
   958  }
   959  
   960  func (r *importReader) byte() byte {
   961  	x, err := r.declReader.ReadByte()
   962  	if err != nil {
   963  		errorf("declReader.ReadByte: %v", err)
   964  	}
   965  	return x
   966  }
   967  
   968  func baseType(typ types.Type) *types.Named {
   969  	// pointer receivers are never types.Named types
   970  	if p, _ := typ.(*types.Pointer); p != nil {
   971  		typ = p.Elem()
   972  	}
   973  	// receiver base types are always (possibly generic) types.Named types
   974  	n, _ := typ.(*types.Named)
   975  	return n
   976  }