func (ctx *ObjectGenCtx) generateForPackage(root *loader.Package) []byte {
	allTypes, err := enabledOnPackage(ctx.Collector, root)
	if err != nil {
		root.AddError(err)
		return nil
	}
	ctx.Checker.Check(root)
	root.NeedTypesInfo()
	byType := make(map[string][]byte)
	imports := &importsList{
		byPath:  make(map[string]string),
		byAlias: make(map[string]string),
		pkg:     root,
	}
	imports.byAlias[root.Name] = ""
	if err := markers.EachType(ctx.Collector, root, func(info *markers.TypeInfo) {
		outContent := new(bytes.Buffer)
		if !enabledOnType(allTypes, info) {
			return
		}
		if !shouldBeCopied(root, info) {
			return
		}
		copyCtx := &copyMethodMaker{
			pkg:         root,
			importsList: imports,
			codeWriter:  &codeWriter{out: outContent},
		}
		copyCtx.GenerateMethodsFor(root, info)
		outBytes := outContent.Bytes()
		if len(outBytes) > 0 {
			byType[info.Name] = outBytes
		}
	}); err != nil {
		root.AddError(err)
		return nil
	}
	if len(byType) == 0 {
		return nil
	}
	outContent := new(bytes.Buffer)
	writeHeader(root, outContent, root.Name, imports, ctx.HeaderText)
	writeMethods(root, outContent, byType)
	outBytes := outContent.Bytes()
	formattedBytes, err := format.Source(outBytes)
	if err != nil {
		root.AddError(err)
	} else {
		outBytes = formattedBytes
	}
	return outBytes
}
generateForPackage generates DeepCopy and runtime.Object implementations for
types in the given package, writing the formatted result to given writer.
May return nil if source could not be generated.
package deepcopy
import (
	"bytes"
	"fmt"
	"go/ast"
	"go/format"
	"io"
	"sort"
	"strings"
	"sigs.k8s.io/controller-tools/pkg/genall"
	"sigs.k8s.io/controller-tools/pkg/loader"
	"sigs.k8s.io/controller-tools/pkg/markers"
)
const (
	runtimeObjPath = "k8s.io/apimachinery/pkg/runtime.Object"
)
var (
	enablePkgMarker  = markers.Must(markers.MakeDefinition("kubebuilder:object:generate", markers.DescribesPackage, false))
	enableTypeMarker = markers.Must(markers.MakeDefinition("kubebuilder:object:generate", markers.DescribesType, false))
	isObjectMarker   = markers.Must(markers.MakeDefinition("kubebuilder:object:root", markers.DescribesType, false))
	legacyEnablePkgMarker  = markers.Must(markers.MakeDefinition("k8s:deepcopy-gen", markers.DescribesPackage, markers.RawArguments(nil)))
	legacyEnableTypeMarker = markers.Must(markers.MakeDefinition("k8s:deepcopy-gen", markers.DescribesType, markers.RawArguments(nil)))
	legacyIsObjectMarker   = markers.Must(markers.MakeDefinition("k8s:deepcopy-gen:interfaces", markers.DescribesType, ""))
)
type Generator struct {
	HeaderFile string `marker:",optional"`
	Year string `marker:",optional"`
}
func (Generator) CheckFilter() loader.NodeFilter {
	return func(node ast.Node) bool {
		_, isIface := node.(*ast.InterfaceType)
		return !isIface
	}
}
func (Generator) RegisterMarkers(into *markers.Registry) error {
	if err := markers.RegisterAll(into,
		enablePkgMarker, legacyEnablePkgMarker, enableTypeMarker,
		legacyEnableTypeMarker, isObjectMarker, legacyIsObjectMarker); err != nil {
		return err
	}
	into.AddHelp(enablePkgMarker,
		markers.SimpleHelp("object", "enables or disables object interface & deepcopy implementation generation for this package"))
	into.AddHelp(
		enableTypeMarker, markers.SimpleHelp("object", "overrides enabling or disabling deepcopy generation for this type"))
	into.AddHelp(isObjectMarker,
		markers.SimpleHelp("object", "enables object interface implementation generation for this type"))
	into.AddHelp(legacyEnablePkgMarker,
		markers.DeprecatedHelp(enablePkgMarker.Name, "object", "enables or disables object interface & deepcopy implementation generation for this package"))
	into.AddHelp(legacyEnableTypeMarker,
		markers.DeprecatedHelp(enableTypeMarker.Name, "object", "overrides enabling or disabling deepcopy generation for this type"))
	into.AddHelp(legacyIsObjectMarker,
		markers.DeprecatedHelp(isObjectMarker.Name, "object", "enables object interface implementation generation for this type"))
	return nil
}
func enabledOnPackage(col *markers.Collector, pkg *loader.Package) (bool, error) {
	pkgMarkers, err := markers.PackageMarkers(col, pkg)
	if err != nil {
		return false, err
	}
	pkgMarker := pkgMarkers.Get(enablePkgMarker.Name)
	if pkgMarker != nil {
		return pkgMarker.(bool), nil
	}
	legacyMarker := pkgMarkers.Get(legacyEnablePkgMarker.Name)
	if legacyMarker != nil {
		legacyMarkerVal := string(legacyMarker.(markers.RawArguments))
		firstArg := strings.Split(legacyMarkerVal, ",")[0]
		return firstArg == "package", nil
	}
	return false, nil
}
func enabledOnType(allTypes bool, info *markers.TypeInfo) bool {
	if typeMarker := info.Markers.Get(enableTypeMarker.Name); typeMarker != nil {
		return typeMarker.(bool)
	}
	legacyMarker := info.Markers.Get(legacyEnableTypeMarker.Name)
	if legacyMarker != nil {
		legacyMarkerVal := string(legacyMarker.(markers.RawArguments))
		return legacyMarkerVal == "true"
	}
	return allTypes || genObjectInterface(info)
}
func genObjectInterface(info *markers.TypeInfo) bool {
	objectEnabled := info.Markers.Get(isObjectMarker.Name)
	if objectEnabled != nil {
		return objectEnabled.(bool)
	}
	for _, legacyEnabled := range info.Markers[legacyIsObjectMarker.Name] {
		if legacyEnabled == runtimeObjPath {
			return true
		}
	}
	return false
}
func (d Generator) Generate(ctx *genall.GenerationContext) error {
	var headerText string
	if d.HeaderFile != "" {
		headerBytes, err := ctx.ReadFile(d.HeaderFile)
		if err != nil {
			return err
		}
		headerText = string(headerBytes)
	}
	headerText = strings.ReplaceAll(headerText, " YEAR", " "+d.Year)
	objGenCtx := ObjectGenCtx{
		Collector:  ctx.Collector,
		Checker:    ctx.Checker,
		HeaderText: headerText,
	}
	for _, root := range ctx.Roots {
		outContents := objGenCtx.generateForPackage(root)
		if outContents == nil {
			continue
		}
		writeOut(ctx, root, outContents)
	}
	return nil
}
type ObjectGenCtx struct {
	Collector  *markers.Collector
	Checker    *loader.TypeChecker
	HeaderText string
}
func writeHeader(pkg *loader.Package, out io.Writer, packageName string, imports *importsList, headerText string) {
	_, err := fmt.Fprintf(out, ` 
%[3]s
package %[1]s
import (
%[2]s
)
`, packageName, strings.Join(imports.ImportSpecs(), "\n"), headerText)
	if err != nil {
		pkg.AddError(err)
	}
}