// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package base

import (
	"cmd/internal/cov/covcmd"
	"cmd/internal/telemetry"
	"encoding/json"
	"flag"
	"fmt"
	"internal/buildcfg"
	"internal/platform"
	"log"
	"os"
	"reflect"
	"runtime"
	"strings"

	"cmd/internal/obj"
	"cmd/internal/objabi"
	"cmd/internal/sys"
)

func usage() {
	fmt.Fprintf(os.Stderr, "usage: compile [options] file.go...\n")
	objabi.Flagprint(os.Stderr)
	Exit(2)
}

// Flag holds the parsed command-line flags.
// See ParseFlag for non-zero defaults.
var Flag CmdFlags

// A CountFlag is a counting integer flag.
// It accepts -name=value to set the value directly,
// but it also accepts -name with no =value to increment the count.
type CountFlag int

// CmdFlags defines the command-line flags (see var Flag).
// Each struct field is a different flag, by default named for the lower-case of the field name.
// If the flag name is a single letter, the default flag name is left upper-case.
// If the flag name is "Lower" followed by a single letter, the default flag name is the lower-case of the last letter.
//
// If this default flag name can't be made right, the `flag` struct tag can be used to replace it,
// but this should be done only in exceptional circumstances: it helps everyone if the flag name
// is obvious from the field name when the flag is used elsewhere in the compiler sources.
// The `flag:"-"` struct tag makes a field invisible to the flag logic and should also be used sparingly.
//
// Each field must have a `help` struct tag giving the flag help message.
//
// The allowed field types are bool, int, string, pointers to those (for values stored elsewhere),
// CountFlag (for a counting flag), and func(string) (for a flag that uses special code for parsing).
type CmdFlags struct {
	// Single letters
	B CountFlag    "help:\"disable bounds checking\""
	C CountFlag    "help:\"disable printing of columns in error messages\""
	D string       "help:\"set relative `path` for local imports\""
	E CountFlag    "help:\"debug symbol export\""
	I func(string) "help:\"add `directory` to import search path\""
	K CountFlag    "help:\"debug missing line numbers\""
	L CountFlag    "help:\"also show actual source file names in error messages for positions affected by //line directives\""
	N CountFlag    "help:\"disable optimizations\""
	S CountFlag    "help:\"print assembly listing\""
	// V is added by objabi.AddVersionFlag
	W CountFlag "help:\"debug parse tree after type checking\""

	LowerC int        "help:\"concurrency during compilation (1 means no concurrency)\""
	LowerD flag.Value "help:\"enable debugging settings; try -d help\""
	LowerE CountFlag  "help:\"no limit on number of errors reported\""
	LowerH CountFlag  "help:\"halt on error\""
	LowerJ CountFlag  "help:\"debug runtime-initialized variables\""
	LowerL CountFlag  "help:\"disable inlining\""
	LowerM CountFlag  "help:\"print optimization decisions\""
	LowerO string     "help:\"write output to `file`\""
	LowerP *string    "help:\"set expected package import `path`\"" // &Ctxt.Pkgpath, set below
	LowerR CountFlag  "help:\"debug generated wrappers\""
	LowerT bool       "help:\"enable tracing for debugging the compiler\""
	LowerW CountFlag  "help:\"debug type checking\""
	LowerV *bool      "help:\"increase debug verbosity\""

	// Special characters
	Percent          CountFlag "flag:\"%\" help:\"debug non-static initializers\""
	CompilingRuntime bool      "flag:\"+\" help:\"compiling runtime\""

	// Longer names
	AsmHdr             string       "help:\"write assembly header to `file`\""
	ASan               bool         "help:\"build code compatible with C/C++ address sanitizer\""
	Bench              string       "help:\"append benchmark times to `file`\""
	BlockProfile       string       "help:\"write block profile to `file`\""
	BuildID            string       "help:\"record `id` as the build id in the export metadata\""
	CPUProfile         string       "help:\"write cpu profile to `file`\""
	Complete           bool         "help:\"compiling complete package (no C or assembly)\""
	ClobberDead        bool         "help:\"clobber dead stack slots (for debugging)\""
	ClobberDeadReg     bool         "help:\"clobber dead registers (for debugging)\""
	Dwarf              bool         "help:\"generate DWARF symbols\""
	DwarfBASEntries    *bool        "help:\"use base address selection entries in DWARF\""                        // &Ctxt.UseBASEntries, set below
	DwarfLocationLists *bool        "help:\"add location lists to DWARF in optimized mode\""                      // &Ctxt.Flag_locationlists, set below
	Dynlink            *bool        "help:\"support references to Go symbols defined in other shared libraries\"" // &Ctxt.Flag_dynlink, set below
	EmbedCfg           func(string) "help:\"read go:embed configuration from `file`\""
	Env                func(string) "help:\"add `definition` of the form key=value to environment\""
	GenDwarfInl        int          "help:\"generate DWARF inline info records\"" // 0=disabled, 1=funcs, 2=funcs+formals/locals
	GoVersion          string       "help:\"required version of the runtime\""
	ImportCfg          func(string) "help:\"read import configuration from `file`\""
	InstallSuffix      string       "help:\"set pkg directory `suffix`\""
	JSON               string       "help:\"version,file for JSON compiler/optimizer detail output\""
	Lang               string       "help:\"Go language version source code expects\""
	LinkObj            string       "help:\"write linker-specific object to `file`\""
	LinkShared         *bool        "help:\"generate code that will be linked against Go shared libraries\"" // &Ctxt.Flag_linkshared, set below
	Live               CountFlag    "help:\"debug liveness analysis\""
	MSan               bool         "help:\"build code compatible with C/C++ memory sanitizer\""
	MemProfile         string       "help:\"write memory profile to `file`\""
	MemProfileRate     int          "help:\"set runtime.MemProfileRate to `rate`\""
	MutexProfile       string       "help:\"write mutex profile to `file`\""
	NoLocalImports     bool         "help:\"reject local (relative) imports\""
	CoverageCfg        func(string) "help:\"read coverage configuration from `file`\""
	Pack               bool         "help:\"write to file.a instead of file.o\""
	Race               bool         "help:\"enable race detector\""
	Shared             *bool        "help:\"generate code that can be linked into a shared library\"" // &Ctxt.Flag_shared, set below
	SmallFrames        bool         "help:\"reduce the size limit for stack allocated objects\""      // small stacks, to diagnose GC latency; see golang.org/issue/27732
	Spectre            string       "help:\"enable spectre mitigations in `list` (all, index, ret)\""
	Std                bool         "help:\"compiling standard library\""
	SymABIs            string       "help:\"read symbol ABIs from `file`\""
	TraceProfile       string       "help:\"write an execution trace to `file`\""
	TrimPath           string       "help:\"remove `prefix` from recorded source file paths\""
	WB                 bool         "help:\"enable write barrier\"" // TODO: remove
	PgoProfile         string       "help:\"read profile or pre-process profile from `file`\""
	ErrorURL           bool         "help:\"print explanatory URL with error message if applicable\""

	// Configuration derived from flags; not a flag itself.
	Cfg struct {
		Embed struct { // set by -embedcfg
			Patterns map[string][]string
			Files    map[string]string
		}
		ImportDirs   []string                 // appended to by -I
		ImportMap    map[string]string        // set by -importcfg
		PackageFile  map[string]string        // set by -importcfg; nil means not in use
		CoverageInfo *covcmd.CoverFixupConfig // set by -coveragecfg
		SpectreIndex bool                     // set by -spectre=index or -spectre=all
		// Whether we are adding any sort of code instrumentation, such as
		// when the race detector is enabled.
		Instrumenting bool
	}
}

func addEnv(s string) {
	i := strings.Index(s, "=")
	if i < 0 {
		log.Fatal("-env argument must be of the form key=value")
	}
	os.Setenv(s[:i], s[i+1:])
}

// ParseFlags parses the command-line flags into Flag.
func ParseFlags() {
	Flag.I = addImportDir

	Flag.LowerC = runtime.GOMAXPROCS(0)
	Flag.LowerD = objabi.NewDebugFlag(&Debug, DebugSSA)
	Flag.LowerP = &Ctxt.Pkgpath
	Flag.LowerV = &Ctxt.Debugvlog

	Flag.Dwarf = buildcfg.GOARCH != "wasm"
	Flag.DwarfBASEntries = &Ctxt.UseBASEntries
	Flag.DwarfLocationLists = &Ctxt.Flag_locationlists
	*Flag.DwarfLocationLists = true
	Flag.Dynlink = &Ctxt.Flag_dynlink
	Flag.EmbedCfg = readEmbedCfg
	Flag.Env = addEnv
	Flag.GenDwarfInl = 2
	Flag.ImportCfg = readImportCfg
	Flag.CoverageCfg = readCoverageCfg
	Flag.LinkShared = &Ctxt.Flag_linkshared
	Flag.Shared = &Ctxt.Flag_shared
	Flag.WB = true

	Debug.ConcurrentOk = true
	Debug.MaxShapeLen = 500
	Debug.AlignHot = 1
	Debug.InlFuncsWithClosures = 1
	Debug.InlStaticInit = 1
	Debug.PGOInline = 1
	Debug.PGODevirtualize = 2
	Debug.SyncFrames = -1 // disable sync markers by default
	Debug.ZeroCopy = 1
	Debug.RangeFuncCheck = 1
	Debug.MergeLocals = 1

	Debug.Checkptr = -1 // so we can tell whether it is set explicitly

	Flag.Cfg.ImportMap = make(map[string]string)

	objabi.AddVersionFlag() // -V
	registerFlags()
	objabi.Flagparse(usage)
	telemetry.CountFlags("compile/flag:", *flag.CommandLine)

	if gcd := os.Getenv("GOCOMPILEDEBUG"); gcd != "" {
		// This will only override the flags set in gcd;
		// any others set on the command line remain set.
		Flag.LowerD.Set(gcd)
	}

	if Debug.Gossahash != "" {
		hashDebug = NewHashDebug("gossahash", Debug.Gossahash, nil)
	}

	// Compute whether we're compiling the runtime from the package path. Test
	// code can also use the flag to set this explicitly.
	if Flag.Std && objabi.LookupPkgSpecial(Ctxt.Pkgpath).Runtime {
		Flag.CompilingRuntime = true
	}

	Ctxt.Std = Flag.Std

	// Three inputs govern loop iteration variable rewriting, hash, experiment, flag.
	// The loop variable rewriting is:
	// IF non-empty hash, then hash determines behavior (function+line match) (*)
	// ELSE IF experiment and flag==0, then experiment (set flag=1)
	// ELSE flag (note that build sets flag per-package), with behaviors:
	//  -1 => no change to behavior.
	//   0 => no change to behavior (unless non-empty hash, see above)
	//   1 => apply change to likely-iteration-variable-escaping loops
	//   2 => apply change, log results
	//   11 => apply change EVERYWHERE, do not log results (for debugging/benchmarking)
	//   12 => apply change EVERYWHERE, log results (for debugging/benchmarking)
	//
	// The expected uses of the these inputs are, in believed most-likely to least likely:
	//  GOEXPERIMENT=loopvar -- apply change to entire application
	//  -gcflags=some_package=-d=loopvar=1 -- apply change to some_package (**)
	//  -gcflags=some_package=-d=loopvar=2 -- apply change to some_package, log it
	//  GOEXPERIMENT=loopvar -gcflags=some_package=-d=loopvar=-1 -- apply change to all but one package
	//  GOCOMPILEDEBUG=loopvarhash=... -- search for failure cause
	//
	//  (*) For debugging purposes, providing loopvar flag >= 11 will expand the hash-eligible set of loops to all.
	// (**) Loop semantics, changed or not, follow code from a package when it is inlined; that is, the behavior
	//      of an application compiled with partially modified loop semantics does not depend on inlining.

	if Debug.LoopVarHash != "" {
		// This first little bit controls the inputs for debug-hash-matching.
		mostInlineOnly := true
		if strings.HasPrefix(Debug.LoopVarHash, "IL") {
			// When hash-searching on a position that is an inline site, default is to use the
			// most-inlined position only.  This makes the hash faster, plus there's no point
			// reporting a problem with all the inlining; there's only one copy of the source.
			// However, if for some reason you wanted it per-site, you can get this.  (The default
			// hash-search behavior for compiler debugging is at an inline site.)
			Debug.LoopVarHash = Debug.LoopVarHash[2:]
			mostInlineOnly = false
		}
		// end of testing trickiness
		LoopVarHash = NewHashDebug("loopvarhash", Debug.LoopVarHash, nil)
		if Debug.LoopVar < 11 { // >= 11 means all loops are rewrite-eligible
			Debug.LoopVar = 1 // 1 means those loops that syntactically escape their dcl vars are eligible.
		}
		LoopVarHash.SetInlineSuffixOnly(mostInlineOnly)
	} else if buildcfg.Experiment.LoopVar && Debug.LoopVar == 0 {
		Debug.LoopVar = 1
	}

	if Debug.Fmahash != "" {
		FmaHash = NewHashDebug("fmahash", Debug.Fmahash, nil)
	}
	if Debug.PGOHash != "" {
		PGOHash = NewHashDebug("pgohash", Debug.PGOHash, nil)
	}
	if Debug.MergeLocalsHash != "" {
		MergeLocalsHash = NewHashDebug("mergelocals", Debug.MergeLocalsHash, nil)
	}

	if Flag.MSan && !platform.MSanSupported(buildcfg.GOOS, buildcfg.GOARCH) {
		log.Fatalf("%s/%s does not support -msan", buildcfg.GOOS, buildcfg.GOARCH)
	}
	if Flag.ASan && !platform.ASanSupported(buildcfg.GOOS, buildcfg.GOARCH) {
		log.Fatalf("%s/%s does not support -asan", buildcfg.GOOS, buildcfg.GOARCH)
	}
	if Flag.Race && !platform.RaceDetectorSupported(buildcfg.GOOS, buildcfg.GOARCH) {
		log.Fatalf("%s/%s does not support -race", buildcfg.GOOS, buildcfg.GOARCH)
	}
	if (*Flag.Shared || *Flag.Dynlink || *Flag.LinkShared) && !Ctxt.Arch.InFamily(sys.AMD64, sys.ARM, sys.ARM64, sys.I386, sys.Loong64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) {
		log.Fatalf("%s/%s does not support -shared", buildcfg.GOOS, buildcfg.GOARCH)
	}
	parseSpectre(Flag.Spectre) // left as string for RecordFlags

	Ctxt.Flag_shared = Ctxt.Flag_dynlink || Ctxt.Flag_shared
	Ctxt.Flag_optimize = Flag.N == 0
	Ctxt.Debugasm = int(Flag.S)
	Ctxt.Flag_maymorestack = Debug.MayMoreStack
	Ctxt.Flag_noRefName = Debug.NoRefName != 0

	if flag.NArg() < 1 {
		usage()
	}

	if Flag.GoVersion != "" && Flag.GoVersion != runtime.Version() {
		fmt.Printf("compile: version %q does not match go tool version %q\n", runtime.Version(), Flag.GoVersion)
		Exit(2)
	}

	if *Flag.LowerP == "" {
		*Flag.LowerP = obj.UnlinkablePkg
	}

	if Flag.LowerO == "" {
		p := flag.Arg(0)
		if i := strings.LastIndex(p, "/"); i >= 0 {
			p = p[i+1:]
		}
		if runtime.GOOS == "windows" {
			if i := strings.LastIndex(p, `\`); i >= 0 {
				p = p[i+1:]
			}
		}
		if i := strings.LastIndex(p, "."); i >= 0 {
			p = p[:i]
		}
		suffix := ".o"
		if Flag.Pack {
			suffix = ".a"
		}
		Flag.LowerO = p + suffix
	}
	switch {
	case Flag.Race && Flag.MSan:
		log.Fatal("cannot use both -race and -msan")
	case Flag.Race && Flag.ASan:
		log.Fatal("cannot use both -race and -asan")
	case Flag.MSan && Flag.ASan:
		log.Fatal("cannot use both -msan and -asan")
	}
	if Flag.Race || Flag.MSan || Flag.ASan {
		// -race, -msan and -asan imply -d=checkptr for now.
		if Debug.Checkptr == -1 { // if not set explicitly
			Debug.Checkptr = 1
		}
	}

	if Flag.LowerC < 1 {
		log.Fatalf("-c must be at least 1, got %d", Flag.LowerC)
	}
	if !concurrentBackendAllowed() {
		Flag.LowerC = 1
	}

	if Flag.CompilingRuntime {
		// It is not possible to build the runtime with no optimizations,
		// because the compiler cannot eliminate enough write barriers.
		Flag.N = 0
		Ctxt.Flag_optimize = true

		// Runtime can't use -d=checkptr, at least not yet.
		Debug.Checkptr = 0

		// Fuzzing the runtime isn't interesting either.
		Debug.Libfuzzer = 0
	}

	if Debug.Checkptr == -1 { // if not set explicitly
		Debug.Checkptr = 0
	}

	// set via a -d flag
	Ctxt.Debugpcln = Debug.PCTab

	// https://golang.org/issue/67502
	if buildcfg.GOOS == "plan9" && buildcfg.GOARCH == "386" {
		Debug.AlignHot = 0
	}
}

// registerFlags adds flag registrations for all the fields in Flag.
// See the comment on type CmdFlags for the rules.
func registerFlags() {
	var (
		boolType      = reflect.TypeOf(bool(false))
		intType       = reflect.TypeOf(int(0))
		stringType    = reflect.TypeOf(string(""))
		ptrBoolType   = reflect.TypeOf(new(bool))
		ptrIntType    = reflect.TypeOf(new(int))
		ptrStringType = reflect.TypeOf(new(string))
		countType     = reflect.TypeOf(CountFlag(0))
		funcType      = reflect.TypeOf((func(string))(nil))
	)

	v := reflect.ValueOf(&Flag).Elem()
	t := v.Type()
	for i := 0; i < t.NumField(); i++ {
		f := t.Field(i)
		if f.Name == "Cfg" {
			continue
		}

		var name string
		if len(f.Name) == 1 {
			name = f.Name
		} else if len(f.Name) == 6 && f.Name[:5] == "Lower" && 'A' <= f.Name[5] && f.Name[5] <= 'Z' {
			name = string(rune(f.Name[5] + 'a' - 'A'))
		} else {
			name = strings.ToLower(f.Name)
		}
		if tag := f.Tag.Get("flag"); tag != "" {
			name = tag
		}

		help := f.Tag.Get("help")
		if help == "" {
			panic(fmt.Sprintf("base.Flag.%s is missing help text", f.Name))
		}

		if k := f.Type.Kind(); (k == reflect.Ptr || k == reflect.Func) && v.Field(i).IsNil() {
			panic(fmt.Sprintf("base.Flag.%s is uninitialized %v", f.Name, f.Type))
		}

		switch f.Type {
		case boolType:
			p := v.Field(i).Addr().Interface().(*bool)
			flag.BoolVar(p, name, *p, help)
		case intType:
			p := v.Field(i).Addr().Interface().(*int)
			flag.IntVar(p, name, *p, help)
		case stringType:
			p := v.Field(i).Addr().Interface().(*string)
			flag.StringVar(p, name, *p, help)
		case ptrBoolType:
			p := v.Field(i).Interface().(*bool)
			flag.BoolVar(p, name, *p, help)
		case ptrIntType:
			p := v.Field(i).Interface().(*int)
			flag.IntVar(p, name, *p, help)
		case ptrStringType:
			p := v.Field(i).Interface().(*string)
			flag.StringVar(p, name, *p, help)
		case countType:
			p := (*int)(v.Field(i).Addr().Interface().(*CountFlag))
			objabi.Flagcount(name, help, p)
		case funcType:
			f := v.Field(i).Interface().(func(string))
			objabi.Flagfn1(name, help, f)
		default:
			if val, ok := v.Field(i).Interface().(flag.Value); ok {
				flag.Var(val, name, help)
			} else {
				panic(fmt.Sprintf("base.Flag.%s has unexpected type %s", f.Name, f.Type))
			}
		}
	}
}

// concurrentFlagOk reports whether the current compiler flags
// are compatible with concurrent compilation.
func concurrentFlagOk() bool {
	// TODO(rsc): Many of these are fine. Remove them.
	return Flag.Percent == 0 &&
		Flag.E == 0 &&
		Flag.K == 0 &&
		Flag.L == 0 &&
		Flag.LowerH == 0 &&
		Flag.LowerJ == 0 &&
		Flag.LowerM == 0 &&
		Flag.LowerR == 0
}

func concurrentBackendAllowed() bool {
	if !concurrentFlagOk() {
		return false
	}

	// Debug.S by itself is ok, because all printing occurs
	// while writing the object file, and that is non-concurrent.
	// Adding Debug_vlog, however, causes Debug.S to also print
	// while flushing the plist, which happens concurrently.
	if Ctxt.Debugvlog || !Debug.ConcurrentOk || Flag.Live > 0 {
		return false
	}
	// TODO: Test and delete this condition.
	if buildcfg.Experiment.FieldTrack {
		return false
	}
	// TODO: fix races and enable the following flags
	if Ctxt.Flag_dynlink || Flag.Race {
		return false
	}
	return true
}

func addImportDir(dir string) {
	if dir != "" {
		Flag.Cfg.ImportDirs = append(Flag.Cfg.ImportDirs, dir)
	}
}

func readImportCfg(file string) {
	if Flag.Cfg.ImportMap == nil {
		Flag.Cfg.ImportMap = make(map[string]string)
	}
	Flag.Cfg.PackageFile = map[string]string{}
	data, err := os.ReadFile(file)
	if err != nil {
		log.Fatalf("-importcfg: %v", err)
	}

	for lineNum, line := range strings.Split(string(data), "\n") {
		lineNum++ // 1-based
		line = strings.TrimSpace(line)
		if line == "" || strings.HasPrefix(line, "#") {
			continue
		}

		verb, args, found := strings.Cut(line, " ")
		if found {
			args = strings.TrimSpace(args)
		}
		before, after, hasEq := strings.Cut(args, "=")

		switch verb {
		default:
			log.Fatalf("%s:%d: unknown directive %q", file, lineNum, verb)
		case "importmap":
			if !hasEq || before == "" || after == "" {
				log.Fatalf(`%s:%d: invalid importmap: syntax is "importmap old=new"`, file, lineNum)
			}
			Flag.Cfg.ImportMap[before] = after
		case "packagefile":
			if !hasEq || before == "" || after == "" {
				log.Fatalf(`%s:%d: invalid packagefile: syntax is "packagefile path=filename"`, file, lineNum)
			}
			Flag.Cfg.PackageFile[before] = after
		}
	}
}

func readCoverageCfg(file string) {
	var cfg covcmd.CoverFixupConfig
	data, err := os.ReadFile(file)
	if err != nil {
		log.Fatalf("-coveragecfg: %v", err)
	}
	if err := json.Unmarshal(data, &cfg); err != nil {
		log.Fatalf("error reading -coveragecfg file %q: %v", file, err)
	}
	Flag.Cfg.CoverageInfo = &cfg
}

func readEmbedCfg(file string) {
	data, err := os.ReadFile(file)
	if err != nil {
		log.Fatalf("-embedcfg: %v", err)
	}
	if err := json.Unmarshal(data, &Flag.Cfg.Embed); err != nil {
		log.Fatalf("%s: %v", file, err)
	}
	if Flag.Cfg.Embed.Patterns == nil {
		log.Fatalf("%s: invalid embedcfg: missing Patterns", file)
	}
	if Flag.Cfg.Embed.Files == nil {
		log.Fatalf("%s: invalid embedcfg: missing Files", file)
	}
}

// parseSpectre parses the spectre configuration from the string s.
func parseSpectre(s string) {
	for _, f := range strings.Split(s, ",") {
		f = strings.TrimSpace(f)
		switch f {
		default:
			log.Fatalf("unknown setting -spectre=%s", f)
		case "":
			// nothing
		case "all":
			Flag.Cfg.SpectreIndex = true
			Ctxt.Retpoline = true
		case "index":
			Flag.Cfg.SpectreIndex = true
		case "ret":
			Ctxt.Retpoline = true
		}
	}

	if Flag.Cfg.SpectreIndex {
		switch buildcfg.GOARCH {
		case "amd64":
			// ok
		default:
			log.Fatalf("GOARCH=%s does not support -spectre=index", buildcfg.GOARCH)
		}
	}
}
