// Copyright 2022 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.

package modindex

import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"go/build"
	"go/build/constraint"
	"go/token"
	"internal/godebug"
	"internal/goroot"
	"path"
	"path/filepath"
	"runtime"
	"runtime/debug"
	"sort"
	"strings"
	"sync"
	"time"
	"unsafe"

	"cmd/go/internal/base"
	"cmd/go/internal/cache"
	"cmd/go/internal/cfg"
	"cmd/go/internal/fsys"
	"cmd/go/internal/imports"
	"cmd/go/internal/par"
	"cmd/go/internal/str"
)

// enabled is used to flag off the behavior of the module index on tip.
// It will be removed before the release.
// TODO(matloob): Remove enabled once we have more confidence on the
// module index.
var enabled = godebug.New("#goindex").Value() != "0"

// Module represents and encoded module index file. It is used to
// do the equivalent of build.Import of packages in the module and answer other
// questions based on the index file's data.
type Module struct {
	modroot string
	d       *decoder
	n       int // number of packages
}

// moduleHash returns an ActionID corresponding to the state of the module
// located at filesystem path modroot.
func moduleHash(modroot string, ismodcache bool) (cache.ActionID, error) {
	// We expect modules stored within the module cache to be checksummed and
	// immutable, and we expect released modules within GOROOT to change only
	// infrequently (when the Go version changes).
	if !ismodcache {
		// The contents of this module may change over time. We don't want to pay
		// the cost to detect changes and re-index whenever they occur, so just
		// don't index it at all.
		//
		// Note that this is true even for modules in GOROOT/src: non-release builds
		// of the Go toolchain may have arbitrary development changes on top of the
		// commit reported by runtime.Version, or could be completely artificial due
		// to lacking a `git` binary (like "devel gomote.XXXXX", as synthesized by
		// "gomote push" as of 2022-06-15). (Release builds shouldn't have
		// modifications, but we don't want to use a behavior for releases that we
		// haven't tested during development.)
		return cache.ActionID{}, ErrNotIndexed
	}

	h := cache.NewHash("moduleIndex")
	// TODO(bcmills): Since modules in the index are checksummed, we could
	// probably improve the cache hit rate by keying off of the module
	// path@version (perhaps including the checksum?) instead of the module root
	// directory.
	fmt.Fprintf(h, "module index %s %s %v\n", runtime.Version(), indexVersion, modroot)
	return h.Sum(), nil
}

const modTimeCutoff = 2 * time.Second

// dirHash returns an ActionID corresponding to the state of the package
// located at filesystem path pkgdir.
func dirHash(modroot, pkgdir string) (cache.ActionID, error) {
	h := cache.NewHash("moduleIndex")
	fmt.Fprintf(h, "modroot %s\n", modroot)
	fmt.Fprintf(h, "package %s %s %v\n", runtime.Version(), indexVersion, pkgdir)
	entries, err := fsys.ReadDir(pkgdir)
	if err != nil {
		// pkgdir might not be a directory. give up on hashing.
		return cache.ActionID{}, ErrNotIndexed
	}
	cutoff := time.Now().Add(-modTimeCutoff)
	for _, info := range entries {
		if info.IsDir() {
			continue
		}

		if !info.Mode().IsRegular() {
			return cache.ActionID{}, ErrNotIndexed
		}
		// To avoid problems for very recent files where a new
		// write might not change the mtime due to file system
		// mtime precision, reject caching if a file was read that
		// is less than modTimeCutoff old.
		//
		// This is the same strategy used for hashing test inputs.
		// See hashOpen in cmd/go/internal/test/test.go for the
		// corresponding code.
		if info.ModTime().After(cutoff) {
			return cache.ActionID{}, ErrNotIndexed
		}

		fmt.Fprintf(h, "file %v %v %v\n", info.Name(), info.ModTime(), info.Size())
	}
	return h.Sum(), nil
}

var ErrNotIndexed = errors.New("not in module index")

var (
	errDisabled           = fmt.Errorf("%w: module indexing disabled", ErrNotIndexed)
	errNotFromModuleCache = fmt.Errorf("%w: not from module cache", ErrNotIndexed)
)

// GetPackage returns the IndexPackage for the directory at the given path.
// It will return ErrNotIndexed if the directory should be read without
// using the index, for instance because the index is disabled, or the package
// is not in a module.
func GetPackage(modroot, pkgdir string) (*IndexPackage, error) {
	mi, err := GetModule(modroot)
	if err == nil {
		return mi.Package(relPath(pkgdir, modroot)), nil
	}
	if !errors.Is(err, errNotFromModuleCache) {
		return nil, err
	}
	if cfg.BuildContext.Compiler == "gccgo" && str.HasPathPrefix(modroot, cfg.GOROOTsrc) {
		return nil, err // gccgo has no sources for GOROOT packages.
	}
	return openIndexPackage(modroot, pkgdir)
}

// GetModule returns the Module for the given modroot.
// It will return ErrNotIndexed if the directory should be read without
// using the index, for instance because the index is disabled, or the package
// is not in a module.
func GetModule(modroot string) (*Module, error) {
	if !enabled || cache.DefaultDir() == "off" {
		return nil, errDisabled
	}
	if modroot == "" {
		panic("modindex.GetPackage called with empty modroot")
	}
	if cfg.BuildMod == "vendor" {
		// Even if the main module is in the module cache,
		// its vendored dependencies are not loaded from their
		// usual cached locations.
		return nil, errNotFromModuleCache
	}
	modroot = filepath.Clean(modroot)
	if str.HasFilePathPrefix(modroot, cfg.GOROOTsrc) || !str.HasFilePathPrefix(modroot, cfg.GOMODCACHE) {
		return nil, errNotFromModuleCache
	}
	return openIndexModule(modroot, true)
}

var mcache par.ErrCache[string, *Module]

// openIndexModule returns the module index for modPath.
// It will return ErrNotIndexed if the module can not be read
// using the index because it contains symlinks.
func openIndexModule(modroot string, ismodcache bool) (*Module, error) {
	return mcache.Do(modroot, func() (*Module, error) {
		fsys.Trace("openIndexModule", modroot)
		id, err := moduleHash(modroot, ismodcache)
		if err != nil {
			return nil, err
		}
		data, _, err := cache.GetMmap(cache.Default(), id)
		if err != nil {
			// Couldn't read from modindex. Assume we couldn't read from
			// the index because the module hasn't been indexed yet.
			data, err = indexModule(modroot)
			if err != nil {
				return nil, err
			}
			if err = cache.PutBytes(cache.Default(), id, data); err != nil {
				return nil, err
			}
		}
		mi, err := fromBytes(modroot, data)
		if err != nil {
			return nil, err
		}
		return mi, nil
	})
}

var pcache par.ErrCache[[2]string, *IndexPackage]

func openIndexPackage(modroot, pkgdir string) (*IndexPackage, error) {
	return pcache.Do([2]string{modroot, pkgdir}, func() (*IndexPackage, error) {
		fsys.Trace("openIndexPackage", pkgdir)
		id, err := dirHash(modroot, pkgdir)
		if err != nil {
			return nil, err
		}
		data, _, err := cache.GetMmap(cache.Default(), id)
		if err != nil {
			// Couldn't read from index. Assume we couldn't read from
			// the index because the package hasn't been indexed yet.
			data = indexPackage(modroot, pkgdir)
			if err = cache.PutBytes(cache.Default(), id, data); err != nil {
				return nil, err
			}
		}
		pkg, err := packageFromBytes(modroot, data)
		if err != nil {
			return nil, err
		}
		return pkg, nil
	})
}

var errCorrupt = errors.New("corrupt index")

// protect marks the start of a large section of code that accesses the index.
// It should be used as:
//
//	defer unprotect(protect, &err)
//
// It should not be used for trivial accesses which would be
// dwarfed by the overhead of the defer.
func protect() bool {
	return debug.SetPanicOnFault(true)
}

var isTest = false

// unprotect marks the end of a large section of code that accesses the index.
// It should be used as:
//
//	defer unprotect(protect, &err)
//
// end looks for panics due to errCorrupt or bad mmap accesses.
// When it finds them, it adds explanatory text, consumes the panic, and sets *errp instead.
// If errp is nil, end adds the explanatory text but then calls base.Fatalf.
func unprotect(old bool, errp *error) {
	// SetPanicOnFault's errors _may_ satisfy this interface. Even though it's not guaranteed
	// that all its errors satisfy this interface, we'll only check for these errors so that
	// we don't suppress panics that could have been produced from other sources.
	type addrer interface {
		Addr() uintptr
	}

	debug.SetPanicOnFault(old)

	if e := recover(); e != nil {
		if _, ok := e.(addrer); ok || e == errCorrupt {
			// This panic was almost certainly caused by SetPanicOnFault or our panic(errCorrupt).
			err := fmt.Errorf("error reading module index: %v", e)
			if errp != nil {
				*errp = err
				return
			}
			if isTest {
				panic(err)
			}
			base.Fatalf("%v", err)
		}
		// The panic was likely not caused by SetPanicOnFault.
		panic(e)
	}
}

// fromBytes returns a *Module given the encoded representation.
func fromBytes(moddir string, data []byte) (m *Module, err error) {
	if !enabled {
		panic("use of index")
	}

	defer unprotect(protect(), &err)

	if !bytes.HasPrefix(data, []byte(indexVersion+"\n")) {
		return nil, errCorrupt
	}

	const hdr = len(indexVersion + "\n")
	d := &decoder{data: data}
	str := d.intAt(hdr)
	if str < hdr+8 || len(d.data) < str {
		return nil, errCorrupt
	}
	d.data, d.str = data[:str], d.data[str:]
	// Check that string table looks valid.
	// First string is empty string (length 0),
	// and we leave a marker byte 0xFF at the end
	// just to make sure that the file is not truncated.
	if len(d.str) == 0 || d.str[0] != 0 || d.str[len(d.str)-1] != 0xFF {
		return nil, errCorrupt
	}

	n := d.intAt(hdr + 4)
	if n < 0 || n > (len(d.data)-8)/8 {
		return nil, errCorrupt
	}

	m = &Module{
		moddir,
		d,
		n,
	}
	return m, nil
}

// packageFromBytes returns a *IndexPackage given the encoded representation.
func packageFromBytes(modroot string, data []byte) (p *IndexPackage, err error) {
	m, err := fromBytes(modroot, data)
	if err != nil {
		return nil, err
	}
	if m.n != 1 {
		return nil, fmt.Errorf("corrupt single-package index")
	}
	return m.pkg(0), nil
}

// pkgDir returns the dir string of the i'th package in the index.
func (m *Module) pkgDir(i int) string {
	if i < 0 || i >= m.n {
		panic(errCorrupt)
	}
	return m.d.stringAt(12 + 8 + 8*i)
}

// pkgOff returns the offset of the data for the i'th package in the index.
func (m *Module) pkgOff(i int) int {
	if i < 0 || i >= m.n {
		panic(errCorrupt)
	}
	return m.d.intAt(12 + 8 + 8*i + 4)
}

// Walk calls f for each package in the index, passing the path to that package relative to the module root.
func (m *Module) Walk(f func(path string)) {
	defer unprotect(protect(), nil)
	for i := 0; i < m.n; i++ {
		f(m.pkgDir(i))
	}
}

// relPath returns the path relative to the module's root.
func relPath(path, modroot string) string {
	return str.TrimFilePathPrefix(filepath.Clean(path), filepath.Clean(modroot))
}

var installgorootAll = godebug.New("installgoroot").Value() == "all"

// Import is the equivalent of build.Import given the information in Module.
func (rp *IndexPackage) Import(bctxt build.Context, mode build.ImportMode) (p *build.Package, err error) {
	defer unprotect(protect(), &err)

	ctxt := (*Context)(&bctxt)

	p = &build.Package{}

	p.ImportPath = "."
	p.Dir = filepath.Join(rp.modroot, rp.dir)

	var pkgerr error
	switch ctxt.Compiler {
	case "gccgo", "gc":
	default:
		// Save error for end of function.
		pkgerr = fmt.Errorf("import %q: unknown compiler %q", p.Dir, ctxt.Compiler)
	}

	if p.Dir == "" {
		return p, fmt.Errorf("import %q: import of unknown directory", p.Dir)
	}

	// goroot and gopath
	inTestdata := func(sub string) bool {
		return strings.Contains(sub, "/testdata/") || strings.HasSuffix(sub, "/testdata") || str.HasPathPrefix(sub, "testdata")
	}
	var pkga string
	if !inTestdata(rp.dir) {
		// In build.go, p.Root should only be set in the non-local-import case, or in
		// GOROOT or GOPATH. Since module mode only calls Import with path set to "."
		// and the module index doesn't apply outside modules, the GOROOT case is
		// the only case where p.Root needs to be set.
		if ctxt.GOROOT != "" && str.HasFilePathPrefix(p.Dir, cfg.GOROOTsrc) && p.Dir != cfg.GOROOTsrc {
			p.Root = ctxt.GOROOT
			p.Goroot = true
			modprefix := str.TrimFilePathPrefix(rp.modroot, cfg.GOROOTsrc)
			p.ImportPath = rp.dir
			if modprefix != "" {
				p.ImportPath = filepath.Join(modprefix, p.ImportPath)
			}

			// Set GOROOT-specific fields (sometimes for modules in a GOPATH directory).
			// The fields set below (SrcRoot, PkgRoot, BinDir, PkgTargetRoot, and PkgObj)
			// are only set in build.Import if p.Root != "".
			var pkgtargetroot string
			suffix := ""
			if ctxt.InstallSuffix != "" {
				suffix = "_" + ctxt.InstallSuffix
			}
			switch ctxt.Compiler {
			case "gccgo":
				pkgtargetroot = "pkg/gccgo_" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
				dir, elem := path.Split(p.ImportPath)
				pkga = pkgtargetroot + "/" + dir + "lib" + elem + ".a"
			case "gc":
				pkgtargetroot = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
				pkga = pkgtargetroot + "/" + p.ImportPath + ".a"
			}
			p.SrcRoot = ctxt.joinPath(p.Root, "src")
			p.PkgRoot = ctxt.joinPath(p.Root, "pkg")
			p.BinDir = ctxt.joinPath(p.Root, "bin")
			if pkga != "" {
				// Always set PkgTargetRoot. It might be used when building in shared
				// mode.
				p.PkgTargetRoot = ctxt.joinPath(p.Root, pkgtargetroot)

				// Set the install target if applicable.
				if !p.Goroot || (installgorootAll && p.ImportPath != "unsafe" && p.ImportPath != "builtin") {
					p.PkgObj = ctxt.joinPath(p.Root, pkga)
				}
			}
		}
	}

	if rp.error != nil {
		if errors.Is(rp.error, errCannotFindPackage) && ctxt.Compiler == "gccgo" && p.Goroot {
			return p, nil
		}
		return p, rp.error
	}

	if mode&build.FindOnly != 0 {
		return p, pkgerr
	}

	// We need to do a second round of bad file processing.
	var badGoError error
	badGoFiles := make(map[string]bool)
	badGoFile := func(name string, err error) {
		if badGoError == nil {
			badGoError = err
		}
		if !badGoFiles[name] {
			p.InvalidGoFiles = append(p.InvalidGoFiles, name)
			badGoFiles[name] = true
		}
	}

	var Sfiles []string // files with ".S"(capital S)/.sx(capital s equivalent for case insensitive filesystems)
	var firstFile string
	embedPos := make(map[string][]token.Position)
	testEmbedPos := make(map[string][]token.Position)
	xTestEmbedPos := make(map[string][]token.Position)
	importPos := make(map[string][]token.Position)
	testImportPos := make(map[string][]token.Position)
	xTestImportPos := make(map[string][]token.Position)
	allTags := make(map[string]bool)
	for _, tf := range rp.sourceFiles {
		name := tf.name()
		// Check errors for go files and call badGoFiles to put them in
		// InvalidGoFiles if they do have an error.
		if strings.HasSuffix(name, ".go") {
			if error := tf.error(); error != "" {
				badGoFile(name, errors.New(tf.error()))
				continue
			} else if parseError := tf.parseError(); parseError != "" {
				badGoFile(name, parseErrorFromString(tf.parseError()))
				// Fall through: we still want to list files with parse errors.
			}
		}

		var shouldBuild = true
		if !ctxt.goodOSArchFile(name, allTags) && !ctxt.UseAllFiles {
			shouldBuild = false
		} else if goBuildConstraint := tf.goBuildConstraint(); goBuildConstraint != "" {
			x, err := constraint.Parse(goBuildConstraint)
			if err != nil {
				return p, fmt.Errorf("%s: parsing //go:build line: %v", name, err)
			}
			shouldBuild = ctxt.eval(x, allTags)
		} else if plusBuildConstraints := tf.plusBuildConstraints(); len(plusBuildConstraints) > 0 {
			for _, text := range plusBuildConstraints {
				if x, err := constraint.Parse(text); err == nil {
					if !ctxt.eval(x, allTags) {
						shouldBuild = false
					}
				}
			}
		}

		ext := nameExt(name)
		if !shouldBuild || tf.ignoreFile() {
			if ext == ".go" {
				p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
			} else if fileListForExt(p, ext) != nil {
				p.IgnoredOtherFiles = append(p.IgnoredOtherFiles, name)
			}
			continue
		}

		// Going to save the file. For non-Go files, can stop here.
		switch ext {
		case ".go":
			// keep going
		case ".S", ".sx":
			// special case for cgo, handled at end
			Sfiles = append(Sfiles, name)
			continue
		default:
			if list := fileListForExt(p, ext); list != nil {
				*list = append(*list, name)
			}
			continue
		}

		pkg := tf.pkgName()
		if pkg == "documentation" {
			p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
			continue
		}
		isTest := strings.HasSuffix(name, "_test.go")
		isXTest := false
		if isTest && strings.HasSuffix(tf.pkgName(), "_test") && p.Name != tf.pkgName() {
			isXTest = true
			pkg = pkg[:len(pkg)-len("_test")]
		}

		if !isTest && tf.binaryOnly() {
			p.BinaryOnly = true
		}

		if p.Name == "" {
			p.Name = pkg
			firstFile = name
		} else if pkg != p.Name {
			// TODO(#45999): The choice of p.Name is arbitrary based on file iteration
			// order. Instead of resolving p.Name arbitrarily, we should clear out the
			// existing Name and mark the existing files as also invalid.
			badGoFile(name, &MultiplePackageError{
				Dir:      p.Dir,
				Packages: []string{p.Name, pkg},
				Files:    []string{firstFile, name},
			})
		}
		// Grab the first package comment as docs, provided it is not from a test file.
		if p.Doc == "" && !isTest && !isXTest {
			if synopsis := tf.synopsis(); synopsis != "" {
				p.Doc = synopsis
			}
		}

		// Record Imports and information about cgo.
		isCgo := false
		imports := tf.imports()
		for _, imp := range imports {
			if imp.path == "C" {
				if isTest {
					badGoFile(name, fmt.Errorf("use of cgo in test %s not supported", name))
					continue
				}
				isCgo = true
			}
		}
		if directives := tf.cgoDirectives(); directives != "" {
			if err := ctxt.saveCgo(name, p, directives); err != nil {
				badGoFile(name, err)
			}
		}

		var fileList *[]string
		var importMap, embedMap map[string][]token.Position
		var directives *[]build.Directive
		switch {
		case isCgo:
			allTags["cgo"] = true
			if ctxt.CgoEnabled {
				fileList = &p.CgoFiles
				importMap = importPos
				embedMap = embedPos
				directives = &p.Directives
			} else {
				// Ignore Imports and Embeds from cgo files if cgo is disabled.
				fileList = &p.IgnoredGoFiles
			}
		case isXTest:
			fileList = &p.XTestGoFiles
			importMap = xTestImportPos
			embedMap = xTestEmbedPos
			directives = &p.XTestDirectives
		case isTest:
			fileList = &p.TestGoFiles
			importMap = testImportPos
			embedMap = testEmbedPos
			directives = &p.TestDirectives
		default:
			fileList = &p.GoFiles
			importMap = importPos
			embedMap = embedPos
			directives = &p.Directives
		}
		*fileList = append(*fileList, name)
		if importMap != nil {
			for _, imp := range imports {
				importMap[imp.path] = append(importMap[imp.path], imp.position)
			}
		}
		if embedMap != nil {
			for _, e := range tf.embeds() {
				embedMap[e.pattern] = append(embedMap[e.pattern], e.position)
			}
		}
		if directives != nil {
			*directives = append(*directives, tf.directives()...)
		}
	}

	p.EmbedPatterns, p.EmbedPatternPos = cleanDecls(embedPos)
	p.TestEmbedPatterns, p.TestEmbedPatternPos = cleanDecls(testEmbedPos)
	p.XTestEmbedPatterns, p.XTestEmbedPatternPos = cleanDecls(xTestEmbedPos)

	p.Imports, p.ImportPos = cleanDecls(importPos)
	p.TestImports, p.TestImportPos = cleanDecls(testImportPos)
	p.XTestImports, p.XTestImportPos = cleanDecls(xTestImportPos)

	for tag := range allTags {
		p.AllTags = append(p.AllTags, tag)
	}
	sort.Strings(p.AllTags)

	if len(p.CgoFiles) > 0 {
		p.SFiles = append(p.SFiles, Sfiles...)
		sort.Strings(p.SFiles)
	} else {
		p.IgnoredOtherFiles = append(p.IgnoredOtherFiles, Sfiles...)
		sort.Strings(p.IgnoredOtherFiles)
	}

	if badGoError != nil {
		return p, badGoError
	}
	if len(p.GoFiles)+len(p.CgoFiles)+len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
		return p, &build.NoGoError{Dir: p.Dir}
	}
	return p, pkgerr
}

// IsStandardPackage reports whether path is a standard package
// for the goroot and compiler using the module index if possible,
// and otherwise falling back to internal/goroot.IsStandardPackage
func IsStandardPackage(goroot_, compiler, path string) bool {
	if !enabled || compiler != "gc" {
		return goroot.IsStandardPackage(goroot_, compiler, path)
	}

	reldir := filepath.FromSlash(path) // relative dir path in module index for package
	modroot := filepath.Join(goroot_, "src")
	if str.HasFilePathPrefix(reldir, "cmd") {
		reldir = str.TrimFilePathPrefix(reldir, "cmd")
		modroot = filepath.Join(modroot, "cmd")
	}
	if pkg, err := GetPackage(modroot, filepath.Join(modroot, reldir)); err == nil {
		hasGo, err := pkg.IsDirWithGoFiles()
		return err == nil && hasGo
	} else if errors.Is(err, ErrNotIndexed) {
		// Fall back because package isn't indexable. (Probably because
		// a file was modified recently)
		return goroot.IsStandardPackage(goroot_, compiler, path)
	}
	return false
}

// IsDirWithGoFiles is the equivalent of fsys.IsDirWithGoFiles using the information in the index.
func (rp *IndexPackage) IsDirWithGoFiles() (_ bool, err error) {
	defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("error reading module index: %v", e)
		}
	}()
	for _, sf := range rp.sourceFiles {
		if strings.HasSuffix(sf.name(), ".go") {
			return true, nil
		}
	}
	return false, nil
}

// ScanDir implements imports.ScanDir using the information in the index.
func (rp *IndexPackage) ScanDir(tags map[string]bool) (sortedImports []string, sortedTestImports []string, err error) {
	// TODO(matloob) dir should eventually be relative to indexed directory
	// TODO(matloob): skip reading raw package and jump straight to data we need?

	defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("error reading module index: %v", e)
		}
	}()

	imports_ := make(map[string]bool)
	testImports := make(map[string]bool)
	numFiles := 0

Files:
	for _, sf := range rp.sourceFiles {
		name := sf.name()
		if strings.HasPrefix(name, "_") || strings.HasPrefix(name, ".") || !strings.HasSuffix(name, ".go") || !imports.MatchFile(name, tags) {
			continue
		}

		// The following section exists for backwards compatibility reasons:
		// scanDir ignores files with import "C" when collecting the list
		// of imports unless the "cgo" tag is provided. The following comment
		// is copied from the original.
		//
		// import "C" is implicit requirement of cgo tag.
		// When listing files on the command line (explicitFiles=true)
		// we do not apply build tag filtering but we still do apply
		// cgo filtering, so no explicitFiles check here.
		// Why? Because we always have, and it's not worth breaking
		// that behavior now.
		imps := sf.imports() // TODO(matloob): directly read import paths to avoid the extra strings?
		for _, imp := range imps {
			if imp.path == "C" && !tags["cgo"] && !tags["*"] {
				continue Files
			}
		}

		if !shouldBuild(sf, tags) {
			continue
		}
		numFiles++
		m := imports_
		if strings.HasSuffix(name, "_test.go") {
			m = testImports
		}
		for _, p := range imps {
			m[p.path] = true
		}
	}
	if numFiles == 0 {
		return nil, nil, imports.ErrNoGo
	}
	return keys(imports_), keys(testImports), nil
}

func keys(m map[string]bool) []string {
	list := make([]string, 0, len(m))
	for k := range m {
		list = append(list, k)
	}
	sort.Strings(list)
	return list
}

// implements imports.ShouldBuild in terms of an index sourcefile.
func shouldBuild(sf *sourceFile, tags map[string]bool) bool {
	if goBuildConstraint := sf.goBuildConstraint(); goBuildConstraint != "" {
		x, err := constraint.Parse(goBuildConstraint)
		if err != nil {
			return false
		}
		return imports.Eval(x, tags, true)
	}

	plusBuildConstraints := sf.plusBuildConstraints()
	for _, text := range plusBuildConstraints {
		if x, err := constraint.Parse(text); err == nil {
			if !imports.Eval(x, tags, true) {
				return false
			}
		}
	}

	return true
}

// IndexPackage holds the information in the index
// needed to load a package in a specific directory.
type IndexPackage struct {
	error error
	dir   string // directory of the package relative to the modroot

	modroot string

	// Source files
	sourceFiles []*sourceFile
}

var errCannotFindPackage = errors.New("cannot find package")

// Package and returns finds the package with the given path (relative to the module root).
// If the package does not exist, Package returns an IndexPackage that will return an
// appropriate error from its methods.
func (m *Module) Package(path string) *IndexPackage {
	defer unprotect(protect(), nil)

	i, ok := sort.Find(m.n, func(i int) int {
		return strings.Compare(path, m.pkgDir(i))
	})
	if !ok {
		return &IndexPackage{error: fmt.Errorf("%w %q in:\n\t%s", errCannotFindPackage, path, filepath.Join(m.modroot, path))}
	}
	return m.pkg(i)
}

// pkg returns the i'th IndexPackage in m.
func (m *Module) pkg(i int) *IndexPackage {
	r := m.d.readAt(m.pkgOff(i))
	p := new(IndexPackage)
	if errstr := r.string(); errstr != "" {
		p.error = errors.New(errstr)
	}
	p.dir = r.string()
	p.sourceFiles = make([]*sourceFile, r.int())
	for i := range p.sourceFiles {
		p.sourceFiles[i] = &sourceFile{
			d:   m.d,
			pos: r.int(),
		}
	}
	p.modroot = m.modroot
	return p
}

// sourceFile represents the information of a given source file in the module index.
type sourceFile struct {
	d               *decoder // encoding of this source file
	pos             int      // start of sourceFile encoding in d
	onceReadImports sync.Once
	savedImports    []rawImport // saved imports so that they're only read once
}

// Offsets for fields in the sourceFile.
const (
	sourceFileError = 4 * iota
	sourceFileParseError
	sourceFileSynopsis
	sourceFileName
	sourceFilePkgName
	sourceFileIgnoreFile
	sourceFileBinaryOnly
	sourceFileCgoDirectives
	sourceFileGoBuildConstraint
	sourceFileNumPlusBuildConstraints
)

func (sf *sourceFile) error() string {
	return sf.d.stringAt(sf.pos + sourceFileError)
}
func (sf *sourceFile) parseError() string {
	return sf.d.stringAt(sf.pos + sourceFileParseError)
}
func (sf *sourceFile) synopsis() string {
	return sf.d.stringAt(sf.pos + sourceFileSynopsis)
}
func (sf *sourceFile) name() string {
	return sf.d.stringAt(sf.pos + sourceFileName)
}
func (sf *sourceFile) pkgName() string {
	return sf.d.stringAt(sf.pos + sourceFilePkgName)
}
func (sf *sourceFile) ignoreFile() bool {
	return sf.d.boolAt(sf.pos + sourceFileIgnoreFile)
}
func (sf *sourceFile) binaryOnly() bool {
	return sf.d.boolAt(sf.pos + sourceFileBinaryOnly)
}
func (sf *sourceFile) cgoDirectives() string {
	return sf.d.stringAt(sf.pos + sourceFileCgoDirectives)
}
func (sf *sourceFile) goBuildConstraint() string {
	return sf.d.stringAt(sf.pos + sourceFileGoBuildConstraint)
}

func (sf *sourceFile) plusBuildConstraints() []string {
	pos := sf.pos + sourceFileNumPlusBuildConstraints
	n := sf.d.intAt(pos)
	pos += 4
	ret := make([]string, n)
	for i := 0; i < n; i++ {
		ret[i] = sf.d.stringAt(pos)
		pos += 4
	}
	return ret
}

func (sf *sourceFile) importsOffset() int {
	pos := sf.pos + sourceFileNumPlusBuildConstraints
	n := sf.d.intAt(pos)
	// each build constraint is 1 uint32
	return pos + 4 + n*4
}

func (sf *sourceFile) embedsOffset() int {
	pos := sf.importsOffset()
	n := sf.d.intAt(pos)
	// each import is 5 uint32s (string + tokpos)
	return pos + 4 + n*(4*5)
}

func (sf *sourceFile) directivesOffset() int {
	pos := sf.embedsOffset()
	n := sf.d.intAt(pos)
	// each embed is 5 uint32s (string + tokpos)
	return pos + 4 + n*(4*5)
}

func (sf *sourceFile) imports() []rawImport {
	sf.onceReadImports.Do(func() {
		importsOffset := sf.importsOffset()
		r := sf.d.readAt(importsOffset)
		numImports := r.int()
		ret := make([]rawImport, numImports)
		for i := 0; i < numImports; i++ {
			ret[i] = rawImport{r.string(), r.tokpos()}
		}
		sf.savedImports = ret
	})
	return sf.savedImports
}

func (sf *sourceFile) embeds() []embed {
	embedsOffset := sf.embedsOffset()
	r := sf.d.readAt(embedsOffset)
	numEmbeds := r.int()
	ret := make([]embed, numEmbeds)
	for i := range ret {
		ret[i] = embed{r.string(), r.tokpos()}
	}
	return ret
}

func (sf *sourceFile) directives() []build.Directive {
	directivesOffset := sf.directivesOffset()
	r := sf.d.readAt(directivesOffset)
	numDirectives := r.int()
	ret := make([]build.Directive, numDirectives)
	for i := range ret {
		ret[i] = build.Directive{Text: r.string(), Pos: r.tokpos()}
	}
	return ret
}

func asString(b []byte) string {
	return unsafe.String(unsafe.SliceData(b), len(b))
}

// A decoder helps decode the index format.
type decoder struct {
	data []byte // data after header
	str  []byte // string table
}

// intAt returns the int at the given offset in d.data.
func (d *decoder) intAt(off int) int {
	if off < 0 || len(d.data)-off < 4 {
		panic(errCorrupt)
	}
	i := binary.LittleEndian.Uint32(d.data[off : off+4])
	if int32(i)>>31 != 0 {
		panic(errCorrupt)
	}
	return int(i)
}

// boolAt returns the bool at the given offset in d.data.
func (d *decoder) boolAt(off int) bool {
	return d.intAt(off) != 0
}

// stringAt returns the string pointed at by the int at the given offset in d.data.
func (d *decoder) stringAt(off int) string {
	return d.stringTableAt(d.intAt(off))
}

// stringTableAt returns the string at the given offset in the string table d.str.
func (d *decoder) stringTableAt(off int) string {
	if off < 0 || off >= len(d.str) {
		panic(errCorrupt)
	}
	s := d.str[off:]
	v, n := binary.Uvarint(s)
	if n <= 0 || v > uint64(len(s[n:])) {
		panic(errCorrupt)
	}
	return asString(s[n : n+int(v)])
}

// A reader reads sequential fields from a section of the index format.
type reader struct {
	d   *decoder
	pos int
}

// readAt returns a reader starting at the given position in d.
func (d *decoder) readAt(pos int) *reader {
	return &reader{d, pos}
}

// int reads the next int.
func (r *reader) int() int {
	i := r.d.intAt(r.pos)
	r.pos += 4
	return i
}

// string reads the next string.
func (r *reader) string() string {
	return r.d.stringTableAt(r.int())
}

// bool reads the next bool.
func (r *reader) bool() bool {
	return r.int() != 0
}

// tokpos reads the next token.Position.
func (r *reader) tokpos() token.Position {
	return token.Position{
		Filename: r.string(),
		Offset:   r.int(),
		Line:     r.int(),
		Column:   r.int(),
	}
}
