/* Copyright 2018 The Bazel Authors. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package golang

import (
	"fmt"
	"go/build"
	"log"
	"path"
	"path/filepath"
	"sort"
	"strings"
	"sync"

	"github.com/bazelbuild/bazel-gazelle/config"
	"github.com/bazelbuild/bazel-gazelle/language"
	"github.com/bazelbuild/bazel-gazelle/language/proto"
	"github.com/bazelbuild/bazel-gazelle/pathtools"
	"github.com/bazelbuild/bazel-gazelle/rule"
)

func (gl *goLang) GenerateRules(args language.GenerateArgs) language.GenerateResult {
	// Extract information about proto files. We need this to exclude .pb.go
	// files and generate go_proto_library rules.
	c := args.Config
	pcMode := getProtoMode(c)

	// This is a collection of proto_library rule names that have a corresponding
	// go_proto_library rule already generated.
	goProtoRules := make(map[string]struct{})

	var protoRuleNames []string
	protoPackages := make(map[string]proto.Package)
	protoFileInfo := make(map[string]proto.FileInfo)
	for _, r := range args.OtherGen {
		if r.Kind() == "go_proto_library" {
			if proto := r.AttrString("proto"); proto != "" {
				goProtoRules[proto] = struct{}{}
			}
			if protos := r.AttrStrings("protos"); protos != nil {
				for _, proto := range protos {
					goProtoRules[proto] = struct{}{}
				}
			}

		}
		if r.Kind() != "proto_library" {
			continue
		}
		pkg := r.PrivateAttr(proto.PackageKey).(proto.Package)
		protoPackages[r.Name()] = pkg
		for name, info := range pkg.Files {
			protoFileInfo[name] = info
		}
		protoRuleNames = append(protoRuleNames, r.Name())
	}
	sort.Strings(protoRuleNames)
	var emptyProtoRuleNames []string
	for _, r := range args.OtherEmpty {
		if r.Kind() == "proto_library" {
			emptyProtoRuleNames = append(emptyProtoRuleNames, r.Name())
		}
	}

	// If proto rule generation is enabled, exclude .pb.go files that correspond
	// to any .proto files present.
	regularFiles := append([]string{}, args.RegularFiles...)
	genFiles := append([]string{}, args.GenFiles...)
	if !pcMode.ShouldIncludePregeneratedFiles() {
		keep := func(f string) bool {
			for _, suffix := range []string{".pb.go", "_grpc.pb.go"} {
				if strings.HasSuffix(f, suffix) {
					if _, ok := protoFileInfo[strings.TrimSuffix(f, suffix)+".proto"]; ok {
						return false
					}
				}
			}
			return true
		}
		filterFiles(&regularFiles, keep)
		filterFiles(&genFiles, keep)
	}

	// Split regular files into files which can determine the package name and
	// import path and other files.
	var goFiles, otherFiles []string
	for _, f := range regularFiles {
		if strings.HasSuffix(f, ".go") {
			goFiles = append(goFiles, f)
		} else {
			otherFiles = append(otherFiles, f)
		}
	}

	// Look for a subdirectory named testdata. Only treat it as data if it does
	// not contain a buildable package.
	var hasTestdata bool
	for _, sub := range args.Subdirs {
		if sub == "testdata" {
			_, ok := gl.goPkgRels[path.Join(args.Rel, "testdata")]
			hasTestdata = !ok
			break
		}
	}

	// Build a set of packages from files in this directory.
	goFileInfos := make([]fileInfo, len(goFiles))
	var er *embedResolver
	for i, name := range goFiles {
		path := filepath.Join(args.Dir, name)
		goFileInfos[i] = goFileInfo(path, args.Rel)
		if len(goFileInfos[i].embeds) > 0 && er == nil {
			er = newEmbedResolver(args.Dir, args.Rel, c.ValidBuildFileNames, gl.goPkgRels, args.Subdirs, args.RegularFiles, args.GenFiles)
		}
	}
	goPackageMap, goFilesWithUnknownPackage := buildPackages(c, args.Dir, args.Rel, hasTestdata, er, goFileInfos)

	// Select a package to generate rules for. If there is no package, create
	// an empty package so we can generate empty rules.
	var protoName string
	pkg, err := selectPackage(c, args.Dir, goPackageMap)
	if err != nil {
		if _, ok := err.(*build.NoGoError); ok {
			if len(protoPackages) == 1 {
				for name, ppkg := range protoPackages {
					if _, ok := goProtoRules[":"+name]; ok {
						// if a go_proto_library rule already exists for this
						// proto package, treat it as if the proto package
						// doesn't exist.
						pkg = emptyPackage(c, args.Dir, args.Rel, args.File)
						break
					}
					pkg = &goPackage{
						name:       goProtoPackageName(ppkg),
						importPath: goProtoImportPath(c, ppkg, args.Rel),
						proto:      protoTargetFromProtoPackage(name, ppkg),
					}
					protoName = name
					break
				}
			} else {
				pkg = emptyPackage(c, args.Dir, args.Rel, args.File)
			}
		} else {
			log.Print(err)
		}
	}

	// Try to link the selected package with a proto package.
	if pkg != nil {
		if pkg.importPath == "" {
			if err := pkg.inferImportPath(c); err != nil && pkg.firstGoFile() != "" {
				inferImportPathErrorOnce.Do(func() { log.Print(err) })
			}
		}
		for _, name := range protoRuleNames {
			ppkg := protoPackages[name]
			if pkg.importPath == goProtoImportPath(c, ppkg, args.Rel) {
				protoName = name
				pkg.proto = protoTargetFromProtoPackage(name, ppkg)
				break
			}
		}
	}

	// Generate rules for proto packages. These should come before the other
	// Go rules.
	g := &generator{
		c:                   c,
		rel:                 args.Rel,
		shouldSetVisibility: shouldSetVisibility(args),
	}
	var res language.GenerateResult
	var rules []*rule.Rule
	var protoEmbeds []string
	var protoEmbed string
	if pcMode == proto.FileMode {
		// get the list of protoRuleNames that are not already in goProtoRules
		var newProtoRuleNames []string
		for _, name := range protoRuleNames {
			if _, ok := goProtoRules[":"+name]; !ok {
				newProtoRuleNames = append(newProtoRuleNames, name)
			}
		}

		// get the protoTargets for the new protoRuleNames
		var importPathToProtoTargets = make(map[string][]protoTarget)
		for _, name := range newProtoRuleNames {
			ppkg := protoPackages[name]
			importPath := goProtoImportPath(c, ppkg, args.Rel)
			importPathToProtoTargets[importPath] = append(importPathToProtoTargets[importPath], protoTargetFromProtoPackage(name, ppkg))
		}

		// Deterministically sort by order of importpath.
		importPaths := []string{}
		for importPath, _ := range importPathToProtoTargets {
			importPaths = append(importPaths, importPath)
		}
		sort.Strings(importPaths)

		for _, importPath := range importPaths {
			var rs []*rule.Rule
			protoTargets := importPathToProtoTargets[importPath]
			protoEmbed, rs = g.generateProto(pcMode, protoTargets, importPath)
			if protoEmbed != "" {
				// check if rs is non-empty and that the first rule is a go_proto_library with the same importPath
				if len(rs) > 0 && rs[0].Kind() == "go_proto_library" && rs[0].AttrString("importpath") == pkg.importPath {
					protoEmbeds = append(protoEmbeds, protoEmbed)
				}
			}
			rules = append(rules, rs...)
		}
	} else {
		for _, name := range protoRuleNames {
			// if a go_proto_library rule exists for this proto_library rule
			// already, skip creating another go_proto_library for it, assuming
			// that a different gazelle extension is responsible for
			// go_proto_library rule generation.
			if _, ok := goProtoRules[":"+name]; ok {
				continue
			}
			ppkg := protoPackages[name]
			var rs []*rule.Rule
			if name == protoName {
				var protoTargets []protoTarget
				if pkg != nil {
					protoTargets = append(protoTargets, pkg.proto)
				}
				protoEmbed, rs = g.generateProto(pcMode, []protoTarget{pkg.proto}, pkg.importPath)
				if protoEmbed != "" {
					// check if rs is non-empty and that the first rule is a go_proto_library with the same importPath
					if len(rs) > 0 && rs[0].Kind() == "go_proto_library" && rs[0].AttrString("importpath") == pkg.importPath {
						protoEmbeds = append(protoEmbeds, protoEmbed)
					}
				}
			} else {
				target := protoTargetFromProtoPackage(name, ppkg)
				importPath := goProtoImportPath(c, ppkg, args.Rel)
				_, rs = g.generateProto(pcMode, []protoTarget{target}, importPath)
			}
			rules = append(rules, rs...)
		}
	}

	for _, name := range emptyProtoRuleNames {
		goProtoName := strings.TrimSuffix(name, "_proto") + goProtoSuffix
		res.Empty = append(res.Empty, rule.NewRule("go_proto_library", goProtoName))
	}
	if pkg != nil && (pcMode == proto.PackageMode || pcMode == proto.FileMode) && pkg.firstGoFile() == "" {
		// In proto package mode, don't generate a go_library embedding a
		// go_proto_library unless there are actually go files.
		protoEmbeds = nil
	}

	// Complete the Go package and generate rules for that.
	if pkg != nil {
		// Add files with unknown packages. This happens when there are parse
		// or I/O errors. We should keep the file in the srcs list and let the
		// compiler deal with the error.
		cgo := pkg.haveCgo()
		for _, info := range goFilesWithUnknownPackage {
			if err := pkg.addFile(c, er, info, cgo); err != nil {
				log.Print(err)
			}
		}

		// Process the other static files.
		for _, file := range otherFiles {
			info := otherFileInfo(filepath.Join(args.Dir, file))
			if err := pkg.addFile(c, er, info, cgo); err != nil {
				log.Print(err)
			}
		}

		// Process generated files. Note that generated files may have the same names
		// as static files. Bazel will use the generated files, but we will look at
		// the content of static files, assuming they will be the same.
		regularFileSet := make(map[string]bool)
		for _, f := range regularFiles {
			regularFileSet[f] = true
		}
		// Some of the generated files may have been consumed by other rules
		consumedFileSet := make(map[string]bool)
		for _, r := range args.OtherGen {
			for _, f := range r.AttrStrings("srcs") {
				consumedFileSet[f] = true
			}
			if f := r.AttrString("src"); f != "" {
				consumedFileSet[f] = true
			}
		}
		for _, f := range genFiles {
			if regularFileSet[f] || consumedFileSet[f] {
				continue
			}
			info := fileNameInfo(filepath.Join(args.Dir, f))
			if err := pkg.addFile(c, er, info, cgo); err != nil {
				log.Print(err)
			}
		}

		// Generate Go rules.
		if protoName == "" {
			// Empty proto rules for deletion.
			_, rs := g.generateProto(pcMode, []protoTarget{pkg.proto}, pkg.importPath)
			rules = append(rules, rs...)
		}
		lib := g.generateLib(pkg, protoEmbeds)
		var libName string
		if !lib.IsEmpty(goKinds[lib.Kind()]) {
			libName = lib.Name()
		}
		rules = append(rules, lib)
		g.maybePublishToolLib(lib, pkg)
		if r := g.maybeGenerateExtraLib(lib, pkg); r != nil {
			rules = append(rules, r)
		}
		if r := g.maybeGenerateAlias(pkg, libName); r != nil {
			g.maybePublishToolLib(r, pkg)
			rules = append(rules, r)
		}
		rules = append(rules, g.generateBin(pkg, libName))
		rules = append(rules, g.generateTests(pkg, libName)...)
	}

	for _, r := range rules {
		if r.IsEmpty(goKinds[r.Kind()]) {
			res.Empty = append(res.Empty, r)
		} else {
			res.Gen = append(res.Gen, r)
			res.Imports = append(res.Imports, r.PrivateAttr(config.GazelleImportsKey))
		}
	}

	if args.File != nil || len(res.Gen) > 0 {
		gl.goPkgRels[args.Rel] = true
	} else {
		for _, sub := range args.Subdirs {
			if _, ok := gl.goPkgRels[path.Join(args.Rel, sub)]; ok {
				gl.goPkgRels[args.Rel] = false
				break
			}
		}
	}

	return res
}

func filterFiles(files *[]string, pred func(string) bool) {
	w := 0
	for r := 0; r < len(*files); r++ {
		f := (*files)[r]
		if pred(f) {
			(*files)[w] = f
			w++
		}
	}
	*files = (*files)[:w]
}

func buildPackages(c *config.Config, dir, rel string, hasTestdata bool, er *embedResolver, goFiles []fileInfo) (packageMap map[string]*goPackage, goFilesWithUnknownPackage []fileInfo) {
	// Process .go and .proto files first, since these determine the package name.
	packageMap = make(map[string]*goPackage)
	for _, f := range goFiles {
		if f.packageName == "" {
			goFilesWithUnknownPackage = append(goFilesWithUnknownPackage, f)
			continue
		}
		if f.packageName == "documentation" {
			// go/build ignores this package
			continue
		}

		if _, ok := packageMap[f.packageName]; !ok {
			packageMap[f.packageName] = &goPackage{
				name:        f.packageName,
				dir:         dir,
				rel:         rel,
				hasTestdata: hasTestdata,
			}
		}
		if err := packageMap[f.packageName].addFile(c, er, f, false); err != nil {
			log.Print(err)
		}
	}
	return packageMap, goFilesWithUnknownPackage
}

var inferImportPathErrorOnce sync.Once

// selectPackages selects one Go packages out of the buildable packages found
// in a directory. If multiple packages are found, it returns the package
// whose name matches the directory if such a package exists.
func selectPackage(c *config.Config, dir string, packageMap map[string]*goPackage) (*goPackage, error) {
	buildablePackages := make(map[string]*goPackage)
	for name, pkg := range packageMap {
		if pkg.isBuildable(c) {
			buildablePackages[name] = pkg
		}
	}

	if len(buildablePackages) == 0 {
		return nil, &build.NoGoError{Dir: dir}
	}

	if len(buildablePackages) == 1 {
		for _, pkg := range buildablePackages {
			return pkg, nil
		}
	}

	if pkg, ok := buildablePackages[defaultPackageName(c, dir)]; ok {
		return pkg, nil
	}

	err := &build.MultiplePackageError{Dir: dir}
	for name, pkg := range buildablePackages {
		// Add the first file for each package for the error message.
		// Error() method expects these lists to be the same length. File
		// lists must be non-empty. These lists are only created by
		// buildPackage for packages with .go files present.
		err.Packages = append(err.Packages, name)
		err.Files = append(err.Files, pkg.firstGoFile())
	}
	return nil, err
}

func emptyPackage(c *config.Config, dir, rel string, f *rule.File) *goPackage {
	var pkgName string
	if fileContainsGoBinary(c, f) {
		// If the file contained a go_binary, its library may have a "_lib" suffix.
		// Set the package name to "main" so that we generate an empty library rule
		// with that name.
		pkgName = "main"
	} else {
		pkgName = defaultPackageName(c, dir)
	}
	pkg := &goPackage{
		name: pkgName,
		dir:  dir,
		rel:  rel,
	}

	return pkg
}

func defaultPackageName(c *config.Config, rel string) string {
	gc := getGoConfig(c)
	return pathtools.RelBaseName(rel, gc.prefix, "")
}

type generator struct {
	c                   *config.Config
	rel                 string
	shouldSetVisibility bool
}

func (g *generator) generateProto(mode proto.Mode, targets []protoTarget, importPath string) (string, []*rule.Rule) {
	if !mode.ShouldGenerateRules() && mode != proto.LegacyMode {
		// Don't create or delete proto rules in this mode. When proto mode is disabled,
		// there may be hand-written rules or pre-generated Go files
		return "", nil
	}

	gc := getGoConfig(g.c)
	filegroupName := legacyProtoFilegroupName
	var protoName string
	if len(targets) == 1 {
		protoName = targets[0].name
	}
	if protoName == "" {
		if importPath == "" {
			importPath = InferImportPath(g.c, g.rel)
		}
		protoName = proto.RuleName(importPath)
	}
	goProtoName := strings.TrimSuffix(protoName, "_proto") + goProtoSuffix
	visibility := g.commonVisibility(importPath)

	if mode == proto.LegacyMode {
		filegroup := rule.NewRule("filegroup", filegroupName)
		if targets[0].sources.isEmpty() {
			return "", []*rule.Rule{filegroup}
		}
		filegroup.SetAttr("srcs", targets[0].sources.build())
		if g.shouldSetVisibility {
			filegroup.SetAttr("visibility", visibility)
		}
		return "", []*rule.Rule{filegroup}
	}

	var atLeastOneTargetHasSources bool
	for _, target := range targets {
		if !target.sources.isEmpty() {
			atLeastOneTargetHasSources = true
			break
		}
	}

	if !atLeastOneTargetHasSources {
		return "", []*rule.Rule{
			rule.NewRule("filegroup", filegroupName),
			rule.NewRule("go_proto_library", goProtoName),
		}
	}

	goProtoLibrary := rule.NewRule("go_proto_library", goProtoName)
	if len(targets) == 1 {
		goProtoLibrary.SetAttr("proto", ":"+protoName)
	} else {
		// generate protoNames with prefix ":"
		protoNames := make([]string, len(targets))
		for i := range targets {
			protoNames[i] = ":" + targets[i].name
		}
		goProtoLibrary.SetAttr("protos", protoNames)
	}

	g.setImportAttrs(goProtoLibrary, importPath)
	var atLeastOneTargetHasServices bool
	for _, target := range targets {
		if target.hasServices {
			atLeastOneTargetHasServices = true
			break
		}
	}
	if atLeastOneTargetHasServices {
		goProtoLibrary.SetAttr("compilers", gc.goGrpcCompilers)
	} else if gc.goProtoCompilersSet {
		goProtoLibrary.SetAttr("compilers", gc.goProtoCompilers)
	}
	if g.shouldSetVisibility {
		goProtoLibrary.SetAttr("visibility", visibility)
	}
	if len(targets) == 1 {
		goProtoLibrary.SetPrivateAttr(config.GazelleImportsKey, targets[0].imports.build())
	} else {
		protoSources := make(map[string]struct{})
		for _, target := range targets {
			for _, src := range target.sources.build().Generic {
				// if src starts with the repo root plus a slash, trim it
				// so that src is relative to the repo root, which is
				// needed for the dep resolution to work correctly
				if strings.HasPrefix(src, g.c.RepoRoot+"/") {
					src = src[len(g.c.RepoRoot)+1:]
				}
				protoSources[src] = struct{}{}
			}
		}
		var combinedImports platformStringsBuilder
		for _, target := range targets {
			builtImports := target.imports.build()
			// handle Generics
			for _, genericString := range builtImports.Generic {
				// if the generic string is not in the set of generic src strings, add it
				if _, ok := protoSources[genericString]; !ok {
					combinedImports.addGenericString(genericString)
				}
			}
		}

		goProtoLibrary.SetPrivateAttr(config.GazelleImportsKey, combinedImports.build())
	}
	return goProtoName, []*rule.Rule{goProtoLibrary}
}

func (g *generator) generateLib(pkg *goPackage, embeds []string) *rule.Rule {
	gc := getGoConfig(g.c)
	name := libNameByConvention(gc.goNamingConvention, pkg.importPath, pkg.name)
	goLibrary := rule.NewRule("go_library", name)
	if !pkg.library.sources.hasGo() && len(embeds) == 0 {
		return goLibrary // empty
	}
	var visibility []string
	if pkg.isCommand() {
		// By default, libraries made for a go_binary should not be exposed to the public.
		visibility = []string{"//visibility:private"}
		if len(getGoConfig(g.c).goVisibility) > 0 {
			visibility = getGoConfig(g.c).goVisibility
		}
	} else {
		visibility = g.commonVisibility(pkg.importPath)
	}
	g.setCommonAttrs(goLibrary, pkg.rel, visibility, pkg.library, embeds)
	g.setImportAttrs(goLibrary, pkg.importPath)
	return goLibrary
}

func (g *generator) maybeGenerateAlias(pkg *goPackage, libName string) *rule.Rule {
	if pkg.isCommand() || libName == "" {
		return nil
	}
	gc := getGoConfig(g.c)
	if gc.goNamingConvention == goDefaultLibraryNamingConvention {
		return nil
	}
	alias := rule.NewRule("alias", defaultLibName)
	alias.SetAttr("visibility", g.commonVisibility(pkg.importPath))
	if gc.goNamingConvention == importAliasNamingConvention {
		alias.SetAttr("actual", ":"+libName)
	}
	return alias
}

func (g *generator) generateBin(pkg *goPackage, library string) *rule.Rule {
	gc := getGoConfig(g.c)
	name := binName(pkg.rel, gc.prefix, g.c.RepoRoot)
	goBinary := rule.NewRule("go_binary", name)
	if !pkg.isCommand() || pkg.binary.sources.isEmpty() && library == "" {
		return goBinary // empty
	}
	visibility := g.commonVisibility(pkg.importPath)
	g.setCommonAttrs(goBinary, pkg.rel, visibility, pkg.binary, []string{library})
	return goBinary
}

func (g *generator) generateTests(pkg *goPackage, library string) []*rule.Rule {
	gc := getGoConfig(g.c)
	tests := pkg.tests
	if len(tests) == 0 && gc.testMode == defaultTestMode {
		tests = []goTarget{goTarget{}}
	}
	var name func(goTarget) string
	switch gc.testMode {
	case defaultTestMode:
		name = func(goTarget) string {
			return testNameByConvention(gc.goNamingConvention, pkg.importPath)
		}
	case fileTestMode:
		name = func(test goTarget) string {
			if test.sources.hasGo() {
				if srcs := test.sources.buildFlat(); len(srcs) == 1 {
					return testNameFromSingleSource(srcs[0])
				}
			}
			return testNameByConvention(gc.goNamingConvention, pkg.importPath)
		}
	}
	var res []*rule.Rule
	for i, test := range tests {
		goTest := rule.NewRule("go_test", name(test))
		hasGo := test.sources.hasGo()
		if hasGo || i == 0 {
			res = append(res, goTest)
			if !hasGo {
				continue
			}
		}
		var embeds []string
		if test.hasInternalTest {
			if library != "" {
				embeds = append(embeds, library)
			}
		}
		g.setCommonAttrs(goTest, pkg.rel, nil, test, embeds)
		if pkg.hasTestdata {
			goTest.SetAttr("data", rule.GlobValue{Patterns: []string{"testdata/**"}})
		}
	}
	return res
}

// maybePublishToolLib makes the given go_library rule public if needed for nogo.
// Updating it here automatically makes it easier to upgrade org_golang_x_tools.
func (g *generator) maybePublishToolLib(lib *rule.Rule, pkg *goPackage) {
	if pkg.importPath == "golang.org/x/tools/go/analysis/internal/facts" || pkg.importPath == "golang.org/x/tools/internal/facts" {
		// Imported by nogo main. We add a visibility exception.
		lib.SetAttr("visibility", []string{"//visibility:public"})
	}
}

// maybeGenerateExtraLib generates extra equivalent library targets for
// certain protobuf libraries. Historically, these "_gen" targets depend on Well Known Types
// built with go_proto_library and are used together with go_proto_library.
// However, these are no longer needed and are kept as aliases to be backward-compatible
func (g *generator) maybeGenerateExtraLib(lib *rule.Rule, pkg *goPackage) *rule.Rule {
	gc := getGoConfig(g.c)
	if gc.prefix != "github.com/golang/protobuf" || gc.prefixRel != "" {
		return nil
	}

	var r *rule.Rule
	switch pkg.importPath {
	case "github.com/golang/protobuf/descriptor":
		r = rule.NewRule("alias", "go_default_library_gen")
		r.SetAttr("actual", ":go_default_library")
		r.SetAttr("visibility", []string{"//visibility:public"})

	case "github.com/golang/protobuf/jsonpb":
		r = rule.NewRule("alias", "go_default_library_gen")
		r.SetAttr("actual", ":go_default_library")
		r.SetAttr("visibility", []string{"//visibility:public"})

	case "github.com/golang/protobuf/protoc-gen-go/generator":
		r = rule.NewRule("alias", "go_default_library_gen")
		r.SetAttr("actual", ":go_default_library")
		r.SetAttr("visibility", []string{"//visibility:public"})

	case "github.com/golang/protobuf/ptypes":
		r = rule.NewRule("alias", "go_default_library_gen")
		r.SetAttr("actual", ":go_default_library")
		r.SetAttr("visibility", []string{"//visibility:public"})
	}

	return r
}

func (g *generator) setCommonAttrs(r *rule.Rule, pkgRel string, visibility []string, target goTarget, embeds []string) {
	if !target.sources.isEmpty() {
		r.SetAttr("srcs", target.sources.buildFlat())
	}
	if !target.embedSrcs.isEmpty() {
		r.SetAttr("embedsrcs", target.embedSrcs.build())
	}
	if target.cgo {
		r.SetAttr("cgo", true)
	}
	if !target.clinkopts.isEmpty() {
		r.SetAttr("clinkopts", g.options(target.clinkopts.build(), pkgRel))
	}
	if !target.cppopts.isEmpty() {
		r.SetAttr("cppopts", g.options(target.cppopts.build(), pkgRel))
	}
	if !target.copts.isEmpty() {
		r.SetAttr("copts", g.options(target.copts.build(), pkgRel))
	}
	if !target.cxxopts.isEmpty() {
		r.SetAttr("cxxopts", g.options(target.cxxopts.build(), pkgRel))
	}
	if g.shouldSetVisibility && len(visibility) > 0 {
		r.SetAttr("visibility", visibility)
	}
	if len(embeds) > 0 {
		colonEmbeds := make([]string, 0, len(embeds))
		for _, embed := range embeds {
			colonEmbeds = append(colonEmbeds, ":"+embed)
		}
		r.SetAttr("embed", colonEmbeds)
	}
	r.SetPrivateAttr(config.GazelleImportsKey, target.imports.build())
}

func (g *generator) setImportAttrs(r *rule.Rule, importPath string) {
	gc := getGoConfig(g.c)
	r.SetAttr("importpath", importPath)

	// Set importpath_aliases if we need minimal module compatibility.
	// If a package is part of a module with a v2+ semantic import version
	// suffix, packages that are not part of modules may import it without
	// the suffix.
	if gc.goRepositoryMode && gc.moduleMode && pathtools.HasPrefix(importPath, gc.prefix) && gc.prefixRel == "" {
		if mmcImportPath := pathWithoutSemver(importPath); mmcImportPath != "" {
			r.SetAttr("importpath_aliases", []string{mmcImportPath})
		}
	}

	if gc.importMapPrefix != "" {
		fromPrefixRel := pathtools.TrimPrefix(g.rel, gc.importMapPrefixRel)
		importMap := path.Join(gc.importMapPrefix, fromPrefixRel)
		if importMap != importPath {
			r.SetAttr("importmap", importMap)
		}
	}
}

func (g *generator) commonVisibility(importPath string) []string {
	// If the Bazel package name (rel) contains "internal", add visibility for
	// subpackages of the parent.
	// If the import path contains "internal" but rel does not, this is
	// probably an internal submodule. Add visibility for all subpackages.
	relIndex := pathtools.Index(g.rel, "internal")
	importIndex := pathtools.Index(importPath, "internal")
	visibility := getGoConfig(g.c).goVisibility
	if relIndex >= 0 {
		parent := strings.TrimSuffix(g.rel[:relIndex], "/")
		visibility = append(visibility, fmt.Sprintf("//%s:__subpackages__", parent))
	} else if importIndex >= 0 {
		// This entire module is within an internal directory.
		// Identify other repos which should have access too.
		visibility = append(visibility, "//:__subpackages__")
		for _, repo := range g.c.Repos {
			if pathtools.HasPrefix(repo.AttrString("importpath"), importPath[:importIndex]) {
				visibility = append(visibility, "@"+repo.Name()+"//:__subpackages__")
			}
		}

	} else {
		return []string{"//visibility:public"}
	}

	// Add visibility for any submodules that have the internal parent as
	// a prefix of their module path.
	if importIndex >= 0 {
		gc := getGoConfig(g.c)
		internalRoot := strings.TrimSuffix(importPath[:importIndex], "/")
		for _, m := range gc.submodules {
			if strings.HasPrefix(m.modulePath, internalRoot) {
				visibility = append(visibility, fmt.Sprintf("@%s//:__subpackages__", m.repoName))
			}
		}
	}

	return visibility
}

var (
	// shortOptPrefixes are strings that come at the beginning of an option
	// argument that includes a path, e.g., -Ifoo/bar.
	shortOptPrefixes = []string{"-I", "-L", "-F"}

	// longOptPrefixes are separate arguments that come before a path argument,
	// e.g., -iquote foo/bar.
	longOptPrefixes = []string{"-I", "-L", "-F", "-iquote", "-isystem"}
)

// options transforms package-relative paths in cgo options into repository-
// root-relative paths that Bazel can understand. For example, if a cgo file
// in //foo declares an include flag in its copts: "-Ibar", this method
// will transform that flag into "-Ifoo/bar".
func (g *generator) options(opts rule.PlatformStrings, pkgRel string) rule.PlatformStrings {
	fixPath := func(opt string) string {
		if strings.HasPrefix(opt, "/") {
			return opt
		}
		return path.Clean(path.Join(pkgRel, opt))
	}

	fixGroups := func(groups []string) ([]string, error) {
		fixedGroups := make([]string, len(groups))
		for i, group := range groups {
			opts := strings.Split(group, optSeparator)
			fixedOpts := make([]string, len(opts))
			isPath := false
			for j, opt := range opts {
				if isPath {
					opt = fixPath(opt)
					isPath = false
					goto next
				}

				for _, short := range shortOptPrefixes {
					if strings.HasPrefix(opt, short) && len(opt) > len(short) {
						opt = short + fixPath(opt[len(short):])
						goto next
					}
				}

				for _, long := range longOptPrefixes {
					if opt == long {
						isPath = true
						goto next
					}
				}

			next:
				fixedOpts[j] = escapeOption(opt)
			}
			fixedGroups[i] = strings.Join(fixedOpts, " ")
		}

		return fixedGroups, nil
	}

	opts, errs := opts.MapSlice(fixGroups)
	if errs != nil {
		log.Panicf("unexpected error when transforming options with pkg %q: %v", pkgRel, errs)
	}
	return opts
}

func escapeOption(opt string) string {
	return strings.NewReplacer(
		`\`, `\\`,
		`'`, `\'`,
		`"`, `\"`,
		` `, `\ `,
		"\t", "\\\t",
		"\n", "\\\n",
		"\r", "\\\r",
		"$(", "$(",
		"$", "$$",
	).Replace(opt)
}

func shouldSetVisibility(args language.GenerateArgs) bool {
	if args.File != nil && args.File.HasDefaultVisibility() {
		return false
	}

	for _, r := range args.OtherGen {
		// This is kind of the same test as *File.HasDefaultVisibility(),
		// but for previously defined rules.
		if r.Kind() == "package" && r.Attr("default_visibility") != nil {
			return false
		}
	}
	return true
}
