1// Copyright 2011 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// Package load loads packages.
6package load
7
8import (
9	"bytes"
10	"context"
11	"encoding/json"
12	"errors"
13	"fmt"
14	"go/build"
15	"go/scanner"
16	"go/token"
17	"internal/goroot"
18	"io/fs"
19	"os"
20	"path"
21	pathpkg "path"
22	"path/filepath"
23	"runtime"
24	"runtime/debug"
25	"sort"
26	"strconv"
27	"strings"
28	"time"
29	"unicode"
30	"unicode/utf8"
31
32	"cmd/go/internal/base"
33	"cmd/go/internal/cfg"
34	"cmd/go/internal/fsys"
35	"cmd/go/internal/imports"
36	"cmd/go/internal/modfetch"
37	"cmd/go/internal/modinfo"
38	"cmd/go/internal/modload"
39	"cmd/go/internal/par"
40	"cmd/go/internal/search"
41	"cmd/go/internal/str"
42	"cmd/go/internal/trace"
43	"cmd/go/internal/vcs"
44	"cmd/internal/sys"
45
46	"golang.org/x/mod/modfile"
47	"golang.org/x/mod/module"
48)
49
50// A Package describes a single package found in a directory.
51type Package struct {
52	PackagePublic                 // visible in 'go list'
53	Internal      PackageInternal // for use inside go command only
54}
55
56type PackagePublic struct {
57	// Note: These fields are part of the go command's public API.
58	// See list.go. It is okay to add fields, but not to change or
59	// remove existing ones. Keep in sync with list.go
60	Dir           string                `json:",omitempty"` // directory containing package sources
61	ImportPath    string                `json:",omitempty"` // import path of package in dir
62	ImportComment string                `json:",omitempty"` // path in import comment on package statement
63	Name          string                `json:",omitempty"` // package name
64	Doc           string                `json:",omitempty"` // package documentation string
65	Target        string                `json:",omitempty"` // installed target for this package (may be executable)
66	Shlib         string                `json:",omitempty"` // the shared library that contains this package (only set when -linkshared)
67	Root          string                `json:",omitempty"` // Go root, Go path dir, or module root dir containing this package
68	ConflictDir   string                `json:",omitempty"` // Dir is hidden by this other directory
69	ForTest       string                `json:",omitempty"` // package is only for use in named test
70	Export        string                `json:",omitempty"` // file containing export data (set by go list -export)
71	BuildID       string                `json:",omitempty"` // build ID of the compiled package (set by go list -export)
72	Module        *modinfo.ModulePublic `json:",omitempty"` // info about package's module, if any
73	Match         []string              `json:",omitempty"` // command-line patterns matching this package
74	Goroot        bool                  `json:",omitempty"` // is this package found in the Go root?
75	Standard      bool                  `json:",omitempty"` // is this package part of the standard Go library?
76	DepOnly       bool                  `json:",omitempty"` // package is only as a dependency, not explicitly listed
77	BinaryOnly    bool                  `json:",omitempty"` // package cannot be recompiled
78	Incomplete    bool                  `json:",omitempty"` // was there an error loading this package or dependencies?
79
80	// Stale and StaleReason remain here *only* for the list command.
81	// They are only initialized in preparation for list execution.
82	// The regular build determines staleness on the fly during action execution.
83	Stale       bool   `json:",omitempty"` // would 'go install' do anything for this package?
84	StaleReason string `json:",omitempty"` // why is Stale true?
85
86	// Source files
87	// If you add to this list you MUST add to p.AllFiles (below) too.
88	// Otherwise file name security lists will not apply to any new additions.
89	GoFiles           []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
90	CgoFiles          []string `json:",omitempty"` // .go source files that import "C"
91	CompiledGoFiles   []string `json:",omitempty"` // .go output from running cgo on CgoFiles
92	IgnoredGoFiles    []string `json:",omitempty"` // .go source files ignored due to build constraints
93	InvalidGoFiles    []string `json:",omitempty"` // .go source files with detected problems (parse error, wrong package name, and so on)
94	IgnoredOtherFiles []string `json:",omitempty"` // non-.go source files ignored due to build constraints
95	CFiles            []string `json:",omitempty"` // .c source files
96	CXXFiles          []string `json:",omitempty"` // .cc, .cpp and .cxx source files
97	MFiles            []string `json:",omitempty"` // .m source files
98	HFiles            []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files
99	FFiles            []string `json:",omitempty"` // .f, .F, .for and .f90 Fortran source files
100	SFiles            []string `json:",omitempty"` // .s source files
101	SwigFiles         []string `json:",omitempty"` // .swig files
102	SwigCXXFiles      []string `json:",omitempty"` // .swigcxx files
103	SysoFiles         []string `json:",omitempty"` // .syso system object files added to package
104
105	// Embedded files
106	EmbedPatterns []string `json:",omitempty"` // //go:embed patterns
107	EmbedFiles    []string `json:",omitempty"` // files matched by EmbedPatterns
108
109	// Cgo directives
110	CgoCFLAGS    []string `json:",omitempty"` // cgo: flags for C compiler
111	CgoCPPFLAGS  []string `json:",omitempty"` // cgo: flags for C preprocessor
112	CgoCXXFLAGS  []string `json:",omitempty"` // cgo: flags for C++ compiler
113	CgoFFLAGS    []string `json:",omitempty"` // cgo: flags for Fortran compiler
114	CgoLDFLAGS   []string `json:",omitempty"` // cgo: flags for linker
115	CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names
116
117	// Dependency information
118	Imports   []string          `json:",omitempty"` // import paths used by this package
119	ImportMap map[string]string `json:",omitempty"` // map from source import to ImportPath (identity entries omitted)
120	Deps      []string          `json:",omitempty"` // all (recursively) imported dependencies
121
122	// Error information
123	// Incomplete is above, packed into the other bools
124	Error      *PackageError   `json:",omitempty"` // error loading this package (not dependencies)
125	DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies
126
127	// Test information
128	// If you add to this list you MUST add to p.AllFiles (below) too.
129	// Otherwise file name security lists will not apply to any new additions.
130	TestGoFiles        []string `json:",omitempty"` // _test.go files in package
131	TestImports        []string `json:",omitempty"` // imports from TestGoFiles
132	TestEmbedPatterns  []string `json:",omitempty"` // //go:embed patterns
133	TestEmbedFiles     []string `json:",omitempty"` // files matched by TestEmbedPatterns
134	XTestGoFiles       []string `json:",omitempty"` // _test.go files outside package
135	XTestImports       []string `json:",omitempty"` // imports from XTestGoFiles
136	XTestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns
137	XTestEmbedFiles    []string `json:",omitempty"` // files matched by XTestEmbedPatterns
138}
139
140// AllFiles returns the names of all the files considered for the package.
141// This is used for sanity and security checks, so we include all files,
142// even IgnoredGoFiles, because some subcommands consider them.
143// The go/build package filtered others out (like foo_wrongGOARCH.s)
144// and that's OK.
145func (p *Package) AllFiles() []string {
146	files := str.StringList(
147		p.GoFiles,
148		p.CgoFiles,
149		// no p.CompiledGoFiles, because they are from GoFiles or generated by us
150		p.IgnoredGoFiles,
151		// no p.InvalidGoFiles, because they are from GoFiles
152		p.IgnoredOtherFiles,
153		p.CFiles,
154		p.CXXFiles,
155		p.MFiles,
156		p.HFiles,
157		p.FFiles,
158		p.SFiles,
159		p.SwigFiles,
160		p.SwigCXXFiles,
161		p.SysoFiles,
162		p.TestGoFiles,
163		p.XTestGoFiles,
164	)
165
166	// EmbedFiles may overlap with the other files.
167	// Dedup, but delay building the map as long as possible.
168	// Only files in the current directory (no slash in name)
169	// need to be checked against the files variable above.
170	var have map[string]bool
171	for _, file := range p.EmbedFiles {
172		if !strings.Contains(file, "/") {
173			if have == nil {
174				have = make(map[string]bool)
175				for _, file := range files {
176					have[file] = true
177				}
178			}
179			if have[file] {
180				continue
181			}
182		}
183		files = append(files, file)
184	}
185	return files
186}
187
188// Desc returns the package "description", for use in b.showOutput.
189func (p *Package) Desc() string {
190	if p.ForTest != "" {
191		return p.ImportPath + " [" + p.ForTest + ".test]"
192	}
193	return p.ImportPath
194}
195
196type PackageInternal struct {
197	// Unexported fields are not part of the public API.
198	Build             *build.Package
199	Imports           []*Package           // this package's direct imports
200	CompiledImports   []string             // additional Imports necessary when using CompiledGoFiles (all from standard library); 1:1 with the end of PackagePublic.Imports
201	RawImports        []string             // this package's original imports as they appear in the text of the program; 1:1 with the end of PackagePublic.Imports
202	ForceLibrary      bool                 // this package is a library (even if named "main")
203	CmdlineFiles      bool                 // package built from files listed on command line
204	CmdlinePkg        bool                 // package listed on command line
205	CmdlinePkgLiteral bool                 // package listed as literal on command line (not via wildcard)
206	Local             bool                 // imported via local path (./ or ../)
207	LocalPrefix       string               // interpret ./ and ../ imports relative to this prefix
208	ExeName           string               // desired name for temporary executable
209	FuzzInstrument    bool                 // package should be instrumented for fuzzing
210	CoverMode         string               // preprocess Go source files with the coverage tool in this mode
211	CoverVars         map[string]*CoverVar // variables created by coverage analysis
212	OmitDebug         bool                 // tell linker not to write debug information
213	GobinSubdir       bool                 // install target would be subdir of GOBIN
214	BuildInfo         string               // add this info to package main
215	TestmainGo        *[]byte              // content for _testmain.go
216	Embed             map[string][]string  // //go:embed comment mapping
217	OrigImportPath    string               // original import path before adding '_test' suffix
218
219	Asmflags   []string // -asmflags for this package
220	Gcflags    []string // -gcflags for this package
221	Ldflags    []string // -ldflags for this package
222	Gccgoflags []string // -gccgoflags for this package
223}
224
225// A NoGoError indicates that no Go files for the package were applicable to the
226// build for that package.
227//
228// That may be because there were no files whatsoever, or because all files were
229// excluded, or because all non-excluded files were test sources.
230type NoGoError struct {
231	Package *Package
232}
233
234func (e *NoGoError) Error() string {
235	if len(e.Package.IgnoredGoFiles) > 0 {
236		// Go files exist, but they were ignored due to build constraints.
237		return "build constraints exclude all Go files in " + e.Package.Dir
238	}
239	if len(e.Package.TestGoFiles)+len(e.Package.XTestGoFiles) > 0 {
240		// Test Go files exist, but we're not interested in them.
241		// The double-negative is unfortunate but we want e.Package.Dir
242		// to appear at the end of error message.
243		return "no non-test Go files in " + e.Package.Dir
244	}
245	return "no Go files in " + e.Package.Dir
246}
247
248// setLoadPackageDataError presents an error found when loading package data
249// as a *PackageError. It has special cases for some common errors to improve
250// messages shown to users and reduce redundancy.
251//
252// setLoadPackageDataError returns true if it's safe to load information about
253// imported packages, for example, if there was a parse error loading imports
254// in one file, but other files are okay.
255func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportStack, importPos []token.Position) {
256	matchErr, isMatchErr := err.(*search.MatchError)
257	if isMatchErr && matchErr.Match.Pattern() == path {
258		if matchErr.Match.IsLiteral() {
259			// The error has a pattern has a pattern similar to the import path.
260			// It may be slightly different (./foo matching example.com/foo),
261			// but close enough to seem redundant.
262			// Unwrap the error so we don't show the pattern.
263			err = matchErr.Err
264		}
265	}
266
267	// Replace (possibly wrapped) *build.NoGoError with *load.NoGoError.
268	// The latter is more specific about the cause.
269	var nogoErr *build.NoGoError
270	if errors.As(err, &nogoErr) {
271		if p.Dir == "" && nogoErr.Dir != "" {
272			p.Dir = nogoErr.Dir
273		}
274		err = &NoGoError{Package: p}
275	}
276
277	// Take only the first error from a scanner.ErrorList. PackageError only
278	// has room for one position, so we report the first error with a position
279	// instead of all of the errors without a position.
280	var pos string
281	var isScanErr bool
282	if scanErr, ok := err.(scanner.ErrorList); ok && len(scanErr) > 0 {
283		isScanErr = true // For stack push/pop below.
284
285		scanPos := scanErr[0].Pos
286		scanPos.Filename = base.ShortPath(scanPos.Filename)
287		pos = scanPos.String()
288		err = errors.New(scanErr[0].Msg)
289	}
290
291	// Report the error on the importing package if the problem is with the import declaration
292	// for example, if the package doesn't exist or if the import path is malformed.
293	// On the other hand, don't include a position if the problem is with the imported package,
294	// for example there are no Go files (NoGoError), or there's a problem in the imported
295	// package's source files themselves (scanner errors).
296	//
297	// TODO(matloob): Perhaps make each of those the errors in the first group
298	// (including modload.ImportMissingError, ImportMissingSumError, and the
299	// corresponding "cannot find package %q in any of" GOPATH-mode error
300	// produced in build.(*Context).Import; modload.AmbiguousImportError,
301	// and modload.PackageNotInModuleError; and the malformed module path errors
302	// produced in golang.org/x/mod/module.CheckMod) implement an interface
303	// to make it easier to check for them? That would save us from having to
304	// move the modload errors into this package to avoid a package import cycle,
305	// and from having to export an error type for the errors produced in build.
306	if !isMatchErr && (nogoErr != nil || isScanErr) {
307		stk.Push(path)
308		defer stk.Pop()
309	}
310
311	p.Error = &PackageError{
312		ImportStack: stk.Copy(),
313		Pos:         pos,
314		Err:         err,
315	}
316
317	if path != stk.Top() {
318		p.Error.setPos(importPos)
319	}
320}
321
322// Resolve returns the resolved version of imports,
323// which should be p.TestImports or p.XTestImports, NOT p.Imports.
324// The imports in p.TestImports and p.XTestImports are not recursively
325// loaded during the initial load of p, so they list the imports found in
326// the source file, but most processing should be over the vendor-resolved
327// import paths. We do this resolution lazily both to avoid file system work
328// and because the eventual real load of the test imports (during 'go test')
329// can produce better error messages if it starts with the original paths.
330// The initial load of p loads all the non-test imports and rewrites
331// the vendored paths, so nothing should ever call p.vendored(p.Imports).
332func (p *Package) Resolve(imports []string) []string {
333	if len(imports) > 0 && len(p.Imports) > 0 && &imports[0] == &p.Imports[0] {
334		panic("internal error: p.Resolve(p.Imports) called")
335	}
336	seen := make(map[string]bool)
337	var all []string
338	for _, path := range imports {
339		path = ResolveImportPath(p, path)
340		if !seen[path] {
341			seen[path] = true
342			all = append(all, path)
343		}
344	}
345	sort.Strings(all)
346	return all
347}
348
349// CoverVar holds the name of the generated coverage variables targeting the named file.
350type CoverVar struct {
351	File string // local file name
352	Var  string // name of count struct
353}
354
355func (p *Package) copyBuild(opts PackageOpts, pp *build.Package) {
356	p.Internal.Build = pp
357
358	if pp.PkgTargetRoot != "" && cfg.BuildPkgdir != "" {
359		old := pp.PkgTargetRoot
360		pp.PkgRoot = cfg.BuildPkgdir
361		pp.PkgTargetRoot = cfg.BuildPkgdir
362		pp.PkgObj = filepath.Join(cfg.BuildPkgdir, strings.TrimPrefix(pp.PkgObj, old))
363	}
364
365	p.Dir = pp.Dir
366	p.ImportPath = pp.ImportPath
367	p.ImportComment = pp.ImportComment
368	p.Name = pp.Name
369	p.Doc = pp.Doc
370	p.Root = pp.Root
371	p.ConflictDir = pp.ConflictDir
372	p.BinaryOnly = pp.BinaryOnly
373
374	// TODO? Target
375	p.Goroot = pp.Goroot
376	p.Standard = p.Goroot && p.ImportPath != "" && search.IsStandardImportPath(p.ImportPath)
377	p.GoFiles = pp.GoFiles
378	p.CgoFiles = pp.CgoFiles
379	p.IgnoredGoFiles = pp.IgnoredGoFiles
380	p.InvalidGoFiles = pp.InvalidGoFiles
381	p.IgnoredOtherFiles = pp.IgnoredOtherFiles
382	p.CFiles = pp.CFiles
383	p.CXXFiles = pp.CXXFiles
384	p.MFiles = pp.MFiles
385	p.HFiles = pp.HFiles
386	p.FFiles = pp.FFiles
387	p.SFiles = pp.SFiles
388	p.SwigFiles = pp.SwigFiles
389	p.SwigCXXFiles = pp.SwigCXXFiles
390	p.SysoFiles = pp.SysoFiles
391	p.CgoCFLAGS = pp.CgoCFLAGS
392	p.CgoCPPFLAGS = pp.CgoCPPFLAGS
393	p.CgoCXXFLAGS = pp.CgoCXXFLAGS
394	p.CgoFFLAGS = pp.CgoFFLAGS
395	p.CgoLDFLAGS = pp.CgoLDFLAGS
396	p.CgoPkgConfig = pp.CgoPkgConfig
397	// We modify p.Imports in place, so make copy now.
398	p.Imports = make([]string, len(pp.Imports))
399	copy(p.Imports, pp.Imports)
400	p.Internal.RawImports = pp.Imports
401	p.TestGoFiles = pp.TestGoFiles
402	p.TestImports = pp.TestImports
403	p.XTestGoFiles = pp.XTestGoFiles
404	p.XTestImports = pp.XTestImports
405	if opts.IgnoreImports {
406		p.Imports = nil
407		p.Internal.RawImports = nil
408		p.TestImports = nil
409		p.XTestImports = nil
410	}
411	p.EmbedPatterns = pp.EmbedPatterns
412	p.TestEmbedPatterns = pp.TestEmbedPatterns
413	p.XTestEmbedPatterns = pp.XTestEmbedPatterns
414	p.Internal.OrigImportPath = pp.ImportPath
415}
416
417// A PackageError describes an error loading information about a package.
418type PackageError struct {
419	ImportStack      []string // shortest path from package named on command line to this one
420	Pos              string   // position of error
421	Err              error    // the error itself
422	IsImportCycle    bool     // the error is an import cycle
423	Hard             bool     // whether the error is soft or hard; soft errors are ignored in some places
424	alwaysPrintStack bool     // whether to always print the ImportStack
425}
426
427func (p *PackageError) Error() string {
428	// TODO(#43696): decide when to print the stack or the position based on
429	// the error type and whether the package is in the main module.
430	// Document the rationale.
431	if p.Pos != "" && (len(p.ImportStack) == 0 || !p.alwaysPrintStack) {
432		// Omit import stack. The full path to the file where the error
433		// is the most important thing.
434		return p.Pos + ": " + p.Err.Error()
435	}
436
437	// If the error is an ImportPathError, and the last path on the stack appears
438	// in the error message, omit that path from the stack to avoid repetition.
439	// If an ImportPathError wraps another ImportPathError that matches the
440	// last path on the stack, we don't omit the path. An error like
441	// "package A imports B: error loading C caused by B" would not be clearer
442	// if "imports B" were omitted.
443	if len(p.ImportStack) == 0 {
444		return p.Err.Error()
445	}
446	var optpos string
447	if p.Pos != "" {
448		optpos = "\n\t" + p.Pos
449	}
450	return "package " + strings.Join(p.ImportStack, "\n\timports ") + optpos + ": " + p.Err.Error()
451}
452
453func (p *PackageError) Unwrap() error { return p.Err }
454
455// PackageError implements MarshalJSON so that Err is marshaled as a string
456// and non-essential fields are omitted.
457func (p *PackageError) MarshalJSON() ([]byte, error) {
458	perr := struct {
459		ImportStack []string
460		Pos         string
461		Err         string
462	}{p.ImportStack, p.Pos, p.Err.Error()}
463	return json.Marshal(perr)
464}
465
466func (p *PackageError) setPos(posList []token.Position) {
467	if len(posList) == 0 {
468		return
469	}
470	pos := posList[0]
471	pos.Filename = base.ShortPath(pos.Filename)
472	p.Pos = pos.String()
473}
474
475// ImportPathError is a type of error that prevents a package from being loaded
476// for a given import path. When such a package is loaded, a *Package is
477// returned with Err wrapping an ImportPathError: the error is attached to
478// the imported package, not the importing package.
479//
480// The string returned by ImportPath must appear in the string returned by
481// Error. Errors that wrap ImportPathError (such as PackageError) may omit
482// the import path.
483type ImportPathError interface {
484	error
485	ImportPath() string
486}
487
488var (
489	_ ImportPathError = (*importError)(nil)
490	_ ImportPathError = (*mainPackageError)(nil)
491	_ ImportPathError = (*modload.ImportMissingError)(nil)
492	_ ImportPathError = (*modload.ImportMissingSumError)(nil)
493	_ ImportPathError = (*modload.DirectImportFromImplicitDependencyError)(nil)
494)
495
496type importError struct {
497	importPath string
498	err        error // created with fmt.Errorf
499}
500
501func ImportErrorf(path, format string, args ...any) ImportPathError {
502	err := &importError{importPath: path, err: fmt.Errorf(format, args...)}
503	if errStr := err.Error(); !strings.Contains(errStr, path) {
504		panic(fmt.Sprintf("path %q not in error %q", path, errStr))
505	}
506	return err
507}
508
509func (e *importError) Error() string {
510	return e.err.Error()
511}
512
513func (e *importError) Unwrap() error {
514	// Don't return e.err directly, since we're only wrapping an error if %w
515	// was passed to ImportErrorf.
516	return errors.Unwrap(e.err)
517}
518
519func (e *importError) ImportPath() string {
520	return e.importPath
521}
522
523// An ImportStack is a stack of import paths, possibly with the suffix " (test)" appended.
524// The import path of a test package is the import path of the corresponding
525// non-test package with the suffix "_test" added.
526type ImportStack []string
527
528func (s *ImportStack) Push(p string) {
529	*s = append(*s, p)
530}
531
532func (s *ImportStack) Pop() {
533	*s = (*s)[0 : len(*s)-1]
534}
535
536func (s *ImportStack) Copy() []string {
537	return append([]string{}, *s...)
538}
539
540func (s *ImportStack) Top() string {
541	if len(*s) == 0 {
542		return ""
543	}
544	return (*s)[len(*s)-1]
545}
546
547// shorterThan reports whether sp is shorter than t.
548// We use this to record the shortest import sequence
549// that leads to a particular package.
550func (sp *ImportStack) shorterThan(t []string) bool {
551	s := *sp
552	if len(s) != len(t) {
553		return len(s) < len(t)
554	}
555	// If they are the same length, settle ties using string ordering.
556	for i := range s {
557		if s[i] != t[i] {
558			return s[i] < t[i]
559		}
560	}
561	return false // they are equal
562}
563
564// packageCache is a lookup cache for LoadImport,
565// so that if we look up a package multiple times
566// we return the same pointer each time.
567var packageCache = map[string]*Package{}
568
569// ClearPackageCache clears the in-memory package cache and the preload caches.
570// It is only for use by GOPATH-based "go get".
571// TODO(jayconrod): When GOPATH-based "go get" is removed, delete this function.
572func ClearPackageCache() {
573	for name := range packageCache {
574		delete(packageCache, name)
575	}
576	resolvedImportCache.Clear()
577	packageDataCache.Clear()
578}
579
580// ClearPackageCachePartial clears packages with the given import paths from the
581// in-memory package cache and the preload caches. It is only for use by
582// GOPATH-based "go get".
583// TODO(jayconrod): When GOPATH-based "go get" is removed, delete this function.
584func ClearPackageCachePartial(args []string) {
585	shouldDelete := make(map[string]bool)
586	for _, arg := range args {
587		shouldDelete[arg] = true
588		if p := packageCache[arg]; p != nil {
589			delete(packageCache, arg)
590		}
591	}
592	resolvedImportCache.DeleteIf(func(key any) bool {
593		return shouldDelete[key.(importSpec).path]
594	})
595	packageDataCache.DeleteIf(func(key any) bool {
596		return shouldDelete[key.(string)]
597	})
598}
599
600// ReloadPackageNoFlags is like LoadImport but makes sure
601// not to use the package cache.
602// It is only for use by GOPATH-based "go get".
603// TODO(rsc): When GOPATH-based "go get" is removed, delete this function.
604func ReloadPackageNoFlags(arg string, stk *ImportStack) *Package {
605	p := packageCache[arg]
606	if p != nil {
607		delete(packageCache, arg)
608		resolvedImportCache.DeleteIf(func(key any) bool {
609			return key.(importSpec).path == p.ImportPath
610		})
611		packageDataCache.Delete(p.ImportPath)
612	}
613	return LoadImport(context.TODO(), PackageOpts{}, arg, base.Cwd(), nil, stk, nil, 0)
614}
615
616// dirToImportPath returns the pseudo-import path we use for a package
617// outside the Go path. It begins with _/ and then contains the full path
618// to the directory. If the package lives in c:\home\gopher\my\pkg then
619// the pseudo-import path is _/c_/home/gopher/my/pkg.
620// Using a pseudo-import path like this makes the ./ imports no longer
621// a special case, so that all the code to deal with ordinary imports works
622// automatically.
623func dirToImportPath(dir string) string {
624	return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir)))
625}
626
627func makeImportValid(r rune) rune {
628	// Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport.
629	const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
630	if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
631		return '_'
632	}
633	return r
634}
635
636// Mode flags for loadImport and download (in get.go).
637const (
638	// ResolveImport means that loadImport should do import path expansion.
639	// That is, ResolveImport means that the import path came from
640	// a source file and has not been expanded yet to account for
641	// vendoring or possible module adjustment.
642	// Every import path should be loaded initially with ResolveImport,
643	// and then the expanded version (for example with the /vendor/ in it)
644	// gets recorded as the canonical import path. At that point, future loads
645	// of that package must not pass ResolveImport, because
646	// disallowVendor will reject direct use of paths containing /vendor/.
647	ResolveImport = 1 << iota
648
649	// ResolveModule is for download (part of "go get") and indicates
650	// that the module adjustment should be done, but not vendor adjustment.
651	ResolveModule
652
653	// GetTestDeps is for download (part of "go get") and indicates
654	// that test dependencies should be fetched too.
655	GetTestDeps
656)
657
658// LoadImport scans the directory named by path, which must be an import path,
659// but possibly a local import path (an absolute file system path or one beginning
660// with ./ or ../). A local relative path is interpreted relative to srcDir.
661// It returns a *Package describing the package found in that directory.
662// LoadImport does not set tool flags and should only be used by
663// this package, as part of a bigger load operation, and by GOPATH-based "go get".
664// TODO(rsc): When GOPATH-based "go get" is removed, unexport this function.
665func LoadImport(ctx context.Context, opts PackageOpts, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
666	return loadImport(ctx, opts, nil, path, srcDir, parent, stk, importPos, mode)
667}
668
669func loadImport(ctx context.Context, opts PackageOpts, pre *preload, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
670	if path == "" {
671		panic("LoadImport called with empty package path")
672	}
673
674	var parentPath, parentRoot string
675	parentIsStd := false
676	if parent != nil {
677		parentPath = parent.ImportPath
678		parentRoot = parent.Root
679		parentIsStd = parent.Standard
680	}
681	bp, loaded, err := loadPackageData(ctx, path, parentPath, srcDir, parentRoot, parentIsStd, mode)
682	if loaded && pre != nil && !opts.IgnoreImports {
683		pre.preloadImports(ctx, opts, bp.Imports, bp)
684	}
685	if bp == nil {
686		p := &Package{
687			PackagePublic: PackagePublic{
688				ImportPath: path,
689				Incomplete: true,
690			},
691		}
692		if importErr, ok := err.(ImportPathError); !ok || importErr.ImportPath() != path {
693			// Only add path to the error's import stack if it's not already present
694			// in the error.
695			//
696			// TODO(bcmills): setLoadPackageDataError itself has a similar Push / Pop
697			// sequence that empirically doesn't trigger for these errors, guarded by
698			// a somewhat complex condition. Figure out how to generalize that
699			// condition and eliminate the explicit calls here.
700			stk.Push(path)
701			defer stk.Pop()
702		}
703		p.setLoadPackageDataError(err, path, stk, nil)
704		return p
705	}
706
707	importPath := bp.ImportPath
708	p := packageCache[importPath]
709	if p != nil {
710		stk.Push(path)
711		p = reusePackage(p, stk)
712		stk.Pop()
713	} else {
714		p = new(Package)
715		p.Internal.Local = build.IsLocalImport(path)
716		p.ImportPath = importPath
717		packageCache[importPath] = p
718
719		// Load package.
720		// loadPackageData may return bp != nil even if an error occurs,
721		// in order to return partial information.
722		p.load(ctx, opts, path, stk, importPos, bp, err)
723
724		if !cfg.ModulesEnabled && path != cleanImport(path) {
725			p.Error = &PackageError{
726				ImportStack: stk.Copy(),
727				Err:         ImportErrorf(path, "non-canonical import path %q: should be %q", path, pathpkg.Clean(path)),
728			}
729			p.Incomplete = true
730			p.Error.setPos(importPos)
731		}
732	}
733
734	// Checked on every import because the rules depend on the code doing the importing.
735	if perr := disallowInternal(ctx, srcDir, parent, parentPath, p, stk); perr != p {
736		perr.Error.setPos(importPos)
737		return perr
738	}
739	if mode&ResolveImport != 0 {
740		if perr := disallowVendor(srcDir, path, parentPath, p, stk); perr != p {
741			perr.Error.setPos(importPos)
742			return perr
743		}
744	}
745
746	if p.Name == "main" && parent != nil && parent.Dir != p.Dir {
747		perr := *p
748		perr.Error = &PackageError{
749			ImportStack: stk.Copy(),
750			Err:         ImportErrorf(path, "import %q is a program, not an importable package", path),
751		}
752		perr.Error.setPos(importPos)
753		return &perr
754	}
755
756	if p.Internal.Local && parent != nil && !parent.Internal.Local {
757		perr := *p
758		var err error
759		if path == "." {
760			err = ImportErrorf(path, "%s: cannot import current directory", path)
761		} else {
762			err = ImportErrorf(path, "local import %q in non-local package", path)
763		}
764		perr.Error = &PackageError{
765			ImportStack: stk.Copy(),
766			Err:         err,
767		}
768		perr.Error.setPos(importPos)
769		return &perr
770	}
771
772	return p
773}
774
775// loadPackageData loads information needed to construct a *Package. The result
776// is cached, and later calls to loadPackageData for the same package will return
777// the same data.
778//
779// loadPackageData returns a non-nil package even if err is non-nil unless
780// the package path is malformed (for example, the path contains "mod/" or "@").
781//
782// loadPackageData returns a boolean, loaded, which is true if this is the
783// first time the package was loaded. Callers may preload imports in this case.
784func loadPackageData(ctx context.Context, path, parentPath, parentDir, parentRoot string, parentIsStd bool, mode int) (bp *build.Package, loaded bool, err error) {
785	if path == "" {
786		panic("loadPackageData called with empty package path")
787	}
788
789	if strings.HasPrefix(path, "mod/") {
790		// Paths beginning with "mod/" might accidentally
791		// look in the module cache directory tree in $GOPATH/pkg/mod/.
792		// This prefix is owned by the Go core for possible use in the
793		// standard library (since it does not begin with a domain name),
794		// so it's OK to disallow entirely.
795		return nil, false, fmt.Errorf("disallowed import path %q", path)
796	}
797
798	if strings.Contains(path, "@") {
799		return nil, false, errors.New("can only use path@version syntax with 'go get' and 'go install' in module-aware mode")
800	}
801
802	// Determine canonical package path and directory.
803	// For a local import the identifier is the pseudo-import path
804	// we create from the full directory to the package.
805	// Otherwise it is the usual import path.
806	// For vendored imports, it is the expanded form.
807	//
808	// Note that when modules are enabled, local import paths are normally
809	// canonicalized by modload.LoadPackages before now. However, if there's an
810	// error resolving a local path, it will be returned untransformed
811	// so that 'go list -e' reports something useful.
812	importKey := importSpec{
813		path:        path,
814		parentPath:  parentPath,
815		parentDir:   parentDir,
816		parentRoot:  parentRoot,
817		parentIsStd: parentIsStd,
818		mode:        mode,
819	}
820	r := resolvedImportCache.Do(importKey, func() any {
821		var r resolvedImport
822		if build.IsLocalImport(path) {
823			r.dir = filepath.Join(parentDir, path)
824			r.path = dirToImportPath(r.dir)
825		} else if cfg.ModulesEnabled {
826			r.dir, r.path, r.err = modload.Lookup(parentPath, parentIsStd, path)
827		} else if mode&ResolveImport != 0 {
828			// We do our own path resolution, because we want to
829			// find out the key to use in packageCache without the
830			// overhead of repeated calls to buildContext.Import.
831			// The code is also needed in a few other places anyway.
832			r.path = resolveImportPath(path, parentPath, parentDir, parentRoot, parentIsStd)
833		} else if mode&ResolveModule != 0 {
834			r.path = moduleImportPath(path, parentPath, parentDir, parentRoot)
835		}
836		if r.path == "" {
837			r.path = path
838		}
839		return r
840	}).(resolvedImport)
841	// Invariant: r.path is set to the resolved import path. If the path cannot
842	// be resolved, r.path is set to path, the source import path.
843	// r.path is never empty.
844
845	// Load the package from its directory. If we already found the package's
846	// directory when resolving its import path, use that.
847	data := packageDataCache.Do(r.path, func() any {
848		loaded = true
849		var data packageData
850		if r.dir != "" {
851			var buildMode build.ImportMode
852			if !cfg.ModulesEnabled {
853				buildMode = build.ImportComment
854			}
855			data.p, data.err = cfg.BuildContext.ImportDir(r.dir, buildMode)
856			if cfg.ModulesEnabled {
857				// Override data.p.Root, since ImportDir sets it to $GOPATH, if
858				// the module is inside $GOPATH/src.
859				if info := modload.PackageModuleInfo(ctx, path); info != nil {
860					data.p.Root = info.Dir
861				}
862			}
863			if r.err != nil {
864				if data.err != nil {
865					// ImportDir gave us one error, and the module loader gave us another.
866					// We arbitrarily choose to keep the error from ImportDir because
867					// that's what our tests already expect, and it seems to provide a bit
868					// more detail in most cases.
869				} else if errors.Is(r.err, imports.ErrNoGo) {
870					// ImportDir said there were files in the package, but the module
871					// loader said there weren't. Which one is right?
872					// Without this special-case hack, the TestScript/test_vet case fails
873					// on the vetfail/p1 package (added in CL 83955).
874					// Apparently, imports.ShouldBuild biases toward rejecting files
875					// with invalid build constraints, whereas ImportDir biases toward
876					// accepting them.
877					//
878					// TODO(#41410: Figure out how this actually ought to work and fix
879					// this mess.
880				} else {
881					data.err = r.err
882				}
883			}
884		} else if r.err != nil {
885			data.p = new(build.Package)
886			data.err = r.err
887		} else if cfg.ModulesEnabled && path != "unsafe" {
888			data.p = new(build.Package)
889			data.err = fmt.Errorf("unknown import path %q: internal error: module loader did not resolve import", r.path)
890		} else {
891			buildMode := build.ImportComment
892			if mode&ResolveImport == 0 || r.path != path {
893				// Not vendoring, or we already found the vendored path.
894				buildMode |= build.IgnoreVendor
895			}
896			data.p, data.err = cfg.BuildContext.Import(r.path, parentDir, buildMode)
897		}
898		data.p.ImportPath = r.path
899
900		// Set data.p.BinDir in cases where go/build.Context.Import
901		// may give us a path we don't want.
902		if !data.p.Goroot {
903			if cfg.GOBIN != "" {
904				data.p.BinDir = cfg.GOBIN
905			} else if cfg.ModulesEnabled {
906				data.p.BinDir = modload.BinDir()
907			}
908		}
909
910		if !cfg.ModulesEnabled && data.err == nil &&
911			data.p.ImportComment != "" && data.p.ImportComment != path &&
912			!strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/") {
913			data.err = fmt.Errorf("code in directory %s expects import %q", data.p.Dir, data.p.ImportComment)
914		}
915		return data
916	}).(packageData)
917
918	return data.p, loaded, data.err
919}
920
921// importSpec describes an import declaration in source code. It is used as a
922// cache key for resolvedImportCache.
923type importSpec struct {
924	path                              string
925	parentPath, parentDir, parentRoot string
926	parentIsStd                       bool
927	mode                              int
928}
929
930// resolvedImport holds a canonical identifier for a package. It may also contain
931// a path to the package's directory and an error if one occurred. resolvedImport
932// is the value type in resolvedImportCache.
933type resolvedImport struct {
934	path, dir string
935	err       error
936}
937
938// packageData holds information loaded from a package. It is the value type
939// in packageDataCache.
940type packageData struct {
941	p   *build.Package
942	err error
943}
944
945// resolvedImportCache maps import strings (importSpec) to canonical package names
946// (resolvedImport).
947var resolvedImportCache par.Cache
948
949// packageDataCache maps canonical package names (string) to package metadata
950// (packageData).
951var packageDataCache par.Cache
952
953// preloadWorkerCount is the number of concurrent goroutines that can load
954// packages. Experimentally, there are diminishing returns with more than
955// 4 workers. This was measured on the following machines.
956//
957// * MacBookPro with a 4-core Intel Core i7 CPU
958// * Linux workstation with 6-core Intel Xeon CPU
959// * Linux workstation with 24-core Intel Xeon CPU
960//
961// It is very likely (though not confirmed) that this workload is limited
962// by memory bandwidth. We don't have a good way to determine the number of
963// workers that would saturate the bus though, so runtime.GOMAXPROCS
964// seems like a reasonable default.
965var preloadWorkerCount = runtime.GOMAXPROCS(0)
966
967// preload holds state for managing concurrent preloading of package data.
968//
969// A preload should be created with newPreload before loading a large
970// package graph. flush must be called when package loading is complete
971// to ensure preload goroutines are no longer active. This is necessary
972// because of global mutable state that cannot safely be read and written
973// concurrently. In particular, packageDataCache may be cleared by "go get"
974// in GOPATH mode, and modload.loaded (accessed via modload.Lookup) may be
975// modified by modload.LoadPackages.
976type preload struct {
977	cancel chan struct{}
978	sema   chan struct{}
979}
980
981// newPreload creates a new preloader. flush must be called later to avoid
982// accessing global state while it is being modified.
983func newPreload() *preload {
984	pre := &preload{
985		cancel: make(chan struct{}),
986		sema:   make(chan struct{}, preloadWorkerCount),
987	}
988	return pre
989}
990
991// preloadMatches loads data for package paths matched by patterns.
992// When preloadMatches returns, some packages may not be loaded yet, but
993// loadPackageData and loadImport are always safe to call.
994func (pre *preload) preloadMatches(ctx context.Context, opts PackageOpts, matches []*search.Match) {
995	for _, m := range matches {
996		for _, pkg := range m.Pkgs {
997			select {
998			case <-pre.cancel:
999				return
1000			case pre.sema <- struct{}{}:
1001				go func(pkg string) {
1002					mode := 0 // don't use vendoring or module import resolution
1003					bp, loaded, err := loadPackageData(ctx, pkg, "", base.Cwd(), "", false, mode)
1004					<-pre.sema
1005					if bp != nil && loaded && err == nil && !opts.IgnoreImports {
1006						pre.preloadImports(ctx, opts, bp.Imports, bp)
1007					}
1008				}(pkg)
1009			}
1010		}
1011	}
1012}
1013
1014// preloadImports queues a list of imports for preloading.
1015// When preloadImports returns, some packages may not be loaded yet,
1016// but loadPackageData and loadImport are always safe to call.
1017func (pre *preload) preloadImports(ctx context.Context, opts PackageOpts, imports []string, parent *build.Package) {
1018	parentIsStd := parent.Goroot && parent.ImportPath != "" && search.IsStandardImportPath(parent.ImportPath)
1019	for _, path := range imports {
1020		if path == "C" || path == "unsafe" {
1021			continue
1022		}
1023		select {
1024		case <-pre.cancel:
1025			return
1026		case pre.sema <- struct{}{}:
1027			go func(path string) {
1028				bp, loaded, err := loadPackageData(ctx, path, parent.ImportPath, parent.Dir, parent.Root, parentIsStd, ResolveImport)
1029				<-pre.sema
1030				if bp != nil && loaded && err == nil && !opts.IgnoreImports {
1031					pre.preloadImports(ctx, opts, bp.Imports, bp)
1032				}
1033			}(path)
1034		}
1035	}
1036}
1037
1038// flush stops pending preload operations. flush blocks until preload calls to
1039// loadPackageData have completed. The preloader will not make any new calls
1040// to loadPackageData.
1041func (pre *preload) flush() {
1042	// flush is usually deferred.
1043	// Don't hang program waiting for workers on panic.
1044	if v := recover(); v != nil {
1045		panic(v)
1046	}
1047
1048	close(pre.cancel)
1049	for i := 0; i < preloadWorkerCount; i++ {
1050		pre.sema <- struct{}{}
1051	}
1052}
1053
1054func cleanImport(path string) string {
1055	orig := path
1056	path = pathpkg.Clean(path)
1057	if strings.HasPrefix(orig, "./") && path != ".." && !strings.HasPrefix(path, "../") {
1058		path = "./" + path
1059	}
1060	return path
1061}
1062
1063var isDirCache par.Cache
1064
1065func isDir(path string) bool {
1066	return isDirCache.Do(path, func() any {
1067		fi, err := fsys.Stat(path)
1068		return err == nil && fi.IsDir()
1069	}).(bool)
1070}
1071
1072// ResolveImportPath returns the true meaning of path when it appears in parent.
1073// There are two different resolutions applied.
1074// First, there is Go 1.5 vendoring (golang.org/s/go15vendor).
1075// If vendor expansion doesn't trigger, then the path is also subject to
1076// Go 1.11 module legacy conversion (golang.org/issue/25069).
1077func ResolveImportPath(parent *Package, path string) (found string) {
1078	var parentPath, parentDir, parentRoot string
1079	parentIsStd := false
1080	if parent != nil {
1081		parentPath = parent.ImportPath
1082		parentDir = parent.Dir
1083		parentRoot = parent.Root
1084		parentIsStd = parent.Standard
1085	}
1086	return resolveImportPath(path, parentPath, parentDir, parentRoot, parentIsStd)
1087}
1088
1089func resolveImportPath(path, parentPath, parentDir, parentRoot string, parentIsStd bool) (found string) {
1090	if cfg.ModulesEnabled {
1091		if _, p, e := modload.Lookup(parentPath, parentIsStd, path); e == nil {
1092			return p
1093		}
1094		return path
1095	}
1096	found = vendoredImportPath(path, parentPath, parentDir, parentRoot)
1097	if found != path {
1098		return found
1099	}
1100	return moduleImportPath(path, parentPath, parentDir, parentRoot)
1101}
1102
1103// dirAndRoot returns the source directory and workspace root
1104// for the package p, guaranteeing that root is a path prefix of dir.
1105func dirAndRoot(path string, dir, root string) (string, string) {
1106	origDir, origRoot := dir, root
1107	dir = filepath.Clean(dir)
1108	root = filepath.Join(root, "src")
1109	if !str.HasFilePathPrefix(dir, root) || path != "command-line-arguments" && filepath.Join(root, path) != dir {
1110		// Look for symlinks before reporting error.
1111		dir = expandPath(dir)
1112		root = expandPath(root)
1113	}
1114
1115	if !str.HasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator || path != "command-line-arguments" && !build.IsLocalImport(path) && filepath.Join(root, path) != dir {
1116		base.Fatalf("unexpected directory layout:\n"+
1117			"	import path: %s\n"+
1118			"	root: %s\n"+
1119			"	dir: %s\n"+
1120			"	expand root: %s\n"+
1121			"	expand dir: %s\n"+
1122			"	separator: %s",
1123			path,
1124			filepath.Join(origRoot, "src"),
1125			filepath.Clean(origDir),
1126			origRoot,
1127			origDir,
1128			string(filepath.Separator))
1129	}
1130
1131	return dir, root
1132}
1133
1134// vendoredImportPath returns the vendor-expansion of path when it appears in parent.
1135// If parent is x/y/z, then path might expand to x/y/z/vendor/path, x/y/vendor/path,
1136// x/vendor/path, vendor/path, or else stay path if none of those exist.
1137// vendoredImportPath returns the expanded path or, if no expansion is found, the original.
1138func vendoredImportPath(path, parentPath, parentDir, parentRoot string) (found string) {
1139	if parentRoot == "" {
1140		return path
1141	}
1142
1143	dir, root := dirAndRoot(parentPath, parentDir, parentRoot)
1144
1145	vpath := "vendor/" + path
1146	for i := len(dir); i >= len(root); i-- {
1147		if i < len(dir) && dir[i] != filepath.Separator {
1148			continue
1149		}
1150		// Note: checking for the vendor directory before checking
1151		// for the vendor/path directory helps us hit the
1152		// isDir cache more often. It also helps us prepare a more useful
1153		// list of places we looked, to report when an import is not found.
1154		if !isDir(filepath.Join(dir[:i], "vendor")) {
1155			continue
1156		}
1157		targ := filepath.Join(dir[:i], vpath)
1158		if isDir(targ) && hasGoFiles(targ) {
1159			importPath := parentPath
1160			if importPath == "command-line-arguments" {
1161				// If parent.ImportPath is 'command-line-arguments'.
1162				// set to relative directory to root (also chopped root directory)
1163				importPath = dir[len(root)+1:]
1164			}
1165			// We started with parent's dir c:\gopath\src\foo\bar\baz\quux\xyzzy.
1166			// We know the import path for parent's dir.
1167			// We chopped off some number of path elements and
1168			// added vendor\path to produce c:\gopath\src\foo\bar\baz\vendor\path.
1169			// Now we want to know the import path for that directory.
1170			// Construct it by chopping the same number of path elements
1171			// (actually the same number of bytes) from parent's import path
1172			// and then append /vendor/path.
1173			chopped := len(dir) - i
1174			if chopped == len(importPath)+1 {
1175				// We walked up from c:\gopath\src\foo\bar
1176				// and found c:\gopath\src\vendor\path.
1177				// We chopped \foo\bar (length 8) but the import path is "foo/bar" (length 7).
1178				// Use "vendor/path" without any prefix.
1179				return vpath
1180			}
1181			return importPath[:len(importPath)-chopped] + "/" + vpath
1182		}
1183	}
1184	return path
1185}
1186
1187var (
1188	modulePrefix   = []byte("\nmodule ")
1189	goModPathCache par.Cache
1190)
1191
1192// goModPath returns the module path in the go.mod in dir, if any.
1193func goModPath(dir string) (path string) {
1194	return goModPathCache.Do(dir, func() any {
1195		data, err := os.ReadFile(filepath.Join(dir, "go.mod"))
1196		if err != nil {
1197			return ""
1198		}
1199		var i int
1200		if bytes.HasPrefix(data, modulePrefix[1:]) {
1201			i = 0
1202		} else {
1203			i = bytes.Index(data, modulePrefix)
1204			if i < 0 {
1205				return ""
1206			}
1207			i++
1208		}
1209		line := data[i:]
1210
1211		// Cut line at \n, drop trailing \r if present.
1212		if j := bytes.IndexByte(line, '\n'); j >= 0 {
1213			line = line[:j]
1214		}
1215		if line[len(line)-1] == '\r' {
1216			line = line[:len(line)-1]
1217		}
1218		line = line[len("module "):]
1219
1220		// If quoted, unquote.
1221		path = strings.TrimSpace(string(line))
1222		if path != "" && path[0] == '"' {
1223			s, err := strconv.Unquote(path)
1224			if err != nil {
1225				return ""
1226			}
1227			path = s
1228		}
1229		return path
1230	}).(string)
1231}
1232
1233// findVersionElement returns the slice indices of the final version element /vN in path.
1234// If there is no such element, it returns -1, -1.
1235func findVersionElement(path string) (i, j int) {
1236	j = len(path)
1237	for i = len(path) - 1; i >= 0; i-- {
1238		if path[i] == '/' {
1239			if isVersionElement(path[i+1 : j]) {
1240				return i, j
1241			}
1242			j = i
1243		}
1244	}
1245	return -1, -1
1246}
1247
1248// isVersionElement reports whether s is a well-formed path version element:
1249// v2, v3, v10, etc, but not v0, v05, v1.
1250func isVersionElement(s string) bool {
1251	if len(s) < 2 || s[0] != 'v' || s[1] == '0' || s[1] == '1' && len(s) == 2 {
1252		return false
1253	}
1254	for i := 1; i < len(s); i++ {
1255		if s[i] < '0' || '9' < s[i] {
1256			return false
1257		}
1258	}
1259	return true
1260}
1261
1262// moduleImportPath translates import paths found in go modules
1263// back down to paths that can be resolved in ordinary builds.
1264//
1265// Define “new” code as code with a go.mod file in the same directory
1266// or a parent directory. If an import in new code says x/y/v2/z but
1267// x/y/v2/z does not exist and x/y/go.mod says “module x/y/v2”,
1268// then go build will read the import as x/y/z instead.
1269// See golang.org/issue/25069.
1270func moduleImportPath(path, parentPath, parentDir, parentRoot string) (found string) {
1271	if parentRoot == "" {
1272		return path
1273	}
1274
1275	// If there are no vN elements in path, leave it alone.
1276	// (The code below would do the same, but only after
1277	// some other file system accesses that we can avoid
1278	// here by returning early.)
1279	if i, _ := findVersionElement(path); i < 0 {
1280		return path
1281	}
1282
1283	dir, root := dirAndRoot(parentPath, parentDir, parentRoot)
1284
1285	// Consider dir and parents, up to and including root.
1286	for i := len(dir); i >= len(root); i-- {
1287		if i < len(dir) && dir[i] != filepath.Separator {
1288			continue
1289		}
1290		if goModPath(dir[:i]) != "" {
1291			goto HaveGoMod
1292		}
1293	}
1294	// This code is not in a tree with a go.mod,
1295	// so apply no changes to the path.
1296	return path
1297
1298HaveGoMod:
1299	// This import is in a tree with a go.mod.
1300	// Allow it to refer to code in GOPATH/src/x/y/z as x/y/v2/z
1301	// if GOPATH/src/x/y/go.mod says module "x/y/v2",
1302
1303	// If x/y/v2/z exists, use it unmodified.
1304	if bp, _ := cfg.BuildContext.Import(path, "", build.IgnoreVendor); bp.Dir != "" {
1305		return path
1306	}
1307
1308	// Otherwise look for a go.mod supplying a version element.
1309	// Some version-like elements may appear in paths but not
1310	// be module versions; we skip over those to look for module
1311	// versions. For example the module m/v2 might have a
1312	// package m/v2/api/v1/foo.
1313	limit := len(path)
1314	for limit > 0 {
1315		i, j := findVersionElement(path[:limit])
1316		if i < 0 {
1317			return path
1318		}
1319		if bp, _ := cfg.BuildContext.Import(path[:i], "", build.IgnoreVendor); bp.Dir != "" {
1320			if mpath := goModPath(bp.Dir); mpath != "" {
1321				// Found a valid go.mod file, so we're stopping the search.
1322				// If the path is m/v2/p and we found m/go.mod that says
1323				// "module m/v2", then we return "m/p".
1324				if mpath == path[:j] {
1325					return path[:i] + path[j:]
1326				}
1327				// Otherwise just return the original path.
1328				// We didn't find anything worth rewriting,
1329				// and the go.mod indicates that we should
1330				// not consider parent directories.
1331				return path
1332			}
1333		}
1334		limit = i
1335	}
1336	return path
1337}
1338
1339// hasGoFiles reports whether dir contains any files with names ending in .go.
1340// For a vendor check we must exclude directories that contain no .go files.
1341// Otherwise it is not possible to vendor just a/b/c and still import the
1342// non-vendored a/b. See golang.org/issue/13832.
1343func hasGoFiles(dir string) bool {
1344	files, _ := os.ReadDir(dir)
1345	for _, f := range files {
1346		if !f.IsDir() && strings.HasSuffix(f.Name(), ".go") {
1347			return true
1348		}
1349	}
1350	return false
1351}
1352
1353// reusePackage reuses package p to satisfy the import at the top
1354// of the import stack stk. If this use causes an import loop,
1355// reusePackage updates p's error information to record the loop.
1356func reusePackage(p *Package, stk *ImportStack) *Package {
1357	// We use p.Internal.Imports==nil to detect a package that
1358	// is in the midst of its own loadPackage call
1359	// (all the recursion below happens before p.Internal.Imports gets set).
1360	if p.Internal.Imports == nil {
1361		if p.Error == nil {
1362			p.Error = &PackageError{
1363				ImportStack:   stk.Copy(),
1364				Err:           errors.New("import cycle not allowed"),
1365				IsImportCycle: true,
1366			}
1367		} else if !p.Error.IsImportCycle {
1368			// If the error is already set, but it does not indicate that
1369			// we are in an import cycle, set IsImportCycle so that we don't
1370			// end up stuck in a loop down the road.
1371			p.Error.IsImportCycle = true
1372		}
1373		p.Incomplete = true
1374	}
1375	// Don't rewrite the import stack in the error if we have an import cycle.
1376	// If we do, we'll lose the path that describes the cycle.
1377	if p.Error != nil && !p.Error.IsImportCycle && stk.shorterThan(p.Error.ImportStack) {
1378		p.Error.ImportStack = stk.Copy()
1379	}
1380	return p
1381}
1382
1383// disallowInternal checks that srcDir (containing package importerPath, if non-empty)
1384// is allowed to import p.
1385// If the import is allowed, disallowInternal returns the original package p.
1386// If not, it returns a new package containing just an appropriate error.
1387func disallowInternal(ctx context.Context, srcDir string, importer *Package, importerPath string, p *Package, stk *ImportStack) *Package {
1388	// golang.org/s/go14internal:
1389	// An import of a path containing the element “internal”
1390	// is disallowed if the importing code is outside the tree
1391	// rooted at the parent of the “internal” directory.
1392
1393	// There was an error loading the package; stop here.
1394	if p.Error != nil {
1395		return p
1396	}
1397
1398	// The generated 'testmain' package is allowed to access testing/internal/...,
1399	// as if it were generated into the testing directory tree
1400	// (it's actually in a temporary directory outside any Go tree).
1401	// This cleans up a former kludge in passing functionality to the testing package.
1402	if str.HasPathPrefix(p.ImportPath, "testing/internal") && importerPath == "testmain" {
1403		return p
1404	}
1405
1406	// We can't check standard packages with gccgo.
1407	if cfg.BuildContext.Compiler == "gccgo" && p.Standard {
1408		return p
1409	}
1410
1411	// The sort package depends on internal/reflectlite, but during bootstrap
1412	// the path rewriting causes the normal internal checks to fail.
1413	// Instead, just ignore the internal rules during bootstrap.
1414	if p.Standard && strings.HasPrefix(importerPath, "bootstrap/") {
1415		return p
1416	}
1417
1418	// importerPath is empty: we started
1419	// with a name given on the command line, not an
1420	// import. Anything listed on the command line is fine.
1421	if importerPath == "" {
1422		return p
1423	}
1424
1425	// Check for "internal" element: three cases depending on begin of string and/or end of string.
1426	i, ok := findInternal(p.ImportPath)
1427	if !ok {
1428		return p
1429	}
1430
1431	// Internal is present.
1432	// Map import path back to directory corresponding to parent of internal.
1433	if i > 0 {
1434		i-- // rewind over slash in ".../internal"
1435	}
1436
1437	if p.Module == nil {
1438		parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)]
1439
1440		if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
1441			return p
1442		}
1443
1444		// Look for symlinks before reporting error.
1445		srcDir = expandPath(srcDir)
1446		parent = expandPath(parent)
1447		if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
1448			return p
1449		}
1450	} else {
1451		// p is in a module, so make it available based on the importer's import path instead
1452		// of the file path (https://golang.org/issue/23970).
1453		if importer.Internal.CmdlineFiles {
1454			// The importer is a list of command-line files.
1455			// Pretend that the import path is the import path of the
1456			// directory containing them.
1457			// If the directory is outside the main modules, this will resolve to ".",
1458			// which is not a prefix of any valid module.
1459			importerPath, _ = modload.MainModules.DirImportPath(ctx, importer.Dir)
1460		}
1461		parentOfInternal := p.ImportPath[:i]
1462		if str.HasPathPrefix(importerPath, parentOfInternal) {
1463			return p
1464		}
1465	}
1466
1467	// Internal is present, and srcDir is outside parent's tree. Not allowed.
1468	perr := *p
1469	perr.Error = &PackageError{
1470		alwaysPrintStack: true,
1471		ImportStack:      stk.Copy(),
1472		Err:              ImportErrorf(p.ImportPath, "use of internal package "+p.ImportPath+" not allowed"),
1473	}
1474	perr.Incomplete = true
1475	return &perr
1476}
1477
1478// findInternal looks for the final "internal" path element in the given import path.
1479// If there isn't one, findInternal returns ok=false.
1480// Otherwise, findInternal returns ok=true and the index of the "internal".
1481func findInternal(path string) (index int, ok bool) {
1482	// Three cases, depending on internal at start/end of string or not.
1483	// The order matters: we must return the index of the final element,
1484	// because the final one produces the most restrictive requirement
1485	// on the importer.
1486	switch {
1487	case strings.HasSuffix(path, "/internal"):
1488		return len(path) - len("internal"), true
1489	case strings.Contains(path, "/internal/"):
1490		return strings.LastIndex(path, "/internal/") + 1, true
1491	case path == "internal", strings.HasPrefix(path, "internal/"):
1492		return 0, true
1493	}
1494	return 0, false
1495}
1496
1497// disallowVendor checks that srcDir is allowed to import p as path.
1498// If the import is allowed, disallowVendor returns the original package p.
1499// If not, it returns a new package containing just an appropriate error.
1500func disallowVendor(srcDir string, path string, importerPath string, p *Package, stk *ImportStack) *Package {
1501	// If the importerPath is empty, we started
1502	// with a name given on the command line, not an
1503	// import. Anything listed on the command line is fine.
1504	if importerPath == "" {
1505		return p
1506	}
1507
1508	if perr := disallowVendorVisibility(srcDir, p, importerPath, stk); perr != p {
1509		return perr
1510	}
1511
1512	// Paths like x/vendor/y must be imported as y, never as x/vendor/y.
1513	if i, ok := FindVendor(path); ok {
1514		perr := *p
1515		perr.Error = &PackageError{
1516			ImportStack: stk.Copy(),
1517			Err:         ImportErrorf(path, "%s must be imported as %s", path, path[i+len("vendor/"):]),
1518		}
1519		perr.Incomplete = true
1520		return &perr
1521	}
1522
1523	return p
1524}
1525
1526// disallowVendorVisibility checks that srcDir is allowed to import p.
1527// The rules are the same as for /internal/ except that a path ending in /vendor
1528// is not subject to the rules, only subdirectories of vendor.
1529// This allows people to have packages and commands named vendor,
1530// for maximal compatibility with existing source trees.
1531func disallowVendorVisibility(srcDir string, p *Package, importerPath string, stk *ImportStack) *Package {
1532	// The stack does not include p.ImportPath.
1533	// If there's nothing on the stack, we started
1534	// with a name given on the command line, not an
1535	// import. Anything listed on the command line is fine.
1536	if importerPath == "" {
1537		return p
1538	}
1539
1540	// Check for "vendor" element.
1541	i, ok := FindVendor(p.ImportPath)
1542	if !ok {
1543		return p
1544	}
1545
1546	// Vendor is present.
1547	// Map import path back to directory corresponding to parent of vendor.
1548	if i > 0 {
1549		i-- // rewind over slash in ".../vendor"
1550	}
1551	truncateTo := i + len(p.Dir) - len(p.ImportPath)
1552	if truncateTo < 0 || len(p.Dir) < truncateTo {
1553		return p
1554	}
1555	parent := p.Dir[:truncateTo]
1556	if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
1557		return p
1558	}
1559
1560	// Look for symlinks before reporting error.
1561	srcDir = expandPath(srcDir)
1562	parent = expandPath(parent)
1563	if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
1564		return p
1565	}
1566
1567	// Vendor is present, and srcDir is outside parent's tree. Not allowed.
1568	perr := *p
1569	perr.Error = &PackageError{
1570		ImportStack: stk.Copy(),
1571		Err:         errors.New("use of vendored package not allowed"),
1572	}
1573	perr.Incomplete = true
1574	return &perr
1575}
1576
1577// FindVendor looks for the last non-terminating "vendor" path element in the given import path.
1578// If there isn't one, FindVendor returns ok=false.
1579// Otherwise, FindVendor returns ok=true and the index of the "vendor".
1580//
1581// Note that terminating "vendor" elements don't count: "x/vendor" is its own package,
1582// not the vendored copy of an import "" (the empty import path).
1583// This will allow people to have packages or commands named vendor.
1584// This may help reduce breakage, or it may just be confusing. We'll see.
1585func FindVendor(path string) (index int, ok bool) {
1586	// Two cases, depending on internal at start of string or not.
1587	// The order matters: we must return the index of the final element,
1588	// because the final one is where the effective import path starts.
1589	switch {
1590	case strings.Contains(path, "/vendor/"):
1591		return strings.LastIndex(path, "/vendor/") + 1, true
1592	case strings.HasPrefix(path, "vendor/"):
1593		return 0, true
1594	}
1595	return 0, false
1596}
1597
1598type TargetDir int
1599
1600const (
1601	ToTool    TargetDir = iota // to GOROOT/pkg/tool (default for cmd/*)
1602	ToBin                      // to bin dir inside package root (default for non-cmd/*)
1603	StalePath                  // an old import path; fail to build
1604)
1605
1606// InstallTargetDir reports the target directory for installing the command p.
1607func InstallTargetDir(p *Package) TargetDir {
1608	if strings.HasPrefix(p.ImportPath, "code.google.com/p/go.tools/cmd/") {
1609		return StalePath
1610	}
1611	if p.Goroot && strings.HasPrefix(p.ImportPath, "cmd/") && p.Name == "main" {
1612		switch p.ImportPath {
1613		case "cmd/go", "cmd/gofmt":
1614			return ToBin
1615		}
1616		return ToTool
1617	}
1618	return ToBin
1619}
1620
1621var cgoExclude = map[string]bool{
1622	"runtime/cgo": true,
1623}
1624
1625var cgoSyscallExclude = map[string]bool{
1626	"runtime/cgo":  true,
1627	"runtime/race": true,
1628	"runtime/msan": true,
1629	"runtime/asan": true,
1630}
1631
1632var foldPath = make(map[string]string)
1633
1634// exeFromImportPath returns an executable name
1635// for a package using the import path.
1636//
1637// The executable name is the last element of the import path.
1638// In module-aware mode, an additional rule is used on import paths
1639// consisting of two or more path elements. If the last element is
1640// a vN path element specifying the major version, then the
1641// second last element of the import path is used instead.
1642func (p *Package) exeFromImportPath() string {
1643	_, elem := pathpkg.Split(p.ImportPath)
1644	if cfg.ModulesEnabled {
1645		// If this is example.com/mycmd/v2, it's more useful to
1646		// install it as mycmd than as v2. See golang.org/issue/24667.
1647		if elem != p.ImportPath && isVersionElement(elem) {
1648			_, elem = pathpkg.Split(pathpkg.Dir(p.ImportPath))
1649		}
1650	}
1651	return elem
1652}
1653
1654// exeFromFiles returns an executable name for a package
1655// using the first element in GoFiles or CgoFiles collections without the prefix.
1656//
1657// Returns empty string in case of empty collection.
1658func (p *Package) exeFromFiles() string {
1659	var src string
1660	if len(p.GoFiles) > 0 {
1661		src = p.GoFiles[0]
1662	} else if len(p.CgoFiles) > 0 {
1663		src = p.CgoFiles[0]
1664	} else {
1665		return ""
1666	}
1667	_, elem := filepath.Split(src)
1668	return elem[:len(elem)-len(".go")]
1669}
1670
1671// DefaultExecName returns the default executable name for a package
1672func (p *Package) DefaultExecName() string {
1673	if p.Internal.CmdlineFiles {
1674		return p.exeFromFiles()
1675	}
1676	return p.exeFromImportPath()
1677}
1678
1679// load populates p using information from bp, err, which should
1680// be the result of calling build.Context.Import.
1681// stk contains the import stack, not including path itself.
1682func (p *Package) load(ctx context.Context, opts PackageOpts, path string, stk *ImportStack, importPos []token.Position, bp *build.Package, err error) {
1683	p.copyBuild(opts, bp)
1684
1685	// The localPrefix is the path we interpret ./ imports relative to,
1686	// if we support them at all (not in module mode!).
1687	// Synthesized main packages sometimes override this.
1688	if p.Internal.Local && !cfg.ModulesEnabled {
1689		p.Internal.LocalPrefix = dirToImportPath(p.Dir)
1690	}
1691
1692	// setError sets p.Error if it hasn't already been set. We may proceed
1693	// after encountering some errors so that 'go list -e' has more complete
1694	// output. If there's more than one error, we should report the first.
1695	setError := func(err error) {
1696		if p.Error == nil {
1697			p.Error = &PackageError{
1698				ImportStack: stk.Copy(),
1699				Err:         err,
1700			}
1701
1702			// Add the importer's position information if the import position exists, and
1703			// the current package being examined is the importer.
1704			// If we have not yet accepted package p onto the import stack,
1705			// then the cause of the error is not within p itself: the error
1706			// must be either in an explicit command-line argument,
1707			// or on the importer side (indicated by a non-empty importPos).
1708			if path != stk.Top() && len(importPos) > 0 {
1709				p.Error.setPos(importPos)
1710			}
1711		}
1712	}
1713
1714	if err != nil {
1715		p.Incomplete = true
1716		p.setLoadPackageDataError(err, path, stk, importPos)
1717	}
1718
1719	useBindir := p.Name == "main"
1720	if !p.Standard {
1721		switch cfg.BuildBuildmode {
1722		case "c-archive", "c-shared", "plugin":
1723			useBindir = false
1724		}
1725	}
1726
1727	if useBindir {
1728		// Report an error when the old code.google.com/p/go.tools paths are used.
1729		if InstallTargetDir(p) == StalePath {
1730			// TODO(matloob): remove this branch, and StalePath itself. code.google.com/p/go is so
1731			// old, even this code checking for it is stale now!
1732			newPath := strings.Replace(p.ImportPath, "code.google.com/p/go.", "golang.org/x/", 1)
1733			e := ImportErrorf(p.ImportPath, "the %v command has moved; use %v instead.", p.ImportPath, newPath)
1734			setError(e)
1735			return
1736		}
1737		elem := p.DefaultExecName()
1738		full := cfg.BuildContext.GOOS + "_" + cfg.BuildContext.GOARCH + "/" + elem
1739		if cfg.BuildContext.GOOS != base.ToolGOOS || cfg.BuildContext.GOARCH != base.ToolGOARCH {
1740			// Install cross-compiled binaries to subdirectories of bin.
1741			elem = full
1742		}
1743		if p.Internal.Build.BinDir == "" && cfg.ModulesEnabled {
1744			p.Internal.Build.BinDir = modload.BinDir()
1745		}
1746		if p.Internal.Build.BinDir != "" {
1747			// Install to GOBIN or bin of GOPATH entry.
1748			p.Target = filepath.Join(p.Internal.Build.BinDir, elem)
1749			if !p.Goroot && strings.Contains(elem, "/") && cfg.GOBIN != "" {
1750				// Do not create $GOBIN/goos_goarch/elem.
1751				p.Target = ""
1752				p.Internal.GobinSubdir = true
1753			}
1754		}
1755		if InstallTargetDir(p) == ToTool {
1756			// This is for 'go tool'.
1757			// Override all the usual logic and force it into the tool directory.
1758			if cfg.BuildToolchainName == "gccgo" {
1759				p.Target = filepath.Join(base.ToolDir, elem)
1760			} else {
1761				p.Target = filepath.Join(cfg.GOROOTpkg, "tool", full)
1762			}
1763		}
1764		if p.Target != "" && cfg.BuildContext.GOOS == "windows" {
1765			p.Target += ".exe"
1766		}
1767	} else if p.Internal.Local {
1768		// Local import turned into absolute path.
1769		// No permanent install target.
1770		p.Target = ""
1771	} else {
1772		p.Target = p.Internal.Build.PkgObj
1773		if cfg.BuildLinkshared && p.Target != "" {
1774			// TODO(bcmills): The reliance on p.Target implies that -linkshared does
1775			// not work for any package that lacks a Target — such as a non-main
1776			// package in module mode. We should probably fix that.
1777			shlibnamefile := p.Target[:len(p.Target)-2] + ".shlibname"
1778			shlib, err := os.ReadFile(shlibnamefile)
1779			if err != nil && !os.IsNotExist(err) {
1780				base.Fatalf("reading shlibname: %v", err)
1781			}
1782			if err == nil {
1783				libname := strings.TrimSpace(string(shlib))
1784				if cfg.BuildContext.Compiler == "gccgo" {
1785					p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, "shlibs", libname)
1786				} else {
1787					p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, libname)
1788				}
1789			}
1790		}
1791	}
1792
1793	// Build augmented import list to add implicit dependencies.
1794	// Be careful not to add imports twice, just to avoid confusion.
1795	importPaths := p.Imports
1796	addImport := func(path string, forCompiler bool) {
1797		for _, p := range importPaths {
1798			if path == p {
1799				return
1800			}
1801		}
1802		importPaths = append(importPaths, path)
1803		if forCompiler {
1804			p.Internal.CompiledImports = append(p.Internal.CompiledImports, path)
1805		}
1806	}
1807
1808	if !opts.IgnoreImports {
1809		// Cgo translation adds imports of "unsafe", "runtime/cgo" and "syscall",
1810		// except for certain packages, to avoid circular dependencies.
1811		if p.UsesCgo() {
1812			addImport("unsafe", true)
1813		}
1814		if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) && cfg.BuildContext.Compiler != "gccgo" {
1815			addImport("runtime/cgo", true)
1816		}
1817		if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
1818			addImport("syscall", true)
1819		}
1820
1821		// SWIG adds imports of some standard packages.
1822		if p.UsesSwig() {
1823			addImport("unsafe", true)
1824			if cfg.BuildContext.Compiler != "gccgo" {
1825				addImport("runtime/cgo", true)
1826			}
1827			addImport("syscall", true)
1828			addImport("sync", true)
1829
1830			// TODO: The .swig and .swigcxx files can use
1831			// %go_import directives to import other packages.
1832		}
1833
1834		// The linker loads implicit dependencies.
1835		if p.Name == "main" && !p.Internal.ForceLibrary {
1836			for _, dep := range LinkerDeps(p) {
1837				addImport(dep, false)
1838			}
1839		}
1840	}
1841
1842	// Check for case-insensitive collisions of import paths.
1843	fold := str.ToFold(p.ImportPath)
1844	if other := foldPath[fold]; other == "" {
1845		foldPath[fold] = p.ImportPath
1846	} else if other != p.ImportPath {
1847		setError(ImportErrorf(p.ImportPath, "case-insensitive import collision: %q and %q", p.ImportPath, other))
1848		return
1849	}
1850
1851	if !SafeArg(p.ImportPath) {
1852		setError(ImportErrorf(p.ImportPath, "invalid import path %q", p.ImportPath))
1853		return
1854	}
1855
1856	// Errors after this point are caused by this package, not the importing
1857	// package. Pushing the path here prevents us from reporting the error
1858	// with the position of the import declaration.
1859	stk.Push(path)
1860	defer stk.Pop()
1861
1862	pkgPath := p.ImportPath
1863	if p.Internal.CmdlineFiles {
1864		pkgPath = "command-line-arguments"
1865	}
1866	if cfg.ModulesEnabled {
1867		p.Module = modload.PackageModuleInfo(ctx, pkgPath)
1868	}
1869
1870	p.EmbedFiles, p.Internal.Embed, err = resolveEmbed(p.Dir, p.EmbedPatterns)
1871	if err != nil {
1872		p.Incomplete = true
1873		setError(err)
1874		embedErr := err.(*EmbedError)
1875		p.Error.setPos(p.Internal.Build.EmbedPatternPos[embedErr.Pattern])
1876	}
1877
1878	// Check for case-insensitive collision of input files.
1879	// To avoid problems on case-insensitive files, we reject any package
1880	// where two different input files have equal names under a case-insensitive
1881	// comparison.
1882	inputs := p.AllFiles()
1883	f1, f2 := str.FoldDup(inputs)
1884	if f1 != "" {
1885		setError(fmt.Errorf("case-insensitive file name collision: %q and %q", f1, f2))
1886		return
1887	}
1888
1889	// If first letter of input file is ASCII, it must be alphanumeric.
1890	// This avoids files turning into flags when invoking commands,
1891	// and other problems we haven't thought of yet.
1892	// Also, _cgo_ files must be generated by us, not supplied.
1893	// They are allowed to have //go:cgo_ldflag directives.
1894	// The directory scan ignores files beginning with _,
1895	// so we shouldn't see any _cgo_ files anyway, but just be safe.
1896	for _, file := range inputs {
1897		if !SafeArg(file) || strings.HasPrefix(file, "_cgo_") {
1898			setError(fmt.Errorf("invalid input file name %q", file))
1899			return
1900		}
1901	}
1902	if name := pathpkg.Base(p.ImportPath); !SafeArg(name) {
1903		setError(fmt.Errorf("invalid input directory name %q", name))
1904		return
1905	}
1906
1907	// Build list of imported packages and full dependency list.
1908	imports := make([]*Package, 0, len(p.Imports))
1909	for i, path := range importPaths {
1910		if path == "C" {
1911			continue
1912		}
1913		p1 := LoadImport(ctx, opts, path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], ResolveImport)
1914
1915		path = p1.ImportPath
1916		importPaths[i] = path
1917		if i < len(p.Imports) {
1918			p.Imports[i] = path
1919		}
1920
1921		imports = append(imports, p1)
1922		if p1.Incomplete {
1923			p.Incomplete = true
1924		}
1925	}
1926	p.Internal.Imports = imports
1927	p.collectDeps()
1928	if p.Error == nil && p.Name == "main" && len(p.DepsErrors) == 0 {
1929		p.setBuildInfo()
1930	}
1931
1932	// unsafe is a fake package.
1933	if p.Standard && (p.ImportPath == "unsafe" || cfg.BuildContext.Compiler == "gccgo") {
1934		p.Target = ""
1935	}
1936
1937	// If cgo is not enabled, ignore cgo supporting sources
1938	// just as we ignore go files containing import "C".
1939	if !cfg.BuildContext.CgoEnabled {
1940		p.CFiles = nil
1941		p.CXXFiles = nil
1942		p.MFiles = nil
1943		p.SwigFiles = nil
1944		p.SwigCXXFiles = nil
1945		// Note that SFiles are okay (they go to the Go assembler)
1946		// and HFiles are okay (they might be used by the SFiles).
1947		// Also Sysofiles are okay (they might not contain object
1948		// code; see issue #16050).
1949	}
1950
1951	// The gc toolchain only permits C source files with cgo or SWIG.
1952	if len(p.CFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() && cfg.BuildContext.Compiler == "gc" {
1953		setError(fmt.Errorf("C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CFiles, " ")))
1954		return
1955	}
1956
1957	// C++, Objective-C, and Fortran source files are permitted only with cgo or SWIG,
1958	// regardless of toolchain.
1959	if len(p.CXXFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
1960		setError(fmt.Errorf("C++ source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CXXFiles, " ")))
1961		return
1962	}
1963	if len(p.MFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
1964		setError(fmt.Errorf("Objective-C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.MFiles, " ")))
1965		return
1966	}
1967	if len(p.FFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
1968		setError(fmt.Errorf("Fortran source files not allowed when not using cgo or SWIG: %s", strings.Join(p.FFiles, " ")))
1969		return
1970	}
1971}
1972
1973// An EmbedError indicates a problem with a go:embed directive.
1974type EmbedError struct {
1975	Pattern string
1976	Err     error
1977}
1978
1979func (e *EmbedError) Error() string {
1980	return fmt.Sprintf("pattern %s: %v", e.Pattern, e.Err)
1981}
1982
1983func (e *EmbedError) Unwrap() error {
1984	return e.Err
1985}
1986
1987// ResolveEmbed resolves //go:embed patterns and returns only the file list.
1988// For use by go mod vendor to find embedded files it should copy into the
1989// vendor directory.
1990// TODO(#42504): Once go mod vendor uses load.PackagesAndErrors, just
1991// call (*Package).ResolveEmbed
1992func ResolveEmbed(dir string, patterns []string) ([]string, error) {
1993	files, _, err := resolveEmbed(dir, patterns)
1994	return files, err
1995}
1996
1997// resolveEmbed resolves //go:embed patterns to precise file lists.
1998// It sets files to the list of unique files matched (for go list),
1999// and it sets pmap to the more precise mapping from
2000// patterns to files.
2001func resolveEmbed(pkgdir string, patterns []string) (files []string, pmap map[string][]string, err error) {
2002	var pattern string
2003	defer func() {
2004		if err != nil {
2005			err = &EmbedError{
2006				Pattern: pattern,
2007				Err:     err,
2008			}
2009		}
2010	}()
2011
2012	// TODO(rsc): All these messages need position information for better error reports.
2013	pmap = make(map[string][]string)
2014	have := make(map[string]int)
2015	dirOK := make(map[string]bool)
2016	pid := 0 // pattern ID, to allow reuse of have map
2017	for _, pattern = range patterns {
2018		pid++
2019
2020		glob := pattern
2021		all := strings.HasPrefix(pattern, "all:")
2022		if all {
2023			glob = pattern[len("all:"):]
2024		}
2025		// Check pattern is valid for //go:embed.
2026		if _, err := path.Match(glob, ""); err != nil || !validEmbedPattern(glob) {
2027			return nil, nil, fmt.Errorf("invalid pattern syntax")
2028		}
2029
2030		// Glob to find matches.
2031		match, err := fsys.Glob(pkgdir + string(filepath.Separator) + filepath.FromSlash(glob))
2032		if err != nil {
2033			return nil, nil, err
2034		}
2035
2036		// Filter list of matches down to the ones that will still exist when
2037		// the directory is packaged up as a module. (If p.Dir is in the module cache,
2038		// only those files exist already, but if p.Dir is in the current module,
2039		// then there may be other things lying around, like symbolic links or .git directories.)
2040		var list []string
2041		for _, file := range match {
2042			rel := filepath.ToSlash(file[len(pkgdir)+1:]) // file, relative to p.Dir
2043
2044			what := "file"
2045			info, err := fsys.Lstat(file)
2046			if err != nil {
2047				return nil, nil, err
2048			}
2049			if info.IsDir() {
2050				what = "directory"
2051			}
2052
2053			// Check that directories along path do not begin a new module
2054			// (do not contain a go.mod).
2055			for dir := file; len(dir) > len(pkgdir)+1 && !dirOK[dir]; dir = filepath.Dir(dir) {
2056				if _, err := fsys.Stat(filepath.Join(dir, "go.mod")); err == nil {
2057					return nil, nil, fmt.Errorf("cannot embed %s %s: in different module", what, rel)
2058				}
2059				if dir != file {
2060					if info, err := fsys.Lstat(dir); err == nil && !info.IsDir() {
2061						return nil, nil, fmt.Errorf("cannot embed %s %s: in non-directory %s", what, rel, dir[len(pkgdir)+1:])
2062					}
2063				}
2064				dirOK[dir] = true
2065				if elem := filepath.Base(dir); isBadEmbedName(elem) {
2066					if dir == file {
2067						return nil, nil, fmt.Errorf("cannot embed %s %s: invalid name %s", what, rel, elem)
2068					} else {
2069						return nil, nil, fmt.Errorf("cannot embed %s %s: in invalid directory %s", what, rel, elem)
2070					}
2071				}
2072			}
2073
2074			switch {
2075			default:
2076				return nil, nil, fmt.Errorf("cannot embed irregular file %s", rel)
2077
2078			case info.Mode().IsRegular():
2079				if have[rel] != pid {
2080					have[rel] = pid
2081					list = append(list, rel)
2082				}
2083
2084			case info.IsDir():
2085				// Gather all files in the named directory, stopping at module boundaries
2086				// and ignoring files that wouldn't be packaged into a module.
2087				count := 0
2088				err := fsys.Walk(file, func(path string, info os.FileInfo, err error) error {
2089					if err != nil {
2090						return err
2091					}
2092					rel := filepath.ToSlash(path[len(pkgdir)+1:])
2093					name := info.Name()
2094					if path != file && (isBadEmbedName(name) || ((name[0] == '.' || name[0] == '_') && !all)) {
2095						// Ignore bad names, assuming they won't go into modules.
2096						// Also avoid hidden files that user may not know about.
2097						// See golang.org/issue/42328.
2098						if info.IsDir() {
2099							return fs.SkipDir
2100						}
2101						return nil
2102					}
2103					if info.IsDir() {
2104						if _, err := fsys.Stat(filepath.Join(path, "go.mod")); err == nil {
2105							return filepath.SkipDir
2106						}
2107						return nil
2108					}
2109					if !info.Mode().IsRegular() {
2110						return nil
2111					}
2112					count++
2113					if have[rel] != pid {
2114						have[rel] = pid
2115						list = append(list, rel)
2116					}
2117					return nil
2118				})
2119				if err != nil {
2120					return nil, nil, err
2121				}
2122				if count == 0 {
2123					return nil, nil, fmt.Errorf("cannot embed directory %s: contains no embeddable files", rel)
2124				}
2125			}
2126		}
2127
2128		if len(list) == 0 {
2129			return nil, nil, fmt.Errorf("no matching files found")
2130		}
2131		sort.Strings(list)
2132		pmap[pattern] = list
2133	}
2134
2135	for file := range have {
2136		files = append(files, file)
2137	}
2138	sort.Strings(files)
2139	return files, pmap, nil
2140}
2141
2142func validEmbedPattern(pattern string) bool {
2143	return pattern != "." && fs.ValidPath(pattern)
2144}
2145
2146// isBadEmbedName reports whether name is the base name of a file that
2147// can't or won't be included in modules and therefore shouldn't be treated
2148// as existing for embedding.
2149func isBadEmbedName(name string) bool {
2150	if err := module.CheckFilePath(name); err != nil {
2151		return true
2152	}
2153	switch name {
2154	// Empty string should be impossible but make it bad.
2155	case "":
2156		return true
2157	// Version control directories won't be present in module.
2158	case ".bzr", ".hg", ".git", ".svn":
2159		return true
2160	}
2161	return false
2162}
2163
2164// collectDeps populates p.Deps and p.DepsErrors by iterating over
2165// p.Internal.Imports.
2166//
2167// TODO(jayconrod): collectDeps iterates over transitive imports for every
2168// package. We should only need to visit direct imports.
2169func (p *Package) collectDeps() {
2170	deps := make(map[string]*Package)
2171	var q []*Package
2172	q = append(q, p.Internal.Imports...)
2173	for i := 0; i < len(q); i++ {
2174		p1 := q[i]
2175		path := p1.ImportPath
2176		// The same import path could produce an error or not,
2177		// depending on what tries to import it.
2178		// Prefer to record entries with errors, so we can report them.
2179		p0 := deps[path]
2180		if p0 == nil || p1.Error != nil && (p0.Error == nil || len(p0.Error.ImportStack) > len(p1.Error.ImportStack)) {
2181			deps[path] = p1
2182			for _, p2 := range p1.Internal.Imports {
2183				if deps[p2.ImportPath] != p2 {
2184					q = append(q, p2)
2185				}
2186			}
2187		}
2188	}
2189
2190	p.Deps = make([]string, 0, len(deps))
2191	for dep := range deps {
2192		p.Deps = append(p.Deps, dep)
2193	}
2194	sort.Strings(p.Deps)
2195	for _, dep := range p.Deps {
2196		p1 := deps[dep]
2197		if p1 == nil {
2198			panic("impossible: missing entry in package cache for " + dep + " imported by " + p.ImportPath)
2199		}
2200		if p1.Error != nil {
2201			p.DepsErrors = append(p.DepsErrors, p1.Error)
2202		}
2203	}
2204}
2205
2206// vcsStatusCache maps repository directories (string)
2207// to their VCS information (vcsStatusError).
2208var vcsStatusCache par.Cache
2209
2210// setBuildInfo gathers build information, formats it as a string to be
2211// embedded in the binary, then sets p.Internal.BuildInfo to that string.
2212// setBuildInfo should only be called on a main package with no errors.
2213//
2214// This information can be retrieved using debug.ReadBuildInfo.
2215//
2216// Note that the GoVersion field is not set here to avoid encoding it twice.
2217// It is stored separately in the binary, mostly for historical reasons.
2218func (p *Package) setBuildInfo() {
2219	// TODO: build and vcs information is not embedded for executables in GOROOT.
2220	// cmd/dist uses -gcflags=all= -ldflags=all= by default, which means these
2221	// executables always appear stale unless the user sets the same flags.
2222	// Perhaps it's safe to omit those flags when GO_GCFLAGS and GO_LDFLAGS
2223	// are not set?
2224	setPkgErrorf := func(format string, args ...any) {
2225		if p.Error == nil {
2226			p.Error = &PackageError{Err: fmt.Errorf(format, args...)}
2227		}
2228	}
2229
2230	var debugModFromModinfo func(*modinfo.ModulePublic) *debug.Module
2231	debugModFromModinfo = func(mi *modinfo.ModulePublic) *debug.Module {
2232		dm := &debug.Module{
2233			Path:    mi.Path,
2234			Version: mi.Version,
2235		}
2236		if mi.Replace != nil {
2237			dm.Replace = debugModFromModinfo(mi.Replace)
2238		} else {
2239			dm.Sum = modfetch.Sum(module.Version{Path: mi.Path, Version: mi.Version})
2240		}
2241		return dm
2242	}
2243
2244	var main debug.Module
2245	if p.Module != nil {
2246		main = *debugModFromModinfo(p.Module)
2247	}
2248
2249	visited := make(map[*Package]bool)
2250	mdeps := make(map[module.Version]*debug.Module)
2251	var q []*Package
2252	q = append(q, p.Internal.Imports...)
2253	for len(q) > 0 {
2254		p1 := q[0]
2255		q = q[1:]
2256		if visited[p1] {
2257			continue
2258		}
2259		visited[p1] = true
2260		if p1.Module != nil {
2261			m := module.Version{Path: p1.Module.Path, Version: p1.Module.Version}
2262			if p1.Module.Path != main.Path && mdeps[m] == nil {
2263				mdeps[m] = debugModFromModinfo(p1.Module)
2264			}
2265		}
2266		q = append(q, p1.Internal.Imports...)
2267	}
2268	sortedMods := make([]module.Version, 0, len(mdeps))
2269	for mod := range mdeps {
2270		sortedMods = append(sortedMods, mod)
2271	}
2272	module.Sort(sortedMods)
2273	deps := make([]*debug.Module, len(sortedMods))
2274	for i, mod := range sortedMods {
2275		deps[i] = mdeps[mod]
2276	}
2277
2278	pkgPath := p.ImportPath
2279	if p.Internal.CmdlineFiles {
2280		pkgPath = "command-line-arguments"
2281	}
2282	info := &debug.BuildInfo{
2283		Path: pkgPath,
2284		Main: main,
2285		Deps: deps,
2286	}
2287	appendSetting := func(key, value string) {
2288		value = strings.ReplaceAll(value, "\n", " ") // make value safe
2289		info.Settings = append(info.Settings, debug.BuildSetting{Key: key, Value: value})
2290	}
2291
2292	// Add command-line flags relevant to the build.
2293	// This is informational, not an exhaustive list.
2294	// Please keep the list sorted.
2295	if cfg.BuildBuildinfo && !p.Standard {
2296		if cfg.BuildASan {
2297			appendSetting("-asan", "true")
2298		}
2299		if BuildAsmflags.present {
2300			appendSetting("-asmflags", BuildAsmflags.String())
2301		}
2302		appendSetting("-compiler", cfg.BuildContext.Compiler)
2303		if BuildGccgoflags.present && cfg.BuildContext.Compiler == "gccgo" {
2304			appendSetting("-gccgoflags", BuildGccgoflags.String())
2305		}
2306		if BuildGcflags.present && cfg.BuildContext.Compiler == "gc" {
2307			appendSetting("-gcflags", BuildGcflags.String())
2308		}
2309		if BuildLdflags.present {
2310			appendSetting("-ldflags", BuildLdflags.String())
2311		}
2312		if cfg.BuildMSan {
2313			appendSetting("-msan", "true")
2314		}
2315		if cfg.BuildRace {
2316			appendSetting("-race", "true")
2317		}
2318		if tags := cfg.BuildContext.BuildTags; len(tags) > 0 {
2319			appendSetting("-tags", strings.Join(tags, ","))
2320		}
2321		cgo := "0"
2322		if cfg.BuildContext.CgoEnabled {
2323			cgo = "1"
2324		}
2325		appendSetting("CGO_ENABLED", cgo)
2326		if cfg.BuildContext.CgoEnabled {
2327			for _, name := range []string{"CGO_CFLAGS", "CGO_CPPFLAGS", "CGO_CXXFLAGS", "CGO_LDFLAGS"} {
2328				appendSetting(name, cfg.Getenv(name))
2329			}
2330		}
2331		appendSetting("GOARCH", cfg.BuildContext.GOARCH)
2332		if cfg.GOEXPERIMENT != "" {
2333			appendSetting("GOEXPERIMENT", cfg.GOEXPERIMENT)
2334		}
2335		appendSetting("GOOS", cfg.BuildContext.GOOS)
2336		if key, val := cfg.GetArchEnv(); key != "" && val != "" {
2337			appendSetting(key, val)
2338		}
2339	}
2340
2341	// Add VCS status if all conditions are true:
2342	//
2343	// - -buildvcs is enabled.
2344	// - p is contained within a main module (there may be multiple main modules
2345	//   in a workspace, but local replacements don't count).
2346	// - Both the current directory and p's module's root directory are contained
2347	//   in the same local repository.
2348	// - We know the VCS commands needed to get the status.
2349	setVCSError := func(err error) {
2350		setPkgErrorf("error obtaining VCS status: %v\n\tUse -buildvcs=false to disable VCS stamping.", err)
2351	}
2352
2353	var repoDir string
2354	var vcsCmd *vcs.Cmd
2355	var err error
2356	const allowNesting = true
2357	if cfg.BuildBuildvcs && p.Module != nil && p.Module.Version == "" && !p.Standard {
2358		repoDir, vcsCmd, err = vcs.FromDir(base.Cwd(), "", allowNesting)
2359		if err != nil && !errors.Is(err, os.ErrNotExist) {
2360			setVCSError(err)
2361			return
2362		}
2363		if !str.HasFilePathPrefix(p.Module.Dir, repoDir) &&
2364			!str.HasFilePathPrefix(repoDir, p.Module.Dir) {
2365			// The module containing the main package does not overlap with the
2366			// repository containing the working directory. Don't include VCS info.
2367			// If the repo contains the module or vice versa, but they are not
2368			// the same directory, it's likely an error (see below).
2369			repoDir, vcsCmd = "", nil
2370		}
2371	}
2372	if repoDir != "" && vcsCmd.Status != nil {
2373		// Check that the current directory, package, and module are in the same
2374		// repository. vcs.FromDir allows nested Git repositories, but nesting
2375		// is not allowed for other VCS tools. The current directory may be outside
2376		// p.Module.Dir when a workspace is used.
2377		pkgRepoDir, _, err := vcs.FromDir(p.Dir, "", allowNesting)
2378		if err != nil {
2379			setVCSError(err)
2380			return
2381		}
2382		if pkgRepoDir != repoDir {
2383			setVCSError(fmt.Errorf("main package is in repository %q but current directory is in repository %q", pkgRepoDir, repoDir))
2384			return
2385		}
2386		modRepoDir, _, err := vcs.FromDir(p.Module.Dir, "", allowNesting)
2387		if err != nil {
2388			setVCSError(err)
2389			return
2390		}
2391		if modRepoDir != repoDir {
2392			setVCSError(fmt.Errorf("main module is in repository %q but current directory is in repository %q", modRepoDir, repoDir))
2393			return
2394		}
2395
2396		type vcsStatusError struct {
2397			Status vcs.Status
2398			Err    error
2399		}
2400		cached := vcsStatusCache.Do(repoDir, func() any {
2401			st, err := vcsCmd.Status(vcsCmd, repoDir)
2402			return vcsStatusError{st, err}
2403		}).(vcsStatusError)
2404		if err := cached.Err; err != nil {
2405			setVCSError(err)
2406			return
2407		}
2408		st := cached.Status
2409
2410		appendSetting("vcs", vcsCmd.Cmd)
2411		if st.Revision != "" {
2412			appendSetting("vcs.revision", st.Revision)
2413		}
2414		if !st.CommitTime.IsZero() {
2415			stamp := st.CommitTime.UTC().Format(time.RFC3339Nano)
2416			appendSetting("vcs.time", stamp)
2417		}
2418		appendSetting("vcs.modified", strconv.FormatBool(st.Uncommitted))
2419	}
2420
2421	text, err := info.MarshalText()
2422	if err != nil {
2423		setPkgErrorf("error formatting build info: %v", err)
2424		return
2425	}
2426	p.Internal.BuildInfo = string(text)
2427}
2428
2429// SafeArg reports whether arg is a "safe" command-line argument,
2430// meaning that when it appears in a command-line, it probably
2431// doesn't have some special meaning other than its own name.
2432// Obviously args beginning with - are not safe (they look like flags).
2433// Less obviously, args beginning with @ are not safe (they look like
2434// GNU binutils flagfile specifiers, sometimes called "response files").
2435// To be conservative, we reject almost any arg beginning with non-alphanumeric ASCII.
2436// We accept leading . _ and / as likely in file system paths.
2437// There is a copy of this function in cmd/compile/internal/gc/noder.go.
2438func SafeArg(name string) bool {
2439	if name == "" {
2440		return false
2441	}
2442	c := name[0]
2443	return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '.' || c == '_' || c == '/' || c >= utf8.RuneSelf
2444}
2445
2446// LinkerDeps returns the list of linker-induced dependencies for main package p.
2447func LinkerDeps(p *Package) []string {
2448	// Everything links runtime.
2449	deps := []string{"runtime"}
2450
2451	// External linking mode forces an import of runtime/cgo.
2452	if externalLinkingForced(p) && cfg.BuildContext.Compiler != "gccgo" {
2453		deps = append(deps, "runtime/cgo")
2454	}
2455	// On ARM with GOARM=5, it forces an import of math, for soft floating point.
2456	if cfg.Goarch == "arm" {
2457		deps = append(deps, "math")
2458	}
2459	// Using the race detector forces an import of runtime/race.
2460	if cfg.BuildRace {
2461		deps = append(deps, "runtime/race")
2462	}
2463	// Using memory sanitizer forces an import of runtime/msan.
2464	if cfg.BuildMSan {
2465		deps = append(deps, "runtime/msan")
2466	}
2467	// Using address sanitizer forces an import of runtime/asan.
2468	if cfg.BuildASan {
2469		deps = append(deps, "runtime/asan")
2470	}
2471
2472	return deps
2473}
2474
2475// externalLinkingForced reports whether external linking is being
2476// forced even for programs that do not use cgo.
2477func externalLinkingForced(p *Package) bool {
2478	if !cfg.BuildContext.CgoEnabled {
2479		return false
2480	}
2481
2482	// Some targets must use external linking even inside GOROOT.
2483	switch cfg.BuildContext.GOOS {
2484	case "android":
2485		if cfg.BuildContext.GOARCH != "arm64" {
2486			return true
2487		}
2488	case "ios":
2489		return true
2490	}
2491
2492	// Currently build modes c-shared, pie (on systems that do not
2493	// support PIE with internal linking mode (currently all
2494	// systems: issue #18968)), plugin, and -linkshared force
2495	// external linking mode, as of course does
2496	// -ldflags=-linkmode=external. External linking mode forces
2497	// an import of runtime/cgo.
2498	// If there are multiple -linkmode options, the last one wins.
2499	pieCgo := cfg.BuildBuildmode == "pie" && !sys.InternalLinkPIESupported(cfg.BuildContext.GOOS, cfg.BuildContext.GOARCH)
2500	linkmodeExternal := false
2501	if p != nil {
2502		ldflags := BuildLdflags.For(p)
2503		for i := len(ldflags) - 1; i >= 0; i-- {
2504			a := ldflags[i]
2505			if a == "-linkmode=external" ||
2506				a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" {
2507				linkmodeExternal = true
2508				break
2509			} else if a == "-linkmode=internal" ||
2510				a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "internal" {
2511				break
2512			}
2513		}
2514	}
2515
2516	return cfg.BuildBuildmode == "c-shared" || cfg.BuildBuildmode == "plugin" || pieCgo || cfg.BuildLinkshared || linkmodeExternal
2517}
2518
2519// mkAbs rewrites list, which must be paths relative to p.Dir,
2520// into a sorted list of absolute paths. It edits list in place but for
2521// convenience also returns list back to its caller.
2522func (p *Package) mkAbs(list []string) []string {
2523	for i, f := range list {
2524		list[i] = filepath.Join(p.Dir, f)
2525	}
2526	sort.Strings(list)
2527	return list
2528}
2529
2530// InternalGoFiles returns the list of Go files being built for the package,
2531// using absolute paths.
2532func (p *Package) InternalGoFiles() []string {
2533	return p.mkAbs(str.StringList(p.GoFiles, p.CgoFiles, p.TestGoFiles))
2534}
2535
2536// InternalXGoFiles returns the list of Go files being built for the XTest package,
2537// using absolute paths.
2538func (p *Package) InternalXGoFiles() []string {
2539	return p.mkAbs(p.XTestGoFiles)
2540}
2541
2542// InternalGoFiles returns the list of all Go files possibly relevant for the package,
2543// using absolute paths. "Possibly relevant" means that files are not excluded
2544// due to build tags, but files with names beginning with . or _ are still excluded.
2545func (p *Package) InternalAllGoFiles() []string {
2546	return p.mkAbs(str.StringList(p.IgnoredGoFiles, p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles))
2547}
2548
2549// usesSwig reports whether the package needs to run SWIG.
2550func (p *Package) UsesSwig() bool {
2551	return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0
2552}
2553
2554// usesCgo reports whether the package needs to run cgo
2555func (p *Package) UsesCgo() bool {
2556	return len(p.CgoFiles) > 0
2557}
2558
2559// PackageList returns the list of packages in the dag rooted at roots
2560// as visited in a depth-first post-order traversal.
2561func PackageList(roots []*Package) []*Package {
2562	seen := map[*Package]bool{}
2563	all := []*Package{}
2564	var walk func(*Package)
2565	walk = func(p *Package) {
2566		if seen[p] {
2567			return
2568		}
2569		seen[p] = true
2570		for _, p1 := range p.Internal.Imports {
2571			walk(p1)
2572		}
2573		all = append(all, p)
2574	}
2575	for _, root := range roots {
2576		walk(root)
2577	}
2578	return all
2579}
2580
2581// TestPackageList returns the list of packages in the dag rooted at roots
2582// as visited in a depth-first post-order traversal, including the test
2583// imports of the roots. This ignores errors in test packages.
2584func TestPackageList(ctx context.Context, opts PackageOpts, roots []*Package) []*Package {
2585	seen := map[*Package]bool{}
2586	all := []*Package{}
2587	var walk func(*Package)
2588	walk = func(p *Package) {
2589		if seen[p] {
2590			return
2591		}
2592		seen[p] = true
2593		for _, p1 := range p.Internal.Imports {
2594			walk(p1)
2595		}
2596		all = append(all, p)
2597	}
2598	walkTest := func(root *Package, path string) {
2599		var stk ImportStack
2600		p1 := LoadImport(ctx, opts, path, root.Dir, root, &stk, root.Internal.Build.TestImportPos[path], ResolveImport)
2601		if p1.Error == nil {
2602			walk(p1)
2603		}
2604	}
2605	for _, root := range roots {
2606		walk(root)
2607		for _, path := range root.TestImports {
2608			walkTest(root, path)
2609		}
2610		for _, path := range root.XTestImports {
2611			walkTest(root, path)
2612		}
2613	}
2614	return all
2615}
2616
2617// LoadImportWithFlags loads the package with the given import path and
2618// sets tool flags on that package. This function is useful loading implicit
2619// dependencies (like sync/atomic for coverage).
2620// TODO(jayconrod): delete this function and set flags automatically
2621// in LoadImport instead.
2622func LoadImportWithFlags(path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
2623	p := LoadImport(context.TODO(), PackageOpts{}, path, srcDir, parent, stk, importPos, mode)
2624	setToolFlags(p)
2625	return p
2626}
2627
2628// PackageOpts control the behavior of PackagesAndErrors and other package
2629// loading functions.
2630type PackageOpts struct {
2631	// IgnoreImports controls whether we ignore explicit and implicit imports
2632	// when loading packages.  Implicit imports are added when supporting Cgo
2633	// or SWIG and when linking main packages.
2634	IgnoreImports bool
2635
2636	// ModResolveTests indicates whether calls to the module loader should also
2637	// resolve test dependencies of the requested packages.
2638	//
2639	// If ModResolveTests is true, then the module loader needs to resolve test
2640	// dependencies at the same time as packages; otherwise, the test dependencies
2641	// of those packages could be missing, and resolving those missing dependencies
2642	// could change the selected versions of modules that provide other packages.
2643	ModResolveTests bool
2644
2645	// MainOnly is true if the caller only wants to load main packages.
2646	// For a literal argument matching a non-main package, a stub may be returned
2647	// with an error. For a non-literal argument (with "..."), non-main packages
2648	// are not be matched, and their dependencies may not be loaded. A warning
2649	// may be printed for non-literal arguments that match no main packages.
2650	MainOnly bool
2651}
2652
2653// PackagesAndErrors returns the packages named by the command line arguments
2654// 'patterns'. If a named package cannot be loaded, PackagesAndErrors returns
2655// a *Package with the Error field describing the failure. If errors are found
2656// loading imported packages, the DepsErrors field is set. The Incomplete field
2657// may be set as well.
2658//
2659// To obtain a flat list of packages, use PackageList.
2660// To report errors loading packages, use ReportPackageErrors.
2661func PackagesAndErrors(ctx context.Context, opts PackageOpts, patterns []string) []*Package {
2662	ctx, span := trace.StartSpan(ctx, "load.PackagesAndErrors")
2663	defer span.Done()
2664
2665	for _, p := range patterns {
2666		// Listing is only supported with all patterns referring to either:
2667		// - Files that are part of the same directory.
2668		// - Explicit package paths or patterns.
2669		if strings.HasSuffix(p, ".go") {
2670			// We need to test whether the path is an actual Go file and not a
2671			// package path or pattern ending in '.go' (see golang.org/issue/34653).
2672			if fi, err := fsys.Stat(p); err == nil && !fi.IsDir() {
2673				return []*Package{GoFilesPackage(ctx, opts, patterns)}
2674			}
2675		}
2676	}
2677
2678	var matches []*search.Match
2679	if modload.Init(); cfg.ModulesEnabled {
2680		modOpts := modload.PackageOpts{
2681			ResolveMissingImports: true,
2682			LoadTests:             opts.ModResolveTests,
2683			SilencePackageErrors:  true,
2684		}
2685		matches, _ = modload.LoadPackages(ctx, modOpts, patterns...)
2686	} else {
2687		noModRoots := []string{}
2688		matches = search.ImportPaths(patterns, noModRoots)
2689	}
2690
2691	var (
2692		pkgs    []*Package
2693		stk     ImportStack
2694		seenPkg = make(map[*Package]bool)
2695	)
2696
2697	pre := newPreload()
2698	defer pre.flush()
2699	pre.preloadMatches(ctx, opts, matches)
2700
2701	for _, m := range matches {
2702		for _, pkg := range m.Pkgs {
2703			if pkg == "" {
2704				panic(fmt.Sprintf("ImportPaths returned empty package for pattern %s", m.Pattern()))
2705			}
2706			p := loadImport(ctx, opts, pre, pkg, base.Cwd(), nil, &stk, nil, 0)
2707			p.Match = append(p.Match, m.Pattern())
2708			p.Internal.CmdlinePkg = true
2709			if m.IsLiteral() {
2710				// Note: do not set = m.IsLiteral unconditionally
2711				// because maybe we'll see p matching both
2712				// a literal and also a non-literal pattern.
2713				p.Internal.CmdlinePkgLiteral = true
2714			}
2715			if seenPkg[p] {
2716				continue
2717			}
2718			seenPkg[p] = true
2719			pkgs = append(pkgs, p)
2720		}
2721
2722		if len(m.Errs) > 0 {
2723			// In addition to any packages that were actually resolved from the
2724			// pattern, there was some error in resolving the pattern itself.
2725			// Report it as a synthetic package.
2726			p := new(Package)
2727			p.ImportPath = m.Pattern()
2728			// Pass an empty ImportStack and nil importPos: the error arose from a pattern, not an import.
2729			var stk ImportStack
2730			var importPos []token.Position
2731			p.setLoadPackageDataError(m.Errs[0], m.Pattern(), &stk, importPos)
2732			p.Incomplete = true
2733			p.Match = append(p.Match, m.Pattern())
2734			p.Internal.CmdlinePkg = true
2735			if m.IsLiteral() {
2736				p.Internal.CmdlinePkgLiteral = true
2737			}
2738			pkgs = append(pkgs, p)
2739		}
2740	}
2741
2742	if opts.MainOnly {
2743		pkgs = mainPackagesOnly(pkgs, matches)
2744	}
2745
2746	// Now that CmdlinePkg is set correctly,
2747	// compute the effective flags for all loaded packages
2748	// (not just the ones matching the patterns but also
2749	// their dependencies).
2750	setToolFlags(pkgs...)
2751
2752	return pkgs
2753}
2754
2755// CheckPackageErrors prints errors encountered loading pkgs and their
2756// dependencies, then exits with a non-zero status if any errors were found.
2757func CheckPackageErrors(pkgs []*Package) {
2758	printed := map[*PackageError]bool{}
2759	for _, pkg := range pkgs {
2760		if pkg.Error != nil {
2761			base.Errorf("%v", pkg.Error)
2762			printed[pkg.Error] = true
2763		}
2764		for _, err := range pkg.DepsErrors {
2765			// Since these are errors in dependencies,
2766			// the same error might show up multiple times,
2767			// once in each package that depends on it.
2768			// Only print each once.
2769			if !printed[err] {
2770				printed[err] = true
2771				base.Errorf("%v", err)
2772			}
2773		}
2774	}
2775	base.ExitIfErrors()
2776
2777	// Check for duplicate loads of the same package.
2778	// That should be impossible, but if it does happen then
2779	// we end up trying to build the same package twice,
2780	// usually in parallel overwriting the same files,
2781	// which doesn't work very well.
2782	seen := map[string]bool{}
2783	reported := map[string]bool{}
2784	for _, pkg := range PackageList(pkgs) {
2785		if seen[pkg.ImportPath] && !reported[pkg.ImportPath] {
2786			reported[pkg.ImportPath] = true
2787			base.Errorf("internal error: duplicate loads of %s", pkg.ImportPath)
2788		}
2789		seen[pkg.ImportPath] = true
2790	}
2791	base.ExitIfErrors()
2792}
2793
2794// mainPackagesOnly filters out non-main packages matched only by arguments
2795// containing "..." and returns the remaining main packages.
2796//
2797// Packages with missing, invalid, or ambiguous names may be treated as
2798// possibly-main packages.
2799//
2800// mainPackagesOnly sets a non-main package's Error field and returns it if it
2801// is named by a literal argument.
2802//
2803// mainPackagesOnly prints warnings for non-literal arguments that only match
2804// non-main packages.
2805func mainPackagesOnly(pkgs []*Package, matches []*search.Match) []*Package {
2806	treatAsMain := map[string]bool{}
2807	for _, m := range matches {
2808		if m.IsLiteral() {
2809			for _, path := range m.Pkgs {
2810				treatAsMain[path] = true
2811			}
2812		}
2813	}
2814
2815	var mains []*Package
2816	for _, pkg := range pkgs {
2817		if pkg.Name == "main" {
2818			treatAsMain[pkg.ImportPath] = true
2819			mains = append(mains, pkg)
2820			continue
2821		}
2822
2823		if len(pkg.InvalidGoFiles) > 0 { // TODO(#45999): && pkg.Name == "", but currently go/build sets pkg.Name arbitrarily if it is ambiguous.
2824			// The package has (or may have) conflicting names, and we can't easily
2825			// tell whether one of them is "main". So assume that it could be, and
2826			// report an error for the package.
2827			treatAsMain[pkg.ImportPath] = true
2828		}
2829		if treatAsMain[pkg.ImportPath] {
2830			if pkg.Error == nil {
2831				pkg.Error = &PackageError{Err: &mainPackageError{importPath: pkg.ImportPath}}
2832			}
2833			mains = append(mains, pkg)
2834		}
2835	}
2836
2837	for _, m := range matches {
2838		if m.IsLiteral() || len(m.Pkgs) == 0 {
2839			continue
2840		}
2841		foundMain := false
2842		for _, path := range m.Pkgs {
2843			if treatAsMain[path] {
2844				foundMain = true
2845				break
2846			}
2847		}
2848		if !foundMain {
2849			fmt.Fprintf(os.Stderr, "go: warning: %q matched only non-main packages\n", m.Pattern())
2850		}
2851	}
2852
2853	return mains
2854}
2855
2856type mainPackageError struct {
2857	importPath string
2858}
2859
2860func (e *mainPackageError) Error() string {
2861	return fmt.Sprintf("package %s is not a main package", e.importPath)
2862}
2863
2864func (e *mainPackageError) ImportPath() string {
2865	return e.importPath
2866}
2867
2868func setToolFlags(pkgs ...*Package) {
2869	for _, p := range PackageList(pkgs) {
2870		p.Internal.Asmflags = BuildAsmflags.For(p)
2871		p.Internal.Gcflags = BuildGcflags.For(p)
2872		p.Internal.Ldflags = BuildLdflags.For(p)
2873		p.Internal.Gccgoflags = BuildGccgoflags.For(p)
2874	}
2875}
2876
2877// GoFilesPackage creates a package for building a collection of Go files
2878// (typically named on the command line). The target is named p.a for
2879// package p or named after the first Go file for package main.
2880func GoFilesPackage(ctx context.Context, opts PackageOpts, gofiles []string) *Package {
2881	modload.Init()
2882
2883	for _, f := range gofiles {
2884		if !strings.HasSuffix(f, ".go") {
2885			pkg := new(Package)
2886			pkg.Internal.Local = true
2887			pkg.Internal.CmdlineFiles = true
2888			pkg.Name = f
2889			pkg.Error = &PackageError{
2890				Err: fmt.Errorf("named files must be .go files: %s", pkg.Name),
2891			}
2892			return pkg
2893		}
2894	}
2895
2896	var stk ImportStack
2897	ctxt := cfg.BuildContext
2898	ctxt.UseAllFiles = true
2899
2900	// Synthesize fake "directory" that only shows the named files,
2901	// to make it look like this is a standard package or
2902	// command directory. So that local imports resolve
2903	// consistently, the files must all be in the same directory.
2904	var dirent []fs.FileInfo
2905	var dir string
2906	for _, file := range gofiles {
2907		fi, err := fsys.Stat(file)
2908		if err != nil {
2909			base.Fatalf("%s", err)
2910		}
2911		if fi.IsDir() {
2912			base.Fatalf("%s is a directory, should be a Go file", file)
2913		}
2914		dir1 := filepath.Dir(file)
2915		if dir == "" {
2916			dir = dir1
2917		} else if dir != dir1 {
2918			base.Fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
2919		}
2920		dirent = append(dirent, fi)
2921	}
2922	ctxt.ReadDir = func(string) ([]fs.FileInfo, error) { return dirent, nil }
2923
2924	if cfg.ModulesEnabled {
2925		modload.ImportFromFiles(ctx, gofiles)
2926	}
2927
2928	var err error
2929	if dir == "" {
2930		dir = base.Cwd()
2931	}
2932	dir, err = filepath.Abs(dir)
2933	if err != nil {
2934		base.Fatalf("%s", err)
2935	}
2936
2937	bp, err := ctxt.ImportDir(dir, 0)
2938	pkg := new(Package)
2939	pkg.Internal.Local = true
2940	pkg.Internal.CmdlineFiles = true
2941	pkg.load(ctx, opts, "command-line-arguments", &stk, nil, bp, err)
2942	if !cfg.ModulesEnabled {
2943		pkg.Internal.LocalPrefix = dirToImportPath(dir)
2944	}
2945	pkg.ImportPath = "command-line-arguments"
2946	pkg.Target = ""
2947	pkg.Match = gofiles
2948
2949	if pkg.Name == "main" {
2950		exe := pkg.DefaultExecName() + cfg.ExeSuffix
2951
2952		if cfg.GOBIN != "" {
2953			pkg.Target = filepath.Join(cfg.GOBIN, exe)
2954		} else if cfg.ModulesEnabled {
2955			pkg.Target = filepath.Join(modload.BinDir(), exe)
2956		}
2957	}
2958
2959	if opts.MainOnly && pkg.Name != "main" && pkg.Error == nil {
2960		pkg.Error = &PackageError{Err: &mainPackageError{importPath: pkg.ImportPath}}
2961	}
2962	setToolFlags(pkg)
2963
2964	return pkg
2965}
2966
2967// PackagesAndErrorsOutsideModule is like PackagesAndErrors but runs in
2968// module-aware mode and ignores the go.mod file in the current directory or any
2969// parent directory, if there is one. This is used in the implementation of 'go
2970// install pkg@version' and other commands that support similar forms.
2971//
2972// modload.ForceUseModules must be true, and modload.RootMode must be NoRoot
2973// before calling this function.
2974//
2975// PackagesAndErrorsOutsideModule imposes several constraints to avoid
2976// ambiguity. All arguments must have the same version suffix (not just a suffix
2977// that resolves to the same version). They must refer to packages in the same
2978// module, which must not be std or cmd. That module is not considered the main
2979// module, but its go.mod file (if it has one) must not contain directives that
2980// would cause it to be interpreted differently if it were the main module
2981// (replace, exclude).
2982func PackagesAndErrorsOutsideModule(ctx context.Context, opts PackageOpts, args []string) ([]*Package, error) {
2983	if !modload.ForceUseModules {
2984		panic("modload.ForceUseModules must be true")
2985	}
2986	if modload.RootMode != modload.NoRoot {
2987		panic("modload.RootMode must be NoRoot")
2988	}
2989
2990	// Check that the arguments satisfy syntactic constraints.
2991	var version string
2992	for _, arg := range args {
2993		if i := strings.Index(arg, "@"); i >= 0 {
2994			version = arg[i+1:]
2995			if version == "" {
2996				return nil, fmt.Errorf("%s: version must not be empty", arg)
2997			}
2998			break
2999		}
3000	}
3001	patterns := make([]string, len(args))
3002	for i, arg := range args {
3003		if !strings.HasSuffix(arg, "@"+version) {
3004			return nil, fmt.Errorf("%s: all arguments must have the same version (@%s)", arg, version)
3005		}
3006		p := arg[:len(arg)-len(version)-1]
3007		switch {
3008		case build.IsLocalImport(p):
3009			return nil, fmt.Errorf("%s: argument must be a package path, not a relative path", arg)
3010		case filepath.IsAbs(p):
3011			return nil, fmt.Errorf("%s: argument must be a package path, not an absolute path", arg)
3012		case search.IsMetaPackage(p):
3013			return nil, fmt.Errorf("%s: argument must be a package path, not a meta-package", arg)
3014		case path.Clean(p) != p:
3015			return nil, fmt.Errorf("%s: argument must be a clean package path", arg)
3016		case !strings.Contains(p, "...") && search.IsStandardImportPath(p) && goroot.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, p):
3017			return nil, fmt.Errorf("%s: argument must not be a package in the standard library", arg)
3018		default:
3019			patterns[i] = p
3020		}
3021	}
3022
3023	// Query the module providing the first argument, load its go.mod file, and
3024	// check that it doesn't contain directives that would cause it to be
3025	// interpreted differently if it were the main module.
3026	//
3027	// If multiple modules match the first argument, accept the longest match
3028	// (first result). It's possible this module won't provide packages named by
3029	// later arguments, and other modules would. Let's not try to be too
3030	// magical though.
3031	allowed := modload.CheckAllowed
3032	if modload.IsRevisionQuery(version) {
3033		// Don't check for retractions if a specific revision is requested.
3034		allowed = nil
3035	}
3036	noneSelected := func(path string) (version string) { return "none" }
3037	qrs, err := modload.QueryPackages(ctx, patterns[0], version, noneSelected, allowed)
3038	if err != nil {
3039		return nil, fmt.Errorf("%s: %w", args[0], err)
3040	}
3041	rootMod := qrs[0].Mod
3042	data, err := modfetch.GoMod(rootMod.Path, rootMod.Version)
3043	if err != nil {
3044		return nil, fmt.Errorf("%s: %w", args[0], err)
3045	}
3046	f, err := modfile.Parse("go.mod", data, nil)
3047	if err != nil {
3048		return nil, fmt.Errorf("%s (in %s): %w", args[0], rootMod, err)
3049	}
3050	directiveFmt := "%s (in %s):\n" +
3051		"\tThe go.mod file for the module providing named packages contains one or\n" +
3052		"\tmore %s directives. It must not contain directives that would cause\n" +
3053		"\tit to be interpreted differently than if it were the main module."
3054	if len(f.Replace) > 0 {
3055		return nil, fmt.Errorf(directiveFmt, args[0], rootMod, "replace")
3056	}
3057	if len(f.Exclude) > 0 {
3058		return nil, fmt.Errorf(directiveFmt, args[0], rootMod, "exclude")
3059	}
3060
3061	// Since we are in NoRoot mode, the build list initially contains only
3062	// the dummy command-line-arguments module. Add a requirement on the
3063	// module that provides the packages named on the command line.
3064	if _, err := modload.EditBuildList(ctx, nil, []module.Version{rootMod}); err != nil {
3065		return nil, fmt.Errorf("%s: %w", args[0], err)
3066	}
3067
3068	// Load packages for all arguments.
3069	pkgs := PackagesAndErrors(ctx, opts, patterns)
3070
3071	// Check that named packages are all provided by the same module.
3072	for _, pkg := range pkgs {
3073		var pkgErr error
3074		if pkg.Module == nil {
3075			// Packages in std, cmd, and their vendored dependencies
3076			// don't have this field set.
3077			pkgErr = fmt.Errorf("package %s not provided by module %s", pkg.ImportPath, rootMod)
3078		} else if pkg.Module.Path != rootMod.Path || pkg.Module.Version != rootMod.Version {
3079			pkgErr = fmt.Errorf("package %s provided by module %s@%s\n\tAll packages must be provided by the same module (%s).", pkg.ImportPath, pkg.Module.Path, pkg.Module.Version, rootMod)
3080		}
3081		if pkgErr != nil && pkg.Error == nil {
3082			pkg.Error = &PackageError{Err: pkgErr}
3083		}
3084	}
3085
3086	matchers := make([]func(string) bool, len(patterns))
3087	for i, p := range patterns {
3088		if strings.Contains(p, "...") {
3089			matchers[i] = search.MatchPattern(p)
3090		}
3091	}
3092	return pkgs, nil
3093}
3094