cuelang.org/go@v0.10.1/internal/golangorgx/tools/gcimporter/iexport.go (about)

     1  // Copyright 2019 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 binary package export.
     6  // This file was derived from $GOROOT/src/cmd/compile/internal/gc/iexport.go;
     7  // see that file for specification of the format.
     8  
     9  package gcimporter
    10  
    11  import (
    12  	"bytes"
    13  	"encoding/binary"
    14  	"fmt"
    15  	"go/constant"
    16  	"go/token"
    17  	"go/types"
    18  	"io"
    19  	"math/big"
    20  	"reflect"
    21  	"sort"
    22  	"strconv"
    23  	"strings"
    24  
    25  	"cuelang.org/go/internal/golangorgx/tools/tokeninternal"
    26  	"golang.org/x/tools/go/types/objectpath"
    27  )
    28  
    29  // IExportShallow encodes "shallow" export data for the specified package.
    30  //
    31  // No promises are made about the encoding other than that it can be decoded by
    32  // the same version of IIExportShallow. If you plan to save export data in the
    33  // file system, be sure to include a cryptographic digest of the executable in
    34  // the key to avoid version skew.
    35  //
    36  // If the provided reportf func is non-nil, it will be used for reporting bugs
    37  // encountered during export.
    38  // TODO(rfindley): remove reportf when we are confident enough in the new
    39  // objectpath encoding.
    40  func IExportShallow(fset *token.FileSet, pkg *types.Package, reportf ReportFunc) ([]byte, error) {
    41  	// In principle this operation can only fail if out.Write fails,
    42  	// but that's impossible for bytes.Buffer---and as a matter of
    43  	// fact iexportCommon doesn't even check for I/O errors.
    44  	// TODO(adonovan): handle I/O errors properly.
    45  	// TODO(adonovan): use byte slices throughout, avoiding copying.
    46  	const bundle, shallow = false, true
    47  	var out bytes.Buffer
    48  	err := iexportCommon(&out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg})
    49  	return out.Bytes(), err
    50  }
    51  
    52  // IImportShallow decodes "shallow" types.Package data encoded by
    53  // IExportShallow in the same executable. This function cannot import data from
    54  // cmd/compile or gcexportdata.Write.
    55  //
    56  // The importer calls getPackages to obtain package symbols for all
    57  // packages mentioned in the export data, including the one being
    58  // decoded.
    59  //
    60  // If the provided reportf func is non-nil, it will be used for reporting bugs
    61  // encountered during import.
    62  // TODO(rfindley): remove reportf when we are confident enough in the new
    63  // objectpath encoding.
    64  func IImportShallow(fset *token.FileSet, getPackages GetPackagesFunc, data []byte, path string, reportf ReportFunc) (*types.Package, error) {
    65  	const bundle = false
    66  	const shallow = true
    67  	pkgs, err := iimportCommon(fset, getPackages, data, bundle, path, shallow, reportf)
    68  	if err != nil {
    69  		return nil, err
    70  	}
    71  	return pkgs[0], nil
    72  }
    73  
    74  // ReportFunc is the type of a function used to report formatted bugs.
    75  type ReportFunc = func(string, ...interface{})
    76  
    77  // Current bundled export format version. Increase with each format change.
    78  // 0: initial implementation
    79  const bundleVersion = 0
    80  
    81  // IExportData writes indexed export data for pkg to out.
    82  //
    83  // If no file set is provided, position info will be missing.
    84  // The package path of the top-level package will not be recorded,
    85  // so that calls to IImportData can override with a provided package path.
    86  func IExportData(out io.Writer, fset *token.FileSet, pkg *types.Package) error {
    87  	const bundle, shallow = false, false
    88  	return iexportCommon(out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg})
    89  }
    90  
    91  // IExportBundle writes an indexed export bundle for pkgs to out.
    92  func IExportBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error {
    93  	const bundle, shallow = true, false
    94  	return iexportCommon(out, fset, bundle, shallow, iexportVersion, pkgs)
    95  }
    96  
    97  func iexportCommon(out io.Writer, fset *token.FileSet, bundle, shallow bool, version int, pkgs []*types.Package) (err error) {
    98  	if !debug {
    99  		defer func() {
   100  			if e := recover(); e != nil {
   101  				if ierr, ok := e.(internalError); ok {
   102  					err = ierr
   103  					return
   104  				}
   105  				// Not an internal error; panic again.
   106  				panic(e)
   107  			}
   108  		}()
   109  	}
   110  
   111  	p := iexporter{
   112  		fset:        fset,
   113  		version:     version,
   114  		shallow:     shallow,
   115  		allPkgs:     map[*types.Package]bool{},
   116  		stringIndex: map[string]uint64{},
   117  		declIndex:   map[types.Object]uint64{},
   118  		tparamNames: map[types.Object]string{},
   119  		typIndex:    map[types.Type]uint64{},
   120  	}
   121  	if !bundle {
   122  		p.localpkg = pkgs[0]
   123  	}
   124  
   125  	for i, pt := range predeclared() {
   126  		p.typIndex[pt] = uint64(i)
   127  	}
   128  	if len(p.typIndex) > predeclReserved {
   129  		panic(internalErrorf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved))
   130  	}
   131  
   132  	// Initialize work queue with exported declarations.
   133  	for _, pkg := range pkgs {
   134  		scope := pkg.Scope()
   135  		for _, name := range scope.Names() {
   136  			if token.IsExported(name) {
   137  				p.pushDecl(scope.Lookup(name))
   138  			}
   139  		}
   140  
   141  		if bundle {
   142  			// Ensure pkg and its imports are included in the index.
   143  			p.allPkgs[pkg] = true
   144  			for _, imp := range pkg.Imports() {
   145  				p.allPkgs[imp] = true
   146  			}
   147  		}
   148  	}
   149  
   150  	// Loop until no more work.
   151  	for !p.declTodo.empty() {
   152  		p.doDecl(p.declTodo.popHead())
   153  	}
   154  
   155  	// Produce index of offset of each file record in files.
   156  	var files intWriter
   157  	var fileOffset []uint64 // fileOffset[i] is offset in files of file encoded as i
   158  	if p.shallow {
   159  		fileOffset = make([]uint64, len(p.fileInfos))
   160  		for i, info := range p.fileInfos {
   161  			fileOffset[i] = uint64(files.Len())
   162  			p.encodeFile(&files, info.file, info.needed)
   163  		}
   164  	}
   165  
   166  	// Append indices to data0 section.
   167  	dataLen := uint64(p.data0.Len())
   168  	w := p.newWriter()
   169  	w.writeIndex(p.declIndex)
   170  
   171  	if bundle {
   172  		w.uint64(uint64(len(pkgs)))
   173  		for _, pkg := range pkgs {
   174  			w.pkg(pkg)
   175  			imps := pkg.Imports()
   176  			w.uint64(uint64(len(imps)))
   177  			for _, imp := range imps {
   178  				w.pkg(imp)
   179  			}
   180  		}
   181  	}
   182  	w.flush()
   183  
   184  	// Assemble header.
   185  	var hdr intWriter
   186  	if bundle {
   187  		hdr.uint64(bundleVersion)
   188  	}
   189  	hdr.uint64(uint64(p.version))
   190  	hdr.uint64(uint64(p.strings.Len()))
   191  	if p.shallow {
   192  		hdr.uint64(uint64(files.Len()))
   193  		hdr.uint64(uint64(len(fileOffset)))
   194  		for _, offset := range fileOffset {
   195  			hdr.uint64(offset)
   196  		}
   197  	}
   198  	hdr.uint64(dataLen)
   199  
   200  	// Flush output.
   201  	io.Copy(out, &hdr)
   202  	io.Copy(out, &p.strings)
   203  	if p.shallow {
   204  		io.Copy(out, &files)
   205  	}
   206  	io.Copy(out, &p.data0)
   207  
   208  	return nil
   209  }
   210  
   211  // encodeFile writes to w a representation of the file sufficient to
   212  // faithfully restore position information about all needed offsets.
   213  // Mutates the needed array.
   214  func (p *iexporter) encodeFile(w *intWriter, file *token.File, needed []uint64) {
   215  	_ = needed[0] // precondition: needed is non-empty
   216  
   217  	w.uint64(p.stringOff(file.Name()))
   218  
   219  	size := uint64(file.Size())
   220  	w.uint64(size)
   221  
   222  	// Sort the set of needed offsets. Duplicates are harmless.
   223  	sort.Slice(needed, func(i, j int) bool { return needed[i] < needed[j] })
   224  
   225  	lines := tokeninternal.GetLines(file) // byte offset of each line start
   226  	w.uint64(uint64(len(lines)))
   227  
   228  	// Rather than record the entire array of line start offsets,
   229  	// we save only a sparse list of (index, offset) pairs for
   230  	// the start of each line that contains a needed position.
   231  	var sparse [][2]int // (index, offset) pairs
   232  outer:
   233  	for i, lineStart := range lines {
   234  		lineEnd := size
   235  		if i < len(lines)-1 {
   236  			lineEnd = uint64(lines[i+1])
   237  		}
   238  		// Does this line contains a needed offset?
   239  		if needed[0] < lineEnd {
   240  			sparse = append(sparse, [2]int{i, lineStart})
   241  			for needed[0] < lineEnd {
   242  				needed = needed[1:]
   243  				if len(needed) == 0 {
   244  					break outer
   245  				}
   246  			}
   247  		}
   248  	}
   249  
   250  	// Delta-encode the columns.
   251  	w.uint64(uint64(len(sparse)))
   252  	var prev [2]int
   253  	for _, pair := range sparse {
   254  		w.uint64(uint64(pair[0] - prev[0]))
   255  		w.uint64(uint64(pair[1] - prev[1]))
   256  		prev = pair
   257  	}
   258  }
   259  
   260  // writeIndex writes out an object index. mainIndex indicates whether
   261  // we're writing out the main index, which is also read by
   262  // non-compiler tools and includes a complete package description
   263  // (i.e., name and height).
   264  func (w *exportWriter) writeIndex(index map[types.Object]uint64) {
   265  	type pkgObj struct {
   266  		obj  types.Object
   267  		name string // qualified name; differs from obj.Name for type params
   268  	}
   269  	// Build a map from packages to objects from that package.
   270  	pkgObjs := map[*types.Package][]pkgObj{}
   271  
   272  	// For the main index, make sure to include every package that
   273  	// we reference, even if we're not exporting (or reexporting)
   274  	// any symbols from it.
   275  	if w.p.localpkg != nil {
   276  		pkgObjs[w.p.localpkg] = nil
   277  	}
   278  	for pkg := range w.p.allPkgs {
   279  		pkgObjs[pkg] = nil
   280  	}
   281  
   282  	for obj := range index {
   283  		name := w.p.exportName(obj)
   284  		pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], pkgObj{obj, name})
   285  	}
   286  
   287  	var pkgs []*types.Package
   288  	for pkg, objs := range pkgObjs {
   289  		pkgs = append(pkgs, pkg)
   290  
   291  		sort.Slice(objs, func(i, j int) bool {
   292  			return objs[i].name < objs[j].name
   293  		})
   294  	}
   295  
   296  	sort.Slice(pkgs, func(i, j int) bool {
   297  		return w.exportPath(pkgs[i]) < w.exportPath(pkgs[j])
   298  	})
   299  
   300  	w.uint64(uint64(len(pkgs)))
   301  	for _, pkg := range pkgs {
   302  		w.string(w.exportPath(pkg))
   303  		w.string(pkg.Name())
   304  		w.uint64(uint64(0)) // package height is not needed for go/types
   305  
   306  		objs := pkgObjs[pkg]
   307  		w.uint64(uint64(len(objs)))
   308  		for _, obj := range objs {
   309  			w.string(obj.name)
   310  			w.uint64(index[obj.obj])
   311  		}
   312  	}
   313  }
   314  
   315  // exportName returns the 'exported' name of an object. It differs from
   316  // obj.Name() only for type parameters (see tparamExportName for details).
   317  func (p *iexporter) exportName(obj types.Object) (res string) {
   318  	if name := p.tparamNames[obj]; name != "" {
   319  		return name
   320  	}
   321  	return obj.Name()
   322  }
   323  
   324  type iexporter struct {
   325  	fset    *token.FileSet
   326  	out     *bytes.Buffer
   327  	version int
   328  
   329  	shallow    bool                // don't put types from other packages in the index
   330  	objEncoder *objectpath.Encoder // encodes objects from other packages in shallow mode; lazily allocated
   331  	localpkg   *types.Package      // (nil in bundle mode)
   332  
   333  	// allPkgs tracks all packages that have been referenced by
   334  	// the export data, so we can ensure to include them in the
   335  	// main index.
   336  	allPkgs map[*types.Package]bool
   337  
   338  	declTodo objQueue
   339  
   340  	strings     intWriter
   341  	stringIndex map[string]uint64
   342  
   343  	// In shallow mode, object positions are encoded as (file, offset).
   344  	// Each file is recorded as a line-number table.
   345  	// Only the lines of needed positions are saved faithfully.
   346  	fileInfo  map[*token.File]uint64 // value is index in fileInfos
   347  	fileInfos []*filePositions
   348  
   349  	data0       intWriter
   350  	declIndex   map[types.Object]uint64
   351  	tparamNames map[types.Object]string // typeparam->exported name
   352  	typIndex    map[types.Type]uint64
   353  
   354  	indent int // for tracing support
   355  }
   356  
   357  type filePositions struct {
   358  	file   *token.File
   359  	needed []uint64 // unordered list of needed file offsets
   360  }
   361  
   362  func (p *iexporter) trace(format string, args ...interface{}) {
   363  	if !trace {
   364  		// Call sites should also be guarded, but having this check here allows
   365  		// easily enabling/disabling debug trace statements.
   366  		return
   367  	}
   368  	fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...)
   369  }
   370  
   371  // objectpathEncoder returns the lazily allocated objectpath.Encoder to use
   372  // when encoding objects in other packages during shallow export.
   373  //
   374  // Using a shared Encoder amortizes some of cost of objectpath search.
   375  func (p *iexporter) objectpathEncoder() *objectpath.Encoder {
   376  	if p.objEncoder == nil {
   377  		p.objEncoder = new(objectpath.Encoder)
   378  	}
   379  	return p.objEncoder
   380  }
   381  
   382  // stringOff returns the offset of s within the string section.
   383  // If not already present, it's added to the end.
   384  func (p *iexporter) stringOff(s string) uint64 {
   385  	off, ok := p.stringIndex[s]
   386  	if !ok {
   387  		off = uint64(p.strings.Len())
   388  		p.stringIndex[s] = off
   389  
   390  		p.strings.uint64(uint64(len(s)))
   391  		p.strings.WriteString(s)
   392  	}
   393  	return off
   394  }
   395  
   396  // fileIndexAndOffset returns the index of the token.File and the byte offset of pos within it.
   397  func (p *iexporter) fileIndexAndOffset(file *token.File, pos token.Pos) (uint64, uint64) {
   398  	index, ok := p.fileInfo[file]
   399  	if !ok {
   400  		index = uint64(len(p.fileInfo))
   401  		p.fileInfos = append(p.fileInfos, &filePositions{file: file})
   402  		if p.fileInfo == nil {
   403  			p.fileInfo = make(map[*token.File]uint64)
   404  		}
   405  		p.fileInfo[file] = index
   406  	}
   407  	// Record each needed offset.
   408  	info := p.fileInfos[index]
   409  	offset := uint64(file.Offset(pos))
   410  	info.needed = append(info.needed, offset)
   411  
   412  	return index, offset
   413  }
   414  
   415  // pushDecl adds n to the declaration work queue, if not already present.
   416  func (p *iexporter) pushDecl(obj types.Object) {
   417  	// Package unsafe is known to the compiler and predeclared.
   418  	// Caller should not ask us to do export it.
   419  	if obj.Pkg() == types.Unsafe {
   420  		panic("cannot export package unsafe")
   421  	}
   422  
   423  	// Shallow export data: don't index decls from other packages.
   424  	if p.shallow && obj.Pkg() != p.localpkg {
   425  		return
   426  	}
   427  
   428  	if _, ok := p.declIndex[obj]; ok {
   429  		return
   430  	}
   431  
   432  	p.declIndex[obj] = ^uint64(0) // mark obj present in work queue
   433  	p.declTodo.pushTail(obj)
   434  }
   435  
   436  // exportWriter handles writing out individual data section chunks.
   437  type exportWriter struct {
   438  	p *iexporter
   439  
   440  	data       intWriter
   441  	prevFile   string
   442  	prevLine   int64
   443  	prevColumn int64
   444  }
   445  
   446  func (w *exportWriter) exportPath(pkg *types.Package) string {
   447  	if pkg == w.p.localpkg {
   448  		return ""
   449  	}
   450  	return pkg.Path()
   451  }
   452  
   453  func (p *iexporter) doDecl(obj types.Object) {
   454  	if trace {
   455  		p.trace("exporting decl %v (%T)", obj, obj)
   456  		p.indent++
   457  		defer func() {
   458  			p.indent--
   459  			p.trace("=> %s", obj)
   460  		}()
   461  	}
   462  	w := p.newWriter()
   463  
   464  	switch obj := obj.(type) {
   465  	case *types.Var:
   466  		w.tag('V')
   467  		w.pos(obj.Pos())
   468  		w.typ(obj.Type(), obj.Pkg())
   469  
   470  	case *types.Func:
   471  		sig, _ := obj.Type().(*types.Signature)
   472  		if sig.Recv() != nil {
   473  			// We shouldn't see methods in the package scope,
   474  			// but the type checker may repair "func () F() {}"
   475  			// to "func (Invalid) F()" and then treat it like "func F()",
   476  			// so allow that. See golang/go#57729.
   477  			if sig.Recv().Type() != types.Typ[types.Invalid] {
   478  				panic(internalErrorf("unexpected method: %v", sig))
   479  			}
   480  		}
   481  
   482  		// Function.
   483  		if sig.TypeParams().Len() == 0 {
   484  			w.tag('F')
   485  		} else {
   486  			w.tag('G')
   487  		}
   488  		w.pos(obj.Pos())
   489  		// The tparam list of the function type is the declaration of the type
   490  		// params. So, write out the type params right now. Then those type params
   491  		// will be referenced via their type offset (via typOff) in all other
   492  		// places in the signature and function where they are used.
   493  		//
   494  		// While importing the type parameters, tparamList computes and records
   495  		// their export name, so that it can be later used when writing the index.
   496  		if tparams := sig.TypeParams(); tparams.Len() > 0 {
   497  			w.tparamList(obj.Name(), tparams, obj.Pkg())
   498  		}
   499  		w.signature(sig)
   500  
   501  	case *types.Const:
   502  		w.tag('C')
   503  		w.pos(obj.Pos())
   504  		w.value(obj.Type(), obj.Val())
   505  
   506  	case *types.TypeName:
   507  		t := obj.Type()
   508  
   509  		if tparam, ok := t.(*types.TypeParam); ok {
   510  			w.tag('P')
   511  			w.pos(obj.Pos())
   512  			constraint := tparam.Constraint()
   513  			if p.version >= iexportVersionGo1_18 {
   514  				implicit := false
   515  				if iface, _ := constraint.(*types.Interface); iface != nil {
   516  					implicit = iface.IsImplicit()
   517  				}
   518  				w.bool(implicit)
   519  			}
   520  			w.typ(constraint, obj.Pkg())
   521  			break
   522  		}
   523  
   524  		if obj.IsAlias() {
   525  			w.tag('A')
   526  			w.pos(obj.Pos())
   527  			w.typ(t, obj.Pkg())
   528  			break
   529  		}
   530  
   531  		// Defined type.
   532  		named, ok := t.(*types.Named)
   533  		if !ok {
   534  			panic(internalErrorf("%s is not a defined type", t))
   535  		}
   536  
   537  		if named.TypeParams().Len() == 0 {
   538  			w.tag('T')
   539  		} else {
   540  			w.tag('U')
   541  		}
   542  		w.pos(obj.Pos())
   543  
   544  		if named.TypeParams().Len() > 0 {
   545  			// While importing the type parameters, tparamList computes and records
   546  			// their export name, so that it can be later used when writing the index.
   547  			w.tparamList(obj.Name(), named.TypeParams(), obj.Pkg())
   548  		}
   549  
   550  		underlying := obj.Type().Underlying()
   551  		w.typ(underlying, obj.Pkg())
   552  
   553  		if types.IsInterface(t) {
   554  			break
   555  		}
   556  
   557  		n := named.NumMethods()
   558  		w.uint64(uint64(n))
   559  		for i := 0; i < n; i++ {
   560  			m := named.Method(i)
   561  			w.pos(m.Pos())
   562  			w.string(m.Name())
   563  			sig, _ := m.Type().(*types.Signature)
   564  
   565  			// Receiver type parameters are type arguments of the receiver type, so
   566  			// their name must be qualified before exporting recv.
   567  			if rparams := sig.RecvTypeParams(); rparams.Len() > 0 {
   568  				prefix := obj.Name() + "." + m.Name()
   569  				for i := 0; i < rparams.Len(); i++ {
   570  					rparam := rparams.At(i)
   571  					name := tparamExportName(prefix, rparam)
   572  					w.p.tparamNames[rparam.Obj()] = name
   573  				}
   574  			}
   575  			w.param(sig.Recv())
   576  			w.signature(sig)
   577  		}
   578  
   579  	default:
   580  		panic(internalErrorf("unexpected object: %v", obj))
   581  	}
   582  
   583  	p.declIndex[obj] = w.flush()
   584  }
   585  
   586  func (w *exportWriter) tag(tag byte) {
   587  	w.data.WriteByte(tag)
   588  }
   589  
   590  func (w *exportWriter) pos(pos token.Pos) {
   591  	if w.p.shallow {
   592  		w.posV2(pos)
   593  	} else if w.p.version >= iexportVersionPosCol {
   594  		w.posV1(pos)
   595  	} else {
   596  		w.posV0(pos)
   597  	}
   598  }
   599  
   600  // posV2 encoding (used only in shallow mode) records positions as
   601  // (file, offset), where file is the index in the token.File table
   602  // (which records the file name and newline offsets) and offset is a
   603  // byte offset. It effectively ignores //line directives.
   604  func (w *exportWriter) posV2(pos token.Pos) {
   605  	if pos == token.NoPos {
   606  		w.uint64(0)
   607  		return
   608  	}
   609  	file := w.p.fset.File(pos) // fset must be non-nil
   610  	index, offset := w.p.fileIndexAndOffset(file, pos)
   611  	w.uint64(1 + index)
   612  	w.uint64(offset)
   613  }
   614  
   615  func (w *exportWriter) posV1(pos token.Pos) {
   616  	if w.p.fset == nil {
   617  		w.int64(0)
   618  		return
   619  	}
   620  
   621  	p := w.p.fset.Position(pos)
   622  	file := p.Filename
   623  	line := int64(p.Line)
   624  	column := int64(p.Column)
   625  
   626  	deltaColumn := (column - w.prevColumn) << 1
   627  	deltaLine := (line - w.prevLine) << 1
   628  
   629  	if file != w.prevFile {
   630  		deltaLine |= 1
   631  	}
   632  	if deltaLine != 0 {
   633  		deltaColumn |= 1
   634  	}
   635  
   636  	w.int64(deltaColumn)
   637  	if deltaColumn&1 != 0 {
   638  		w.int64(deltaLine)
   639  		if deltaLine&1 != 0 {
   640  			w.string(file)
   641  		}
   642  	}
   643  
   644  	w.prevFile = file
   645  	w.prevLine = line
   646  	w.prevColumn = column
   647  }
   648  
   649  func (w *exportWriter) posV0(pos token.Pos) {
   650  	if w.p.fset == nil {
   651  		w.int64(0)
   652  		return
   653  	}
   654  
   655  	p := w.p.fset.Position(pos)
   656  	file := p.Filename
   657  	line := int64(p.Line)
   658  
   659  	// When file is the same as the last position (common case),
   660  	// we can save a few bytes by delta encoding just the line
   661  	// number.
   662  	//
   663  	// Note: Because data objects may be read out of order (or not
   664  	// at all), we can only apply delta encoding within a single
   665  	// object. This is handled implicitly by tracking prevFile and
   666  	// prevLine as fields of exportWriter.
   667  
   668  	if file == w.prevFile {
   669  		delta := line - w.prevLine
   670  		w.int64(delta)
   671  		if delta == deltaNewFile {
   672  			w.int64(-1)
   673  		}
   674  	} else {
   675  		w.int64(deltaNewFile)
   676  		w.int64(line) // line >= 0
   677  		w.string(file)
   678  		w.prevFile = file
   679  	}
   680  	w.prevLine = line
   681  }
   682  
   683  func (w *exportWriter) pkg(pkg *types.Package) {
   684  	// Ensure any referenced packages are declared in the main index.
   685  	w.p.allPkgs[pkg] = true
   686  
   687  	w.string(w.exportPath(pkg))
   688  }
   689  
   690  func (w *exportWriter) qualifiedType(obj *types.TypeName) {
   691  	name := w.p.exportName(obj)
   692  
   693  	// Ensure any referenced declarations are written out too.
   694  	w.p.pushDecl(obj)
   695  	w.string(name)
   696  	w.pkg(obj.Pkg())
   697  }
   698  
   699  // TODO(rfindley): what does 'pkg' even mean here? It would be better to pass
   700  // it in explicitly into signatures and structs that may use it for
   701  // constructing fields.
   702  func (w *exportWriter) typ(t types.Type, pkg *types.Package) {
   703  	w.data.uint64(w.p.typOff(t, pkg))
   704  }
   705  
   706  func (p *iexporter) newWriter() *exportWriter {
   707  	return &exportWriter{p: p}
   708  }
   709  
   710  func (w *exportWriter) flush() uint64 {
   711  	off := uint64(w.p.data0.Len())
   712  	io.Copy(&w.p.data0, &w.data)
   713  	return off
   714  }
   715  
   716  func (p *iexporter) typOff(t types.Type, pkg *types.Package) uint64 {
   717  	off, ok := p.typIndex[t]
   718  	if !ok {
   719  		w := p.newWriter()
   720  		w.doTyp(t, pkg)
   721  		off = predeclReserved + w.flush()
   722  		p.typIndex[t] = off
   723  	}
   724  	return off
   725  }
   726  
   727  func (w *exportWriter) startType(k itag) {
   728  	w.data.uint64(uint64(k))
   729  }
   730  
   731  func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
   732  	if trace {
   733  		w.p.trace("exporting type %s (%T)", t, t)
   734  		w.p.indent++
   735  		defer func() {
   736  			w.p.indent--
   737  			w.p.trace("=> %s", t)
   738  		}()
   739  	}
   740  	switch t := t.(type) {
   741  	case *types.Named:
   742  		if targs := t.TypeArgs(); targs.Len() > 0 {
   743  			w.startType(instanceType)
   744  			// TODO(rfindley): investigate if this position is correct, and if it
   745  			// matters.
   746  			w.pos(t.Obj().Pos())
   747  			w.typeList(targs, pkg)
   748  			w.typ(t.Origin(), pkg)
   749  			return
   750  		}
   751  		w.startType(definedType)
   752  		w.qualifiedType(t.Obj())
   753  
   754  	case *types.TypeParam:
   755  		w.startType(typeParamType)
   756  		w.qualifiedType(t.Obj())
   757  
   758  	case *types.Pointer:
   759  		w.startType(pointerType)
   760  		w.typ(t.Elem(), pkg)
   761  
   762  	case *types.Slice:
   763  		w.startType(sliceType)
   764  		w.typ(t.Elem(), pkg)
   765  
   766  	case *types.Array:
   767  		w.startType(arrayType)
   768  		w.uint64(uint64(t.Len()))
   769  		w.typ(t.Elem(), pkg)
   770  
   771  	case *types.Chan:
   772  		w.startType(chanType)
   773  		// 1 RecvOnly; 2 SendOnly; 3 SendRecv
   774  		var dir uint64
   775  		switch t.Dir() {
   776  		case types.RecvOnly:
   777  			dir = 1
   778  		case types.SendOnly:
   779  			dir = 2
   780  		case types.SendRecv:
   781  			dir = 3
   782  		}
   783  		w.uint64(dir)
   784  		w.typ(t.Elem(), pkg)
   785  
   786  	case *types.Map:
   787  		w.startType(mapType)
   788  		w.typ(t.Key(), pkg)
   789  		w.typ(t.Elem(), pkg)
   790  
   791  	case *types.Signature:
   792  		w.startType(signatureType)
   793  		w.pkg(pkg)
   794  		w.signature(t)
   795  
   796  	case *types.Struct:
   797  		w.startType(structType)
   798  		n := t.NumFields()
   799  		// Even for struct{} we must emit some qualifying package, because that's
   800  		// what the compiler does, and thus that's what the importer expects.
   801  		fieldPkg := pkg
   802  		if n > 0 {
   803  			fieldPkg = t.Field(0).Pkg()
   804  		}
   805  		if fieldPkg == nil {
   806  			// TODO(rfindley): improve this very hacky logic.
   807  			//
   808  			// The importer expects a package to be set for all struct types, even
   809  			// those with no fields. A better encoding might be to set NumFields
   810  			// before pkg. setPkg panics with a nil package, which may be possible
   811  			// to reach with invalid packages (and perhaps valid packages, too?), so
   812  			// (arbitrarily) set the localpkg if available.
   813  			//
   814  			// Alternatively, we may be able to simply guarantee that pkg != nil, by
   815  			// reconsidering the encoding of constant values.
   816  			if w.p.shallow {
   817  				fieldPkg = w.p.localpkg
   818  			} else {
   819  				panic(internalErrorf("no package to set for empty struct"))
   820  			}
   821  		}
   822  		w.pkg(fieldPkg)
   823  		w.uint64(uint64(n))
   824  
   825  		for i := 0; i < n; i++ {
   826  			f := t.Field(i)
   827  			if w.p.shallow {
   828  				w.objectPath(f)
   829  			}
   830  			w.pos(f.Pos())
   831  			w.string(f.Name()) // unexported fields implicitly qualified by prior setPkg
   832  			w.typ(f.Type(), fieldPkg)
   833  			w.bool(f.Anonymous())
   834  			w.string(t.Tag(i)) // note (or tag)
   835  		}
   836  
   837  	case *types.Interface:
   838  		w.startType(interfaceType)
   839  		w.pkg(pkg)
   840  
   841  		n := t.NumEmbeddeds()
   842  		w.uint64(uint64(n))
   843  		for i := 0; i < n; i++ {
   844  			ft := t.EmbeddedType(i)
   845  			tPkg := pkg
   846  			if named, _ := ft.(*types.Named); named != nil {
   847  				w.pos(named.Obj().Pos())
   848  			} else {
   849  				w.pos(token.NoPos)
   850  			}
   851  			w.typ(ft, tPkg)
   852  		}
   853  
   854  		// See comment for struct fields. In shallow mode we change the encoding
   855  		// for interface methods that are promoted from other packages.
   856  
   857  		n = t.NumExplicitMethods()
   858  		w.uint64(uint64(n))
   859  		for i := 0; i < n; i++ {
   860  			m := t.ExplicitMethod(i)
   861  			if w.p.shallow {
   862  				w.objectPath(m)
   863  			}
   864  			w.pos(m.Pos())
   865  			w.string(m.Name())
   866  			sig, _ := m.Type().(*types.Signature)
   867  			w.signature(sig)
   868  		}
   869  
   870  	case *types.Union:
   871  		w.startType(unionType)
   872  		nt := t.Len()
   873  		w.uint64(uint64(nt))
   874  		for i := 0; i < nt; i++ {
   875  			term := t.Term(i)
   876  			w.bool(term.Tilde())
   877  			w.typ(term.Type(), pkg)
   878  		}
   879  
   880  	default:
   881  		panic(internalErrorf("unexpected type: %v, %v", t, reflect.TypeOf(t)))
   882  	}
   883  }
   884  
   885  // objectPath writes the package and objectPath to use to look up obj in a
   886  // different package, when encoding in "shallow" mode.
   887  //
   888  // When doing a shallow import, the importer creates only the local package,
   889  // and requests package symbols for dependencies from the client.
   890  // However, certain types defined in the local package may hold objects defined
   891  // (perhaps deeply) within another package.
   892  //
   893  // For example, consider the following:
   894  //
   895  //	package a
   896  //	func F() chan * map[string] struct { X int }
   897  //
   898  //	package b
   899  //	import "a"
   900  //	var B = a.F()
   901  //
   902  // In this example, the type of b.B holds fields defined in package a.
   903  // In order to have the correct canonical objects for the field defined in the
   904  // type of B, they are encoded as objectPaths and later looked up in the
   905  // importer. The same problem applies to interface methods.
   906  func (w *exportWriter) objectPath(obj types.Object) {
   907  	if obj.Pkg() == nil || obj.Pkg() == w.p.localpkg {
   908  		// obj.Pkg() may be nil for the builtin error.Error.
   909  		// In this case, or if obj is declared in the local package, no need to
   910  		// encode.
   911  		w.string("")
   912  		return
   913  	}
   914  	objectPath, err := w.p.objectpathEncoder().For(obj)
   915  	if err != nil {
   916  		// Fall back to the empty string, which will cause the importer to create a
   917  		// new object, which matches earlier behavior. Creating a new object is
   918  		// sufficient for many purposes (such as type checking), but causes certain
   919  		// references algorithms to fail (golang/go#60819). However, we didn't
   920  		// notice this problem during months of gopls@v0.12.0 testing.
   921  		//
   922  		// TODO(golang/go#61674): this workaround is insufficient, as in the case
   923  		// where the field forwarded from an instantiated type that may not appear
   924  		// in the export data of the original package:
   925  		//
   926  		//  // package a
   927  		//  type A[P any] struct{ F P }
   928  		//
   929  		//  // package b
   930  		//  type B a.A[int]
   931  		//
   932  		// We need to update references algorithms not to depend on this
   933  		// de-duplication, at which point we may want to simply remove the
   934  		// workaround here.
   935  		w.string("")
   936  		return
   937  	}
   938  	w.string(string(objectPath))
   939  	w.pkg(obj.Pkg())
   940  }
   941  
   942  func (w *exportWriter) signature(sig *types.Signature) {
   943  	w.paramList(sig.Params())
   944  	w.paramList(sig.Results())
   945  	if sig.Params().Len() > 0 {
   946  		w.bool(sig.Variadic())
   947  	}
   948  }
   949  
   950  func (w *exportWriter) typeList(ts *types.TypeList, pkg *types.Package) {
   951  	w.uint64(uint64(ts.Len()))
   952  	for i := 0; i < ts.Len(); i++ {
   953  		w.typ(ts.At(i), pkg)
   954  	}
   955  }
   956  
   957  func (w *exportWriter) tparamList(prefix string, list *types.TypeParamList, pkg *types.Package) {
   958  	ll := uint64(list.Len())
   959  	w.uint64(ll)
   960  	for i := 0; i < list.Len(); i++ {
   961  		tparam := list.At(i)
   962  		// Set the type parameter exportName before exporting its type.
   963  		exportName := tparamExportName(prefix, tparam)
   964  		w.p.tparamNames[tparam.Obj()] = exportName
   965  		w.typ(list.At(i), pkg)
   966  	}
   967  }
   968  
   969  const blankMarker = "$"
   970  
   971  // tparamExportName returns the 'exported' name of a type parameter, which
   972  // differs from its actual object name: it is prefixed with a qualifier, and
   973  // blank type parameter names are disambiguated by their index in the type
   974  // parameter list.
   975  func tparamExportName(prefix string, tparam *types.TypeParam) string {
   976  	assert(prefix != "")
   977  	name := tparam.Obj().Name()
   978  	if name == "_" {
   979  		name = blankMarker + strconv.Itoa(tparam.Index())
   980  	}
   981  	return prefix + "." + name
   982  }
   983  
   984  // tparamName returns the real name of a type parameter, after stripping its
   985  // qualifying prefix and reverting blank-name encoding. See tparamExportName
   986  // for details.
   987  func tparamName(exportName string) string {
   988  	// Remove the "path" from the type param name that makes it unique.
   989  	ix := strings.LastIndex(exportName, ".")
   990  	if ix < 0 {
   991  		errorf("malformed type parameter export name %s: missing prefix", exportName)
   992  	}
   993  	name := exportName[ix+1:]
   994  	if strings.HasPrefix(name, blankMarker) {
   995  		return "_"
   996  	}
   997  	return name
   998  }
   999  
  1000  func (w *exportWriter) paramList(tup *types.Tuple) {
  1001  	n := tup.Len()
  1002  	w.uint64(uint64(n))
  1003  	for i := 0; i < n; i++ {
  1004  		w.param(tup.At(i))
  1005  	}
  1006  }
  1007  
  1008  func (w *exportWriter) param(obj types.Object) {
  1009  	w.pos(obj.Pos())
  1010  	w.localIdent(obj)
  1011  	w.typ(obj.Type(), obj.Pkg())
  1012  }
  1013  
  1014  func (w *exportWriter) value(typ types.Type, v constant.Value) {
  1015  	w.typ(typ, nil)
  1016  	if w.p.version >= iexportVersionGo1_18 {
  1017  		w.int64(int64(v.Kind()))
  1018  	}
  1019  
  1020  	if v.Kind() == constant.Unknown {
  1021  		// golang/go#60605: treat unknown constant values as if they have invalid type
  1022  		//
  1023  		// This loses some fidelity over the package type-checked from source, but that
  1024  		// is acceptable.
  1025  		//
  1026  		// TODO(rfindley): we should switch on the recorded constant kind rather
  1027  		// than the constant type
  1028  		return
  1029  	}
  1030  
  1031  	switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
  1032  	case types.IsBoolean:
  1033  		w.bool(constant.BoolVal(v))
  1034  	case types.IsInteger:
  1035  		var i big.Int
  1036  		if i64, exact := constant.Int64Val(v); exact {
  1037  			i.SetInt64(i64)
  1038  		} else if ui64, exact := constant.Uint64Val(v); exact {
  1039  			i.SetUint64(ui64)
  1040  		} else {
  1041  			i.SetString(v.ExactString(), 10)
  1042  		}
  1043  		w.mpint(&i, typ)
  1044  	case types.IsFloat:
  1045  		f := constantToFloat(v)
  1046  		w.mpfloat(f, typ)
  1047  	case types.IsComplex:
  1048  		w.mpfloat(constantToFloat(constant.Real(v)), typ)
  1049  		w.mpfloat(constantToFloat(constant.Imag(v)), typ)
  1050  	case types.IsString:
  1051  		w.string(constant.StringVal(v))
  1052  	default:
  1053  		if b.Kind() == types.Invalid {
  1054  			// package contains type errors
  1055  			break
  1056  		}
  1057  		panic(internalErrorf("unexpected type %v (%v)", typ, typ.Underlying()))
  1058  	}
  1059  }
  1060  
  1061  // constantToFloat converts a constant.Value with kind constant.Float to a
  1062  // big.Float.
  1063  func constantToFloat(x constant.Value) *big.Float {
  1064  	x = constant.ToFloat(x)
  1065  	// Use the same floating-point precision (512) as cmd/compile
  1066  	// (see Mpprec in cmd/compile/internal/gc/mpfloat.go).
  1067  	const mpprec = 512
  1068  	var f big.Float
  1069  	f.SetPrec(mpprec)
  1070  	if v, exact := constant.Float64Val(x); exact {
  1071  		// float64
  1072  		f.SetFloat64(v)
  1073  	} else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int {
  1074  		// TODO(gri): add big.Rat accessor to constant.Value.
  1075  		n := valueToRat(num)
  1076  		d := valueToRat(denom)
  1077  		f.SetRat(n.Quo(n, d))
  1078  	} else {
  1079  		// Value too large to represent as a fraction => inaccessible.
  1080  		// TODO(gri): add big.Float accessor to constant.Value.
  1081  		_, ok := f.SetString(x.ExactString())
  1082  		assert(ok)
  1083  	}
  1084  	return &f
  1085  }
  1086  
  1087  func valueToRat(x constant.Value) *big.Rat {
  1088  	// Convert little-endian to big-endian.
  1089  	// I can't believe this is necessary.
  1090  	bytes := constant.Bytes(x)
  1091  	for i := 0; i < len(bytes)/2; i++ {
  1092  		bytes[i], bytes[len(bytes)-1-i] = bytes[len(bytes)-1-i], bytes[i]
  1093  	}
  1094  	return new(big.Rat).SetInt(new(big.Int).SetBytes(bytes))
  1095  }
  1096  
  1097  // mpint exports a multi-precision integer.
  1098  //
  1099  // For unsigned types, small values are written out as a single
  1100  // byte. Larger values are written out as a length-prefixed big-endian
  1101  // byte string, where the length prefix is encoded as its complement.
  1102  // For example, bytes 0, 1, and 2 directly represent the integer
  1103  // values 0, 1, and 2; while bytes 255, 254, and 253 indicate a 1-,
  1104  // 2-, and 3-byte big-endian string follow.
  1105  //
  1106  // Encoding for signed types use the same general approach as for
  1107  // unsigned types, except small values use zig-zag encoding and the
  1108  // bottom bit of length prefix byte for large values is reserved as a
  1109  // sign bit.
  1110  //
  1111  // The exact boundary between small and large encodings varies
  1112  // according to the maximum number of bytes needed to encode a value
  1113  // of type typ. As a special case, 8-bit types are always encoded as a
  1114  // single byte.
  1115  //
  1116  // TODO(mdempsky): Is this level of complexity really worthwhile?
  1117  func (w *exportWriter) mpint(x *big.Int, typ types.Type) {
  1118  	basic, ok := typ.Underlying().(*types.Basic)
  1119  	if !ok {
  1120  		panic(internalErrorf("unexpected type %v (%T)", typ.Underlying(), typ.Underlying()))
  1121  	}
  1122  
  1123  	signed, maxBytes := intSize(basic)
  1124  
  1125  	negative := x.Sign() < 0
  1126  	if !signed && negative {
  1127  		panic(internalErrorf("negative unsigned integer; type %v, value %v", typ, x))
  1128  	}
  1129  
  1130  	b := x.Bytes()
  1131  	if len(b) > 0 && b[0] == 0 {
  1132  		panic(internalErrorf("leading zeros"))
  1133  	}
  1134  	if uint(len(b)) > maxBytes {
  1135  		panic(internalErrorf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x))
  1136  	}
  1137  
  1138  	maxSmall := 256 - maxBytes
  1139  	if signed {
  1140  		maxSmall = 256 - 2*maxBytes
  1141  	}
  1142  	if maxBytes == 1 {
  1143  		maxSmall = 256
  1144  	}
  1145  
  1146  	// Check if x can use small value encoding.
  1147  	if len(b) <= 1 {
  1148  		var ux uint
  1149  		if len(b) == 1 {
  1150  			ux = uint(b[0])
  1151  		}
  1152  		if signed {
  1153  			ux <<= 1
  1154  			if negative {
  1155  				ux--
  1156  			}
  1157  		}
  1158  		if ux < maxSmall {
  1159  			w.data.WriteByte(byte(ux))
  1160  			return
  1161  		}
  1162  	}
  1163  
  1164  	n := 256 - uint(len(b))
  1165  	if signed {
  1166  		n = 256 - 2*uint(len(b))
  1167  		if negative {
  1168  			n |= 1
  1169  		}
  1170  	}
  1171  	if n < maxSmall || n >= 256 {
  1172  		panic(internalErrorf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n))
  1173  	}
  1174  
  1175  	w.data.WriteByte(byte(n))
  1176  	w.data.Write(b)
  1177  }
  1178  
  1179  // mpfloat exports a multi-precision floating point number.
  1180  //
  1181  // The number's value is decomposed into mantissa × 2**exponent, where
  1182  // mantissa is an integer. The value is written out as mantissa (as a
  1183  // multi-precision integer) and then the exponent, except exponent is
  1184  // omitted if mantissa is zero.
  1185  func (w *exportWriter) mpfloat(f *big.Float, typ types.Type) {
  1186  	if f.IsInf() {
  1187  		panic("infinite constant")
  1188  	}
  1189  
  1190  	// Break into f = mant × 2**exp, with 0.5 <= mant < 1.
  1191  	var mant big.Float
  1192  	exp := int64(f.MantExp(&mant))
  1193  
  1194  	// Scale so that mant is an integer.
  1195  	prec := mant.MinPrec()
  1196  	mant.SetMantExp(&mant, int(prec))
  1197  	exp -= int64(prec)
  1198  
  1199  	manti, acc := mant.Int(nil)
  1200  	if acc != big.Exact {
  1201  		panic(internalErrorf("mantissa scaling failed for %f (%s)", f, acc))
  1202  	}
  1203  	w.mpint(manti, typ)
  1204  	if manti.Sign() != 0 {
  1205  		w.int64(exp)
  1206  	}
  1207  }
  1208  
  1209  func (w *exportWriter) bool(b bool) bool {
  1210  	var x uint64
  1211  	if b {
  1212  		x = 1
  1213  	}
  1214  	w.uint64(x)
  1215  	return b
  1216  }
  1217  
  1218  func (w *exportWriter) int64(x int64)   { w.data.int64(x) }
  1219  func (w *exportWriter) uint64(x uint64) { w.data.uint64(x) }
  1220  func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) }
  1221  
  1222  func (w *exportWriter) localIdent(obj types.Object) {
  1223  	// Anonymous parameters.
  1224  	if obj == nil {
  1225  		w.string("")
  1226  		return
  1227  	}
  1228  
  1229  	name := obj.Name()
  1230  	if name == "_" {
  1231  		w.string("_")
  1232  		return
  1233  	}
  1234  
  1235  	w.string(name)
  1236  }
  1237  
  1238  type intWriter struct {
  1239  	bytes.Buffer
  1240  }
  1241  
  1242  func (w *intWriter) int64(x int64) {
  1243  	var buf [binary.MaxVarintLen64]byte
  1244  	n := binary.PutVarint(buf[:], x)
  1245  	w.Write(buf[:n])
  1246  }
  1247  
  1248  func (w *intWriter) uint64(x uint64) {
  1249  	var buf [binary.MaxVarintLen64]byte
  1250  	n := binary.PutUvarint(buf[:], x)
  1251  	w.Write(buf[:n])
  1252  }
  1253  
  1254  func assert(cond bool) {
  1255  	if !cond {
  1256  		panic("internal error: assertion failed")
  1257  	}
  1258  }
  1259  
  1260  // The below is copied from go/src/cmd/compile/internal/gc/syntax.go.
  1261  
  1262  // objQueue is a FIFO queue of types.Object. The zero value of objQueue is
  1263  // a ready-to-use empty queue.
  1264  type objQueue struct {
  1265  	ring       []types.Object
  1266  	head, tail int
  1267  }
  1268  
  1269  // empty returns true if q contains no Nodes.
  1270  func (q *objQueue) empty() bool {
  1271  	return q.head == q.tail
  1272  }
  1273  
  1274  // pushTail appends n to the tail of the queue.
  1275  func (q *objQueue) pushTail(obj types.Object) {
  1276  	if len(q.ring) == 0 {
  1277  		q.ring = make([]types.Object, 16)
  1278  	} else if q.head+len(q.ring) == q.tail {
  1279  		// Grow the ring.
  1280  		nring := make([]types.Object, len(q.ring)*2)
  1281  		// Copy the old elements.
  1282  		part := q.ring[q.head%len(q.ring):]
  1283  		if q.tail-q.head <= len(part) {
  1284  			part = part[:q.tail-q.head]
  1285  			copy(nring, part)
  1286  		} else {
  1287  			pos := copy(nring, part)
  1288  			copy(nring[pos:], q.ring[:q.tail%len(q.ring)])
  1289  		}
  1290  		q.ring, q.head, q.tail = nring, 0, q.tail-q.head
  1291  	}
  1292  
  1293  	q.ring[q.tail%len(q.ring)] = obj
  1294  	q.tail++
  1295  }
  1296  
  1297  // popHead pops a node from the head of the queue. It panics if q is empty.
  1298  func (q *objQueue) popHead() types.Object {
  1299  	if q.empty() {
  1300  		panic("dequeue empty")
  1301  	}
  1302  	obj := q.ring[q.head%len(q.ring)]
  1303  	q.head++
  1304  	return obj
  1305  }
  1306  
  1307  // internalError represents an error generated inside this package.
  1308  type internalError string
  1309  
  1310  func (e internalError) Error() string { return "gcimporter: " + string(e) }
  1311  
  1312  // TODO(adonovan): make this call panic, so that it's symmetric with errorf.
  1313  // Otherwise it's easy to forget to do anything with the error.
  1314  //
  1315  // TODO(adonovan): also, consider switching the names "errorf" and
  1316  // "internalErrorf" as the former is used for bugs, whose cause is
  1317  // internal inconsistency, whereas the latter is used for ordinary
  1318  // situations like bad input, whose cause is external.
  1319  func internalErrorf(format string, args ...interface{}) error {
  1320  	return internalError(fmt.Sprintf(format, args...))
  1321  }