Add generated file
This PR adds generated files under pkg/client and vendor folder.
This commit is contained in:
1
vendor/k8s.io/gengo/examples/deepcopy-gen/.gitignore
generated
vendored
Normal file
1
vendor/k8s.io/gengo/examples/deepcopy-gen/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
deepcopy-gen
|
16
vendor/k8s.io/gengo/examples/deepcopy-gen/Makefile
generated
vendored
Normal file
16
vendor/k8s.io/gengo/examples/deepcopy-gen/Makefile
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
TOOL=deepcopy-gen
|
||||
|
||||
test:
|
||||
@if ! git diff --quiet HEAD; then \
|
||||
echo "FAIL: git client is not clean"; \
|
||||
false; \
|
||||
fi
|
||||
@go build -o /tmp/$(TOOL)
|
||||
@PKGS=$$(go list ./output_tests/... | paste -sd' ' -); \
|
||||
/tmp/$(TOOL) --logtostderr --v=4 -i $$(echo $$PKGS | sed 's/ /,/g') -O zz_generated
|
||||
@if ! git diff --quiet HEAD; then \
|
||||
echo "FAIL: output files changed"; \
|
||||
git diff; \
|
||||
false; \
|
||||
fi
|
||||
|
905
vendor/k8s.io/gengo/examples/deepcopy-gen/generators/deepcopy.go
generated
vendored
Normal file
905
vendor/k8s.io/gengo/examples/deepcopy-gen/generators/deepcopy.go
generated
vendored
Normal file
@@ -0,0 +1,905 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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 generators
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/gengo/args"
|
||||
"k8s.io/gengo/examples/set-gen/sets"
|
||||
"k8s.io/gengo/generator"
|
||||
"k8s.io/gengo/namer"
|
||||
"k8s.io/gengo/types"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// CustomArgs is used tby the go2idl framework to pass args specific to this
|
||||
// generator.
|
||||
type CustomArgs struct {
|
||||
BoundingDirs []string // Only deal with types rooted under these dirs.
|
||||
}
|
||||
|
||||
// This is the comment tag that carries parameters for deep-copy generation.
|
||||
const (
|
||||
tagName = "k8s:deepcopy-gen"
|
||||
interfacesTagName = tagName + ":interfaces"
|
||||
interfacesNonPointerTagName = tagName + ":nonpointer-interfaces" // attach the DeepCopy<Interface> methods to the
|
||||
)
|
||||
|
||||
// Known values for the comment tag.
|
||||
const tagValuePackage = "package"
|
||||
|
||||
// tagValue holds parameters from a tagName tag.
|
||||
type tagValue struct {
|
||||
value string
|
||||
register bool
|
||||
}
|
||||
|
||||
func extractTag(comments []string) *tagValue {
|
||||
tagVals := types.ExtractCommentTags("+", comments)[tagName]
|
||||
if tagVals == nil {
|
||||
// No match for the tag.
|
||||
return nil
|
||||
}
|
||||
// If there are multiple values, abort.
|
||||
if len(tagVals) > 1 {
|
||||
glog.Fatalf("Found %d %s tags: %q", len(tagVals), tagName, tagVals)
|
||||
}
|
||||
|
||||
// If we got here we are returning something.
|
||||
tag := &tagValue{}
|
||||
|
||||
// Get the primary value.
|
||||
parts := strings.Split(tagVals[0], ",")
|
||||
if len(parts) >= 1 {
|
||||
tag.value = parts[0]
|
||||
}
|
||||
|
||||
// Parse extra arguments.
|
||||
parts = parts[1:]
|
||||
for i := range parts {
|
||||
kv := strings.SplitN(parts[i], "=", 2)
|
||||
k := kv[0]
|
||||
v := ""
|
||||
if len(kv) == 2 {
|
||||
v = kv[1]
|
||||
}
|
||||
switch k {
|
||||
case "register":
|
||||
if v != "false" {
|
||||
tag.register = true
|
||||
}
|
||||
default:
|
||||
glog.Fatalf("Unsupported %s param: %q", tagName, parts[i])
|
||||
}
|
||||
}
|
||||
return tag
|
||||
}
|
||||
|
||||
// TODO: This is created only to reduce number of changes in a single PR.
|
||||
// Remove it and use PublicNamer instead.
|
||||
func deepCopyNamer() *namer.NameStrategy {
|
||||
return &namer.NameStrategy{
|
||||
Join: func(pre string, in []string, post string) string {
|
||||
return strings.Join(in, "_")
|
||||
},
|
||||
PrependPackageNames: 1,
|
||||
}
|
||||
}
|
||||
|
||||
// NameSystems returns the name system used by the generators in this package.
|
||||
func NameSystems() namer.NameSystems {
|
||||
return namer.NameSystems{
|
||||
"public": deepCopyNamer(),
|
||||
"raw": namer.NewRawNamer("", nil),
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultNameSystem returns the default name system for ordering the types to be
|
||||
// processed by the generators in this package.
|
||||
func DefaultNameSystem() string {
|
||||
return "public"
|
||||
}
|
||||
|
||||
func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
|
||||
boilerplate, err := arguments.LoadGoBoilerplate()
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed loading boilerplate: %v", err)
|
||||
}
|
||||
|
||||
inputs := sets.NewString(context.Inputs...)
|
||||
packages := generator.Packages{}
|
||||
header := append([]byte(fmt.Sprintf("// +build !%s\n\n", arguments.GeneratedBuildTag)), boilerplate...)
|
||||
|
||||
boundingDirs := []string{}
|
||||
if customArgs, ok := arguments.CustomArgs.(*CustomArgs); ok {
|
||||
if customArgs.BoundingDirs == nil {
|
||||
customArgs.BoundingDirs = context.Inputs
|
||||
}
|
||||
for i := range customArgs.BoundingDirs {
|
||||
// Strip any trailing slashes - they are not exactly "correct" but
|
||||
// this is friendlier.
|
||||
boundingDirs = append(boundingDirs, strings.TrimRight(customArgs.BoundingDirs[i], "/"))
|
||||
}
|
||||
}
|
||||
|
||||
for i := range inputs {
|
||||
glog.V(5).Infof("Considering pkg %q", i)
|
||||
pkg := context.Universe[i]
|
||||
if pkg == nil {
|
||||
// If the input had no Go files, for example.
|
||||
continue
|
||||
}
|
||||
|
||||
ptag := extractTag(pkg.Comments)
|
||||
ptagValue := ""
|
||||
ptagRegister := false
|
||||
if ptag != nil {
|
||||
ptagValue = ptag.value
|
||||
if ptagValue != tagValuePackage {
|
||||
glog.Fatalf("Package %v: unsupported %s value: %q", i, tagName, ptagValue)
|
||||
}
|
||||
ptagRegister = ptag.register
|
||||
glog.V(5).Infof(" tag.value: %q, tag.register: %t", ptagValue, ptagRegister)
|
||||
} else {
|
||||
glog.V(5).Infof(" no tag")
|
||||
}
|
||||
|
||||
// If the pkg-scoped tag says to generate, we can skip scanning types.
|
||||
pkgNeedsGeneration := (ptagValue == tagValuePackage)
|
||||
if !pkgNeedsGeneration {
|
||||
// If the pkg-scoped tag did not exist, scan all types for one that
|
||||
// explicitly wants generation.
|
||||
for _, t := range pkg.Types {
|
||||
glog.V(5).Infof(" considering type %q", t.Name.String())
|
||||
ttag := extractTag(t.CommentLines)
|
||||
if ttag != nil && ttag.value == "true" {
|
||||
glog.V(5).Infof(" tag=true")
|
||||
if !copyableType(t) {
|
||||
glog.Fatalf("Type %v requests deepcopy generation but is not copyable", t)
|
||||
}
|
||||
pkgNeedsGeneration = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if pkgNeedsGeneration {
|
||||
glog.V(3).Infof("Package %q needs generation", i)
|
||||
path := pkg.Path
|
||||
// if the source path is within a /vendor/ directory (for example,
|
||||
// k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1), allow
|
||||
// generation to output to the proper relative path (under vendor).
|
||||
// Otherwise, the generator will create the file in the wrong location
|
||||
// in the output directory.
|
||||
// TODO: build a more fundamental concept in gengo for dealing with modifications
|
||||
// to vendored packages.
|
||||
if strings.HasPrefix(pkg.SourcePath, arguments.OutputBase) {
|
||||
expandedPath := strings.TrimPrefix(pkg.SourcePath, arguments.OutputBase)
|
||||
if strings.Contains(expandedPath, "/vendor/") {
|
||||
path = expandedPath
|
||||
}
|
||||
}
|
||||
packages = append(packages,
|
||||
&generator.DefaultPackage{
|
||||
PackageName: strings.Split(filepath.Base(pkg.Path), ".")[0],
|
||||
PackagePath: path,
|
||||
HeaderText: header,
|
||||
GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
|
||||
return []generator.Generator{
|
||||
NewGenDeepCopy(arguments.OutputFileBaseName, pkg.Path, boundingDirs, (ptagValue == tagValuePackage), ptagRegister),
|
||||
}
|
||||
},
|
||||
FilterFunc: func(c *generator.Context, t *types.Type) bool {
|
||||
return t.Name.Package == pkg.Path
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
return packages
|
||||
}
|
||||
|
||||
// genDeepCopy produces a file with autogenerated deep-copy functions.
|
||||
type genDeepCopy struct {
|
||||
generator.DefaultGen
|
||||
targetPackage string
|
||||
boundingDirs []string
|
||||
allTypes bool
|
||||
registerTypes bool
|
||||
imports namer.ImportTracker
|
||||
typesForInit []*types.Type
|
||||
}
|
||||
|
||||
func NewGenDeepCopy(sanitizedName, targetPackage string, boundingDirs []string, allTypes, registerTypes bool) generator.Generator {
|
||||
return &genDeepCopy{
|
||||
DefaultGen: generator.DefaultGen{
|
||||
OptionalName: sanitizedName,
|
||||
},
|
||||
targetPackage: targetPackage,
|
||||
boundingDirs: boundingDirs,
|
||||
allTypes: allTypes,
|
||||
registerTypes: registerTypes,
|
||||
imports: generator.NewImportTracker(),
|
||||
typesForInit: make([]*types.Type, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) Namers(c *generator.Context) namer.NameSystems {
|
||||
// Have the raw namer for this file track what it imports.
|
||||
return namer.NameSystems{
|
||||
"raw": namer.NewRawNamer(g.targetPackage, g.imports),
|
||||
}
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) Filter(c *generator.Context, t *types.Type) bool {
|
||||
// Filter out types not being processed or not copyable within the package.
|
||||
enabled := g.allTypes
|
||||
if !enabled {
|
||||
ttag := extractTag(t.CommentLines)
|
||||
if ttag != nil && ttag.value == "true" {
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
if !enabled {
|
||||
return false
|
||||
}
|
||||
if !copyableType(t) {
|
||||
glog.V(2).Infof("Type %v is not copyable", t)
|
||||
return false
|
||||
}
|
||||
glog.V(4).Infof("Type %v is copyable", t)
|
||||
g.typesForInit = append(g.typesForInit, t)
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) copyableAndInBounds(t *types.Type) bool {
|
||||
if !copyableType(t) {
|
||||
return false
|
||||
}
|
||||
// Only packages within the restricted range can be processed.
|
||||
if !isRootedUnder(t.Name.Package, g.boundingDirs) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// deepCopyMethod returns the signature of a DeepCopy() method, nil or an error
|
||||
// if the type does not match. This allows more efficient deep copy
|
||||
// implementations to be defined by the type's author. The correct signature
|
||||
// for a type T is:
|
||||
// func (t T) DeepCopy() T
|
||||
// or:
|
||||
// func (t *T) DeepCopy() *T
|
||||
func deepCopyMethod(t *types.Type) (*types.Signature, error) {
|
||||
f, found := t.Methods["DeepCopy"]
|
||||
if !found {
|
||||
return nil, nil
|
||||
}
|
||||
if len(f.Signature.Parameters) != 0 {
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected no parameters", t)
|
||||
}
|
||||
if len(f.Signature.Results) != 1 {
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected exactly one result", t)
|
||||
}
|
||||
|
||||
ptrResult := f.Signature.Results[0].Kind == types.Pointer && f.Signature.Results[0].Elem.Name == t.Name
|
||||
nonPtrResult := f.Signature.Results[0].Name == t.Name
|
||||
|
||||
if !ptrResult && !nonPtrResult {
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected to return %s or *%s", t, t.Name.Name, t.Name.Name)
|
||||
}
|
||||
|
||||
ptrRcvr := f.Signature.Receiver != nil && f.Signature.Receiver.Kind == types.Pointer && f.Signature.Receiver.Elem.Name == t.Name
|
||||
nonPtrRcvr := f.Signature.Receiver != nil && f.Signature.Receiver.Name == t.Name
|
||||
|
||||
if ptrRcvr && !ptrResult {
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected a *%s result for a *%s receiver", t, t.Name.Name, t.Name.Name)
|
||||
}
|
||||
if nonPtrRcvr && !nonPtrResult {
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected a %s result for a %s receiver", t, t.Name.Name, t.Name.Name)
|
||||
}
|
||||
|
||||
return f.Signature, nil
|
||||
}
|
||||
|
||||
// deepCopyMethodOrDie returns the signatrue of a DeepCopy method, nil or calls glog.Fatalf
|
||||
// if the type does not match.
|
||||
func deepCopyMethodOrDie(t *types.Type) *types.Signature {
|
||||
ret, err := deepCopyMethod(t)
|
||||
if err != nil {
|
||||
glog.Fatal(err)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// deepCopyIntoMethod returns the signature of a DeepCopyInto() method, nil or an error
|
||||
// if the type is wrong. DeepCopyInto allows more efficient deep copy
|
||||
// implementations to be defined by the type's author. The correct signature
|
||||
// for a type T is:
|
||||
// func (t T) DeepCopyInto(t *T)
|
||||
// or:
|
||||
// func (t *T) DeepCopyInto(t *T)
|
||||
func deepCopyIntoMethod(t *types.Type) (*types.Signature, error) {
|
||||
f, found := t.Methods["DeepCopyInto"]
|
||||
if !found {
|
||||
return nil, nil
|
||||
}
|
||||
if len(f.Signature.Parameters) != 1 {
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected exactly one parameter", t)
|
||||
}
|
||||
if len(f.Signature.Results) != 0 {
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected no result type", t)
|
||||
}
|
||||
|
||||
ptrParam := f.Signature.Parameters[0].Kind == types.Pointer && f.Signature.Parameters[0].Elem.Name == t.Name
|
||||
|
||||
if !ptrParam {
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected parameter of type *%s", t, t.Name.Name)
|
||||
}
|
||||
|
||||
ptrRcvr := f.Signature.Receiver != nil && f.Signature.Receiver.Kind == types.Pointer && f.Signature.Receiver.Elem.Name == t.Name
|
||||
nonPtrRcvr := f.Signature.Receiver != nil && f.Signature.Receiver.Name == t.Name
|
||||
|
||||
if !ptrRcvr && !nonPtrRcvr {
|
||||
// this should never happen
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected a receiver of type %s or *%s", t, t.Name.Name, t.Name.Name)
|
||||
}
|
||||
|
||||
return f.Signature, nil
|
||||
}
|
||||
|
||||
// deepCopyIntoMethodOrDie returns the signature of a DeepCopyInto() method, nil or calls glog.Fatalf
|
||||
// if the type is wrong.
|
||||
func deepCopyIntoMethodOrDie(t *types.Type) *types.Signature {
|
||||
ret, err := deepCopyIntoMethod(t)
|
||||
if err != nil {
|
||||
glog.Fatal(err)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func isRootedUnder(pkg string, roots []string) bool {
|
||||
// Add trailing / to avoid false matches, e.g. foo/bar vs foo/barn. This
|
||||
// assumes that bounding dirs do not have trailing slashes.
|
||||
pkg = pkg + "/"
|
||||
for _, root := range roots {
|
||||
if strings.HasPrefix(pkg, root+"/") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func copyableType(t *types.Type) bool {
|
||||
// If the type opts out of copy-generation, stop.
|
||||
ttag := extractTag(t.CommentLines)
|
||||
if ttag != nil && ttag.value == "false" {
|
||||
return false
|
||||
}
|
||||
|
||||
// Filter out private types.
|
||||
if namer.IsPrivateGoName(t.Name.Name) {
|
||||
return false
|
||||
}
|
||||
|
||||
if t.Kind == types.Alias {
|
||||
// if the underlying built-in is not deepcopy-able, deepcopy is opt-in through definition of custom methods.
|
||||
// Note that aliases of builtins, maps, slices can have deepcopy methods.
|
||||
if deepCopyMethodOrDie(t) != nil || deepCopyIntoMethodOrDie(t) != nil {
|
||||
return true
|
||||
} else {
|
||||
return t.Underlying.Kind != types.Builtin || copyableType(t.Underlying)
|
||||
}
|
||||
}
|
||||
|
||||
if t.Kind != types.Struct {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func underlyingType(t *types.Type) *types.Type {
|
||||
for t.Kind == types.Alias {
|
||||
t = t.Underlying
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) isOtherPackage(pkg string) bool {
|
||||
if pkg == g.targetPackage {
|
||||
return false
|
||||
}
|
||||
if strings.HasSuffix(pkg, "\""+g.targetPackage+"\"") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) Imports(c *generator.Context) (imports []string) {
|
||||
importLines := []string{}
|
||||
for _, singleImport := range g.imports.ImportLines() {
|
||||
if g.isOtherPackage(singleImport) {
|
||||
importLines = append(importLines, singleImport)
|
||||
}
|
||||
}
|
||||
return importLines
|
||||
}
|
||||
|
||||
func argsFromType(ts ...*types.Type) generator.Args {
|
||||
a := generator.Args{
|
||||
"type": ts[0],
|
||||
}
|
||||
for i, t := range ts {
|
||||
a[fmt.Sprintf("type%d", i+1)] = t
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) Init(c *generator.Context, w io.Writer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) needsGeneration(t *types.Type) bool {
|
||||
tag := extractTag(t.CommentLines)
|
||||
tv := ""
|
||||
if tag != nil {
|
||||
tv = tag.value
|
||||
if tv != "true" && tv != "false" {
|
||||
glog.Fatalf("Type %v: unsupported %s value: %q", t, tagName, tag.value)
|
||||
}
|
||||
}
|
||||
if g.allTypes && tv == "false" {
|
||||
// The whole package is being generated, but this type has opted out.
|
||||
glog.V(5).Infof("Not generating for type %v because type opted out", t)
|
||||
return false
|
||||
}
|
||||
if !g.allTypes && tv != "true" {
|
||||
// The whole package is NOT being generated, and this type has NOT opted in.
|
||||
glog.V(5).Infof("Not generating for type %v because type did not opt in", t)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func extractInterfacesTag(comments []string) []string {
|
||||
var result []string
|
||||
values := types.ExtractCommentTags("+", comments)[interfacesTagName]
|
||||
for _, v := range values {
|
||||
if len(v) == 0 {
|
||||
continue
|
||||
}
|
||||
intfs := strings.Split(v, ",")
|
||||
for _, intf := range intfs {
|
||||
if intf == "" {
|
||||
continue
|
||||
}
|
||||
result = append(result, intf)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func extractNonPointerInterfaces(comments []string) (bool, error) {
|
||||
values := types.ExtractCommentTags("+", comments)[interfacesNonPointerTagName]
|
||||
if len(values) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
result := values[0] == "true"
|
||||
for _, v := range values {
|
||||
if v == "true" != result {
|
||||
return false, fmt.Errorf("contradicting %v value %q found to previous value %v", interfacesNonPointerTagName, v, result)
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) deepCopyableInterfacesInner(c *generator.Context, t *types.Type) ([]*types.Type, error) {
|
||||
if t.Kind != types.Struct {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
intfs := extractInterfacesTag(append(t.SecondClosestCommentLines, t.CommentLines...))
|
||||
|
||||
var ts []*types.Type
|
||||
for _, intf := range intfs {
|
||||
t := types.ParseFullyQualifiedName(intf)
|
||||
c.AddDir(t.Package)
|
||||
intfT := c.Universe.Type(t)
|
||||
if intfT == nil {
|
||||
return nil, fmt.Errorf("unknown type %q in %s tag of type %s", intf, interfacesTagName, intfT)
|
||||
}
|
||||
if intfT.Kind != types.Interface {
|
||||
return nil, fmt.Errorf("type %q in %s tag of type %s is not an interface, but: %q", intf, interfacesTagName, t, intfT.Kind)
|
||||
}
|
||||
g.imports.AddType(intfT)
|
||||
ts = append(ts, intfT)
|
||||
}
|
||||
|
||||
return ts, nil
|
||||
}
|
||||
|
||||
// deepCopyableInterfaces returns the interface types to implement and whether they apply to a non-pointer receiver.
|
||||
func (g *genDeepCopy) deepCopyableInterfaces(c *generator.Context, t *types.Type) ([]*types.Type, bool, error) {
|
||||
ts, err := g.deepCopyableInterfacesInner(c, t)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
set := map[string]*types.Type{}
|
||||
for _, t := range ts {
|
||||
set[t.String()] = t
|
||||
}
|
||||
|
||||
result := []*types.Type{}
|
||||
for _, t := range set {
|
||||
result = append(result, t)
|
||||
}
|
||||
|
||||
TypeSlice(result).Sort() // we need a stable sorting because it determines the order in generation
|
||||
|
||||
nonPointerReceiver, err := extractNonPointerInterfaces(append(t.SecondClosestCommentLines, t.CommentLines...))
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
return result, nonPointerReceiver, nil
|
||||
}
|
||||
|
||||
type TypeSlice []*types.Type
|
||||
|
||||
func (s TypeSlice) Len() int { return len(s) }
|
||||
func (s TypeSlice) Less(i, j int) bool { return s[i].String() < s[j].String() }
|
||||
func (s TypeSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s TypeSlice) Sort() { sort.Sort(s) }
|
||||
|
||||
func (g *genDeepCopy) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
|
||||
if !g.needsGeneration(t) {
|
||||
return nil
|
||||
}
|
||||
glog.V(5).Infof("Generating deepcopy function for type %v", t)
|
||||
|
||||
sw := generator.NewSnippetWriter(w, c, "$", "$")
|
||||
args := argsFromType(t)
|
||||
|
||||
if deepCopyIntoMethodOrDie(t) == nil {
|
||||
sw.Do("// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\n", args)
|
||||
if isReference(t) {
|
||||
sw.Do("func (in $.type|raw$) DeepCopyInto(out *$.type|raw$) {\n", args)
|
||||
sw.Do("{in:=&in\n", nil)
|
||||
} else {
|
||||
sw.Do("func (in *$.type|raw$) DeepCopyInto(out *$.type|raw$) {\n", args)
|
||||
}
|
||||
if deepCopyMethodOrDie(t) != nil {
|
||||
if t.Methods["DeepCopy"].Signature.Receiver.Kind == types.Pointer {
|
||||
sw.Do("clone := in.DeepCopy()\n", nil)
|
||||
sw.Do("*out = *clone\n", nil)
|
||||
} else {
|
||||
sw.Do("*out = in.DeepCopy()\n", nil)
|
||||
}
|
||||
sw.Do("return\n", nil)
|
||||
} else {
|
||||
g.generateFor(t, sw)
|
||||
sw.Do("return\n", nil)
|
||||
}
|
||||
if isReference(t) {
|
||||
sw.Do("}\n", nil)
|
||||
}
|
||||
sw.Do("}\n\n", nil)
|
||||
}
|
||||
|
||||
if deepCopyMethodOrDie(t) == nil {
|
||||
sw.Do("// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new $.type|raw$.\n", args)
|
||||
if isReference(t) {
|
||||
sw.Do("func (in $.type|raw$) DeepCopy() $.type|raw$ {\n", args)
|
||||
} else {
|
||||
sw.Do("func (in *$.type|raw$) DeepCopy() *$.type|raw$ {\n", args)
|
||||
}
|
||||
sw.Do("if in == nil { return nil }\n", nil)
|
||||
sw.Do("out := new($.type|raw$)\n", args)
|
||||
sw.Do("in.DeepCopyInto(out)\n", nil)
|
||||
if isReference(t) {
|
||||
sw.Do("return *out\n", nil)
|
||||
} else {
|
||||
sw.Do("return out\n", nil)
|
||||
}
|
||||
sw.Do("}\n\n", nil)
|
||||
}
|
||||
|
||||
intfs, nonPointerReceiver, err := g.deepCopyableInterfaces(c, t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, intf := range intfs {
|
||||
sw.Do(fmt.Sprintf("// DeepCopy%s is an autogenerated deepcopy function, copying the receiver, creating a new $.type2|raw$.\n", intf.Name.Name), argsFromType(t, intf))
|
||||
if nonPointerReceiver {
|
||||
sw.Do(fmt.Sprintf("func (in $.type|raw$) DeepCopy%s() $.type2|raw$ {\n", intf.Name.Name), argsFromType(t, intf))
|
||||
sw.Do("return *in.DeepCopy()", nil)
|
||||
sw.Do("}\n\n", nil)
|
||||
} else {
|
||||
sw.Do(fmt.Sprintf("func (in *$.type|raw$) DeepCopy%s() $.type2|raw$ {\n", intf.Name.Name), argsFromType(t, intf))
|
||||
sw.Do("if c := in.DeepCopy(); c != nil {\n", nil)
|
||||
sw.Do("return c\n", nil)
|
||||
sw.Do("}\n", nil)
|
||||
sw.Do("return nil\n", nil)
|
||||
sw.Do("}\n\n", nil)
|
||||
}
|
||||
}
|
||||
|
||||
return sw.Error()
|
||||
}
|
||||
|
||||
// isReference return true for pointer, maps, slices and aliases of those.
|
||||
func isReference(t *types.Type) bool {
|
||||
if t.Kind == types.Pointer || t.Kind == types.Map || t.Kind == types.Slice {
|
||||
return true
|
||||
}
|
||||
return t.Kind == types.Alias && isReference(underlyingType(t))
|
||||
}
|
||||
|
||||
// we use the system of shadowing 'in' and 'out' so that the same code is valid
|
||||
// at any nesting level. This makes the autogenerator easy to understand, and
|
||||
// the compiler shouldn't care.
|
||||
func (g *genDeepCopy) generateFor(t *types.Type, sw *generator.SnippetWriter) {
|
||||
// derive inner types if t is an alias. We call the do* methods below with the alias type.
|
||||
// basic rule: generate according to inner type, but construct objects with the alias type.
|
||||
ut := underlyingType(t)
|
||||
|
||||
var f func(*types.Type, *generator.SnippetWriter)
|
||||
switch ut.Kind {
|
||||
case types.Builtin:
|
||||
f = g.doBuiltin
|
||||
case types.Map:
|
||||
f = g.doMap
|
||||
case types.Slice:
|
||||
f = g.doSlice
|
||||
case types.Struct:
|
||||
f = g.doStruct
|
||||
case types.Pointer:
|
||||
f = g.doPointer
|
||||
case types.Interface:
|
||||
// interfaces are handled in-line in the other cases
|
||||
glog.Fatalf("Hit an interface type %v. This should never happen.", t)
|
||||
case types.Alias:
|
||||
// can never happen because we branch on the underlying type which is never an alias
|
||||
glog.Fatalf("Hit an alias type %v. This should never happen.", t)
|
||||
default:
|
||||
glog.Fatalf("Hit an unsupported type %v.", t)
|
||||
}
|
||||
f(t, sw)
|
||||
}
|
||||
|
||||
// doBuiltin generates code for a builtin or an alias to a builtin. The generated code is
|
||||
// is the same for both cases, i.e. it's the code for the underlying type.
|
||||
func (g *genDeepCopy) doBuiltin(t *types.Type, sw *generator.SnippetWriter) {
|
||||
if deepCopyMethodOrDie(t) != nil || deepCopyIntoMethodOrDie(t) != nil {
|
||||
sw.Do("*out = in.DeepCopy()\n", nil)
|
||||
return
|
||||
}
|
||||
|
||||
sw.Do("*out = *in\n", nil)
|
||||
}
|
||||
|
||||
// doMap generates code for a map or an alias to a map. The generated code is
|
||||
// is the same for both cases, i.e. it's the code for the underlying type.
|
||||
func (g *genDeepCopy) doMap(t *types.Type, sw *generator.SnippetWriter) {
|
||||
ut := underlyingType(t)
|
||||
uet := underlyingType(ut.Elem)
|
||||
|
||||
if deepCopyMethodOrDie(t) != nil || deepCopyIntoMethodOrDie(t) != nil {
|
||||
sw.Do("*out = in.DeepCopy()\n", nil)
|
||||
return
|
||||
}
|
||||
|
||||
if !ut.Key.IsAssignable() {
|
||||
glog.Fatalf("Hit an unsupported type %v.", uet)
|
||||
}
|
||||
|
||||
sw.Do("*out = make($.|raw$, len(*in))\n", t)
|
||||
sw.Do("for key, val := range *in {\n", nil)
|
||||
dc, dci := deepCopyMethodOrDie(ut.Elem), deepCopyIntoMethodOrDie(ut.Elem)
|
||||
switch {
|
||||
case dc != nil || dci != nil:
|
||||
// Note: a DeepCopy exists because it is added if DeepCopyInto is manually defined
|
||||
leftPointer := ut.Elem.Kind == types.Pointer
|
||||
rightPointer := !isReference(ut.Elem)
|
||||
if dc != nil {
|
||||
rightPointer = dc.Results[0].Kind == types.Pointer
|
||||
}
|
||||
if leftPointer == rightPointer {
|
||||
sw.Do("(*out)[key] = val.DeepCopy()\n", nil)
|
||||
} else if leftPointer {
|
||||
sw.Do("x := val.DeepCopy()\n", nil)
|
||||
sw.Do("(*out)[key] = &x\n", nil)
|
||||
} else {
|
||||
sw.Do("(*out)[key] = *val.DeepCopy()\n", nil)
|
||||
}
|
||||
case ut.Elem.IsAnonymousStruct(): // not uet here because it needs type cast
|
||||
sw.Do("(*out)[key] = val\n", nil)
|
||||
case uet.IsAssignable():
|
||||
sw.Do("(*out)[key] = val\n", nil)
|
||||
case uet.Kind == types.Interface:
|
||||
sw.Do("if val == nil {(*out)[key]=nil} else {\n", nil)
|
||||
// Note: if t.Elem has been an alias "J" of an interface "I" in Go, we will see it
|
||||
// as kind Interface of name "J" here, i.e. generate val.DeepCopyJ(). The golang
|
||||
// parser does not give us the underlying interface name. So we cannot do any better.
|
||||
sw.Do(fmt.Sprintf("(*out)[key] = val.DeepCopy%s()\n", uet.Name.Name), nil)
|
||||
sw.Do("}\n", nil)
|
||||
case uet.Kind == types.Slice || uet.Kind == types.Map || uet.Kind == types.Pointer:
|
||||
sw.Do("var outVal $.|raw$\n", uet)
|
||||
sw.Do("if val == nil { (*out)[key] = nil } else {\n", nil)
|
||||
sw.Do("in, out := &val, &outVal\n", uet)
|
||||
g.generateFor(ut.Elem, sw)
|
||||
sw.Do("}\n", nil)
|
||||
sw.Do("(*out)[key] = outVal\n", nil)
|
||||
case uet.Kind == types.Struct:
|
||||
sw.Do("(*out)[key] = *val.DeepCopy()\n", uet)
|
||||
default:
|
||||
glog.Fatalf("Hit an unsupported type %v.", uet)
|
||||
}
|
||||
sw.Do("}\n", nil)
|
||||
}
|
||||
|
||||
// doSlice generates code for a slice or an alias to a slice. The generated code is
|
||||
// is the same for both cases, i.e. it's the code for the underlying type.
|
||||
func (g *genDeepCopy) doSlice(t *types.Type, sw *generator.SnippetWriter) {
|
||||
ut := underlyingType(t)
|
||||
uet := underlyingType(ut.Elem)
|
||||
|
||||
if deepCopyMethodOrDie(t) != nil || deepCopyIntoMethodOrDie(t) != nil {
|
||||
sw.Do("*out = in.DeepCopy()\n", nil)
|
||||
return
|
||||
}
|
||||
|
||||
sw.Do("*out = make($.|raw$, len(*in))\n", t)
|
||||
if deepCopyMethodOrDie(ut.Elem) != nil || deepCopyIntoMethodOrDie(ut.Elem) != nil {
|
||||
sw.Do("for i := range *in {\n", nil)
|
||||
// Note: a DeepCopyInto exists because it is added if DeepCopy is manually defined
|
||||
sw.Do("(*in)[i].DeepCopyInto(&(*out)[i])\n", nil)
|
||||
sw.Do("}\n", nil)
|
||||
} else if uet.Kind == types.Builtin || uet.IsAssignable() {
|
||||
sw.Do("copy(*out, *in)\n", nil)
|
||||
} else {
|
||||
sw.Do("for i := range *in {\n", nil)
|
||||
if uet.Kind == types.Slice || uet.Kind == types.Map || uet.Kind == types.Pointer || deepCopyMethodOrDie(ut.Elem) != nil || deepCopyIntoMethodOrDie(ut.Elem) != nil {
|
||||
sw.Do("if (*in)[i] != nil {\n", nil)
|
||||
sw.Do("in, out := &(*in)[i], &(*out)[i]\n", nil)
|
||||
g.generateFor(ut.Elem, sw)
|
||||
sw.Do("}\n", nil)
|
||||
} else if uet.Kind == types.Interface {
|
||||
sw.Do("if (*in)[i] != nil {\n", nil)
|
||||
// Note: if t.Elem has been an alias "J" of an interface "I" in Go, we will see it
|
||||
// as kind Interface of name "J" here, i.e. generate val.DeepCopyJ(). The golang
|
||||
// parser does not give us the underlying interface name. So we cannot do any better.
|
||||
sw.Do(fmt.Sprintf("(*out)[i] = (*in)[i].DeepCopy%s()\n", uet.Name.Name), nil)
|
||||
sw.Do("}\n", nil)
|
||||
} else if uet.Kind == types.Struct {
|
||||
sw.Do("(*in)[i].DeepCopyInto(&(*out)[i])\n", nil)
|
||||
} else {
|
||||
glog.Fatalf("Hit an unsupported type %v.", uet)
|
||||
}
|
||||
sw.Do("}\n", nil)
|
||||
}
|
||||
}
|
||||
|
||||
// doStruct generates code for a struct or an alias to a struct. The generated code is
|
||||
// is the same for both cases, i.e. it's the code for the underlying type.
|
||||
func (g *genDeepCopy) doStruct(t *types.Type, sw *generator.SnippetWriter) {
|
||||
ut := underlyingType(t)
|
||||
|
||||
if deepCopyMethodOrDie(t) != nil || deepCopyIntoMethodOrDie(t) != nil {
|
||||
sw.Do("*out = in.DeepCopy()\n", nil)
|
||||
return
|
||||
}
|
||||
|
||||
// Simple copy covers a lot of cases.
|
||||
sw.Do("*out = *in\n", nil)
|
||||
|
||||
// Now fix-up fields as needed.
|
||||
for _, m := range ut.Members {
|
||||
ft := m.Type
|
||||
uft := underlyingType(ft)
|
||||
|
||||
args := generator.Args{
|
||||
"type": ft,
|
||||
"kind": ft.Kind,
|
||||
"name": m.Name,
|
||||
}
|
||||
dc, dci := deepCopyMethodOrDie(ft), deepCopyIntoMethodOrDie(ft)
|
||||
switch {
|
||||
case dc != nil || dci != nil:
|
||||
// Note: a DeepCopyInto exists because it is added if DeepCopy is manually defined
|
||||
leftPointer := ft.Kind == types.Pointer
|
||||
rightPointer := !isReference(ft)
|
||||
if dc != nil {
|
||||
rightPointer = dc.Results[0].Kind == types.Pointer
|
||||
}
|
||||
if leftPointer == rightPointer {
|
||||
sw.Do("out.$.name$ = in.$.name$.DeepCopy()\n", args)
|
||||
} else if leftPointer {
|
||||
sw.Do("x := in.$.name$.DeepCopy()\n", args)
|
||||
sw.Do("out.$.name$ = = &x\n", args)
|
||||
} else {
|
||||
sw.Do("in.$.name$.DeepCopyInto(&out.$.name$)\n", args)
|
||||
}
|
||||
case uft.Kind == types.Builtin:
|
||||
// the initial *out = *in was enough
|
||||
case uft.Kind == types.Map, uft.Kind == types.Slice, uft.Kind == types.Pointer:
|
||||
// Fixup non-nil reference-semantic types.
|
||||
sw.Do("if in.$.name$ != nil {\n", args)
|
||||
sw.Do("in, out := &in.$.name$, &out.$.name$\n", args)
|
||||
g.generateFor(ft, sw)
|
||||
sw.Do("}\n", nil)
|
||||
case uft.Kind == types.Struct:
|
||||
if ft.IsAssignable() {
|
||||
sw.Do("out.$.name$ = in.$.name$\n", args)
|
||||
} else {
|
||||
sw.Do("in.$.name$.DeepCopyInto(&out.$.name$)\n", args)
|
||||
}
|
||||
case uft.Kind == types.Interface:
|
||||
sw.Do("if in.$.name$ != nil {\n", args)
|
||||
// Note: if t.Elem has been an alias "J" of an interface "I" in Go, we will see it
|
||||
// as kind Interface of name "J" here, i.e. generate val.DeepCopyJ(). The golang
|
||||
// parser does not give us the underlying interface name. So we cannot do any better.
|
||||
sw.Do(fmt.Sprintf("out.$.name$ = in.$.name$.DeepCopy%s()\n", uft.Name.Name), args)
|
||||
sw.Do("}\n", nil)
|
||||
default:
|
||||
glog.Fatalf("Hit an unsupported type %v.", uft)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// doPointer generates code for a pointer or an alias to a pointer. The generated code is
|
||||
// is the same for both cases, i.e. it's the code for the underlying type.
|
||||
func (g *genDeepCopy) doPointer(t *types.Type, sw *generator.SnippetWriter) {
|
||||
ut := underlyingType(t)
|
||||
uet := underlyingType(ut.Elem)
|
||||
|
||||
dc, dci := deepCopyMethodOrDie(ut.Elem), deepCopyIntoMethodOrDie(ut.Elem)
|
||||
switch {
|
||||
case dc != nil || dci != nil:
|
||||
rightPointer := !isReference(ut.Elem)
|
||||
if dc != nil {
|
||||
rightPointer = dc.Results[0].Kind == types.Pointer
|
||||
}
|
||||
if rightPointer {
|
||||
sw.Do("*out = (*in).DeepCopy()\n", nil)
|
||||
} else {
|
||||
sw.Do("x := (*in).DeepCopy()\n", nil)
|
||||
sw.Do("*out = &x\n", nil)
|
||||
}
|
||||
case uet.IsAssignable():
|
||||
sw.Do("*out = new($.Elem|raw$)\n", ut)
|
||||
sw.Do("**out = **in", nil)
|
||||
case uet.Kind == types.Map, uet.Kind == types.Slice, uet.Kind == types.Pointer:
|
||||
sw.Do("*out = new($.Elem|raw$)\n", ut)
|
||||
sw.Do("if **in != nil {\n", nil)
|
||||
sw.Do("in, out := *in, *out\n", nil)
|
||||
g.generateFor(uet, sw)
|
||||
sw.Do("}\n", nil)
|
||||
case uet.Kind == types.Struct:
|
||||
sw.Do("*out = new($.Elem|raw$)\n", ut)
|
||||
sw.Do("(*in).DeepCopyInto(*out)\n", nil)
|
||||
default:
|
||||
glog.Fatalf("Hit an unsupported type %v.", uet)
|
||||
}
|
||||
}
|
713
vendor/k8s.io/gengo/examples/deepcopy-gen/generators/deepcopy_test.go
generated
vendored
Normal file
713
vendor/k8s.io/gengo/examples/deepcopy-gen/generators/deepcopy_test.go
generated
vendored
Normal file
@@ -0,0 +1,713 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 generators
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/gengo/types"
|
||||
)
|
||||
|
||||
func Test_isRootedUnder(t *testing.T) {
|
||||
testCases := []struct {
|
||||
path string
|
||||
roots []string
|
||||
expect bool
|
||||
}{
|
||||
{
|
||||
path: "/foo/bar",
|
||||
roots: nil,
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
path: "/foo/bar",
|
||||
roots: []string{},
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
path: "/foo/bar",
|
||||
roots: []string{
|
||||
"/bad",
|
||||
},
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
path: "/foo/bar",
|
||||
roots: []string{
|
||||
"/foo",
|
||||
},
|
||||
expect: true,
|
||||
},
|
||||
{
|
||||
path: "/foo/bar",
|
||||
roots: []string{
|
||||
"/bad",
|
||||
"/foo",
|
||||
},
|
||||
expect: true,
|
||||
},
|
||||
{
|
||||
path: "/foo/bar/qux/zorb",
|
||||
roots: []string{
|
||||
"/foo/bar/qux",
|
||||
},
|
||||
expect: true,
|
||||
},
|
||||
{
|
||||
path: "/foo/bar",
|
||||
roots: []string{
|
||||
"/foo/bar",
|
||||
},
|
||||
expect: true,
|
||||
},
|
||||
{
|
||||
path: "/foo/barn",
|
||||
roots: []string{
|
||||
"/foo/bar",
|
||||
},
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
path: "/foo/bar",
|
||||
roots: []string{
|
||||
"/foo/barn",
|
||||
},
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
path: "/foo/bar",
|
||||
roots: []string{
|
||||
"",
|
||||
},
|
||||
expect: true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
r := isRootedUnder(tc.path, tc.roots)
|
||||
if r != tc.expect {
|
||||
t.Errorf("case[%d]: expected %t, got %t for %q in %q", i, tc.expect, r, tc.path, tc.roots)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_deepCopyMethod(t *testing.T) {
|
||||
testCases := []struct {
|
||||
typ types.Type
|
||||
expect bool
|
||||
error bool
|
||||
}{
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
// No DeepCopy method.
|
||||
Methods: map[string]*types.Type{},
|
||||
},
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// No DeepCopy method.
|
||||
"method": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func()"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature (no result).
|
||||
"DeepCopy": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func()"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature (wrong result).
|
||||
"DeepCopy": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func() int"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{
|
||||
{
|
||||
Name: types.Name{Name: "int"},
|
||||
Kind: types.Builtin,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature with pointer receiver, but non-pointer result.
|
||||
"DeepCopy": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func() pkgname.typename"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{
|
||||
{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature with non-pointer receiver, but pointer result.
|
||||
"DeepCopy": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func() pkgname.typename"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{
|
||||
{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Correct signature with non-pointer receiver.
|
||||
"DeepCopy": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func() pkgname.typename"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{
|
||||
{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Correct signature with pointer receiver.
|
||||
"DeepCopy": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func() pkgname.typename"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{
|
||||
{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature (has params).
|
||||
"DeepCopy": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func(int) pkgname.typename"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{
|
||||
{
|
||||
Name: types.Name{Name: "int"},
|
||||
Kind: types.Builtin,
|
||||
},
|
||||
},
|
||||
Results: []*types.Type{
|
||||
{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature (extra results).
|
||||
"DeepCopy": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func() (pkgname.typename, int)"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{
|
||||
{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
},
|
||||
{
|
||||
Name: types.Name{Name: "int"},
|
||||
Kind: types.Builtin,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
r, err := deepCopyMethod(&tc.typ)
|
||||
if tc.error && err == nil {
|
||||
t.Errorf("case[%d]: expected an error, got none", i)
|
||||
} else if !tc.error && err != nil {
|
||||
t.Errorf("case[%d]: expected no error, got: %v", i, err)
|
||||
} else if !tc.error && (r != nil) != tc.expect {
|
||||
t.Errorf("case[%d]: expected result %v, got: %v", i, tc.expect, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_deepCopyIntoMethod(t *testing.T) {
|
||||
testCases := []struct {
|
||||
typ types.Type
|
||||
expect bool
|
||||
error bool
|
||||
}{
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
// No DeepCopyInto method.
|
||||
Methods: map[string]*types.Type{},
|
||||
},
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// No DeepCopyInto method.
|
||||
"method": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func()"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature (no parameter).
|
||||
"DeepCopyInto": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func()"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature (unexpected result).
|
||||
"DeepCopyInto": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func(*pkgname.typename) int"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{
|
||||
{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
},
|
||||
Results: []*types.Type{
|
||||
{
|
||||
Name: types.Name{Name: "int"},
|
||||
Kind: types.Builtin,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature (non-pointer parameter, pointer receiver).
|
||||
"DeepCopyInto": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func(pkgname.typename)"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{
|
||||
{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Results: []*types.Type{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature (non-pointer parameter, non-pointer receiver).
|
||||
"DeepCopyInto": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func(pkgname.typename)"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
Parameters: []*types.Type{
|
||||
{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Results: []*types.Type{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Correct signature with non-pointer receiver.
|
||||
"DeepCopyInto": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func(*pkgname.typename)"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
Parameters: []*types.Type{
|
||||
{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
},
|
||||
Results: []*types.Type{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Correct signature with pointer receiver.
|
||||
"DeepCopyInto": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func(*pkgname.typename)"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{
|
||||
{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
},
|
||||
Results: []*types.Type{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
r, err := deepCopyIntoMethod(&tc.typ)
|
||||
if tc.error && err == nil {
|
||||
t.Errorf("case[%d]: expected an error, got none", i)
|
||||
} else if !tc.error && err != nil {
|
||||
t.Errorf("case[%d]: expected no error, got: %v", i, err)
|
||||
} else if !tc.error && (r != nil) != tc.expect {
|
||||
t.Errorf("case[%d]: expected result %v, got: %v", i, tc.expect, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_extractTagParams(t *testing.T) {
|
||||
testCases := []struct {
|
||||
comments []string
|
||||
expect *tagValue
|
||||
}{
|
||||
{
|
||||
comments: []string{
|
||||
"Human comment",
|
||||
},
|
||||
expect: nil,
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"Human comment",
|
||||
"+k8s:deepcopy-gen",
|
||||
},
|
||||
expect: &tagValue{
|
||||
value: "",
|
||||
register: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"Human comment",
|
||||
"+k8s:deepcopy-gen=package",
|
||||
},
|
||||
expect: &tagValue{
|
||||
value: "package",
|
||||
register: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"Human comment",
|
||||
"+k8s:deepcopy-gen=package,register",
|
||||
},
|
||||
expect: &tagValue{
|
||||
value: "package",
|
||||
register: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"Human comment",
|
||||
"+k8s:deepcopy-gen=package,register=true",
|
||||
},
|
||||
expect: &tagValue{
|
||||
value: "package",
|
||||
register: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"Human comment",
|
||||
"+k8s:deepcopy-gen=package,register=false",
|
||||
},
|
||||
expect: &tagValue{
|
||||
value: "package",
|
||||
register: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
r := extractTag(tc.comments)
|
||||
if r == nil && tc.expect != nil {
|
||||
t.Errorf("case[%d]: expected non-nil", i)
|
||||
}
|
||||
if r != nil && tc.expect == nil {
|
||||
t.Errorf("case[%d]: expected nil, got %v", i, *r)
|
||||
}
|
||||
if r != nil && *r != *tc.expect {
|
||||
t.Errorf("case[%d]: expected %v, got %v", i, *tc.expect, *r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_extractInterfacesTag(t *testing.T) {
|
||||
testCases := []struct {
|
||||
comments []string
|
||||
expect []string
|
||||
}{
|
||||
{
|
||||
comments: []string{},
|
||||
expect: nil,
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"+k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/runtime.Object",
|
||||
},
|
||||
expect: []string{
|
||||
"k8s.io/kubernetes/runtime.Object",
|
||||
},
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"+k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/runtime.Object",
|
||||
"+k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/runtime.List",
|
||||
},
|
||||
expect: []string{
|
||||
"k8s.io/kubernetes/runtime.Object",
|
||||
"k8s.io/kubernetes/runtime.List",
|
||||
},
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"+k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/runtime.Object",
|
||||
"+k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/runtime.Object",
|
||||
},
|
||||
expect: []string{
|
||||
"k8s.io/kubernetes/runtime.Object",
|
||||
"k8s.io/kubernetes/runtime.Object",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
r := extractInterfacesTag(tc.comments)
|
||||
if r == nil && tc.expect != nil {
|
||||
t.Errorf("case[%d]: expected non-nil", i)
|
||||
}
|
||||
if r != nil && tc.expect == nil {
|
||||
t.Errorf("case[%d]: expected nil, got %v", i, r)
|
||||
}
|
||||
if r != nil && !reflect.DeepEqual(r, tc.expect) {
|
||||
t.Errorf("case[%d]: expected %v, got %v", i, tc.expect, r)
|
||||
}
|
||||
}
|
||||
}
|
88
vendor/k8s.io/gengo/examples/deepcopy-gen/main.go
generated
vendored
Normal file
88
vendor/k8s.io/gengo/examples/deepcopy-gen/main.go
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// deepcopy-gen is a tool for auto-generating DeepCopy functions.
|
||||
//
|
||||
// Given a list of input directories, it will generate DeepCopy and DeepCopyInto
|
||||
// methods that efficiently perform a full deep-copy of each type. If these
|
||||
// already exist (are predefined by the developer), they are used instead of
|
||||
// generating new ones.
|
||||
//
|
||||
// If interfaces are referenced in types, it is expected that corresponding
|
||||
// DeepCopyInterfaceName methods exist, e.g. DeepCopyObject for runtime.Object.
|
||||
// These can be predefined by the developer or generated through tags, see below.
|
||||
// They must be added to the interfaces themselves manually, e.g.
|
||||
// type Object interface {
|
||||
// ...
|
||||
// DeepCopyObject() Object
|
||||
// }
|
||||
//
|
||||
// All generation is governed by comment tags in the source. Any package may
|
||||
// request DeepCopy generation by including a comment in the file-comments of
|
||||
// one file, of the form:
|
||||
// // +k8s:deepcopy-gen=package
|
||||
//
|
||||
// DeepCopy functions can be generated for individual types, rather than the
|
||||
// entire package by specifying a comment on the type definion of the form:
|
||||
// // +k8s:deepcopy-gen=true
|
||||
//
|
||||
// When generating for a whole package, individual types may opt out of
|
||||
// DeepCopy generation by specifying a comment on the type definition of the form:
|
||||
// // +k8s:deepcopy-gen=false
|
||||
//
|
||||
// Additional DeepCopyInterfaceName methods can be generated by sepcifying a
|
||||
// comment on the type definition of the form:
|
||||
// // +k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/runtime.Object,k8s.io/kubernetes/runtime.List
|
||||
// This leads to the generation of DeepCopyObject and DeepCopyList with the given
|
||||
// interfaces as return types. We say that the tagged type implements deepcopy for the
|
||||
// interfaces.
|
||||
//
|
||||
// The deepcopy funcs for interfaces using "+k8s:deepcopy-gen:interfaces" use the pointer
|
||||
// of the type as receiver. For those special cases where the non-pointer object should
|
||||
// implement the interface, this can be done with:
|
||||
// // +k8s:deepcopy-gen:nonpointer-interfaces=true
|
||||
package main
|
||||
|
||||
import (
|
||||
"k8s.io/gengo/args"
|
||||
"k8s.io/gengo/examples/deepcopy-gen/generators"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func main() {
|
||||
arguments := args.Default()
|
||||
|
||||
// Override defaults.
|
||||
arguments.OutputFileBaseName = "deepcopy_generated"
|
||||
|
||||
// Custom args.
|
||||
customArgs := &generators.CustomArgs{}
|
||||
pflag.CommandLine.StringSliceVar(&customArgs.BoundingDirs, "bounding-dirs", customArgs.BoundingDirs,
|
||||
"Comma-separated list of import paths which bound the types for which deep-copies will be generated.")
|
||||
arguments.CustomArgs = customArgs
|
||||
|
||||
// Run it.
|
||||
if err := arguments.Execute(
|
||||
generators.NameSystems(),
|
||||
generators.DefaultNameSystem(),
|
||||
generators.Packages,
|
||||
); err != nil {
|
||||
glog.Fatalf("Error: %v", err)
|
||||
}
|
||||
glog.V(2).Info("Completed successfully.")
|
||||
}
|
89
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/aliases/doc.go
generated
vendored
Normal file
89
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/aliases/doc.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// This is a test package.
|
||||
package aliases
|
||||
|
||||
// Note: the following AliasInterface and AliasAliasInterface +k8s:deepcopy-gen:interfaces tags
|
||||
// are necessary because Golang flattens interface alias in the type system. I.e. an alias J of
|
||||
// an interface I is actually equivalent to I. So support deepcopies of those aliases, we have
|
||||
// to implement all aliases of that interface.
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/gengo/examples/deepcopy-gen/output_tests/aliases.Interface
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/gengo/examples/deepcopy-gen/output_tests/aliases.AliasInterface
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/gengo/examples/deepcopy-gen/output_tests/aliases.AliasAliasInterface
|
||||
type Foo struct {
|
||||
X int
|
||||
}
|
||||
|
||||
type Interface interface {
|
||||
DeepCopyInterface() Interface
|
||||
DeepCopyAliasInterface() AliasInterface
|
||||
DeepCopyAliasAliasInterface() AliasAliasInterface
|
||||
}
|
||||
|
||||
type Builtin int
|
||||
type Slice []int
|
||||
type Pointer *int
|
||||
type PointerAlias *Builtin
|
||||
type Struct Foo
|
||||
type Map map[string]int
|
||||
|
||||
type FooAlias Foo
|
||||
type FooSlice []Foo
|
||||
type FooPointer *Foo
|
||||
type FooMap map[string]Foo
|
||||
|
||||
type AliasBuiltin Builtin
|
||||
type AliasSlice Slice
|
||||
type AliasPointer Pointer
|
||||
type AliasStruct Struct
|
||||
type AliasMap Map
|
||||
|
||||
type AliasInterface Interface
|
||||
type AliasAliasInterface AliasInterface
|
||||
type AliasInterfaceMap map[string]AliasInterface
|
||||
type AliasInterfaceSlice []AliasInterface
|
||||
|
||||
// Aliases
|
||||
type Ttest struct {
|
||||
Builtin Builtin
|
||||
Slice Slice
|
||||
Pointer Pointer
|
||||
PointerAlias PointerAlias
|
||||
Struct Struct
|
||||
Map Map
|
||||
SliceSlice []Slice
|
||||
MapSlice map[string]Slice
|
||||
|
||||
FooAlias FooAlias
|
||||
FooSlice FooSlice
|
||||
FooPointer FooPointer
|
||||
FooMap FooMap
|
||||
|
||||
AliasBuiltin AliasBuiltin
|
||||
AliasSlice AliasSlice
|
||||
AliasPointer AliasPointer
|
||||
AliasStruct AliasStruct
|
||||
AliasMap AliasMap
|
||||
|
||||
AliasInterface AliasInterface
|
||||
AliasAliasInterface AliasAliasInterface
|
||||
AliasInterfaceMap AliasInterfaceMap
|
||||
AliasInterfaceSlice AliasInterfaceSlice
|
||||
}
|
412
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/aliases/zz_generated.go
generated
vendored
Normal file
412
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/aliases/zz_generated.go
generated
vendored
Normal file
@@ -0,0 +1,412 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package aliases
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in AliasInterfaceMap) DeepCopyInto(out *AliasInterfaceMap) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(AliasInterfaceMap, len(*in))
|
||||
for key, val := range *in {
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
(*out)[key] = val.DeepCopyAliasInterface()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AliasInterfaceMap.
|
||||
func (in AliasInterfaceMap) DeepCopy() AliasInterfaceMap {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AliasInterfaceMap)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in AliasInterfaceSlice) DeepCopyInto(out *AliasInterfaceSlice) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(AliasInterfaceSlice, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
(*out)[i] = (*in)[i].DeepCopyAliasInterface()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AliasInterfaceSlice.
|
||||
func (in AliasInterfaceSlice) DeepCopy() AliasInterfaceSlice {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AliasInterfaceSlice)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in AliasMap) DeepCopyInto(out *AliasMap) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(AliasMap, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AliasMap.
|
||||
func (in AliasMap) DeepCopy() AliasMap {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AliasMap)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in AliasSlice) DeepCopyInto(out *AliasSlice) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(AliasSlice, len(*in))
|
||||
copy(*out, *in)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AliasSlice.
|
||||
func (in AliasSlice) DeepCopy() AliasSlice {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AliasSlice)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AliasStruct) DeepCopyInto(out *AliasStruct) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AliasStruct.
|
||||
func (in *AliasStruct) DeepCopy() *AliasStruct {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AliasStruct)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Foo) DeepCopyInto(out *Foo) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Foo.
|
||||
func (in *Foo) DeepCopy() *Foo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Foo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyAliasAliasInterface is an autogenerated deepcopy function, copying the receiver, creating a new AliasAliasInterface.
|
||||
func (in *Foo) DeepCopyAliasAliasInterface() AliasAliasInterface {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyAliasInterface is an autogenerated deepcopy function, copying the receiver, creating a new AliasInterface.
|
||||
func (in *Foo) DeepCopyAliasInterface() AliasInterface {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Interface.
|
||||
func (in *Foo) DeepCopyInterface() Interface {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FooAlias) DeepCopyInto(out *FooAlias) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FooAlias.
|
||||
func (in *FooAlias) DeepCopy() *FooAlias {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FooAlias)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in FooMap) DeepCopyInto(out *FooMap) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(FooMap, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FooMap.
|
||||
func (in FooMap) DeepCopy() FooMap {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FooMap)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in FooSlice) DeepCopyInto(out *FooSlice) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(FooSlice, len(*in))
|
||||
copy(*out, *in)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FooSlice.
|
||||
func (in FooSlice) DeepCopy() FooSlice {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FooSlice)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in Map) DeepCopyInto(out *Map) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(Map, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Map.
|
||||
func (in Map) DeepCopy() Map {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Map)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in Slice) DeepCopyInto(out *Slice) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(Slice, len(*in))
|
||||
copy(*out, *in)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Slice.
|
||||
func (in Slice) DeepCopy() Slice {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Slice)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct) DeepCopyInto(out *Struct) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct.
|
||||
func (in *Struct) DeepCopy() *Struct {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Ttest) DeepCopyInto(out *Ttest) {
|
||||
*out = *in
|
||||
if in.Slice != nil {
|
||||
in, out := &in.Slice, &out.Slice
|
||||
*out = make(Slice, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Pointer != nil {
|
||||
in, out := &in.Pointer, &out.Pointer
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.PointerAlias != nil {
|
||||
in, out := &in.PointerAlias, &out.PointerAlias
|
||||
*out = new(Builtin)
|
||||
**out = **in
|
||||
}
|
||||
out.Struct = in.Struct
|
||||
if in.Map != nil {
|
||||
in, out := &in.Map, &out.Map
|
||||
*out = make(Map, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.SliceSlice != nil {
|
||||
in, out := &in.SliceSlice, &out.SliceSlice
|
||||
*out = make([]Slice, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = make(Slice, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.MapSlice != nil {
|
||||
in, out := &in.MapSlice, &out.MapSlice
|
||||
*out = make(map[string]Slice, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal []int
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = make(Slice, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
out.FooAlias = in.FooAlias
|
||||
if in.FooSlice != nil {
|
||||
in, out := &in.FooSlice, &out.FooSlice
|
||||
*out = make(FooSlice, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.FooPointer != nil {
|
||||
in, out := &in.FooPointer, &out.FooPointer
|
||||
*out = new(Foo)
|
||||
**out = **in
|
||||
}
|
||||
if in.FooMap != nil {
|
||||
in, out := &in.FooMap, &out.FooMap
|
||||
*out = make(FooMap, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.AliasSlice != nil {
|
||||
in, out := &in.AliasSlice, &out.AliasSlice
|
||||
*out = make(AliasSlice, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.AliasPointer != nil {
|
||||
in, out := &in.AliasPointer, &out.AliasPointer
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
out.AliasStruct = in.AliasStruct
|
||||
if in.AliasMap != nil {
|
||||
in, out := &in.AliasMap, &out.AliasMap
|
||||
*out = make(AliasMap, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.AliasInterface != nil {
|
||||
out.AliasInterface = in.AliasInterface.DeepCopyAliasInterface()
|
||||
}
|
||||
if in.AliasAliasInterface != nil {
|
||||
out.AliasAliasInterface = in.AliasAliasInterface.DeepCopyAliasAliasInterface()
|
||||
}
|
||||
if in.AliasInterfaceMap != nil {
|
||||
in, out := &in.AliasInterfaceMap, &out.AliasInterfaceMap
|
||||
*out = make(AliasInterfaceMap, len(*in))
|
||||
for key, val := range *in {
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
(*out)[key] = val.DeepCopyAliasInterface()
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.AliasInterfaceSlice != nil {
|
||||
in, out := &in.AliasInterfaceSlice, &out.AliasInterfaceSlice
|
||||
*out = make(AliasInterfaceSlice, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
(*out)[i] = (*in)[i].DeepCopyAliasInterface()
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ttest.
|
||||
func (in *Ttest) DeepCopy() *Ttest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Ttest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
35
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/builtins/doc.go
generated
vendored
Normal file
35
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/builtins/doc.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// This is a test package.
|
||||
package builtins
|
||||
|
||||
type Ttest struct {
|
||||
Byte byte
|
||||
//Int8 int8 //TODO: int8 becomes byte in SnippetWriter
|
||||
Int16 int16
|
||||
Int32 int32
|
||||
Int64 int64
|
||||
Uint8 uint8
|
||||
Uint16 uint16
|
||||
Uint32 uint32
|
||||
Uint64 uint64
|
||||
Float32 float32
|
||||
Float64 float64
|
||||
String string
|
||||
}
|
37
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/builtins/zz_generated.go
generated
vendored
Normal file
37
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/builtins/zz_generated.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package builtins
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Ttest) DeepCopyInto(out *Ttest) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ttest.
|
||||
func (in *Ttest) DeepCopy() *Ttest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Ttest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
131
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/interface_fuzzer.go
generated
vendored
Normal file
131
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/interface_fuzzer.go
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
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 output_tests
|
||||
|
||||
import (
|
||||
"github.com/google/gofuzz"
|
||||
|
||||
"k8s.io/gengo/examples/deepcopy-gen/output_tests/aliases"
|
||||
"k8s.io/gengo/examples/deepcopy-gen/output_tests/interfaces"
|
||||
)
|
||||
|
||||
// interfaceFuzzers contains fuzzer that set all interface to nil because our
|
||||
// JSON deepcopy does not work with it.
|
||||
// TODO: test also interface deepcopy
|
||||
var interfaceFuzzers = []interface{}{
|
||||
func(s *aliases.AliasAliasInterface, c fuzz.Continue) {
|
||||
if c.RandBool() {
|
||||
*s = nil
|
||||
} else {
|
||||
*s = &aliasAliasInterfaceInstance{X: c.Int()}
|
||||
}
|
||||
},
|
||||
func(s *aliases.AliasInterface, c fuzz.Continue) {
|
||||
if c.RandBool() {
|
||||
*s = nil
|
||||
} else {
|
||||
*s = &aliasAliasInterfaceInstance{X: c.Int()}
|
||||
}
|
||||
},
|
||||
func(s *aliases.Interface, c fuzz.Continue) {
|
||||
if c.RandBool() {
|
||||
*s = nil
|
||||
} else {
|
||||
*s = &aliasAliasInterfaceInstance{X: c.Int()}
|
||||
}
|
||||
},
|
||||
func(s *aliases.AliasInterfaceMap, c fuzz.Continue) {
|
||||
if c.RandBool() {
|
||||
*s = nil
|
||||
} else {
|
||||
*s = make(aliases.AliasInterfaceMap)
|
||||
for i := 0; i < c.Intn(3); i++ {
|
||||
if c.RandBool() {
|
||||
(*s)[c.RandString()] = nil
|
||||
} else {
|
||||
(*s)[c.RandString()] = &aliasAliasInterfaceInstance{X: c.Int()}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
func(s *aliases.AliasInterfaceSlice, c fuzz.Continue) {
|
||||
if c.RandBool() {
|
||||
*s = nil
|
||||
} else {
|
||||
*s = make(aliases.AliasInterfaceSlice, 0, 0)
|
||||
for i := 0; i < c.Intn(3); i++ {
|
||||
if c.RandBool() {
|
||||
*s = append(*s, nil)
|
||||
} else {
|
||||
*s = append(*s, &aliasAliasInterfaceInstance{X: c.Int()})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
func(s *interfaces.Inner, c fuzz.Continue) {
|
||||
if c.RandBool() {
|
||||
*s = nil
|
||||
} else {
|
||||
*s = &interfacesInnerInstance{X: c.Float64()}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
type aliasAliasInterfaceInstance struct {
|
||||
X int
|
||||
}
|
||||
|
||||
func (i *aliasAliasInterfaceInstance) DeepCopyInterface() aliases.Interface {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &aliasAliasInterfaceInstance{X: i.X}
|
||||
}
|
||||
|
||||
func (i *aliasAliasInterfaceInstance) DeepCopyAliasInterface() aliases.AliasInterface {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &aliasAliasInterfaceInstance{X: i.X}
|
||||
}
|
||||
|
||||
func (i *aliasAliasInterfaceInstance) DeepCopyAliasAliasInterface() aliases.AliasAliasInterface {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &aliasAliasInterfaceInstance{X: i.X}
|
||||
}
|
||||
|
||||
type interfacesInnerInstance struct {
|
||||
X float64
|
||||
}
|
||||
|
||||
func (i *interfacesInnerInstance) DeepCopyInner() interfaces.Inner {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &interfacesInnerInstance{X: i.X}
|
||||
}
|
||||
|
||||
func (i *interfacesInnerInstance) Function() float64 {
|
||||
return i.X
|
||||
}
|
29
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/interfaces/doc.go
generated
vendored
Normal file
29
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/interfaces/doc.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// This is a test package.
|
||||
package interfaces
|
||||
|
||||
type Inner interface {
|
||||
Function() float64
|
||||
DeepCopyInner() Inner
|
||||
}
|
||||
|
||||
type Ttest struct {
|
||||
I []Inner
|
||||
}
|
46
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/interfaces/zz_generated.go
generated
vendored
Normal file
46
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/interfaces/zz_generated.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package interfaces
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Ttest) DeepCopyInto(out *Ttest) {
|
||||
*out = *in
|
||||
if in.I != nil {
|
||||
in, out := &in.I, &out.I
|
||||
*out = make([]Inner, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
(*out)[i] = (*in)[i].DeepCopyInner()
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ttest.
|
||||
func (in *Ttest) DeepCopy() *Ttest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Ttest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
43
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/maps/doc.go
generated
vendored
Normal file
43
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/maps/doc.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// This is a test package.
|
||||
package maps
|
||||
|
||||
type Ttest struct {
|
||||
Byte map[string]byte
|
||||
//Int8 map[string]int8 //TODO: int8 becomes byte in SnippetWriter
|
||||
Int16 map[string]int16
|
||||
Int32 map[string]int32
|
||||
Int64 map[string]int64
|
||||
Uint8 map[string]uint8
|
||||
Uint16 map[string]uint16
|
||||
Uint32 map[string]uint32
|
||||
Uint64 map[string]uint64
|
||||
Float32 map[string]float32
|
||||
Float64 map[string]float64
|
||||
String map[string]string
|
||||
StringPtr map[string]*string
|
||||
StringPtrPtr map[string]**string
|
||||
Map map[string]map[string]string
|
||||
MapPtr map[string]*map[string]string
|
||||
Slice map[string][]string
|
||||
SlicePtr map[string]*[]string
|
||||
Struct map[string]Ttest
|
||||
StructPtr map[string]*Ttest
|
||||
}
|
242
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/maps/zz_generated.go
generated
vendored
Normal file
242
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/maps/zz_generated.go
generated
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package maps
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Ttest) DeepCopyInto(out *Ttest) {
|
||||
*out = *in
|
||||
if in.Byte != nil {
|
||||
in, out := &in.Byte, &out.Byte
|
||||
*out = make(map[string]byte, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Int16 != nil {
|
||||
in, out := &in.Int16, &out.Int16
|
||||
*out = make(map[string]int16, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Int32 != nil {
|
||||
in, out := &in.Int32, &out.Int32
|
||||
*out = make(map[string]int32, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Int64 != nil {
|
||||
in, out := &in.Int64, &out.Int64
|
||||
*out = make(map[string]int64, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Uint8 != nil {
|
||||
in, out := &in.Uint8, &out.Uint8
|
||||
*out = make(map[string]byte, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Uint16 != nil {
|
||||
in, out := &in.Uint16, &out.Uint16
|
||||
*out = make(map[string]uint16, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Uint32 != nil {
|
||||
in, out := &in.Uint32, &out.Uint32
|
||||
*out = make(map[string]uint32, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Uint64 != nil {
|
||||
in, out := &in.Uint64, &out.Uint64
|
||||
*out = make(map[string]uint64, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Float32 != nil {
|
||||
in, out := &in.Float32, &out.Float32
|
||||
*out = make(map[string]float32, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Float64 != nil {
|
||||
in, out := &in.Float64, &out.Float64
|
||||
*out = make(map[string]float64, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.String != nil {
|
||||
in, out := &in.String, &out.String
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.StringPtr != nil {
|
||||
in, out := &in.StringPtr, &out.StringPtr
|
||||
*out = make(map[string]*string, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal *string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
if in.StringPtrPtr != nil {
|
||||
in, out := &in.StringPtrPtr, &out.StringPtrPtr
|
||||
*out = make(map[string]**string, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal **string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = new(*string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
if in.Map != nil {
|
||||
in, out := &in.Map, &out.Map
|
||||
*out = make(map[string]map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal map[string]string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
if in.MapPtr != nil {
|
||||
in, out := &in.MapPtr, &out.MapPtr
|
||||
*out = make(map[string]*map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal *map[string]string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = new(map[string]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
if in.Slice != nil {
|
||||
in, out := &in.Slice, &out.Slice
|
||||
*out = make(map[string][]string, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal []string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
if in.SlicePtr != nil {
|
||||
in, out := &in.SlicePtr, &out.SlicePtr
|
||||
*out = make(map[string]*[]string, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal *[]string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = new([]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
if in.Struct != nil {
|
||||
in, out := &in.Struct, &out.Struct
|
||||
*out = make(map[string]Ttest, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = *val.DeepCopy()
|
||||
}
|
||||
}
|
||||
if in.StructPtr != nil {
|
||||
in, out := &in.StructPtr, &out.StructPtr
|
||||
*out = make(map[string]*Ttest, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal *Ttest
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = new(Ttest)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ttest.
|
||||
func (in *Ttest) DeepCopy() *Ttest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Ttest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
25
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/otherpkg/interfaces.go
generated
vendored
Normal file
25
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/otherpkg/interfaces.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
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 otherpkg
|
||||
|
||||
type Object interface {
|
||||
DeepCopyObject() Object
|
||||
}
|
||||
|
||||
type List interface {
|
||||
DeepCopyList() List
|
||||
}
|
157
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/output_test.go
generated
vendored
Normal file
157
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/output_test.go
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
package output_tests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/google/gofuzz"
|
||||
|
||||
"k8s.io/gengo/examples/deepcopy-gen/output_tests/aliases"
|
||||
"k8s.io/gengo/examples/deepcopy-gen/output_tests/builtins"
|
||||
"k8s.io/gengo/examples/deepcopy-gen/output_tests/interfaces"
|
||||
"k8s.io/gengo/examples/deepcopy-gen/output_tests/maps"
|
||||
"k8s.io/gengo/examples/deepcopy-gen/output_tests/pointer"
|
||||
"k8s.io/gengo/examples/deepcopy-gen/output_tests/slices"
|
||||
"k8s.io/gengo/examples/deepcopy-gen/output_tests/structs"
|
||||
)
|
||||
|
||||
func TestWithValueFuzzer(t *testing.T) {
|
||||
tests := []interface{}{
|
||||
aliases.Ttest{},
|
||||
builtins.Ttest{},
|
||||
interfaces.Ttest{},
|
||||
maps.Ttest{},
|
||||
pointer.Ttest{},
|
||||
slices.Ttest{},
|
||||
structs.Ttest{},
|
||||
}
|
||||
|
||||
fuzzer := fuzz.New()
|
||||
fuzzer.NilChance(0.5)
|
||||
fuzzer.NumElements(0, 2)
|
||||
fuzzer.Funcs(interfaceFuzzers...)
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(fmt.Sprintf("%T", test), func(t *testing.T) {
|
||||
N := 1000
|
||||
for i := 0; i < N; i++ {
|
||||
original := reflect.New(reflect.TypeOf(test)).Interface()
|
||||
|
||||
fuzzer.Fuzz(original)
|
||||
|
||||
reflectCopy := ReflectDeepCopy(original)
|
||||
|
||||
if !reflect.DeepEqual(original, reflectCopy) {
|
||||
t.Errorf("original and reflectCopy are different:\n\n original = %s\n\n jsonCopy = %s", spew.Sdump(original), spew.Sdump(reflectCopy))
|
||||
}
|
||||
|
||||
deepCopy := reflect.ValueOf(original).MethodByName("DeepCopy").Call(nil)[0].Interface()
|
||||
|
||||
if !reflect.DeepEqual(original, deepCopy) {
|
||||
t.Fatalf("original and deepCopy are different:\n\n original = %s\n\n deepCopy() = %s", spew.Sdump(original), spew.Sdump(deepCopy))
|
||||
}
|
||||
|
||||
ValueFuzz(original)
|
||||
|
||||
if !reflect.DeepEqual(reflectCopy, deepCopy) {
|
||||
t.Fatalf("reflectCopy and deepCopy are different:\n\n origin = %s\n\n jsonCopy() = %s", spew.Sdump(original), spew.Sdump(deepCopy))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkReflectDeepCopy(b *testing.B) {
|
||||
fourtytwo := "fourtytwo"
|
||||
fourtytwoPtr := &fourtytwo
|
||||
var nilMap map[string]string
|
||||
var nilSlice []string
|
||||
mapPtr := &map[string]string{"0": "fourtytwo", "1": "fourtytwo"}
|
||||
slicePtr := &[]string{"fourtytwo", "fourtytwo", "fourtytwo"}
|
||||
structPtr := &pointer.Ttest{
|
||||
Builtin: &fourtytwo,
|
||||
Ptr: &fourtytwoPtr,
|
||||
}
|
||||
|
||||
tests := []interface{}{
|
||||
maps.Ttest{
|
||||
Byte: map[string]byte{"0": 42, "1": 42, "3": 42},
|
||||
Int16: map[string]int16{"0": 42, "1": 42, "3": 42},
|
||||
Int32: map[string]int32{"0": 42, "1": 42, "3": 42},
|
||||
Int64: map[string]int64{"0": 42, "1": 42, "3": 42},
|
||||
Uint8: map[string]uint8{"0": 42, "1": 42, "3": 42},
|
||||
Uint16: map[string]uint16{"0": 42, "1": 42, "3": 42},
|
||||
Uint32: map[string]uint32{"0": 42, "1": 42, "3": 42},
|
||||
Uint64: map[string]uint64{"0": 42, "1": 42, "3": 42},
|
||||
Float32: map[string]float32{"0": 42.0, "1": 42.0, "3": 42.0},
|
||||
Float64: map[string]float64{"0": 42, "1": 42, "3": 42},
|
||||
String: map[string]string{"0": "fourtytwo", "1": "fourtytwo", "3": "fourtytwo"},
|
||||
StringPtr: map[string]*string{"0": &fourtytwo, "1": &fourtytwo, "3": &fourtytwo},
|
||||
StringPtrPtr: map[string]**string{"0": &fourtytwoPtr, "1": &fourtytwoPtr, "3": &fourtytwoPtr},
|
||||
Map: map[string]map[string]string{"0": nil, "1": {"a": fourtytwo, "b": fourtytwo}, "3": {}},
|
||||
MapPtr: map[string]*map[string]string{"0": nil, "1": {"a": fourtytwo, "b": fourtytwo}, "3": &nilMap},
|
||||
Slice: map[string][]string{"0": nil, "1": {"a", "b"}, "2": {}},
|
||||
SlicePtr: map[string]*[]string{"0": nil, "1": {"a", "b"}, "2": &nilSlice},
|
||||
Struct: map[string]maps.Ttest{"0": {}, "1": {Byte: map[string]byte{"0": 42, "1": 42, "3": 42}}},
|
||||
StructPtr: map[string]*maps.Ttest{"0": nil, "1": {}, "2": {Byte: map[string]byte{"0": 42, "1": 42, "3": 42}}},
|
||||
},
|
||||
slices.Ttest{
|
||||
Byte: []byte{42, 42, 42},
|
||||
Int16: []int16{42, 42, 42},
|
||||
Int32: []int32{42, 42, 42},
|
||||
Int64: []int64{42, 42, 42},
|
||||
Uint8: []uint8{42, 42, 42},
|
||||
Uint16: []uint16{42, 42, 42},
|
||||
Uint32: []uint32{42, 42, 42},
|
||||
Uint64: []uint64{42, 42, 42},
|
||||
Float32: []float32{42.0, 42.0, 42.0},
|
||||
Float64: []float64{42, 42, 42},
|
||||
String: []string{"fourtytwo", "fourtytwo", "fourtytwo"},
|
||||
StringPtr: []*string{&fourtytwo, &fourtytwo, &fourtytwo},
|
||||
StringPtrPtr: []**string{&fourtytwoPtr, &fourtytwoPtr, &fourtytwoPtr},
|
||||
Map: []map[string]string{nil, {"a": fourtytwo, "b": fourtytwo}, {}},
|
||||
MapPtr: []*map[string]string{nil, {"a": fourtytwo, "b": fourtytwo}, &nilMap},
|
||||
Slice: [][]string{nil, {"a", "b"}, {}},
|
||||
SlicePtr: []*[]string{nil, {"a", "b"}, &nilSlice},
|
||||
Struct: []slices.Ttest{{}, {Byte: []byte{42, 42, 42}}},
|
||||
StructPtr: []*slices.Ttest{nil, {}, {Byte: []byte{42, 42, 42}}},
|
||||
},
|
||||
pointer.Ttest{
|
||||
Builtin: &fourtytwo,
|
||||
Ptr: &fourtytwoPtr,
|
||||
Map: &map[string]string{"0": "fourtytwo", "1": "fourtytwo"},
|
||||
Slice: &[]string{"fourtytwo", "fourtytwo", "fourtytwo"},
|
||||
MapPtr: &mapPtr,
|
||||
SlicePtr: &slicePtr,
|
||||
Struct: &pointer.Ttest{
|
||||
Builtin: &fourtytwo,
|
||||
Ptr: &fourtytwoPtr,
|
||||
},
|
||||
StructPtr: &structPtr,
|
||||
},
|
||||
}
|
||||
|
||||
fuzzer := fuzz.New()
|
||||
fuzzer.NilChance(0.5)
|
||||
fuzzer.NumElements(0, 2)
|
||||
fuzzer.Funcs(interfaceFuzzers...)
|
||||
|
||||
for _, test := range tests {
|
||||
b.Run(fmt.Sprintf("%T", test), func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
switch t := test.(type) {
|
||||
case maps.Ttest:
|
||||
t.DeepCopy()
|
||||
case slices.Ttest:
|
||||
t.DeepCopy()
|
||||
case pointer.Ttest:
|
||||
t.DeepCopy()
|
||||
default:
|
||||
b.Fatalf("missing type case in switch for %T", t)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
31
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/pointer/doc.go
generated
vendored
Normal file
31
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/pointer/doc.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// This is a test package.
|
||||
package pointer
|
||||
|
||||
type Ttest struct {
|
||||
Builtin *string
|
||||
Ptr **string
|
||||
Map *map[string]string
|
||||
Slice *[]string
|
||||
MapPtr **map[string]string
|
||||
SlicePtr **[]string
|
||||
Struct *Ttest
|
||||
StructPtr **Ttest
|
||||
}
|
113
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/pointer/zz_generated.go
generated
vendored
Normal file
113
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/pointer/zz_generated.go
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package pointer
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Ttest) DeepCopyInto(out *Ttest) {
|
||||
*out = *in
|
||||
if in.Builtin != nil {
|
||||
in, out := &in.Builtin, &out.Builtin
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Ptr != nil {
|
||||
in, out := &in.Ptr, &out.Ptr
|
||||
*out = new(*string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
if in.Map != nil {
|
||||
in, out := &in.Map, &out.Map
|
||||
*out = new(map[string]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.Slice != nil {
|
||||
in, out := &in.Slice, &out.Slice
|
||||
*out = new([]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
if in.MapPtr != nil {
|
||||
in, out := &in.MapPtr, &out.MapPtr
|
||||
*out = new(*map[string]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = new(map[string]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.SlicePtr != nil {
|
||||
in, out := &in.SlicePtr, &out.SlicePtr
|
||||
*out = new(*[]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = new([]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.Struct != nil {
|
||||
in, out := &in.Struct, &out.Struct
|
||||
*out = new(Ttest)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.StructPtr != nil {
|
||||
in, out := &in.StructPtr, &out.StructPtr
|
||||
*out = new(*Ttest)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = new(Ttest)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ttest.
|
||||
func (in *Ttest) DeepCopy() *Ttest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Ttest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
81
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/reflect_deepcopy.go
generated
vendored
Normal file
81
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/reflect_deepcopy.go
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
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 output_tests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// ReflectDeepCopy deep copies the object using reflection.
|
||||
func ReflectDeepCopy(in interface{}) interface{} {
|
||||
return reflectDeepCopy(reflect.ValueOf(in)).Interface()
|
||||
}
|
||||
|
||||
func reflectDeepCopy(src reflect.Value) reflect.Value {
|
||||
switch src.Kind() {
|
||||
case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
|
||||
if src.IsNil() {
|
||||
return src
|
||||
}
|
||||
}
|
||||
|
||||
switch src.Kind() {
|
||||
case reflect.Chan, reflect.Func, reflect.UnsafePointer, reflect.Uintptr:
|
||||
panic(fmt.Sprintf("cannot deep copy kind: %s", src.Kind()))
|
||||
case reflect.Array:
|
||||
dst := reflect.New(src.Type())
|
||||
for i := 0; i < src.Len(); i++ {
|
||||
dst.Elem().Index(i).Set(reflectDeepCopy(src.Index(i)))
|
||||
}
|
||||
return dst.Elem()
|
||||
case reflect.Interface:
|
||||
return reflectDeepCopy(src.Elem())
|
||||
case reflect.Map:
|
||||
dst := reflect.MakeMap(src.Type())
|
||||
for _, k := range src.MapKeys() {
|
||||
dst.SetMapIndex(k, reflectDeepCopy(src.MapIndex(k)))
|
||||
}
|
||||
return dst
|
||||
case reflect.Ptr:
|
||||
dst := reflect.New(src.Type().Elem())
|
||||
dst.Elem().Set(reflectDeepCopy(src.Elem()))
|
||||
return dst
|
||||
case reflect.Slice:
|
||||
dst := reflect.MakeSlice(src.Type(), 0, src.Len())
|
||||
for i := 0; i < src.Len(); i++ {
|
||||
dst = reflect.Append(dst, reflectDeepCopy(src.Index(i)))
|
||||
}
|
||||
return dst
|
||||
case reflect.Struct:
|
||||
dst := reflect.New(src.Type())
|
||||
for i := 0; i < src.NumField(); i++ {
|
||||
if !dst.Elem().Field(i).CanSet() {
|
||||
// Can't set private fields. At this point, the
|
||||
// best we can do is a shallow copy. For
|
||||
// example, time.Time is a value type with
|
||||
// private members that can be shallow copied.
|
||||
return src
|
||||
}
|
||||
dst.Elem().Field(i).Set(reflectDeepCopy(src.Field(i)))
|
||||
}
|
||||
return dst.Elem()
|
||||
default:
|
||||
// Value types like numbers, booleans, and strings.
|
||||
return src
|
||||
}
|
||||
}
|
43
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/slices/doc.go
generated
vendored
Normal file
43
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/slices/doc.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// This is a test package.
|
||||
package slices
|
||||
|
||||
type Ttest struct {
|
||||
Byte []byte
|
||||
//Int8 []int8 //TODO: int8 becomes byte in SnippetWriter
|
||||
Int16 []int16
|
||||
Int32 []int32
|
||||
Int64 []int64
|
||||
Uint8 []uint8
|
||||
Uint16 []uint16
|
||||
Uint32 []uint32
|
||||
Uint64 []uint64
|
||||
Float32 []float32
|
||||
Float64 []float64
|
||||
String []string
|
||||
StringPtr []*string
|
||||
StringPtrPtr []**string
|
||||
Map []map[string]string
|
||||
MapPtr []*map[string]string
|
||||
Slice [][]string
|
||||
SlicePtr []*[]string
|
||||
Struct []Ttest
|
||||
StructPtr []*Ttest
|
||||
}
|
192
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/slices/zz_generated.go
generated
vendored
Normal file
192
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/slices/zz_generated.go
generated
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package slices
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Ttest) DeepCopyInto(out *Ttest) {
|
||||
*out = *in
|
||||
if in.Byte != nil {
|
||||
in, out := &in.Byte, &out.Byte
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Int16 != nil {
|
||||
in, out := &in.Int16, &out.Int16
|
||||
*out = make([]int16, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Int32 != nil {
|
||||
in, out := &in.Int32, &out.Int32
|
||||
*out = make([]int32, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Int64 != nil {
|
||||
in, out := &in.Int64, &out.Int64
|
||||
*out = make([]int64, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Uint8 != nil {
|
||||
in, out := &in.Uint8, &out.Uint8
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Uint16 != nil {
|
||||
in, out := &in.Uint16, &out.Uint16
|
||||
*out = make([]uint16, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Uint32 != nil {
|
||||
in, out := &in.Uint32, &out.Uint32
|
||||
*out = make([]uint32, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Uint64 != nil {
|
||||
in, out := &in.Uint64, &out.Uint64
|
||||
*out = make([]uint64, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Float32 != nil {
|
||||
in, out := &in.Float32, &out.Float32
|
||||
*out = make([]float32, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Float64 != nil {
|
||||
in, out := &in.Float64, &out.Float64
|
||||
*out = make([]float64, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.String != nil {
|
||||
in, out := &in.String, &out.String
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.StringPtr != nil {
|
||||
in, out := &in.StringPtr, &out.StringPtr
|
||||
*out = make([]*string, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.StringPtrPtr != nil {
|
||||
in, out := &in.StringPtrPtr, &out.StringPtrPtr
|
||||
*out = make([]**string, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(*string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.Map != nil {
|
||||
in, out := &in.Map, &out.Map
|
||||
*out = make([]map[string]string, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.MapPtr != nil {
|
||||
in, out := &in.MapPtr, &out.MapPtr
|
||||
*out = make([]*map[string]string, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(map[string]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.Slice != nil {
|
||||
in, out := &in.Slice, &out.Slice
|
||||
*out = make([][]string, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.SlicePtr != nil {
|
||||
in, out := &in.SlicePtr, &out.SlicePtr
|
||||
*out = make([]*[]string, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new([]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.Struct != nil {
|
||||
in, out := &in.Struct, &out.Struct
|
||||
*out = make([]Ttest, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.StructPtr != nil {
|
||||
in, out := &in.StructPtr, &out.StructPtr
|
||||
*out = make([]*Ttest, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(Ttest)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ttest.
|
||||
func (in *Ttest) DeepCopy() *Ttest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Ttest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
40
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/structs/doc.go
generated
vendored
Normal file
40
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/structs/doc.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// This is a test package.
|
||||
package structs
|
||||
|
||||
type Inner struct {
|
||||
Byte byte
|
||||
//Int8 int8 //TODO: int8 becomes byte in SnippetWriter
|
||||
Int16 int16
|
||||
Int32 int32
|
||||
Int64 int64
|
||||
Uint8 uint8
|
||||
Uint16 uint16
|
||||
Uint32 uint32
|
||||
Uint64 uint64
|
||||
Float32 float32
|
||||
Float64 float64
|
||||
String string
|
||||
}
|
||||
|
||||
type Ttest struct {
|
||||
Inner1 Inner
|
||||
Inner2 Inner
|
||||
}
|
55
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/structs/zz_generated.go
generated
vendored
Normal file
55
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/structs/zz_generated.go
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package structs
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Inner) DeepCopyInto(out *Inner) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Inner.
|
||||
func (in *Inner) DeepCopy() *Inner {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Inner)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Ttest) DeepCopyInto(out *Ttest) {
|
||||
*out = *in
|
||||
out.Inner1 = in.Inner1
|
||||
out.Inner2 = in.Inner2
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ttest.
|
||||
func (in *Ttest) DeepCopy() *Ttest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Ttest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
86
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/value_fuzzer.go
generated
vendored
Normal file
86
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/value_fuzzer.go
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
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 output_tests
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// ValueFuzz recursively changes all basic type values in an object. Any kind of references will not
|
||||
// be touched, i.e. the addresses of slices, maps, pointers will stay unchanged.
|
||||
func ValueFuzz(obj interface{}) {
|
||||
valueFuzz(reflect.ValueOf(obj))
|
||||
}
|
||||
|
||||
func valueFuzz(obj reflect.Value) {
|
||||
switch obj.Kind() {
|
||||
case reflect.Array:
|
||||
for i := 0; i < obj.Len(); i++ {
|
||||
valueFuzz(obj.Index(i))
|
||||
}
|
||||
case reflect.Slice:
|
||||
if obj.IsNil() {
|
||||
// TODO: set non-nil value
|
||||
} else {
|
||||
for i := 0; i < obj.Len(); i++ {
|
||||
valueFuzz(obj.Index(i))
|
||||
}
|
||||
}
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
if obj.IsNil() {
|
||||
// TODO: set non-nil value
|
||||
} else {
|
||||
valueFuzz(obj.Elem())
|
||||
}
|
||||
case reflect.Struct:
|
||||
for i, n := 0, obj.NumField(); i < n; i++ {
|
||||
valueFuzz(obj.Field(i))
|
||||
}
|
||||
case reflect.Map:
|
||||
if obj.IsNil() {
|
||||
// TODO: set non-nil value
|
||||
} else {
|
||||
for _, k := range obj.MapKeys() {
|
||||
// map values are not addressable. We need a copy.
|
||||
v := obj.MapIndex(k)
|
||||
copy := reflect.New(v.Type())
|
||||
copy.Elem().Set(v)
|
||||
valueFuzz(copy.Elem())
|
||||
obj.SetMapIndex(k, copy.Elem())
|
||||
}
|
||||
// TODO: set some new value
|
||||
}
|
||||
case reflect.Func: // ignore, we don't have function types in our API
|
||||
default:
|
||||
if !obj.CanSet() {
|
||||
return
|
||||
}
|
||||
switch obj.Kind() {
|
||||
case reflect.String:
|
||||
obj.SetString(obj.String() + "x")
|
||||
case reflect.Bool:
|
||||
obj.SetBool(!obj.Bool())
|
||||
case reflect.Float32, reflect.Float64:
|
||||
obj.SetFloat(obj.Float()*2.0 + 1.0)
|
||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||
obj.SetInt(obj.Int() + 1)
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||
obj.SetUint(obj.Uint() + 1)
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
171
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/wholepkg/a.go
generated
vendored
Normal file
171
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/wholepkg/a.go
generated
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 wholepkg
|
||||
|
||||
import "k8s.io/gengo/examples/deepcopy-gen/output_tests/otherpkg"
|
||||
|
||||
// Trivial
|
||||
type Struct_Empty struct{}
|
||||
|
||||
// Only primitives
|
||||
type Struct_Primitives struct {
|
||||
BoolField bool
|
||||
IntField int
|
||||
StringField string
|
||||
FloatField float64
|
||||
}
|
||||
type Struct_Primitives_Alias Struct_Primitives
|
||||
type Struct_Embed_Struct_Primitives struct {
|
||||
Struct_Primitives
|
||||
}
|
||||
type Struct_Embed_Int struct {
|
||||
int
|
||||
}
|
||||
type Struct_Struct_Primitives struct {
|
||||
StructField Struct_Primitives
|
||||
}
|
||||
|
||||
// Manual DeepCopy method
|
||||
type ManualStruct struct {
|
||||
StringField string
|
||||
}
|
||||
|
||||
func (m ManualStruct) DeepCopy() ManualStruct {
|
||||
return m
|
||||
}
|
||||
|
||||
type ManualStruct_Alias ManualStruct
|
||||
|
||||
type Struct_Embed_ManualStruct struct {
|
||||
ManualStruct
|
||||
}
|
||||
|
||||
// Only pointers to primitives
|
||||
type Struct_PrimitivePointers struct {
|
||||
BoolPtrField *bool
|
||||
IntPtrField *int
|
||||
StringPtrField *string
|
||||
FloatPtrField *float64
|
||||
}
|
||||
type Struct_PrimitivePointers_Alias Struct_PrimitivePointers
|
||||
type Struct_Embed_Struct_PrimitivePointers struct {
|
||||
Struct_PrimitivePointers
|
||||
}
|
||||
type Struct_Embed_Pointer struct {
|
||||
*int
|
||||
}
|
||||
type Struct_Struct_PrimitivePointers struct {
|
||||
StructField Struct_PrimitivePointers
|
||||
}
|
||||
|
||||
// Manual DeepCopy method
|
||||
type ManualSlice []string
|
||||
|
||||
func (m ManualSlice) DeepCopy() ManualSlice {
|
||||
r := make(ManualSlice, len(m))
|
||||
copy(r, m)
|
||||
return r
|
||||
}
|
||||
|
||||
// Slices
|
||||
type Struct_Slices struct {
|
||||
SliceBoolField []bool
|
||||
SliceByteField []byte
|
||||
SliceIntField []int
|
||||
SliceStringField []string
|
||||
SliceFloatField []float64
|
||||
SliceStructPrimitivesField []Struct_Primitives
|
||||
SliceStructPrimitivesAliasField []Struct_Primitives_Alias
|
||||
SliceStructPrimitivePointersField []Struct_PrimitivePointers
|
||||
SliceStructPrimitivePointersAliasField []Struct_PrimitivePointers_Alias
|
||||
SliceSliceIntField [][]int
|
||||
SliceManualStructField []ManualStruct
|
||||
ManualSliceField ManualSlice
|
||||
}
|
||||
type Struct_Slices_Alias Struct_Slices
|
||||
type Struct_Embed_Struct_Slices struct {
|
||||
Struct_Slices
|
||||
}
|
||||
type Struct_Struct_Slices struct {
|
||||
StructField Struct_Slices
|
||||
}
|
||||
|
||||
// Everything
|
||||
type Struct_Everything struct {
|
||||
BoolField bool
|
||||
IntField int
|
||||
StringField string
|
||||
FloatField float64
|
||||
StructField Struct_Primitives
|
||||
EmptyStructField Struct_Empty
|
||||
ManualStructField ManualStruct
|
||||
ManualStructAliasField ManualStruct_Alias
|
||||
BoolPtrField *bool
|
||||
IntPtrField *int
|
||||
StringPtrField *string
|
||||
FloatPtrField *float64
|
||||
PrimitivePointersField Struct_PrimitivePointers
|
||||
ManualStructPtrField *ManualStruct
|
||||
ManualStructAliasPtrField *ManualStruct_Alias
|
||||
SliceBoolField []bool
|
||||
SliceByteField []byte
|
||||
SliceIntField []int
|
||||
SliceStringField []string
|
||||
SliceFloatField []float64
|
||||
SlicesField Struct_Slices
|
||||
SliceManualStructField []ManualStruct
|
||||
ManualSliceField ManualSlice
|
||||
}
|
||||
|
||||
// An Object
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/gengo/examples/deepcopy-gen/output_tests/otherpkg.Object
|
||||
type Struct_ExplicitObject struct {
|
||||
x int
|
||||
}
|
||||
|
||||
// An Object which is used a non-pointer
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/gengo/examples/deepcopy-gen/output_tests/otherpkg.Object
|
||||
// +k8s:deepcopy-gen:nonpointer-interfaces=true
|
||||
type Struct_NonPointerExplicitObject struct {
|
||||
x int
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=false
|
||||
type Struct_TypeMeta struct {
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/gengo/examples/deepcopy-gen/output_tests/otherpkg.Object
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/gengo/examples/deepcopy-gen/output_tests/otherpkg.List
|
||||
type Struct_ObjectAndList struct {
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/gengo/examples/deepcopy-gen/output_tests/otherpkg.Object
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/gengo/examples/deepcopy-gen/output_tests/otherpkg.Object
|
||||
type Struct_ObjectAndObject struct {
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/gengo/examples/deepcopy-gen/output_tests/wholepkg.Selector
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/gengo/examples/deepcopy-gen/output_tests/otherpkg.Object
|
||||
type Struct_ExplicitSelectorExplicitObject struct {
|
||||
Struct_TypeMeta
|
||||
}
|
||||
|
||||
type Struct_Interfaces struct {
|
||||
ObjectField otherpkg.Object
|
||||
NilObjectField otherpkg.Object
|
||||
SelectorField Selector
|
||||
}
|
20
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/wholepkg/b.go
generated
vendored
Normal file
20
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/wholepkg/b.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 wholepkg
|
||||
|
||||
// Another type in another file.
|
||||
type Struct_B struct{}
|
145
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/wholepkg/deepcopy_test.go
generated
vendored
Normal file
145
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/wholepkg/deepcopy_test.go
generated
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 wholepkg
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
fuzz "github.com/google/gofuzz"
|
||||
)
|
||||
|
||||
func TestDeepCopyPrimitives(t *testing.T) {
|
||||
x := Struct_Primitives{}
|
||||
y := Struct_Primitives{}
|
||||
|
||||
if !reflect.DeepEqual(&x, &y) {
|
||||
t.Errorf("objects should be equal to start, but are not")
|
||||
}
|
||||
|
||||
fuzzer := fuzz.New()
|
||||
fuzzer.Fuzz(&x)
|
||||
fuzzer.Fuzz(&y)
|
||||
|
||||
if reflect.DeepEqual(&x, &y) {
|
||||
t.Errorf("objects should not be equal, but are")
|
||||
}
|
||||
|
||||
x.DeepCopyInto(&y)
|
||||
if !reflect.DeepEqual(&x, &y) {
|
||||
t.Errorf("objects should be equal, but are not")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeepCopyInterfaceFields(t *testing.T) {
|
||||
x := Struct_Interfaces{}
|
||||
y := Struct_Interfaces{}
|
||||
|
||||
if !reflect.DeepEqual(&x, &y) {
|
||||
t.Errorf("objects should be equal to start, but are not")
|
||||
}
|
||||
|
||||
fuzzer := fuzz.New()
|
||||
|
||||
obj := Struct_ExplicitObject{}
|
||||
fuzzer.Fuzz(&obj)
|
||||
x.ObjectField = &obj
|
||||
|
||||
sel := Struct_ExplicitSelectorExplicitObject{}
|
||||
fuzzer.Fuzz(&sel)
|
||||
x.SelectorField = &sel
|
||||
|
||||
if reflect.DeepEqual(&x, &y) {
|
||||
t.Errorf("objects should not be equal, but are")
|
||||
}
|
||||
|
||||
x.DeepCopyInto(&y)
|
||||
if !reflect.DeepEqual(&x, &y) {
|
||||
t.Errorf("objects should be equal, but are not")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNilCopy(t *testing.T) {
|
||||
var x *Struct_B
|
||||
y := x.DeepCopy()
|
||||
if y != nil {
|
||||
t.Errorf("Expected nil as deepcopy of nil, got %+v", y)
|
||||
}
|
||||
}
|
||||
|
||||
func assertMethod(t *testing.T, typ reflect.Type, name string) {
|
||||
if _, found := typ.MethodByName(name); !found {
|
||||
t.Errorf("Struct_ExplicitObject must have %v method", name)
|
||||
}
|
||||
}
|
||||
|
||||
func assertNotMethod(t *testing.T, typ reflect.Type, name string) {
|
||||
if _, found := typ.MethodByName(name); found {
|
||||
t.Errorf("%v must not have %v method", typ, name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterfaceTypes(t *testing.T) {
|
||||
explicitObject := reflect.TypeOf(&Struct_ExplicitObject{})
|
||||
assertMethod(t, explicitObject, "DeepCopyObject")
|
||||
|
||||
typeMeta := reflect.TypeOf(&Struct_TypeMeta{})
|
||||
assertNotMethod(t, typeMeta, "DeepCopy")
|
||||
|
||||
objectAndList := reflect.TypeOf(&Struct_ObjectAndList{})
|
||||
assertMethod(t, objectAndList, "DeepCopyObject")
|
||||
assertMethod(t, objectAndList, "DeepCopyList")
|
||||
|
||||
objectAndObject := reflect.TypeOf(&Struct_ObjectAndObject{})
|
||||
assertMethod(t, objectAndObject, "DeepCopyObject")
|
||||
|
||||
explicitSelectorExplicitObject := reflect.TypeOf(&Struct_ExplicitSelectorExplicitObject{})
|
||||
assertMethod(t, explicitSelectorExplicitObject, "DeepCopySelector")
|
||||
assertMethod(t, explicitSelectorExplicitObject, "DeepCopyObject")
|
||||
}
|
||||
|
||||
func TestInterfaceDeepCopy(t *testing.T) {
|
||||
x := Struct_ExplicitObject{}
|
||||
|
||||
fuzzer := fuzz.New()
|
||||
fuzzer.Fuzz(&x)
|
||||
|
||||
y_obj := x.DeepCopyObject()
|
||||
y, ok := y_obj.(*Struct_ExplicitObject)
|
||||
if !ok {
|
||||
t.Fatalf("epxected Struct_ExplicitObject from Struct_ExplicitObject.DeepCopyObject, got: %t", y_obj)
|
||||
}
|
||||
if !reflect.DeepEqual(y, &x) {
|
||||
t.Error("objects should be equal, but are not")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterfaceNonPointerDeepCopy(t *testing.T) {
|
||||
x := Struct_NonPointerExplicitObject{}
|
||||
|
||||
fuzzer := fuzz.New()
|
||||
fuzzer.Fuzz(&x)
|
||||
|
||||
y_obj := x.DeepCopyObject()
|
||||
y, ok := y_obj.(Struct_NonPointerExplicitObject)
|
||||
if !ok {
|
||||
t.Fatalf("epxected Struct_NonPointerExplicitObject from Struct_NonPointerExplicitObject.DeepCopyObject, got: %t", y_obj)
|
||||
}
|
||||
if !reflect.DeepEqual(y, x) {
|
||||
t.Error("objects should be equal, but are not")
|
||||
}
|
||||
}
|
20
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/wholepkg/doc.go
generated
vendored
Normal file
20
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/wholepkg/doc.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// This is a test package.
|
||||
package wholepkg
|
21
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/wholepkg/interfaces.go
generated
vendored
Normal file
21
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/wholepkg/interfaces.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
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 wholepkg
|
||||
|
||||
type Selector interface {
|
||||
DeepCopySelector() Selector
|
||||
}
|
760
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/wholepkg/zz_generated.go
generated
vendored
Normal file
760
vendor/k8s.io/gengo/examples/deepcopy-gen/output_tests/wholepkg/zz_generated.go
generated
vendored
Normal file
@@ -0,0 +1,760 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package wholepkg
|
||||
|
||||
import (
|
||||
otherpkg "k8s.io/gengo/examples/deepcopy-gen/output_tests/otherpkg"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in ManualSlice) DeepCopyInto(out *ManualSlice) {
|
||||
{
|
||||
in := &in
|
||||
*out = in.DeepCopy()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ManualStruct) DeepCopyInto(out *ManualStruct) {
|
||||
*out = in.DeepCopy()
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ManualStruct_Alias) DeepCopyInto(out *ManualStruct_Alias) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManualStruct_Alias.
|
||||
func (in *ManualStruct_Alias) DeepCopy() *ManualStruct_Alias {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ManualStruct_Alias)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_B) DeepCopyInto(out *Struct_B) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_B.
|
||||
func (in *Struct_B) DeepCopy() *Struct_B {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_B)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_Embed_Int) DeepCopyInto(out *Struct_Embed_Int) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Embed_Int.
|
||||
func (in *Struct_Embed_Int) DeepCopy() *Struct_Embed_Int {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_Embed_Int)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_Embed_ManualStruct) DeepCopyInto(out *Struct_Embed_ManualStruct) {
|
||||
*out = *in
|
||||
out.ManualStruct = in.ManualStruct.DeepCopy()
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Embed_ManualStruct.
|
||||
func (in *Struct_Embed_ManualStruct) DeepCopy() *Struct_Embed_ManualStruct {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_Embed_ManualStruct)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_Embed_Pointer) DeepCopyInto(out *Struct_Embed_Pointer) {
|
||||
*out = *in
|
||||
if in.int != nil {
|
||||
in, out := &in.int, &out.int
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Embed_Pointer.
|
||||
func (in *Struct_Embed_Pointer) DeepCopy() *Struct_Embed_Pointer {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_Embed_Pointer)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_Embed_Struct_PrimitivePointers) DeepCopyInto(out *Struct_Embed_Struct_PrimitivePointers) {
|
||||
*out = *in
|
||||
in.Struct_PrimitivePointers.DeepCopyInto(&out.Struct_PrimitivePointers)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Embed_Struct_PrimitivePointers.
|
||||
func (in *Struct_Embed_Struct_PrimitivePointers) DeepCopy() *Struct_Embed_Struct_PrimitivePointers {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_Embed_Struct_PrimitivePointers)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_Embed_Struct_Primitives) DeepCopyInto(out *Struct_Embed_Struct_Primitives) {
|
||||
*out = *in
|
||||
out.Struct_Primitives = in.Struct_Primitives
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Embed_Struct_Primitives.
|
||||
func (in *Struct_Embed_Struct_Primitives) DeepCopy() *Struct_Embed_Struct_Primitives {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_Embed_Struct_Primitives)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_Embed_Struct_Slices) DeepCopyInto(out *Struct_Embed_Struct_Slices) {
|
||||
*out = *in
|
||||
in.Struct_Slices.DeepCopyInto(&out.Struct_Slices)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Embed_Struct_Slices.
|
||||
func (in *Struct_Embed_Struct_Slices) DeepCopy() *Struct_Embed_Struct_Slices {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_Embed_Struct_Slices)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_Empty) DeepCopyInto(out *Struct_Empty) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Empty.
|
||||
func (in *Struct_Empty) DeepCopy() *Struct_Empty {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_Empty)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_Everything) DeepCopyInto(out *Struct_Everything) {
|
||||
*out = *in
|
||||
out.StructField = in.StructField
|
||||
out.EmptyStructField = in.EmptyStructField
|
||||
out.ManualStructField = in.ManualStructField.DeepCopy()
|
||||
out.ManualStructAliasField = in.ManualStructAliasField
|
||||
if in.BoolPtrField != nil {
|
||||
in, out := &in.BoolPtrField, &out.BoolPtrField
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.IntPtrField != nil {
|
||||
in, out := &in.IntPtrField, &out.IntPtrField
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.StringPtrField != nil {
|
||||
in, out := &in.StringPtrField, &out.StringPtrField
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.FloatPtrField != nil {
|
||||
in, out := &in.FloatPtrField, &out.FloatPtrField
|
||||
*out = new(float64)
|
||||
**out = **in
|
||||
}
|
||||
in.PrimitivePointersField.DeepCopyInto(&out.PrimitivePointersField)
|
||||
if in.ManualStructPtrField != nil {
|
||||
in, out := &in.ManualStructPtrField, &out.ManualStructPtrField
|
||||
x := (*in).DeepCopy()
|
||||
*out = &x
|
||||
}
|
||||
if in.ManualStructAliasPtrField != nil {
|
||||
in, out := &in.ManualStructAliasPtrField, &out.ManualStructAliasPtrField
|
||||
*out = new(ManualStruct_Alias)
|
||||
**out = **in
|
||||
}
|
||||
if in.SliceBoolField != nil {
|
||||
in, out := &in.SliceBoolField, &out.SliceBoolField
|
||||
*out = make([]bool, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceByteField != nil {
|
||||
in, out := &in.SliceByteField, &out.SliceByteField
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceIntField != nil {
|
||||
in, out := &in.SliceIntField, &out.SliceIntField
|
||||
*out = make([]int, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStringField != nil {
|
||||
in, out := &in.SliceStringField, &out.SliceStringField
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceFloatField != nil {
|
||||
in, out := &in.SliceFloatField, &out.SliceFloatField
|
||||
*out = make([]float64, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
in.SlicesField.DeepCopyInto(&out.SlicesField)
|
||||
if in.SliceManualStructField != nil {
|
||||
in, out := &in.SliceManualStructField, &out.SliceManualStructField
|
||||
*out = make([]ManualStruct, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
out.ManualSliceField = in.ManualSliceField.DeepCopy()
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Everything.
|
||||
func (in *Struct_Everything) DeepCopy() *Struct_Everything {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_Everything)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_ExplicitObject) DeepCopyInto(out *Struct_ExplicitObject) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_ExplicitObject.
|
||||
func (in *Struct_ExplicitObject) DeepCopy() *Struct_ExplicitObject {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_ExplicitObject)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new otherpkg.Object.
|
||||
func (in *Struct_ExplicitObject) DeepCopyObject() otherpkg.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_ExplicitSelectorExplicitObject) DeepCopyInto(out *Struct_ExplicitSelectorExplicitObject) {
|
||||
*out = *in
|
||||
out.Struct_TypeMeta = in.Struct_TypeMeta
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_ExplicitSelectorExplicitObject.
|
||||
func (in *Struct_ExplicitSelectorExplicitObject) DeepCopy() *Struct_ExplicitSelectorExplicitObject {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_ExplicitSelectorExplicitObject)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new otherpkg.Object.
|
||||
func (in *Struct_ExplicitSelectorExplicitObject) DeepCopyObject() otherpkg.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopySelector is an autogenerated deepcopy function, copying the receiver, creating a new Selector.
|
||||
func (in *Struct_ExplicitSelectorExplicitObject) DeepCopySelector() Selector {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_Interfaces) DeepCopyInto(out *Struct_Interfaces) {
|
||||
*out = *in
|
||||
if in.ObjectField != nil {
|
||||
out.ObjectField = in.ObjectField.DeepCopyObject()
|
||||
}
|
||||
if in.NilObjectField != nil {
|
||||
out.NilObjectField = in.NilObjectField.DeepCopyObject()
|
||||
}
|
||||
if in.SelectorField != nil {
|
||||
out.SelectorField = in.SelectorField.DeepCopySelector()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Interfaces.
|
||||
func (in *Struct_Interfaces) DeepCopy() *Struct_Interfaces {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_Interfaces)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_NonPointerExplicitObject) DeepCopyInto(out *Struct_NonPointerExplicitObject) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_NonPointerExplicitObject.
|
||||
func (in *Struct_NonPointerExplicitObject) DeepCopy() *Struct_NonPointerExplicitObject {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_NonPointerExplicitObject)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new otherpkg.Object.
|
||||
func (in Struct_NonPointerExplicitObject) DeepCopyObject() otherpkg.Object {
|
||||
return *in.DeepCopy()
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_ObjectAndList) DeepCopyInto(out *Struct_ObjectAndList) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_ObjectAndList.
|
||||
func (in *Struct_ObjectAndList) DeepCopy() *Struct_ObjectAndList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_ObjectAndList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyList is an autogenerated deepcopy function, copying the receiver, creating a new otherpkg.List.
|
||||
func (in *Struct_ObjectAndList) DeepCopyList() otherpkg.List {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new otherpkg.Object.
|
||||
func (in *Struct_ObjectAndList) DeepCopyObject() otherpkg.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_ObjectAndObject) DeepCopyInto(out *Struct_ObjectAndObject) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_ObjectAndObject.
|
||||
func (in *Struct_ObjectAndObject) DeepCopy() *Struct_ObjectAndObject {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_ObjectAndObject)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new otherpkg.Object.
|
||||
func (in *Struct_ObjectAndObject) DeepCopyObject() otherpkg.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_PrimitivePointers) DeepCopyInto(out *Struct_PrimitivePointers) {
|
||||
*out = *in
|
||||
if in.BoolPtrField != nil {
|
||||
in, out := &in.BoolPtrField, &out.BoolPtrField
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.IntPtrField != nil {
|
||||
in, out := &in.IntPtrField, &out.IntPtrField
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.StringPtrField != nil {
|
||||
in, out := &in.StringPtrField, &out.StringPtrField
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.FloatPtrField != nil {
|
||||
in, out := &in.FloatPtrField, &out.FloatPtrField
|
||||
*out = new(float64)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_PrimitivePointers.
|
||||
func (in *Struct_PrimitivePointers) DeepCopy() *Struct_PrimitivePointers {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_PrimitivePointers)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_PrimitivePointers_Alias) DeepCopyInto(out *Struct_PrimitivePointers_Alias) {
|
||||
*out = *in
|
||||
if in.BoolPtrField != nil {
|
||||
in, out := &in.BoolPtrField, &out.BoolPtrField
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.IntPtrField != nil {
|
||||
in, out := &in.IntPtrField, &out.IntPtrField
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.StringPtrField != nil {
|
||||
in, out := &in.StringPtrField, &out.StringPtrField
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.FloatPtrField != nil {
|
||||
in, out := &in.FloatPtrField, &out.FloatPtrField
|
||||
*out = new(float64)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_PrimitivePointers_Alias.
|
||||
func (in *Struct_PrimitivePointers_Alias) DeepCopy() *Struct_PrimitivePointers_Alias {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_PrimitivePointers_Alias)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_Primitives) DeepCopyInto(out *Struct_Primitives) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Primitives.
|
||||
func (in *Struct_Primitives) DeepCopy() *Struct_Primitives {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_Primitives)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_Primitives_Alias) DeepCopyInto(out *Struct_Primitives_Alias) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Primitives_Alias.
|
||||
func (in *Struct_Primitives_Alias) DeepCopy() *Struct_Primitives_Alias {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_Primitives_Alias)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_Slices) DeepCopyInto(out *Struct_Slices) {
|
||||
*out = *in
|
||||
if in.SliceBoolField != nil {
|
||||
in, out := &in.SliceBoolField, &out.SliceBoolField
|
||||
*out = make([]bool, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceByteField != nil {
|
||||
in, out := &in.SliceByteField, &out.SliceByteField
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceIntField != nil {
|
||||
in, out := &in.SliceIntField, &out.SliceIntField
|
||||
*out = make([]int, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStringField != nil {
|
||||
in, out := &in.SliceStringField, &out.SliceStringField
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceFloatField != nil {
|
||||
in, out := &in.SliceFloatField, &out.SliceFloatField
|
||||
*out = make([]float64, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStructPrimitivesField != nil {
|
||||
in, out := &in.SliceStructPrimitivesField, &out.SliceStructPrimitivesField
|
||||
*out = make([]Struct_Primitives, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStructPrimitivesAliasField != nil {
|
||||
in, out := &in.SliceStructPrimitivesAliasField, &out.SliceStructPrimitivesAliasField
|
||||
*out = make([]Struct_Primitives_Alias, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStructPrimitivePointersField != nil {
|
||||
in, out := &in.SliceStructPrimitivePointersField, &out.SliceStructPrimitivePointersField
|
||||
*out = make([]Struct_PrimitivePointers, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.SliceStructPrimitivePointersAliasField != nil {
|
||||
in, out := &in.SliceStructPrimitivePointersAliasField, &out.SliceStructPrimitivePointersAliasField
|
||||
*out = make([]Struct_PrimitivePointers_Alias, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.SliceSliceIntField != nil {
|
||||
in, out := &in.SliceSliceIntField, &out.SliceSliceIntField
|
||||
*out = make([][]int, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = make([]int, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.SliceManualStructField != nil {
|
||||
in, out := &in.SliceManualStructField, &out.SliceManualStructField
|
||||
*out = make([]ManualStruct, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
out.ManualSliceField = in.ManualSliceField.DeepCopy()
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Slices.
|
||||
func (in *Struct_Slices) DeepCopy() *Struct_Slices {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_Slices)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_Slices_Alias) DeepCopyInto(out *Struct_Slices_Alias) {
|
||||
*out = *in
|
||||
if in.SliceBoolField != nil {
|
||||
in, out := &in.SliceBoolField, &out.SliceBoolField
|
||||
*out = make([]bool, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceByteField != nil {
|
||||
in, out := &in.SliceByteField, &out.SliceByteField
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceIntField != nil {
|
||||
in, out := &in.SliceIntField, &out.SliceIntField
|
||||
*out = make([]int, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStringField != nil {
|
||||
in, out := &in.SliceStringField, &out.SliceStringField
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceFloatField != nil {
|
||||
in, out := &in.SliceFloatField, &out.SliceFloatField
|
||||
*out = make([]float64, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStructPrimitivesField != nil {
|
||||
in, out := &in.SliceStructPrimitivesField, &out.SliceStructPrimitivesField
|
||||
*out = make([]Struct_Primitives, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStructPrimitivesAliasField != nil {
|
||||
in, out := &in.SliceStructPrimitivesAliasField, &out.SliceStructPrimitivesAliasField
|
||||
*out = make([]Struct_Primitives_Alias, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStructPrimitivePointersField != nil {
|
||||
in, out := &in.SliceStructPrimitivePointersField, &out.SliceStructPrimitivePointersField
|
||||
*out = make([]Struct_PrimitivePointers, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.SliceStructPrimitivePointersAliasField != nil {
|
||||
in, out := &in.SliceStructPrimitivePointersAliasField, &out.SliceStructPrimitivePointersAliasField
|
||||
*out = make([]Struct_PrimitivePointers_Alias, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.SliceSliceIntField != nil {
|
||||
in, out := &in.SliceSliceIntField, &out.SliceSliceIntField
|
||||
*out = make([][]int, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = make([]int, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.SliceManualStructField != nil {
|
||||
in, out := &in.SliceManualStructField, &out.SliceManualStructField
|
||||
*out = make([]ManualStruct, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
out.ManualSliceField = in.ManualSliceField.DeepCopy()
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Slices_Alias.
|
||||
func (in *Struct_Slices_Alias) DeepCopy() *Struct_Slices_Alias {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_Slices_Alias)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_Struct_PrimitivePointers) DeepCopyInto(out *Struct_Struct_PrimitivePointers) {
|
||||
*out = *in
|
||||
in.StructField.DeepCopyInto(&out.StructField)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Struct_PrimitivePointers.
|
||||
func (in *Struct_Struct_PrimitivePointers) DeepCopy() *Struct_Struct_PrimitivePointers {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_Struct_PrimitivePointers)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_Struct_Primitives) DeepCopyInto(out *Struct_Struct_Primitives) {
|
||||
*out = *in
|
||||
out.StructField = in.StructField
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Struct_Primitives.
|
||||
func (in *Struct_Struct_Primitives) DeepCopy() *Struct_Struct_Primitives {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_Struct_Primitives)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct_Struct_Slices) DeepCopyInto(out *Struct_Struct_Slices) {
|
||||
*out = *in
|
||||
in.StructField.DeepCopyInto(&out.StructField)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Struct_Slices.
|
||||
func (in *Struct_Struct_Slices) DeepCopy() *Struct_Struct_Slices {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct_Struct_Slices)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
1
vendor/k8s.io/gengo/examples/defaulter-gen/.gitignore
generated
vendored
Normal file
1
vendor/k8s.io/gengo/examples/defaulter-gen/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
defaulter-gen
|
12
vendor/k8s.io/gengo/examples/defaulter-gen/.import-restrictions
generated
vendored
Normal file
12
vendor/k8s.io/gengo/examples/defaulter-gen/.import-restrictions
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"Rules": [
|
||||
{
|
||||
"SelectorRegexp": "k8s[.]io",
|
||||
"AllowedPrefixes": [
|
||||
"k8s.io/gengo",
|
||||
"k8s.io/kubernetes/third_party/forked/golang",
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
15
vendor/k8s.io/gengo/examples/defaulter-gen/Makefile
generated
vendored
Normal file
15
vendor/k8s.io/gengo/examples/defaulter-gen/Makefile
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
TOOL=defaulter-gen
|
||||
|
||||
test:
|
||||
@if ! git diff --quiet HEAD; then \
|
||||
echo "FAIL: git client is not clean"; \
|
||||
false; \
|
||||
fi
|
||||
@go build -o /tmp/$(TOOL)
|
||||
@PKGS=$$(cd _output_tests; go list ./... | paste -sd' ' -); \
|
||||
/tmp/$(TOOL) --logtostderr --v=4 -i $$(echo $$PKGS | sed 's/ /,/g') -O zz_generated
|
||||
@if ! git diff --quiet HEAD; then \
|
||||
echo "FAIL: output files changed"; \
|
||||
git diff; \
|
||||
false; \
|
||||
fi
|
2
vendor/k8s.io/gengo/examples/defaulter-gen/OWNERS
generated
vendored
Normal file
2
vendor/k8s.io/gengo/examples/defaulter-gen/OWNERS
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
approvers:
|
||||
- smarterclayton
|
20
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/empty/doc.go
generated
vendored
Normal file
20
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/empty/doc.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:defaulter-gen=covers
|
||||
|
||||
// This is a test package.
|
||||
package empty // import "k8s.io/gengo/examples/defaulter-gen/_output_tests/empty"
|
29
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/empty/type.go
generated
vendored
Normal file
29
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/empty/type.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
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 empty
|
||||
|
||||
// Only test
|
||||
type Ttest struct {
|
||||
BoolField bool
|
||||
IntField int
|
||||
StringField string
|
||||
FloatField float64
|
||||
}
|
||||
|
||||
type TypeMeta struct {
|
||||
Fortest bool
|
||||
}
|
32
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/empty/zz_generated.go
generated
vendored
Normal file
32
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/empty/zz_generated.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by defaulter-gen. DO NOT EDIT.
|
||||
|
||||
package empty
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// RegisterDefaults adds defaulters functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
// All generated defaulters are covering - they call all nested defaulters.
|
||||
func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||
return nil
|
||||
}
|
32
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/pointer/defaults.go
generated
vendored
Normal file
32
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/pointer/defaults.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
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 pointer
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
||||
return RegisterDefaults(scheme)
|
||||
}
|
||||
|
||||
func SetDefaults_Tpointer(obj *Tpointer) {
|
||||
if obj.BoolField == nil {
|
||||
obj.BoolField = new(bool)
|
||||
*obj.BoolField = true
|
||||
}
|
||||
}
|
20
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/pointer/doc.go
generated
vendored
Normal file
20
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/pointer/doc.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
|
||||
// This is a test package.
|
||||
package pointer // import "k8s.io/gengo/examples/defaulter-gen/_output_tests/pointer"
|
33
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/pointer/type.go
generated
vendored
Normal file
33
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/pointer/type.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
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 pointer
|
||||
|
||||
import (
|
||||
"k8s.io/gengo/examples/defaulter-gen/_output_tests/empty"
|
||||
)
|
||||
|
||||
type Tpointer struct {
|
||||
empty.TypeMeta
|
||||
BoolField *bool
|
||||
}
|
||||
|
||||
// Only test
|
||||
type Ttest struct {
|
||||
empty.TypeMeta
|
||||
NTP Tpointer
|
||||
Tp *Tpointer
|
||||
}
|
45
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/pointer/zz_generated.go
generated
vendored
Normal file
45
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/pointer/zz_generated.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by defaulter-gen. DO NOT EDIT.
|
||||
|
||||
package pointer
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// RegisterDefaults adds defaulters functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
// All generated defaulters are covering - they call all nested defaulters.
|
||||
func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||
scheme.AddTypeDefaultingFunc(&Tpointer{}, func(obj interface{}) { SetObjectDefaults_Tpointer(obj.(*Tpointer)) })
|
||||
scheme.AddTypeDefaultingFunc(&Ttest{}, func(obj interface{}) { SetObjectDefaults_Ttest(obj.(*Ttest)) })
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetObjectDefaults_Tpointer(in *Tpointer) {
|
||||
SetDefaults_Tpointer(in)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_Ttest(in *Ttest) {
|
||||
SetObjectDefaults_Tpointer(&in.NTP)
|
||||
if in.Tp != nil {
|
||||
SetObjectDefaults_Tpointer(in.Tp)
|
||||
}
|
||||
}
|
32
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/slices/defaults.go
generated
vendored
Normal file
32
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/slices/defaults.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
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 slices
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
||||
return RegisterDefaults(scheme)
|
||||
}
|
||||
|
||||
func SetDefaults_Ttest(obj *Ttest) {
|
||||
if obj.BoolField == nil {
|
||||
obj.BoolField = new(bool)
|
||||
*obj.BoolField = true
|
||||
}
|
||||
}
|
20
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/slices/doc.go
generated
vendored
Normal file
20
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/slices/doc.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
|
||||
// This is a test package.
|
||||
package slices // import "k8s.io/gengo/examples/defaulter-gen/_output_tests/slices"
|
37
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/slices/type.go
generated
vendored
Normal file
37
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/slices/type.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
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 slices
|
||||
|
||||
import (
|
||||
"k8s.io/gengo/examples/defaulter-gen/_output_tests/empty"
|
||||
)
|
||||
|
||||
// Only test
|
||||
type Ttest struct {
|
||||
empty.TypeMeta
|
||||
BoolField *bool
|
||||
}
|
||||
|
||||
type TtestList struct {
|
||||
empty.TypeMeta
|
||||
Items []Ttest
|
||||
}
|
||||
|
||||
type TtestPointerList struct {
|
||||
empty.TypeMeta
|
||||
Items []*Ttest
|
||||
}
|
55
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/slices/zz_generated.go
generated
vendored
Normal file
55
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/slices/zz_generated.go
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by defaulter-gen. DO NOT EDIT.
|
||||
|
||||
package slices
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// RegisterDefaults adds defaulters functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
// All generated defaulters are covering - they call all nested defaulters.
|
||||
func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||
scheme.AddTypeDefaultingFunc(&Ttest{}, func(obj interface{}) { SetObjectDefaults_Ttest(obj.(*Ttest)) })
|
||||
scheme.AddTypeDefaultingFunc(&TtestList{}, func(obj interface{}) { SetObjectDefaults_TtestList(obj.(*TtestList)) })
|
||||
scheme.AddTypeDefaultingFunc(&TtestPointerList{}, func(obj interface{}) { SetObjectDefaults_TtestPointerList(obj.(*TtestPointerList)) })
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetObjectDefaults_Ttest(in *Ttest) {
|
||||
SetDefaults_Ttest(in)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_TtestList(in *TtestList) {
|
||||
for i := range in.Items {
|
||||
a := &in.Items[i]
|
||||
SetObjectDefaults_Ttest(a)
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_TtestPointerList(in *TtestPointerList) {
|
||||
for i := range in.Items {
|
||||
a := in.Items[i]
|
||||
if a != nil {
|
||||
SetObjectDefaults_Ttest(a)
|
||||
}
|
||||
}
|
||||
}
|
32
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/wholepkg/defaults.go
generated
vendored
Normal file
32
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/wholepkg/defaults.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
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 wholepkg
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
||||
return RegisterDefaults(scheme)
|
||||
}
|
||||
|
||||
func SetDefaults_Struct_Primitives(obj *Struct_Primitives) {
|
||||
if obj.BoolField == nil {
|
||||
obj.BoolField = new(bool)
|
||||
*obj.BoolField = true
|
||||
}
|
||||
}
|
20
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/wholepkg/doc.go
generated
vendored
Normal file
20
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/wholepkg/doc.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
|
||||
// This is a test package.
|
||||
package wholepkg // import "k8s.io/gengo/examples/defaulter-gen/_output_tests/wholepkg"
|
74
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/wholepkg/type.go
generated
vendored
Normal file
74
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/wholepkg/type.go
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
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 wholepkg
|
||||
|
||||
import (
|
||||
"k8s.io/gengo/examples/defaulter-gen/_output_tests/empty"
|
||||
)
|
||||
|
||||
// Only primitives
|
||||
type Struct_Primitives struct {
|
||||
empty.TypeMeta
|
||||
BoolField *bool
|
||||
IntField *int
|
||||
StringField *string
|
||||
FloatField *float64
|
||||
}
|
||||
type Struct_Primitives_Alias Struct_Primitives
|
||||
|
||||
type Struct_Struct_Primitives struct {
|
||||
empty.TypeMeta
|
||||
StructField Struct_Primitives
|
||||
}
|
||||
|
||||
//Pointer
|
||||
type Struct_Pointer struct {
|
||||
empty.TypeMeta
|
||||
PointerStructPrimitivesField Struct_Primitives
|
||||
PointerPointerStructPrimitivesField *Struct_Primitives
|
||||
PointerStructPrimitivesAliasField Struct_Primitives_Alias
|
||||
PointerPointerStructPrimitivesAliasField Struct_Primitives_Alias
|
||||
PointerStructStructPrimitives Struct_Struct_Primitives
|
||||
PointerPointerStructStructPrimitives *Struct_Struct_Primitives
|
||||
}
|
||||
|
||||
// Slices
|
||||
type Struct_Slices struct {
|
||||
empty.TypeMeta
|
||||
SliceStructPrimitivesField []Struct_Primitives
|
||||
SlicePointerStructPrimitivesField []*Struct_Primitives
|
||||
SliceStructPrimitivesAliasField []Struct_Primitives_Alias
|
||||
SlicePointerStructPrimitivesAliasField []*Struct_Primitives_Alias
|
||||
SliceStructStructPrimitives []Struct_Struct_Primitives
|
||||
SlicePointerStructStructPrimitives []*Struct_Struct_Primitives
|
||||
}
|
||||
|
||||
// Everything
|
||||
type Struct_Everything struct {
|
||||
empty.TypeMeta
|
||||
BoolPtrField *bool
|
||||
IntPtrField *int
|
||||
StringPtrField *string
|
||||
FloatPtrField *float64
|
||||
PointerStructField Struct_Pointer
|
||||
SliceBoolField []bool
|
||||
SliceByteField []byte
|
||||
SliceIntField []int
|
||||
SliceStringField []string
|
||||
SliceFloatField []float64
|
||||
SlicesStructField Struct_Slices
|
||||
}
|
84
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/wholepkg/zz_generated.go
generated
vendored
Normal file
84
vendor/k8s.io/gengo/examples/defaulter-gen/_output_tests/wholepkg/zz_generated.go
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by defaulter-gen. DO NOT EDIT.
|
||||
|
||||
package wholepkg
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// RegisterDefaults adds defaulters functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
// All generated defaulters are covering - they call all nested defaulters.
|
||||
func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||
scheme.AddTypeDefaultingFunc(&Struct_Everything{}, func(obj interface{}) { SetObjectDefaults_Struct_Everything(obj.(*Struct_Everything)) })
|
||||
scheme.AddTypeDefaultingFunc(&Struct_Pointer{}, func(obj interface{}) { SetObjectDefaults_Struct_Pointer(obj.(*Struct_Pointer)) })
|
||||
scheme.AddTypeDefaultingFunc(&Struct_Primitives{}, func(obj interface{}) { SetObjectDefaults_Struct_Primitives(obj.(*Struct_Primitives)) })
|
||||
scheme.AddTypeDefaultingFunc(&Struct_Slices{}, func(obj interface{}) { SetObjectDefaults_Struct_Slices(obj.(*Struct_Slices)) })
|
||||
scheme.AddTypeDefaultingFunc(&Struct_Struct_Primitives{}, func(obj interface{}) { SetObjectDefaults_Struct_Struct_Primitives(obj.(*Struct_Struct_Primitives)) })
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetObjectDefaults_Struct_Everything(in *Struct_Everything) {
|
||||
SetObjectDefaults_Struct_Pointer(&in.PointerStructField)
|
||||
SetObjectDefaults_Struct_Slices(&in.SlicesStructField)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_Struct_Pointer(in *Struct_Pointer) {
|
||||
SetObjectDefaults_Struct_Primitives(&in.PointerStructPrimitivesField)
|
||||
if in.PointerPointerStructPrimitivesField != nil {
|
||||
SetObjectDefaults_Struct_Primitives(in.PointerPointerStructPrimitivesField)
|
||||
}
|
||||
SetObjectDefaults_Struct_Struct_Primitives(&in.PointerStructStructPrimitives)
|
||||
if in.PointerPointerStructStructPrimitives != nil {
|
||||
SetObjectDefaults_Struct_Struct_Primitives(in.PointerPointerStructStructPrimitives)
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_Struct_Primitives(in *Struct_Primitives) {
|
||||
SetDefaults_Struct_Primitives(in)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_Struct_Slices(in *Struct_Slices) {
|
||||
for i := range in.SliceStructPrimitivesField {
|
||||
a := &in.SliceStructPrimitivesField[i]
|
||||
SetObjectDefaults_Struct_Primitives(a)
|
||||
}
|
||||
for i := range in.SlicePointerStructPrimitivesField {
|
||||
a := in.SlicePointerStructPrimitivesField[i]
|
||||
if a != nil {
|
||||
SetObjectDefaults_Struct_Primitives(a)
|
||||
}
|
||||
}
|
||||
for i := range in.SliceStructStructPrimitives {
|
||||
a := &in.SliceStructStructPrimitives[i]
|
||||
SetObjectDefaults_Struct_Struct_Primitives(a)
|
||||
}
|
||||
for i := range in.SlicePointerStructStructPrimitives {
|
||||
a := in.SlicePointerStructStructPrimitives[i]
|
||||
if a != nil {
|
||||
SetObjectDefaults_Struct_Struct_Primitives(a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_Struct_Struct_Primitives(in *Struct_Struct_Primitives) {
|
||||
SetObjectDefaults_Struct_Primitives(&in.StructField)
|
||||
}
|
828
vendor/k8s.io/gengo/examples/defaulter-gen/generators/defaulter.go
generated
vendored
Normal file
828
vendor/k8s.io/gengo/examples/defaulter-gen/generators/defaulter.go
generated
vendored
Normal file
@@ -0,0 +1,828 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 generators
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"k8s.io/gengo/args"
|
||||
"k8s.io/gengo/generator"
|
||||
"k8s.io/gengo/namer"
|
||||
"k8s.io/gengo/types"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// CustomArgs is used tby the go2idl framework to pass args specific to this
|
||||
// generator.
|
||||
type CustomArgs struct {
|
||||
ExtraPeerDirs []string // Always consider these as last-ditch possibilities for conversions.
|
||||
}
|
||||
|
||||
// These are the comment tags that carry parameters for defaulter generation.
|
||||
const tagName = "k8s:defaulter-gen"
|
||||
const intputTagName = "k8s:defaulter-gen-input"
|
||||
|
||||
func extractTag(comments []string) []string {
|
||||
return types.ExtractCommentTags("+", comments)[tagName]
|
||||
}
|
||||
|
||||
func extractInputTag(comments []string) []string {
|
||||
return types.ExtractCommentTags("+", comments)[intputTagName]
|
||||
}
|
||||
|
||||
func checkTag(comments []string, require ...string) bool {
|
||||
values := types.ExtractCommentTags("+", comments)[tagName]
|
||||
if len(require) == 0 {
|
||||
return len(values) == 1 && values[0] == ""
|
||||
}
|
||||
return reflect.DeepEqual(values, require)
|
||||
}
|
||||
|
||||
func defaultFnNamer() *namer.NameStrategy {
|
||||
return &namer.NameStrategy{
|
||||
Prefix: "SetDefaults_",
|
||||
Join: func(pre string, in []string, post string) string {
|
||||
return pre + strings.Join(in, "_") + post
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func objectDefaultFnNamer() *namer.NameStrategy {
|
||||
return &namer.NameStrategy{
|
||||
Prefix: "SetObjectDefaults_",
|
||||
Join: func(pre string, in []string, post string) string {
|
||||
return pre + strings.Join(in, "_") + post
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// NameSystems returns the name system used by the generators in this package.
|
||||
func NameSystems() namer.NameSystems {
|
||||
return namer.NameSystems{
|
||||
"public": namer.NewPublicNamer(1),
|
||||
"raw": namer.NewRawNamer("", nil),
|
||||
"defaultfn": defaultFnNamer(),
|
||||
"objectdefaultfn": objectDefaultFnNamer(),
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultNameSystem returns the default name system for ordering the types to be
|
||||
// processed by the generators in this package.
|
||||
func DefaultNameSystem() string {
|
||||
return "public"
|
||||
}
|
||||
|
||||
// defaults holds the declared defaulting functions for a given type (all defaulting functions
|
||||
// are expected to be func(1))
|
||||
type defaults struct {
|
||||
// object is the defaulter function for a top level type (typically one with TypeMeta) that
|
||||
// invokes all child defaulters. May be nil if the object defaulter has not yet been generated.
|
||||
object *types.Type
|
||||
// base is a defaulter function defined for a type SetDefaults_Pod which does not invoke all
|
||||
// child defaults - the base defaulter alone is insufficient to default a type
|
||||
base *types.Type
|
||||
// additional is zero or more defaulter functions of the form SetDefaults_Pod_XXXX that can be
|
||||
// included in the Object defaulter.
|
||||
additional []*types.Type
|
||||
}
|
||||
|
||||
// All of the types in conversions map are of type "DeclarationOf" with
|
||||
// the underlying type being "Func".
|
||||
type defaulterFuncMap map[*types.Type]defaults
|
||||
|
||||
// Returns all manually-defined defaulting functions in the package.
|
||||
func getManualDefaultingFunctions(context *generator.Context, pkg *types.Package, manualMap defaulterFuncMap) {
|
||||
buffer := &bytes.Buffer{}
|
||||
sw := generator.NewSnippetWriter(buffer, context, "$", "$")
|
||||
|
||||
for _, f := range pkg.Functions {
|
||||
if f.Underlying == nil || f.Underlying.Kind != types.Func {
|
||||
glog.Errorf("Malformed function: %#v", f)
|
||||
continue
|
||||
}
|
||||
if f.Underlying.Signature == nil {
|
||||
glog.Errorf("Function without signature: %#v", f)
|
||||
continue
|
||||
}
|
||||
signature := f.Underlying.Signature
|
||||
// Check whether the function is defaulting function.
|
||||
// Note that all of them have signature:
|
||||
// object: func SetObjectDefaults_inType(*inType)
|
||||
// base: func SetDefaults_inType(*inType)
|
||||
// additional: func SetDefaults_inType_Qualifier(*inType)
|
||||
if signature.Receiver != nil {
|
||||
continue
|
||||
}
|
||||
if len(signature.Parameters) != 1 {
|
||||
continue
|
||||
}
|
||||
if len(signature.Results) != 0 {
|
||||
continue
|
||||
}
|
||||
inType := signature.Parameters[0]
|
||||
if inType.Kind != types.Pointer {
|
||||
continue
|
||||
}
|
||||
// Check if this is the primary defaulter.
|
||||
args := defaultingArgsFromType(inType.Elem)
|
||||
sw.Do("$.inType|defaultfn$", args)
|
||||
switch {
|
||||
case f.Name.Name == buffer.String():
|
||||
key := inType.Elem
|
||||
// We might scan the same package twice, and that's OK.
|
||||
v, ok := manualMap[key]
|
||||
if ok && v.base != nil && v.base.Name.Package != pkg.Path {
|
||||
panic(fmt.Sprintf("duplicate static defaulter defined: %#v", key))
|
||||
}
|
||||
v.base = f
|
||||
manualMap[key] = v
|
||||
glog.V(6).Infof("found base defaulter function for %s from %s", key.Name, f.Name)
|
||||
// Is one of the additional defaulters - a top level defaulter on a type that is
|
||||
// also invoked.
|
||||
case strings.HasPrefix(f.Name.Name, buffer.String()+"_"):
|
||||
key := inType.Elem
|
||||
v, ok := manualMap[key]
|
||||
if ok {
|
||||
exists := false
|
||||
for _, existing := range v.additional {
|
||||
if existing.Name == f.Name {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if exists {
|
||||
continue
|
||||
}
|
||||
}
|
||||
v.additional = append(v.additional, f)
|
||||
manualMap[key] = v
|
||||
glog.V(6).Infof("found additional defaulter function for %s from %s", key.Name, f.Name)
|
||||
}
|
||||
buffer.Reset()
|
||||
sw.Do("$.inType|objectdefaultfn$", args)
|
||||
if f.Name.Name == buffer.String() {
|
||||
key := inType.Elem
|
||||
// We might scan the same package twice, and that's OK.
|
||||
v, ok := manualMap[key]
|
||||
if ok && v.base != nil && v.base.Name.Package != pkg.Path {
|
||||
panic(fmt.Sprintf("duplicate static defaulter defined: %#v", key))
|
||||
}
|
||||
v.object = f
|
||||
manualMap[key] = v
|
||||
glog.V(6).Infof("found object defaulter function for %s from %s", key.Name, f.Name)
|
||||
}
|
||||
buffer.Reset()
|
||||
}
|
||||
}
|
||||
|
||||
func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
|
||||
boilerplate, err := arguments.LoadGoBoilerplate()
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed loading boilerplate: %v", err)
|
||||
}
|
||||
|
||||
packages := generator.Packages{}
|
||||
header := append([]byte(fmt.Sprintf("// +build !%s\n\n", arguments.GeneratedBuildTag)), boilerplate...)
|
||||
|
||||
// Accumulate pre-existing default functions.
|
||||
// TODO: This is too ad-hoc. We need a better way.
|
||||
existingDefaulters := defaulterFuncMap{}
|
||||
|
||||
buffer := &bytes.Buffer{}
|
||||
sw := generator.NewSnippetWriter(buffer, context, "$", "$")
|
||||
|
||||
// We are generating defaults only for packages that are explicitly
|
||||
// passed as InputDir.
|
||||
for _, i := range context.Inputs {
|
||||
glog.V(5).Infof("considering pkg %q", i)
|
||||
pkg := context.Universe[i]
|
||||
if pkg == nil {
|
||||
// If the input had no Go files, for example.
|
||||
continue
|
||||
}
|
||||
// typesPkg is where the types that needs defaulter are defined.
|
||||
// Sometimes it is different from pkg. For example, kubernetes core/v1
|
||||
// types are defined in vendor/k8s.io/api/core/v1, while pkg is at
|
||||
// pkg/api/v1.
|
||||
typesPkg := pkg
|
||||
|
||||
// Add defaulting functions.
|
||||
getManualDefaultingFunctions(context, pkg, existingDefaulters)
|
||||
|
||||
var peerPkgs []string
|
||||
if customArgs, ok := arguments.CustomArgs.(*CustomArgs); ok {
|
||||
for _, pkg := range customArgs.ExtraPeerDirs {
|
||||
if i := strings.Index(pkg, "/vendor/"); i != -1 {
|
||||
pkg = pkg[i+len("/vendor/"):]
|
||||
}
|
||||
peerPkgs = append(peerPkgs, pkg)
|
||||
}
|
||||
}
|
||||
// Make sure our peer-packages are added and fully parsed.
|
||||
for _, pp := range peerPkgs {
|
||||
context.AddDir(pp)
|
||||
getManualDefaultingFunctions(context, context.Universe[pp], existingDefaulters)
|
||||
}
|
||||
|
||||
typesWith := extractTag(pkg.Comments)
|
||||
shouldCreateObjectDefaulterFn := func(t *types.Type) bool {
|
||||
if defaults, ok := existingDefaulters[t]; ok && defaults.object != nil {
|
||||
// A default generator is defined
|
||||
glog.V(5).Infof(" an object defaulter already exists as %s", defaults.base.Name)
|
||||
return false
|
||||
}
|
||||
// opt-out
|
||||
if checkTag(t.SecondClosestCommentLines, "false") {
|
||||
return false
|
||||
}
|
||||
// opt-in
|
||||
if checkTag(t.SecondClosestCommentLines, "true") {
|
||||
return true
|
||||
}
|
||||
// For every k8s:defaulter-gen tag at the package level, interpret the value as a
|
||||
// field name (like TypeMeta, ListMeta, ObjectMeta) and trigger defaulter generation
|
||||
// for any type with any of the matching field names. Provides a more useful package
|
||||
// level defaulting than global (because we only need defaulters on a subset of objects -
|
||||
// usually those with TypeMeta).
|
||||
if t.Kind == types.Struct && len(typesWith) > 0 {
|
||||
for _, field := range t.Members {
|
||||
for _, s := range typesWith {
|
||||
if field.Name == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// if the types are not in the same package where the defaulter functions to be generated
|
||||
inputTags := extractInputTag(pkg.Comments)
|
||||
if len(inputTags) > 1 {
|
||||
panic(fmt.Sprintf("there could only be one input tag, got %#v", inputTags))
|
||||
}
|
||||
if len(inputTags) == 1 {
|
||||
var err error
|
||||
typesPkg, err = context.AddDirectory(filepath.Join(pkg.Path, inputTags[0]))
|
||||
if err != nil {
|
||||
glog.Fatalf("cannot import package %s", inputTags[0])
|
||||
}
|
||||
// update context.Order to the latest context.Universe
|
||||
orderer := namer.Orderer{Namer: namer.NewPublicNamer(1)}
|
||||
context.Order = orderer.OrderUniverse(context.Universe)
|
||||
}
|
||||
|
||||
newDefaulters := defaulterFuncMap{}
|
||||
for _, t := range typesPkg.Types {
|
||||
if !shouldCreateObjectDefaulterFn(t) {
|
||||
continue
|
||||
}
|
||||
if namer.IsPrivateGoName(t.Name.Name) {
|
||||
// We won't be able to convert to a private type.
|
||||
glog.V(5).Infof(" found a type %v, but it is a private name", t)
|
||||
continue
|
||||
}
|
||||
|
||||
// create a synthetic type we can use during generation
|
||||
newDefaulters[t] = defaults{}
|
||||
}
|
||||
|
||||
// only generate defaulters for objects that actually have defined defaulters
|
||||
// prevents empty defaulters from being registered
|
||||
for {
|
||||
promoted := 0
|
||||
for t, d := range newDefaulters {
|
||||
if d.object != nil {
|
||||
continue
|
||||
}
|
||||
if newCallTreeForType(existingDefaulters, newDefaulters).build(t, true) != nil {
|
||||
args := defaultingArgsFromType(t)
|
||||
sw.Do("$.inType|objectdefaultfn$", args)
|
||||
newDefaulters[t] = defaults{
|
||||
object: &types.Type{
|
||||
Name: types.Name{
|
||||
Package: pkg.Path,
|
||||
Name: buffer.String(),
|
||||
},
|
||||
Kind: types.Func,
|
||||
},
|
||||
}
|
||||
buffer.Reset()
|
||||
promoted++
|
||||
}
|
||||
}
|
||||
if promoted != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// prune any types that were not used
|
||||
for t, d := range newDefaulters {
|
||||
if d.object == nil {
|
||||
glog.V(6).Infof("did not generate defaulter for %s because no child defaulters were registered", t.Name)
|
||||
delete(newDefaulters, t)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if len(newDefaulters) == 0 {
|
||||
glog.V(5).Infof("no defaulters in package %s", pkg.Name)
|
||||
}
|
||||
|
||||
path := pkg.Path
|
||||
// if the source path is within a /vendor/ directory (for example,
|
||||
// k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1), allow
|
||||
// generation to output to the proper relative path (under vendor).
|
||||
// Otherwise, the generator will create the file in the wrong location
|
||||
// in the output directory.
|
||||
// TODO: build a more fundamental concept in gengo for dealing with modifications
|
||||
// to vendored packages.
|
||||
if strings.HasPrefix(pkg.SourcePath, arguments.OutputBase) {
|
||||
expandedPath := strings.TrimPrefix(pkg.SourcePath, arguments.OutputBase)
|
||||
if strings.Contains(expandedPath, "/vendor/") {
|
||||
path = expandedPath
|
||||
}
|
||||
}
|
||||
|
||||
packages = append(packages,
|
||||
&generator.DefaultPackage{
|
||||
PackageName: filepath.Base(pkg.Path),
|
||||
PackagePath: path,
|
||||
HeaderText: header,
|
||||
GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
|
||||
return []generator.Generator{
|
||||
NewGenDefaulter(arguments.OutputFileBaseName, typesPkg.Path, pkg.Path, existingDefaulters, newDefaulters, peerPkgs),
|
||||
}
|
||||
},
|
||||
FilterFunc: func(c *generator.Context, t *types.Type) bool {
|
||||
return t.Name.Package == typesPkg.Path
|
||||
},
|
||||
})
|
||||
}
|
||||
return packages
|
||||
}
|
||||
|
||||
// callTreeForType contains fields necessary to build a tree for types.
|
||||
type callTreeForType struct {
|
||||
existingDefaulters defaulterFuncMap
|
||||
newDefaulters defaulterFuncMap
|
||||
currentlyBuildingTypes map[*types.Type]bool
|
||||
}
|
||||
|
||||
func newCallTreeForType(existingDefaulters, newDefaulters defaulterFuncMap) *callTreeForType {
|
||||
return &callTreeForType{
|
||||
existingDefaulters: existingDefaulters,
|
||||
newDefaulters: newDefaulters,
|
||||
currentlyBuildingTypes: make(map[*types.Type]bool),
|
||||
}
|
||||
}
|
||||
|
||||
// build creates a tree of paths to fields (based on how they would be accessed in Go - pointer, elem,
|
||||
// slice, or key) and the functions that should be invoked on each field. An in-order traversal of the resulting tree
|
||||
// can be used to generate a Go function that invokes each nested function on the appropriate type. The return
|
||||
// value may be nil if there are no functions to call on type or the type is a primitive (Defaulters can only be
|
||||
// invoked on structs today). When root is true this function will not use a newDefaulter. existingDefaulters should
|
||||
// contain all defaulting functions by type defined in code - newDefaulters should contain all object defaulters
|
||||
// that could be or will be generated. If newDefaulters has an entry for a type, but the 'object' field is nil,
|
||||
// this function skips adding that defaulter - this allows us to avoid generating object defaulter functions for
|
||||
// list types that call empty defaulters.
|
||||
func (c *callTreeForType) build(t *types.Type, root bool) *callNode {
|
||||
parent := &callNode{}
|
||||
|
||||
if root {
|
||||
// the root node is always a pointer
|
||||
parent.elem = true
|
||||
}
|
||||
|
||||
defaults, _ := c.existingDefaulters[t]
|
||||
newDefaults, generated := c.newDefaulters[t]
|
||||
switch {
|
||||
case !root && generated && newDefaults.object != nil:
|
||||
parent.call = append(parent.call, newDefaults.object)
|
||||
// if we will be generating the defaulter, it by definition is a covering
|
||||
// defaulter, so we halt recursion
|
||||
glog.V(6).Infof("the defaulter %s will be generated as an object defaulter", t.Name)
|
||||
return parent
|
||||
|
||||
case defaults.object != nil:
|
||||
// object defaulters are always covering
|
||||
parent.call = append(parent.call, defaults.object)
|
||||
return parent
|
||||
|
||||
case defaults.base != nil:
|
||||
parent.call = append(parent.call, defaults.base)
|
||||
// if the base function indicates it "covers" (it already includes defaulters)
|
||||
// we can halt recursion
|
||||
if checkTag(defaults.base.CommentLines, "covers") {
|
||||
glog.V(6).Infof("the defaulter %s indicates it covers all sub generators", t.Name)
|
||||
return parent
|
||||
}
|
||||
}
|
||||
|
||||
// base has been added already, now add any additional defaulters defined for this object
|
||||
parent.call = append(parent.call, defaults.additional...)
|
||||
|
||||
// if the type already exists, don't build the tree for it and don't generate anything.
|
||||
// This is used to avoid recursion for nested recursive types.
|
||||
if c.currentlyBuildingTypes[t] {
|
||||
return nil
|
||||
}
|
||||
// if type doesn't exist, mark it as existing
|
||||
c.currentlyBuildingTypes[t] = true
|
||||
|
||||
defer func() {
|
||||
// The type will now acts as a parent, not a nested recursive type.
|
||||
// We can now build the tree for it safely.
|
||||
c.currentlyBuildingTypes[t] = false
|
||||
}()
|
||||
|
||||
switch t.Kind {
|
||||
case types.Pointer:
|
||||
if child := c.build(t.Elem, false); child != nil {
|
||||
child.elem = true
|
||||
parent.children = append(parent.children, *child)
|
||||
}
|
||||
case types.Slice, types.Array:
|
||||
if child := c.build(t.Elem, false); child != nil {
|
||||
child.index = true
|
||||
if t.Elem.Kind == types.Pointer {
|
||||
child.elem = true
|
||||
}
|
||||
parent.children = append(parent.children, *child)
|
||||
}
|
||||
case types.Map:
|
||||
if child := c.build(t.Elem, false); child != nil {
|
||||
child.key = true
|
||||
parent.children = append(parent.children, *child)
|
||||
}
|
||||
case types.Struct:
|
||||
for _, field := range t.Members {
|
||||
name := field.Name
|
||||
if len(name) == 0 {
|
||||
if field.Type.Kind == types.Pointer {
|
||||
name = field.Type.Elem.Name.Name
|
||||
} else {
|
||||
name = field.Type.Name.Name
|
||||
}
|
||||
}
|
||||
if child := c.build(field.Type, false); child != nil {
|
||||
child.field = name
|
||||
parent.children = append(parent.children, *child)
|
||||
}
|
||||
}
|
||||
case types.Alias:
|
||||
if child := c.build(t.Underlying, false); child != nil {
|
||||
parent.children = append(parent.children, *child)
|
||||
}
|
||||
}
|
||||
if len(parent.children) == 0 && len(parent.call) == 0 {
|
||||
//glog.V(6).Infof("decided type %s needs no generation", t.Name)
|
||||
return nil
|
||||
}
|
||||
return parent
|
||||
}
|
||||
|
||||
const (
|
||||
runtimePackagePath = "k8s.io/apimachinery/pkg/runtime"
|
||||
conversionPackagePath = "k8s.io/apimachinery/pkg/conversion"
|
||||
)
|
||||
|
||||
// genDefaulter produces a file with a autogenerated conversions.
|
||||
type genDefaulter struct {
|
||||
generator.DefaultGen
|
||||
typesPackage string
|
||||
outputPackage string
|
||||
peerPackages []string
|
||||
newDefaulters defaulterFuncMap
|
||||
existingDefaulters defaulterFuncMap
|
||||
imports namer.ImportTracker
|
||||
typesForInit []*types.Type
|
||||
}
|
||||
|
||||
func NewGenDefaulter(sanitizedName, typesPackage, outputPackage string, existingDefaulters, newDefaulters defaulterFuncMap, peerPkgs []string) generator.Generator {
|
||||
return &genDefaulter{
|
||||
DefaultGen: generator.DefaultGen{
|
||||
OptionalName: sanitizedName,
|
||||
},
|
||||
typesPackage: typesPackage,
|
||||
outputPackage: outputPackage,
|
||||
peerPackages: peerPkgs,
|
||||
newDefaulters: newDefaulters,
|
||||
existingDefaulters: existingDefaulters,
|
||||
imports: generator.NewImportTracker(),
|
||||
typesForInit: make([]*types.Type, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (g *genDefaulter) Namers(c *generator.Context) namer.NameSystems {
|
||||
// Have the raw namer for this file track what it imports.
|
||||
return namer.NameSystems{
|
||||
"raw": namer.NewRawNamer(g.outputPackage, g.imports),
|
||||
}
|
||||
}
|
||||
|
||||
func (g *genDefaulter) isOtherPackage(pkg string) bool {
|
||||
if pkg == g.outputPackage {
|
||||
return false
|
||||
}
|
||||
if strings.HasSuffix(pkg, `"`+g.outputPackage+`"`) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *genDefaulter) Filter(c *generator.Context, t *types.Type) bool {
|
||||
defaults, ok := g.newDefaulters[t]
|
||||
if !ok || defaults.object == nil {
|
||||
return false
|
||||
}
|
||||
g.typesForInit = append(g.typesForInit, t)
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *genDefaulter) Imports(c *generator.Context) (imports []string) {
|
||||
var importLines []string
|
||||
for _, singleImport := range g.imports.ImportLines() {
|
||||
if g.isOtherPackage(singleImport) {
|
||||
importLines = append(importLines, singleImport)
|
||||
}
|
||||
}
|
||||
return importLines
|
||||
}
|
||||
|
||||
func (g *genDefaulter) Init(c *generator.Context, w io.Writer) error {
|
||||
sw := generator.NewSnippetWriter(w, c, "$", "$")
|
||||
|
||||
scheme := c.Universe.Type(types.Name{Package: runtimePackagePath, Name: "Scheme"})
|
||||
schemePtr := &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: scheme,
|
||||
}
|
||||
sw.Do("// RegisterDefaults adds defaulters functions to the given scheme.\n", nil)
|
||||
sw.Do("// Public to allow building arbitrary schemes.\n", nil)
|
||||
sw.Do("// All generated defaulters are covering - they call all nested defaulters.\n", nil)
|
||||
sw.Do("func RegisterDefaults(scheme $.|raw$) error {\n", schemePtr)
|
||||
for _, t := range g.typesForInit {
|
||||
args := defaultingArgsFromType(t)
|
||||
sw.Do("scheme.AddTypeDefaultingFunc(&$.inType|raw${}, func(obj interface{}) { $.inType|objectdefaultfn$(obj.(*$.inType|raw$)) })\n", args)
|
||||
}
|
||||
sw.Do("return nil\n", nil)
|
||||
sw.Do("}\n\n", nil)
|
||||
return sw.Error()
|
||||
}
|
||||
|
||||
func (g *genDefaulter) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
|
||||
if _, ok := g.newDefaulters[t]; !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
glog.V(5).Infof("generating for type %v", t)
|
||||
|
||||
callTree := newCallTreeForType(g.existingDefaulters, g.newDefaulters).build(t, true)
|
||||
if callTree == nil {
|
||||
glog.V(5).Infof(" no defaulters defined")
|
||||
return nil
|
||||
}
|
||||
i := 0
|
||||
callTree.VisitInOrder(func(ancestors []*callNode, current *callNode) {
|
||||
if len(current.call) == 0 {
|
||||
return
|
||||
}
|
||||
path := callPath(append(ancestors, current))
|
||||
glog.V(5).Infof(" %d: %s", i, path)
|
||||
i++
|
||||
})
|
||||
|
||||
sw := generator.NewSnippetWriter(w, c, "$", "$")
|
||||
g.generateDefaulter(t, callTree, sw)
|
||||
return sw.Error()
|
||||
}
|
||||
|
||||
func defaultingArgsFromType(inType *types.Type) generator.Args {
|
||||
return generator.Args{
|
||||
"inType": inType,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *genDefaulter) generateDefaulter(inType *types.Type, callTree *callNode, sw *generator.SnippetWriter) {
|
||||
sw.Do("func $.inType|objectdefaultfn$(in *$.inType|raw$) {\n", defaultingArgsFromType(inType))
|
||||
callTree.WriteMethod("in", 0, nil, sw)
|
||||
sw.Do("}\n\n", nil)
|
||||
}
|
||||
|
||||
// callNode represents an entry in a tree of Go type accessors - the path from the root to a leaf represents
|
||||
// how in Go code an access would be performed. For example, if a defaulting function exists on a container
|
||||
// lifecycle hook, to invoke that defaulter correctly would require this Go code:
|
||||
//
|
||||
// for i := range pod.Spec.Containers {
|
||||
// o := &pod.Spec.Containers[i]
|
||||
// if o.LifecycleHook != nil {
|
||||
// SetDefaults_LifecycleHook(o.LifecycleHook)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// That would be represented by a call tree like:
|
||||
//
|
||||
// callNode
|
||||
// field: "Spec"
|
||||
// children:
|
||||
// - field: "Containers"
|
||||
// children:
|
||||
// - index: true
|
||||
// children:
|
||||
// - field: "LifecycleHook"
|
||||
// elem: true
|
||||
// call:
|
||||
// - SetDefaults_LifecycleHook
|
||||
//
|
||||
// which we can traverse to build that Go struct (you must call the field Spec, then Containers, then range over
|
||||
// that field, then check whether the LifecycleHook field is nil, before calling SetDefaults_LifecycleHook on
|
||||
// the pointer to that field).
|
||||
type callNode struct {
|
||||
// field is the name of the Go member to access
|
||||
field string
|
||||
// key is true if this is a map and we must range over the key and values
|
||||
key bool
|
||||
// index is true if this is a slice and we must range over the slice values
|
||||
index bool
|
||||
// elem is true if the previous elements refer to a pointer (typically just field)
|
||||
elem bool
|
||||
|
||||
// call is all of the functions that must be invoked on this particular node, in order
|
||||
call []*types.Type
|
||||
// children is the child call nodes that must also be traversed
|
||||
children []callNode
|
||||
}
|
||||
|
||||
// CallNodeVisitorFunc is a function for visiting a call tree. ancestors is the list of all parents
|
||||
// of this node to the root of the tree - will be empty at the root.
|
||||
type CallNodeVisitorFunc func(ancestors []*callNode, node *callNode)
|
||||
|
||||
func (n *callNode) VisitInOrder(fn CallNodeVisitorFunc) {
|
||||
n.visitInOrder(nil, fn)
|
||||
}
|
||||
|
||||
func (n *callNode) visitInOrder(ancestors []*callNode, fn CallNodeVisitorFunc) {
|
||||
fn(ancestors, n)
|
||||
ancestors = append(ancestors, n)
|
||||
for i := range n.children {
|
||||
n.children[i].visitInOrder(ancestors, fn)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
indexVariables = "ijklmnop"
|
||||
localVariables = "abcdefgh"
|
||||
)
|
||||
|
||||
// varsForDepth creates temporary variables guaranteed to be unique within lexical Go scopes
|
||||
// of this depth in a function. It uses canonical Go loop variables for the first 7 levels
|
||||
// and then resorts to uglier prefixes.
|
||||
func varsForDepth(depth int) (index, local string) {
|
||||
if depth > len(indexVariables) {
|
||||
index = fmt.Sprintf("i%d", depth)
|
||||
} else {
|
||||
index = indexVariables[depth : depth+1]
|
||||
}
|
||||
if depth > len(localVariables) {
|
||||
local = fmt.Sprintf("local%d", depth)
|
||||
} else {
|
||||
local = localVariables[depth : depth+1]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// writeCalls generates a list of function calls based on the calls field for the provided variable
|
||||
// name and pointer.
|
||||
func (n *callNode) writeCalls(varName string, isVarPointer bool, sw *generator.SnippetWriter) {
|
||||
accessor := varName
|
||||
if !isVarPointer {
|
||||
accessor = "&" + accessor
|
||||
}
|
||||
for _, fn := range n.call {
|
||||
sw.Do("$.fn|raw$($.var$)\n", generator.Args{
|
||||
"fn": fn,
|
||||
"var": accessor,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WriteMethod performs an in-order traversal of the calltree, generating loops and if blocks as necessary
|
||||
// to correctly turn the call tree into a method body that invokes all calls on all child nodes of the call tree.
|
||||
// Depth is used to generate local variables at the proper depth.
|
||||
func (n *callNode) WriteMethod(varName string, depth int, ancestors []*callNode, sw *generator.SnippetWriter) {
|
||||
// if len(n.call) > 0 {
|
||||
// sw.Do(fmt.Sprintf("// %s\n", callPath(append(ancestors, n)).String()), nil)
|
||||
// }
|
||||
|
||||
if len(n.field) > 0 {
|
||||
varName = varName + "." + n.field
|
||||
}
|
||||
|
||||
index, local := varsForDepth(depth)
|
||||
vars := generator.Args{
|
||||
"index": index,
|
||||
"local": local,
|
||||
"var": varName,
|
||||
}
|
||||
|
||||
isPointer := n.elem && !n.index
|
||||
if isPointer && len(ancestors) > 0 {
|
||||
sw.Do("if $.var$ != nil {\n", vars)
|
||||
}
|
||||
|
||||
switch {
|
||||
case n.index:
|
||||
sw.Do("for $.index$ := range $.var$ {\n", vars)
|
||||
if n.elem {
|
||||
sw.Do("$.local$ := $.var$[$.index$]\n", vars)
|
||||
} else {
|
||||
sw.Do("$.local$ := &$.var$[$.index$]\n", vars)
|
||||
}
|
||||
|
||||
n.writeCalls(local, true, sw)
|
||||
for i := range n.children {
|
||||
n.children[i].WriteMethod(local, depth+1, append(ancestors, n), sw)
|
||||
}
|
||||
sw.Do("}\n", nil)
|
||||
case n.key:
|
||||
default:
|
||||
n.writeCalls(varName, isPointer, sw)
|
||||
for i := range n.children {
|
||||
n.children[i].WriteMethod(varName, depth, append(ancestors, n), sw)
|
||||
}
|
||||
}
|
||||
|
||||
if isPointer && len(ancestors) > 0 {
|
||||
sw.Do("}\n", nil)
|
||||
}
|
||||
}
|
||||
|
||||
type callPath []*callNode
|
||||
|
||||
// String prints a representation of a callPath that roughly approximates what a Go accessor
|
||||
// would look like. Used for debugging only.
|
||||
func (path callPath) String() string {
|
||||
if len(path) == 0 {
|
||||
return "<none>"
|
||||
}
|
||||
var parts []string
|
||||
for _, p := range path {
|
||||
last := len(parts) - 1
|
||||
switch {
|
||||
case p.elem:
|
||||
if len(parts) > 0 {
|
||||
parts[last] = "*" + parts[last]
|
||||
} else {
|
||||
parts = append(parts, "*")
|
||||
}
|
||||
case p.index:
|
||||
if len(parts) > 0 {
|
||||
parts[last] = parts[last] + "[i]"
|
||||
} else {
|
||||
parts = append(parts, "[i]")
|
||||
}
|
||||
case p.key:
|
||||
if len(parts) > 0 {
|
||||
parts[last] = parts[last] + "[key]"
|
||||
} else {
|
||||
parts = append(parts, "[key]")
|
||||
}
|
||||
default:
|
||||
if len(p.field) > 0 {
|
||||
parts = append(parts, p.field)
|
||||
} else {
|
||||
parts = append(parts, "<root>")
|
||||
}
|
||||
}
|
||||
}
|
||||
var calls []string
|
||||
for _, fn := range path[len(path)-1].call {
|
||||
calls = append(calls, fn.Name.String())
|
||||
}
|
||||
if len(calls) == 0 {
|
||||
calls = append(calls, "<none>")
|
||||
}
|
||||
|
||||
return strings.Join(parts, ".") + " calls " + strings.Join(calls, ", ")
|
||||
}
|
75
vendor/k8s.io/gengo/examples/defaulter-gen/main.go
generated
vendored
Normal file
75
vendor/k8s.io/gengo/examples/defaulter-gen/main.go
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// defaulter-gen is a tool for auto-generating Defaulter functions.
|
||||
//
|
||||
// Given a list of input directories, it will scan for top level types
|
||||
// and generate efficient defaulters for an entire object from the sum
|
||||
// of the SetDefault_* methods contained in the object tree.
|
||||
//
|
||||
// Generation is governed by comment tags in the source. Any package may
|
||||
// request defaulter generation by including one or more comment tags at
|
||||
// the package comment level:
|
||||
//
|
||||
// // +k8s:defaulter-gen=<field-name-to-flag>
|
||||
//
|
||||
// which will create defaulters for any type that contains the provided
|
||||
// field name (if the type has defaulters). Any type may request explicit
|
||||
// defaulting by providing the comment tag:
|
||||
//
|
||||
// // +k8s:defaulter-gen=true|false
|
||||
//
|
||||
// An existing defaulter method (`SetDefaults_TYPE`) can provide the
|
||||
// comment tag:
|
||||
//
|
||||
// // +k8s:defaulter-gen=covers
|
||||
//
|
||||
// to indicate that the defaulter does not or should not call any nested
|
||||
// defaulters.
|
||||
package main
|
||||
|
||||
import (
|
||||
"k8s.io/gengo/args"
|
||||
"k8s.io/gengo/examples/defaulter-gen/generators"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func main() {
|
||||
arguments := args.Default()
|
||||
|
||||
// Override defaults.
|
||||
arguments.OutputFileBaseName = "defaulter_generated"
|
||||
|
||||
// Custom args.
|
||||
customArgs := &generators.CustomArgs{
|
||||
ExtraPeerDirs: []string{},
|
||||
}
|
||||
pflag.CommandLine.StringSliceVar(&customArgs.ExtraPeerDirs, "extra-peer-dirs", customArgs.ExtraPeerDirs,
|
||||
"Comma-separated list of import paths which are considered, after tag-specified peers, for conversions.")
|
||||
arguments.CustomArgs = customArgs
|
||||
|
||||
// Run it.
|
||||
if err := arguments.Execute(
|
||||
generators.NameSystems(),
|
||||
generators.DefaultNameSystem(),
|
||||
generators.Packages,
|
||||
); err != nil {
|
||||
glog.Fatalf("Error: %v", err)
|
||||
}
|
||||
glog.V(2).Info("Completed successfully.")
|
||||
}
|
1
vendor/k8s.io/gengo/examples/go-to-protobuf/.gitignore
generated
vendored
Normal file
1
vendor/k8s.io/gengo/examples/go-to-protobuf/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
go-to-protobuf
|
11
vendor/k8s.io/gengo/examples/go-to-protobuf/.import-restrictions
generated
vendored
Normal file
11
vendor/k8s.io/gengo/examples/go-to-protobuf/.import-restrictions
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"Rules": [
|
||||
{
|
||||
"SelectorRegexp": "k8s[.]io",
|
||||
"AllowedPrefixes": [
|
||||
"k8s.io/gengo",
|
||||
"k8s.io/kubernetes/third_party/forked/golang"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
2
vendor/k8s.io/gengo/examples/go-to-protobuf/OWNERS
generated
vendored
Normal file
2
vendor/k8s.io/gengo/examples/go-to-protobuf/OWNERS
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
approvers:
|
||||
- smarterclayton
|
24
vendor/k8s.io/gengo/examples/go-to-protobuf/build-image/Dockerfile
generated
vendored
Normal file
24
vendor/k8s.io/gengo/examples/go-to-protobuf/build-image/Dockerfile
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# Copyright 2016 The Kubernetes Authors.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# This file creates a standard build environment for building Kubernetes
|
||||
FROM k8s.gcr.io/kube-cross:KUBE_BUILD_IMAGE_CROSS_TAG
|
||||
|
||||
# Mark this as a kube-build container
|
||||
RUN touch /kube-build-image
|
||||
|
||||
WORKDIR /go/src/k8s.io/kubernetes
|
||||
|
||||
# Install goimports tool
|
||||
RUN go get golang.org/x/tools/cmd/goimports
|
36
vendor/k8s.io/gengo/examples/go-to-protobuf/main.go
generated
vendored
Normal file
36
vendor/k8s.io/gengo/examples/go-to-protobuf/main.go
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// go-to-protobuf generates a Protobuf IDL from a Go struct, respecting any
|
||||
// existing IDL tags on the Go struct.
|
||||
package main
|
||||
|
||||
import (
|
||||
"k8s.io/gengo/examples/go-to-protobuf/protobuf"
|
||||
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
var g = protobuf.New()
|
||||
|
||||
func init() {
|
||||
g.BindFlags(flag.CommandLine)
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
protobuf.Run(g)
|
||||
}
|
306
vendor/k8s.io/gengo/examples/go-to-protobuf/protobuf/cmd.go
generated
vendored
Normal file
306
vendor/k8s.io/gengo/examples/go-to-protobuf/protobuf/cmd.go
generated
vendored
Normal file
@@ -0,0 +1,306 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// go-to-protobuf generates a Protobuf IDL from a Go struct, respecting any
|
||||
// existing IDL tags on the Go struct.
|
||||
package protobuf
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"k8s.io/gengo/args"
|
||||
"k8s.io/gengo/generator"
|
||||
"k8s.io/gengo/namer"
|
||||
"k8s.io/gengo/parser"
|
||||
"k8s.io/gengo/types"
|
||||
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
type Generator struct {
|
||||
Common args.GeneratorArgs
|
||||
Packages string
|
||||
OutputBase string
|
||||
ProtoImport []string
|
||||
Conditional string
|
||||
Clean bool
|
||||
OnlyIDL bool
|
||||
KeepGogoproto bool
|
||||
SkipGeneratedRewrite bool
|
||||
DropEmbeddedFields string
|
||||
}
|
||||
|
||||
func New() *Generator {
|
||||
sourceTree := args.DefaultSourceTree()
|
||||
common := args.GeneratorArgs{
|
||||
OutputBase: sourceTree,
|
||||
GoHeaderFilePath: filepath.Join(sourceTree, "k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt"),
|
||||
}
|
||||
defaultProtoImport := filepath.Join(sourceTree, "k8s.io", "kubernetes", "vendor", "github.com", "gogo", "protobuf", "protobuf")
|
||||
return &Generator{
|
||||
Common: common,
|
||||
OutputBase: sourceTree,
|
||||
ProtoImport: []string{defaultProtoImport},
|
||||
Packages: strings.Join([]string{
|
||||
`+k8s.io/kubernetes/pkg/util/intstr`,
|
||||
`+k8s.io/kubernetes/pkg/api/resource`,
|
||||
`+k8s.io/kubernetes/pkg/runtime`,
|
||||
`+k8s.io/kubernetes/pkg/watch/versioned`,
|
||||
`k8s.io/kubernetes/pkg/api/unversioned`,
|
||||
`k8s.io/kubernetes/pkg/api/v1`,
|
||||
`k8s.io/kubernetes/pkg/apis/policy/v1alpha1`,
|
||||
`k8s.io/kubernetes/pkg/apis/extensions/v1beta1`,
|
||||
`k8s.io/kubernetes/pkg/apis/autoscaling/v1`,
|
||||
`k8s.io/kubernetes/pkg/apis/authorization/v1beta1`,
|
||||
`k8s.io/kubernetes/pkg/apis/batch/v1`,
|
||||
`k8s.io/kubernetes/pkg/apis/batch/v2alpha1`,
|
||||
`k8s.io/kubernetes/pkg/apis/apps/v1alpha1`,
|
||||
`k8s.io/kubernetes/pkg/apis/authentication/v1beta1`,
|
||||
`k8s.io/kubernetes/pkg/apis/rbac/v1alpha1`,
|
||||
`k8s.io/kubernetes/federation/apis/federation/v1beta1`,
|
||||
`k8s.io/kubernetes/pkg/apis/certificates/v1alpha1`,
|
||||
`k8s.io/kubernetes/pkg/apis/imagepolicy/v1alpha1`,
|
||||
}, ","),
|
||||
DropEmbeddedFields: "k8s.io/kubernetes/pkg/api/unversioned.TypeMeta",
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Generator) BindFlags(flag *flag.FlagSet) {
|
||||
flag.StringVarP(&g.Common.GoHeaderFilePath, "go-header-file", "h", g.Common.GoHeaderFilePath, "File containing boilerplate header text. The string YEAR will be replaced with the current 4-digit year.")
|
||||
flag.BoolVar(&g.Common.VerifyOnly, "verify-only", g.Common.VerifyOnly, "If true, only verify existing output, do not write anything.")
|
||||
flag.StringVarP(&g.Packages, "packages", "p", g.Packages, "comma-separated list of directories to get input types from. Directories prefixed with '-' are not generated, directories prefixed with '+' only create types with explicit IDL instructions.")
|
||||
flag.StringVarP(&g.OutputBase, "output-base", "o", g.OutputBase, "Output base; defaults to $GOPATH/src/")
|
||||
flag.StringSliceVar(&g.ProtoImport, "proto-import", g.ProtoImport, "The search path for the core protobuf .protos, required, defaults to GODEPS on path.")
|
||||
flag.StringVar(&g.Conditional, "conditional", g.Conditional, "An optional Golang build tag condition to add to the generated Go code")
|
||||
flag.BoolVar(&g.Clean, "clean", g.Clean, "If true, remove all generated files for the specified Packages.")
|
||||
flag.BoolVar(&g.OnlyIDL, "only-idl", g.OnlyIDL, "If true, only generate the IDL for each package.")
|
||||
flag.BoolVar(&g.KeepGogoproto, "keep-gogoproto", g.KeepGogoproto, "If true, the generated IDL will contain gogoprotobuf extensions which are normally removed")
|
||||
flag.BoolVar(&g.SkipGeneratedRewrite, "skip-generated-rewrite", g.SkipGeneratedRewrite, "If true, skip fixing up the generated.pb.go file (debugging only).")
|
||||
flag.StringVar(&g.DropEmbeddedFields, "drop-embedded-fields", g.DropEmbeddedFields, "Comma-delimited list of embedded Go types to omit from generated protobufs")
|
||||
}
|
||||
|
||||
func Run(g *Generator) {
|
||||
if g.Common.VerifyOnly {
|
||||
g.OnlyIDL = true
|
||||
g.Clean = false
|
||||
}
|
||||
|
||||
b := parser.New()
|
||||
b.AddBuildTags("proto")
|
||||
|
||||
omitTypes := map[types.Name]struct{}{}
|
||||
for _, t := range strings.Split(g.DropEmbeddedFields, ",") {
|
||||
name := types.Name{}
|
||||
if i := strings.LastIndex(t, "."); i != -1 {
|
||||
name.Package, name.Name = t[:i], t[i+1:]
|
||||
} else {
|
||||
name.Name = t
|
||||
}
|
||||
if len(name.Name) == 0 {
|
||||
log.Fatalf("--drop-embedded-types requires names in the form of [GOPACKAGE.]TYPENAME: %v", t)
|
||||
}
|
||||
omitTypes[name] = struct{}{}
|
||||
}
|
||||
|
||||
boilerplate, err := g.Common.LoadGoBoilerplate()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed loading boilerplate: %v", err)
|
||||
}
|
||||
|
||||
protobufNames := NewProtobufNamer()
|
||||
outputPackages := generator.Packages{}
|
||||
for _, d := range strings.Split(g.Packages, ",") {
|
||||
generateAllTypes, outputPackage := true, true
|
||||
switch {
|
||||
case strings.HasPrefix(d, "+"):
|
||||
d = d[1:]
|
||||
generateAllTypes = false
|
||||
case strings.HasPrefix(d, "-"):
|
||||
d = d[1:]
|
||||
outputPackage = false
|
||||
}
|
||||
name := protoSafePackage(d)
|
||||
parts := strings.SplitN(d, "=", 2)
|
||||
if len(parts) > 1 {
|
||||
d = parts[0]
|
||||
name = parts[1]
|
||||
}
|
||||
p := newProtobufPackage(d, name, generateAllTypes, omitTypes)
|
||||
header := append([]byte{}, boilerplate...)
|
||||
header = append(header, p.HeaderText...)
|
||||
p.HeaderText = header
|
||||
protobufNames.Add(p)
|
||||
if outputPackage {
|
||||
outputPackages = append(outputPackages, p)
|
||||
}
|
||||
}
|
||||
|
||||
if !g.Common.VerifyOnly {
|
||||
for _, p := range outputPackages {
|
||||
if err := p.(*protobufPackage).Clean(g.OutputBase); err != nil {
|
||||
log.Fatalf("Unable to clean package %s: %v", p.Name(), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if g.Clean {
|
||||
return
|
||||
}
|
||||
|
||||
for _, p := range protobufNames.List() {
|
||||
if err := b.AddDir(p.Path()); err != nil {
|
||||
log.Fatalf("Unable to add directory %q: %v", p.Path(), err)
|
||||
}
|
||||
}
|
||||
|
||||
c, err := generator.NewContext(
|
||||
b,
|
||||
namer.NameSystems{
|
||||
"public": namer.NewPublicNamer(3),
|
||||
"proto": protobufNames,
|
||||
},
|
||||
"public",
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed making a context: %v", err)
|
||||
}
|
||||
|
||||
c.Verify = g.Common.VerifyOnly
|
||||
c.FileTypes["protoidl"] = NewProtoFile()
|
||||
|
||||
if err := protobufNames.AssignTypesToPackages(c); err != nil {
|
||||
log.Fatalf("Failed to identify Common types: %v", err)
|
||||
}
|
||||
|
||||
if err := c.ExecutePackages(g.OutputBase, outputPackages); err != nil {
|
||||
log.Fatalf("Failed executing generator: %v", err)
|
||||
}
|
||||
|
||||
if g.OnlyIDL {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := exec.LookPath("protoc"); err != nil {
|
||||
log.Fatalf("Unable to find 'protoc': %v", err)
|
||||
}
|
||||
|
||||
searchArgs := []string{"-I", ".", "-I", g.OutputBase}
|
||||
if len(g.ProtoImport) != 0 {
|
||||
for _, s := range g.ProtoImport {
|
||||
searchArgs = append(searchArgs, "-I", s)
|
||||
}
|
||||
}
|
||||
args := append(searchArgs, fmt.Sprintf("--gogo_out=%s", g.OutputBase))
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
if len(g.Conditional) > 0 {
|
||||
fmt.Fprintf(buf, "// +build %s\n\n", g.Conditional)
|
||||
}
|
||||
buf.Write(boilerplate)
|
||||
|
||||
for _, outputPackage := range outputPackages {
|
||||
p := outputPackage.(*protobufPackage)
|
||||
|
||||
path := filepath.Join(g.OutputBase, p.ImportPath())
|
||||
outputPath := filepath.Join(g.OutputBase, p.OutputPath())
|
||||
|
||||
// generate the gogoprotobuf protoc
|
||||
cmd := exec.Command("protoc", append(args, path)...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if len(out) > 0 {
|
||||
log.Printf(string(out))
|
||||
}
|
||||
if err != nil {
|
||||
log.Println(strings.Join(cmd.Args, " "))
|
||||
log.Fatalf("Unable to generate protoc on %s: %v", p.PackageName, err)
|
||||
}
|
||||
|
||||
if g.SkipGeneratedRewrite {
|
||||
continue
|
||||
}
|
||||
|
||||
// alter the generated protobuf file to remove the generated types (but leave the serializers) and rewrite the
|
||||
// package statement to match the desired package name
|
||||
if err := RewriteGeneratedGogoProtobufFile(outputPath, p.ExtractGeneratedType, p.OptionalTypeName, buf.Bytes()); err != nil {
|
||||
log.Fatalf("Unable to rewrite generated %s: %v", outputPath, err)
|
||||
}
|
||||
|
||||
// sort imports
|
||||
cmd = exec.Command("goimports", "-w", outputPath)
|
||||
out, err = cmd.CombinedOutput()
|
||||
if len(out) > 0 {
|
||||
log.Printf(string(out))
|
||||
}
|
||||
if err != nil {
|
||||
log.Println(strings.Join(cmd.Args, " "))
|
||||
log.Fatalf("Unable to rewrite imports for %s: %v", p.PackageName, err)
|
||||
}
|
||||
|
||||
// format and simplify the generated file
|
||||
cmd = exec.Command("gofmt", "-s", "-w", outputPath)
|
||||
out, err = cmd.CombinedOutput()
|
||||
if len(out) > 0 {
|
||||
log.Printf(string(out))
|
||||
}
|
||||
if err != nil {
|
||||
log.Println(strings.Join(cmd.Args, " "))
|
||||
log.Fatalf("Unable to apply gofmt for %s: %v", p.PackageName, err)
|
||||
}
|
||||
}
|
||||
|
||||
if g.SkipGeneratedRewrite {
|
||||
return
|
||||
}
|
||||
|
||||
if !g.KeepGogoproto {
|
||||
// generate, but do so without gogoprotobuf extensions
|
||||
for _, outputPackage := range outputPackages {
|
||||
p := outputPackage.(*protobufPackage)
|
||||
p.OmitGogo = true
|
||||
}
|
||||
if err := c.ExecutePackages(g.OutputBase, outputPackages); err != nil {
|
||||
log.Fatalf("Failed executing generator: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, outputPackage := range outputPackages {
|
||||
p := outputPackage.(*protobufPackage)
|
||||
|
||||
if len(p.StructTags) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
pattern := filepath.Join(g.OutputBase, p.PackagePath, "*.go")
|
||||
files, err := filepath.Glob(pattern)
|
||||
if err != nil {
|
||||
log.Fatalf("Can't glob pattern %q: %v", pattern, err)
|
||||
}
|
||||
|
||||
for _, s := range files {
|
||||
if strings.HasSuffix(s, "_test.go") {
|
||||
continue
|
||||
}
|
||||
if err := RewriteTypesWithProtobufStructTags(s, p.StructTags); err != nil {
|
||||
log.Fatalf("Unable to rewrite with struct tags %s: %v", s, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
762
vendor/k8s.io/gengo/examples/go-to-protobuf/protobuf/generator.go
generated
vendored
Normal file
762
vendor/k8s.io/gengo/examples/go-to-protobuf/protobuf/generator.go
generated
vendored
Normal file
@@ -0,0 +1,762 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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 protobuf
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/gengo/generator"
|
||||
"k8s.io/gengo/namer"
|
||||
"k8s.io/gengo/types"
|
||||
)
|
||||
|
||||
// genProtoIDL produces a .proto IDL.
|
||||
type genProtoIDL struct {
|
||||
generator.DefaultGen
|
||||
localPackage types.Name
|
||||
localGoPackage types.Name
|
||||
imports namer.ImportTracker
|
||||
|
||||
generateAll bool
|
||||
omitGogo bool
|
||||
omitFieldTypes map[types.Name]struct{}
|
||||
}
|
||||
|
||||
func (g *genProtoIDL) PackageVars(c *generator.Context) []string {
|
||||
if g.omitGogo {
|
||||
return []string{
|
||||
fmt.Sprintf("option go_package = %q;", g.localGoPackage.Name),
|
||||
}
|
||||
}
|
||||
return []string{
|
||||
"option (gogoproto.marshaler_all) = true;",
|
||||
"option (gogoproto.sizer_all) = true;",
|
||||
"option (gogoproto.goproto_stringer_all) = false;",
|
||||
"option (gogoproto.stringer_all) = true;",
|
||||
"option (gogoproto.unmarshaler_all) = true;",
|
||||
"option (gogoproto.goproto_unrecognized_all) = false;",
|
||||
"option (gogoproto.goproto_enum_prefix_all) = false;",
|
||||
"option (gogoproto.goproto_getters_all) = false;",
|
||||
fmt.Sprintf("option go_package = %q;", g.localGoPackage.Name),
|
||||
}
|
||||
}
|
||||
func (g *genProtoIDL) Filename() string { return g.OptionalName + ".proto" }
|
||||
func (g *genProtoIDL) FileType() string { return "protoidl" }
|
||||
func (g *genProtoIDL) Namers(c *generator.Context) namer.NameSystems {
|
||||
return namer.NameSystems{
|
||||
// The local namer returns the correct protobuf name for a proto type
|
||||
// in the context of a package
|
||||
"local": localNamer{g.localPackage},
|
||||
}
|
||||
}
|
||||
|
||||
// Filter ignores types that are identified as not exportable.
|
||||
func (g *genProtoIDL) Filter(c *generator.Context, t *types.Type) bool {
|
||||
tagVals := types.ExtractCommentTags("+", t.CommentLines)["protobuf"]
|
||||
if tagVals != nil {
|
||||
if tagVals[0] == "false" {
|
||||
// Type specified "false".
|
||||
return false
|
||||
}
|
||||
if tagVals[0] == "true" {
|
||||
// Type specified "true".
|
||||
return true
|
||||
}
|
||||
glog.Fatalf(`Comment tag "protobuf" must be true or false, found: %q`, tagVals[0])
|
||||
}
|
||||
if !g.generateAll {
|
||||
// We're not generating everything.
|
||||
return false
|
||||
}
|
||||
seen := map[*types.Type]bool{}
|
||||
ok := isProtoable(seen, t)
|
||||
return ok
|
||||
}
|
||||
|
||||
func isProtoable(seen map[*types.Type]bool, t *types.Type) bool {
|
||||
if seen[t] {
|
||||
// be optimistic in the case of type cycles.
|
||||
return true
|
||||
}
|
||||
seen[t] = true
|
||||
switch t.Kind {
|
||||
case types.Builtin:
|
||||
return true
|
||||
case types.Alias:
|
||||
return isProtoable(seen, t.Underlying)
|
||||
case types.Slice, types.Pointer:
|
||||
return isProtoable(seen, t.Elem)
|
||||
case types.Map:
|
||||
return isProtoable(seen, t.Key) && isProtoable(seen, t.Elem)
|
||||
case types.Struct:
|
||||
for _, m := range t.Members {
|
||||
if isProtoable(seen, m.Type) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
case types.Func, types.Chan:
|
||||
return false
|
||||
case types.DeclarationOf, types.Unknown, types.Unsupported:
|
||||
return false
|
||||
case types.Interface:
|
||||
return false
|
||||
default:
|
||||
log.Printf("WARNING: type %q is not portable: %s", t.Kind, t.Name)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// isOptionalAlias should return true if the specified type has an underlying type
|
||||
// (is an alias) of a map or slice and has the comment tag protobuf.nullable=true,
|
||||
// indicating that the type should be nullable in protobuf.
|
||||
func isOptionalAlias(t *types.Type) bool {
|
||||
if t.Underlying == nil || (t.Underlying.Kind != types.Map && t.Underlying.Kind != types.Slice) {
|
||||
return false
|
||||
}
|
||||
if extractBoolTagOrDie("protobuf.nullable", t.CommentLines) == false {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *genProtoIDL) Imports(c *generator.Context) (imports []string) {
|
||||
lines := []string{}
|
||||
// TODO: this could be expressed more cleanly
|
||||
for _, line := range g.imports.ImportLines() {
|
||||
if g.omitGogo && line == "github.com/gogo/protobuf/gogoproto/gogo.proto" {
|
||||
continue
|
||||
}
|
||||
lines = append(lines, line)
|
||||
}
|
||||
return lines
|
||||
}
|
||||
|
||||
// GenerateType makes the body of a file implementing a set for type t.
|
||||
func (g *genProtoIDL) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
|
||||
sw := generator.NewSnippetWriter(w, c, "$", "$")
|
||||
b := bodyGen{
|
||||
locator: &protobufLocator{
|
||||
namer: c.Namers["proto"].(ProtobufFromGoNamer),
|
||||
tracker: g.imports,
|
||||
universe: c.Universe,
|
||||
|
||||
localGoPackage: g.localGoPackage.Package,
|
||||
},
|
||||
localPackage: g.localPackage,
|
||||
|
||||
omitGogo: g.omitGogo,
|
||||
omitFieldTypes: g.omitFieldTypes,
|
||||
|
||||
t: t,
|
||||
}
|
||||
switch t.Kind {
|
||||
case types.Alias:
|
||||
return b.doAlias(sw)
|
||||
case types.Struct:
|
||||
return b.doStruct(sw)
|
||||
default:
|
||||
return b.unknown(sw)
|
||||
}
|
||||
}
|
||||
|
||||
// ProtobufFromGoNamer finds the protobuf name of a type (and its package, and
|
||||
// the package path) from its Go name.
|
||||
type ProtobufFromGoNamer interface {
|
||||
GoNameToProtoName(name types.Name) types.Name
|
||||
}
|
||||
|
||||
type ProtobufLocator interface {
|
||||
ProtoTypeFor(t *types.Type) (*types.Type, error)
|
||||
GoTypeForName(name types.Name) *types.Type
|
||||
CastTypeName(name types.Name) string
|
||||
}
|
||||
|
||||
type protobufLocator struct {
|
||||
namer ProtobufFromGoNamer
|
||||
tracker namer.ImportTracker
|
||||
universe types.Universe
|
||||
|
||||
localGoPackage string
|
||||
}
|
||||
|
||||
// CastTypeName returns the cast type name of a Go type
|
||||
// TODO: delegate to a new localgo namer?
|
||||
func (p protobufLocator) CastTypeName(name types.Name) string {
|
||||
if name.Package == p.localGoPackage {
|
||||
return name.Name
|
||||
}
|
||||
return name.String()
|
||||
}
|
||||
|
||||
func (p protobufLocator) GoTypeForName(name types.Name) *types.Type {
|
||||
if len(name.Package) == 0 {
|
||||
name.Package = p.localGoPackage
|
||||
}
|
||||
return p.universe.Type(name)
|
||||
}
|
||||
|
||||
// ProtoTypeFor locates a Protobuf type for the provided Go type (if possible).
|
||||
func (p protobufLocator) ProtoTypeFor(t *types.Type) (*types.Type, error) {
|
||||
switch {
|
||||
// we've already converted the type, or it's a map
|
||||
case t.Kind == types.Protobuf || t.Kind == types.Map:
|
||||
p.tracker.AddType(t)
|
||||
return t, nil
|
||||
}
|
||||
// it's a fundamental type
|
||||
if t, ok := isFundamentalProtoType(t); ok {
|
||||
p.tracker.AddType(t)
|
||||
return t, nil
|
||||
}
|
||||
// it's a message
|
||||
if t.Kind == types.Struct || isOptionalAlias(t) {
|
||||
t := &types.Type{
|
||||
Name: p.namer.GoNameToProtoName(t.Name),
|
||||
Kind: types.Protobuf,
|
||||
|
||||
CommentLines: t.CommentLines,
|
||||
}
|
||||
p.tracker.AddType(t)
|
||||
return t, nil
|
||||
}
|
||||
return nil, errUnrecognizedType
|
||||
}
|
||||
|
||||
type bodyGen struct {
|
||||
locator ProtobufLocator
|
||||
localPackage types.Name
|
||||
omitGogo bool
|
||||
omitFieldTypes map[types.Name]struct{}
|
||||
|
||||
t *types.Type
|
||||
}
|
||||
|
||||
func (b bodyGen) unknown(sw *generator.SnippetWriter) error {
|
||||
return fmt.Errorf("not sure how to generate: %#v", b.t)
|
||||
}
|
||||
|
||||
func (b bodyGen) doAlias(sw *generator.SnippetWriter) error {
|
||||
if !isOptionalAlias(b.t) {
|
||||
return nil
|
||||
}
|
||||
|
||||
var kind string
|
||||
switch b.t.Underlying.Kind {
|
||||
case types.Map:
|
||||
kind = "map"
|
||||
default:
|
||||
kind = "slice"
|
||||
}
|
||||
optional := &types.Type{
|
||||
Name: b.t.Name,
|
||||
Kind: types.Struct,
|
||||
|
||||
CommentLines: b.t.CommentLines,
|
||||
SecondClosestCommentLines: b.t.SecondClosestCommentLines,
|
||||
Members: []types.Member{
|
||||
{
|
||||
Name: "Items",
|
||||
CommentLines: []string{fmt.Sprintf("items, if empty, will result in an empty %s\n", kind)},
|
||||
Type: b.t.Underlying,
|
||||
},
|
||||
},
|
||||
}
|
||||
nested := b
|
||||
nested.t = optional
|
||||
return nested.doStruct(sw)
|
||||
}
|
||||
|
||||
func (b bodyGen) doStruct(sw *generator.SnippetWriter) error {
|
||||
if len(b.t.Name.Name) == 0 {
|
||||
return nil
|
||||
}
|
||||
if namer.IsPrivateGoName(b.t.Name.Name) {
|
||||
return nil
|
||||
}
|
||||
|
||||
var alias *types.Type
|
||||
var fields []protoField
|
||||
options := []string{}
|
||||
allOptions := types.ExtractCommentTags("+", b.t.CommentLines)
|
||||
for k, v := range allOptions {
|
||||
switch {
|
||||
case strings.HasPrefix(k, "protobuf.options."):
|
||||
key := strings.TrimPrefix(k, "protobuf.options.")
|
||||
switch key {
|
||||
case "marshal":
|
||||
if v[0] == "false" {
|
||||
if !b.omitGogo {
|
||||
options = append(options,
|
||||
"(gogoproto.marshaler) = false",
|
||||
"(gogoproto.unmarshaler) = false",
|
||||
"(gogoproto.sizer) = false",
|
||||
)
|
||||
}
|
||||
}
|
||||
default:
|
||||
if !b.omitGogo || !strings.HasPrefix(key, "(gogoproto.") {
|
||||
if key == "(gogoproto.goproto_stringer)" && v[0] == "false" {
|
||||
options = append(options, "(gogoproto.stringer) = false")
|
||||
}
|
||||
options = append(options, fmt.Sprintf("%s = %s", key, v[0]))
|
||||
}
|
||||
}
|
||||
// protobuf.as allows a type to have the same message contents as another Go type
|
||||
case k == "protobuf.as":
|
||||
fields = nil
|
||||
if alias = b.locator.GoTypeForName(types.Name{Name: v[0]}); alias == nil {
|
||||
return fmt.Errorf("type %v references alias %q which does not exist", b.t, v[0])
|
||||
}
|
||||
// protobuf.embed instructs the generator to use the named type in this package
|
||||
// as an embedded message.
|
||||
case k == "protobuf.embed":
|
||||
fields = []protoField{
|
||||
{
|
||||
Tag: 1,
|
||||
Name: v[0],
|
||||
Type: &types.Type{
|
||||
Name: types.Name{
|
||||
Name: v[0],
|
||||
Package: b.localPackage.Package,
|
||||
Path: b.localPackage.Path,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
if alias == nil {
|
||||
alias = b.t
|
||||
}
|
||||
|
||||
// If we don't explicitly embed anything, generate fields by traversing fields.
|
||||
if fields == nil {
|
||||
memberFields, err := membersToFields(b.locator, alias, b.localPackage, b.omitFieldTypes)
|
||||
if err != nil {
|
||||
return fmt.Errorf("type %v cannot be converted to protobuf: %v", b.t, err)
|
||||
}
|
||||
fields = memberFields
|
||||
}
|
||||
|
||||
out := sw.Out()
|
||||
genComment(out, b.t.CommentLines, "")
|
||||
sw.Do(`message $.Name.Name$ {
|
||||
`, b.t)
|
||||
|
||||
if len(options) > 0 {
|
||||
sort.Sort(sort.StringSlice(options))
|
||||
for _, s := range options {
|
||||
fmt.Fprintf(out, " option %s;\n", s)
|
||||
}
|
||||
fmt.Fprintln(out)
|
||||
}
|
||||
|
||||
for i, field := range fields {
|
||||
genComment(out, field.CommentLines, " ")
|
||||
fmt.Fprintf(out, " ")
|
||||
switch {
|
||||
case field.Map:
|
||||
case field.Repeated:
|
||||
fmt.Fprintf(out, "repeated ")
|
||||
case field.Required:
|
||||
fmt.Fprintf(out, "required ")
|
||||
default:
|
||||
fmt.Fprintf(out, "optional ")
|
||||
}
|
||||
sw.Do(`$.Type|local$ $.Name$ = $.Tag$`, field)
|
||||
if len(field.Extras) > 0 {
|
||||
extras := []string{}
|
||||
for k, v := range field.Extras {
|
||||
if b.omitGogo && strings.HasPrefix(k, "(gogoproto.") {
|
||||
continue
|
||||
}
|
||||
extras = append(extras, fmt.Sprintf("%s = %s", k, v))
|
||||
}
|
||||
sort.Sort(sort.StringSlice(extras))
|
||||
if len(extras) > 0 {
|
||||
fmt.Fprintf(out, " [")
|
||||
fmt.Fprint(out, strings.Join(extras, ", "))
|
||||
fmt.Fprintf(out, "]")
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(out, ";\n")
|
||||
if i != len(fields)-1 {
|
||||
fmt.Fprintf(out, "\n")
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(out, "}\n\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
type protoField struct {
|
||||
LocalPackage types.Name
|
||||
|
||||
Tag int
|
||||
Name string
|
||||
Type *types.Type
|
||||
Map bool
|
||||
Repeated bool
|
||||
Optional bool
|
||||
Required bool
|
||||
Nullable bool
|
||||
Extras map[string]string
|
||||
|
||||
CommentLines []string
|
||||
}
|
||||
|
||||
var (
|
||||
errUnrecognizedType = fmt.Errorf("did not recognize the provided type")
|
||||
)
|
||||
|
||||
func isFundamentalProtoType(t *types.Type) (*types.Type, bool) {
|
||||
// TODO: when we enable proto3, also include other fundamental types in the google.protobuf package
|
||||
// switch {
|
||||
// case t.Kind == types.Struct && t.Name == types.Name{Package: "time", Name: "Time"}:
|
||||
// return &types.Type{
|
||||
// Kind: types.Protobuf,
|
||||
// Name: types.Name{Path: "google/protobuf/timestamp.proto", Package: "google.protobuf", Name: "Timestamp"},
|
||||
// }, true
|
||||
// }
|
||||
switch t.Kind {
|
||||
case types.Slice:
|
||||
if t.Elem.Name.Name == "byte" && len(t.Elem.Name.Package) == 0 {
|
||||
return &types.Type{Name: types.Name{Name: "bytes"}, Kind: types.Protobuf}, true
|
||||
}
|
||||
case types.Builtin:
|
||||
switch t.Name.Name {
|
||||
case "string", "uint32", "int32", "uint64", "int64", "bool":
|
||||
return &types.Type{Name: types.Name{Name: t.Name.Name}, Kind: types.Protobuf}, true
|
||||
case "int":
|
||||
return &types.Type{Name: types.Name{Name: "int64"}, Kind: types.Protobuf}, true
|
||||
case "uint":
|
||||
return &types.Type{Name: types.Name{Name: "uint64"}, Kind: types.Protobuf}, true
|
||||
case "float64", "float":
|
||||
return &types.Type{Name: types.Name{Name: "double"}, Kind: types.Protobuf}, true
|
||||
case "float32":
|
||||
return &types.Type{Name: types.Name{Name: "float"}, Kind: types.Protobuf}, true
|
||||
case "uintptr":
|
||||
return &types.Type{Name: types.Name{Name: "uint64"}, Kind: types.Protobuf}, true
|
||||
}
|
||||
// TODO: complex?
|
||||
}
|
||||
return t, false
|
||||
}
|
||||
|
||||
func memberTypeToProtobufField(locator ProtobufLocator, field *protoField, t *types.Type) error {
|
||||
var err error
|
||||
switch t.Kind {
|
||||
case types.Protobuf:
|
||||
field.Type, err = locator.ProtoTypeFor(t)
|
||||
case types.Builtin:
|
||||
field.Type, err = locator.ProtoTypeFor(t)
|
||||
case types.Map:
|
||||
valueField := &protoField{}
|
||||
if err := memberTypeToProtobufField(locator, valueField, t.Elem); err != nil {
|
||||
return err
|
||||
}
|
||||
keyField := &protoField{}
|
||||
if err := memberTypeToProtobufField(locator, keyField, t.Key); err != nil {
|
||||
return err
|
||||
}
|
||||
// All other protobuf types have kind types.Protobuf, so setting types.Map
|
||||
// here would be very misleading.
|
||||
field.Type = &types.Type{
|
||||
Kind: types.Protobuf,
|
||||
Key: keyField.Type,
|
||||
Elem: valueField.Type,
|
||||
}
|
||||
if !strings.HasPrefix(t.Name.Name, "map[") {
|
||||
field.Extras["(gogoproto.casttype)"] = strconv.Quote(locator.CastTypeName(t.Name))
|
||||
}
|
||||
if k, ok := keyField.Extras["(gogoproto.casttype)"]; ok {
|
||||
field.Extras["(gogoproto.castkey)"] = k
|
||||
}
|
||||
if v, ok := valueField.Extras["(gogoproto.casttype)"]; ok {
|
||||
field.Extras["(gogoproto.castvalue)"] = v
|
||||
}
|
||||
field.Map = true
|
||||
case types.Pointer:
|
||||
if err := memberTypeToProtobufField(locator, field, t.Elem); err != nil {
|
||||
return err
|
||||
}
|
||||
field.Nullable = true
|
||||
case types.Alias:
|
||||
if isOptionalAlias(t) {
|
||||
field.Type, err = locator.ProtoTypeFor(t)
|
||||
field.Nullable = true
|
||||
} else {
|
||||
if err := memberTypeToProtobufField(locator, field, t.Underlying); err != nil {
|
||||
log.Printf("failed to alias: %s %s: err %v", t.Name, t.Underlying.Name, err)
|
||||
return err
|
||||
}
|
||||
if field.Extras == nil {
|
||||
field.Extras = make(map[string]string)
|
||||
}
|
||||
field.Extras["(gogoproto.casttype)"] = strconv.Quote(locator.CastTypeName(t.Name))
|
||||
}
|
||||
case types.Slice:
|
||||
if t.Elem.Name.Name == "byte" && len(t.Elem.Name.Package) == 0 {
|
||||
field.Type = &types.Type{Name: types.Name{Name: "bytes"}, Kind: types.Protobuf}
|
||||
return nil
|
||||
}
|
||||
if err := memberTypeToProtobufField(locator, field, t.Elem); err != nil {
|
||||
return err
|
||||
}
|
||||
field.Repeated = true
|
||||
case types.Struct:
|
||||
if len(t.Name.Name) == 0 {
|
||||
return errUnrecognizedType
|
||||
}
|
||||
field.Type, err = locator.ProtoTypeFor(t)
|
||||
field.Nullable = false
|
||||
default:
|
||||
return errUnrecognizedType
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// protobufTagToField extracts information from an existing protobuf tag
|
||||
func protobufTagToField(tag string, field *protoField, m types.Member, t *types.Type, localPackage types.Name) error {
|
||||
if len(tag) == 0 || tag == "-" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// protobuf:"bytes,3,opt,name=Id,customtype=github.com/gogo/protobuf/test.Uuid"
|
||||
parts := strings.Split(tag, ",")
|
||||
if len(parts) < 3 {
|
||||
return fmt.Errorf("member %q of %q malformed 'protobuf' tag, not enough segments\n", m.Name, t.Name)
|
||||
}
|
||||
protoTag, err := strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("member %q of %q malformed 'protobuf' tag, field ID is %q which is not an integer: %v\n", m.Name, t.Name, parts[1], err)
|
||||
}
|
||||
field.Tag = protoTag
|
||||
|
||||
// In general there is doesn't make sense to parse the protobuf tags to get the type,
|
||||
// as all auto-generated once will have wire type "bytes", "varint" or "fixed64".
|
||||
// However, sometimes we explicitly set them to have a custom serialization, e.g.:
|
||||
// type Time struct {
|
||||
// time.Time `protobuf:"Timestamp,1,req,name=time"`
|
||||
// }
|
||||
// to force the generator to use a given type (that we manually wrote serialization &
|
||||
// deserialization methods for).
|
||||
switch parts[0] {
|
||||
case "varint", "fixed32", "fixed64", "bytes", "group":
|
||||
default:
|
||||
name := types.Name{}
|
||||
if last := strings.LastIndex(parts[0], "."); last != -1 {
|
||||
prefix := parts[0][:last]
|
||||
name = types.Name{
|
||||
Name: parts[0][last+1:],
|
||||
Package: prefix,
|
||||
Path: strings.Replace(prefix, ".", "/", -1),
|
||||
}
|
||||
} else {
|
||||
name = types.Name{
|
||||
Name: parts[0],
|
||||
Package: localPackage.Package,
|
||||
Path: localPackage.Path,
|
||||
}
|
||||
}
|
||||
field.Type = &types.Type{
|
||||
Name: name,
|
||||
Kind: types.Protobuf,
|
||||
}
|
||||
}
|
||||
|
||||
protoExtra := make(map[string]string)
|
||||
for i, extra := range parts[3:] {
|
||||
parts := strings.SplitN(extra, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
return fmt.Errorf("member %q of %q malformed 'protobuf' tag, tag %d should be key=value, got %q\n", m.Name, t.Name, i+4, extra)
|
||||
}
|
||||
switch parts[0] {
|
||||
case "name":
|
||||
protoExtra[parts[0]] = parts[1]
|
||||
case "casttype", "castkey", "castvalue":
|
||||
parts[0] = fmt.Sprintf("(gogoproto.%s)", parts[0])
|
||||
protoExtra[parts[0]] = parts[1]
|
||||
}
|
||||
}
|
||||
|
||||
field.Extras = protoExtra
|
||||
if name, ok := protoExtra["name"]; ok {
|
||||
field.Name = name
|
||||
delete(protoExtra, "name")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func membersToFields(locator ProtobufLocator, t *types.Type, localPackage types.Name, omitFieldTypes map[types.Name]struct{}) ([]protoField, error) {
|
||||
fields := []protoField{}
|
||||
|
||||
for _, m := range t.Members {
|
||||
if namer.IsPrivateGoName(m.Name) {
|
||||
// skip private fields
|
||||
continue
|
||||
}
|
||||
if _, ok := omitFieldTypes[types.Name{Name: m.Type.Name.Name, Package: m.Type.Name.Package}]; ok {
|
||||
continue
|
||||
}
|
||||
tags := reflect.StructTag(m.Tags)
|
||||
field := protoField{
|
||||
LocalPackage: localPackage,
|
||||
|
||||
Tag: -1,
|
||||
Extras: make(map[string]string),
|
||||
}
|
||||
|
||||
protobufTag := tags.Get("protobuf")
|
||||
if protobufTag == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := protobufTagToField(protobufTag, &field, m, t, localPackage); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// extract information from JSON field tag
|
||||
if tag := tags.Get("json"); len(tag) > 0 {
|
||||
parts := strings.Split(tag, ",")
|
||||
if len(field.Name) == 0 && len(parts[0]) != 0 {
|
||||
field.Name = parts[0]
|
||||
}
|
||||
if field.Tag == -1 && field.Name == "-" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if field.Type == nil {
|
||||
if err := memberTypeToProtobufField(locator, &field, m.Type); err != nil {
|
||||
return nil, fmt.Errorf("unable to embed type %q as field %q in %q: %v", m.Type, field.Name, t.Name, err)
|
||||
}
|
||||
}
|
||||
if len(field.Name) == 0 {
|
||||
field.Name = namer.IL(m.Name)
|
||||
}
|
||||
|
||||
if field.Map && field.Repeated {
|
||||
// maps cannot be repeated
|
||||
field.Repeated = false
|
||||
field.Nullable = true
|
||||
}
|
||||
|
||||
if !field.Nullable {
|
||||
field.Extras["(gogoproto.nullable)"] = "false"
|
||||
}
|
||||
if (field.Type.Name.Name == "bytes" && field.Type.Name.Package == "") || (field.Repeated && field.Type.Name.Package == "" && namer.IsPrivateGoName(field.Type.Name.Name)) {
|
||||
delete(field.Extras, "(gogoproto.nullable)")
|
||||
}
|
||||
if field.Name != m.Name {
|
||||
field.Extras["(gogoproto.customname)"] = strconv.Quote(m.Name)
|
||||
}
|
||||
field.CommentLines = m.CommentLines
|
||||
fields = append(fields, field)
|
||||
}
|
||||
|
||||
// assign tags
|
||||
highest := 0
|
||||
byTag := make(map[int]*protoField)
|
||||
// fields are in Go struct order, which we preserve
|
||||
for i := range fields {
|
||||
field := &fields[i]
|
||||
tag := field.Tag
|
||||
if tag != -1 {
|
||||
if existing, ok := byTag[tag]; ok {
|
||||
return nil, fmt.Errorf("field %q and %q both have tag %d", field.Name, existing.Name, tag)
|
||||
}
|
||||
byTag[tag] = field
|
||||
}
|
||||
if tag > highest {
|
||||
highest = tag
|
||||
}
|
||||
}
|
||||
// starting from the highest observed tag, assign new field tags
|
||||
for i := range fields {
|
||||
field := &fields[i]
|
||||
if field.Tag != -1 {
|
||||
continue
|
||||
}
|
||||
highest++
|
||||
field.Tag = highest
|
||||
byTag[field.Tag] = field
|
||||
}
|
||||
return fields, nil
|
||||
}
|
||||
|
||||
func genComment(out io.Writer, lines []string, indent string) {
|
||||
for {
|
||||
l := len(lines)
|
||||
if l == 0 || len(lines[l-1]) != 0 {
|
||||
break
|
||||
}
|
||||
lines = lines[:l-1]
|
||||
}
|
||||
for _, c := range lines {
|
||||
fmt.Fprintf(out, "%s// %s\n", indent, c)
|
||||
}
|
||||
}
|
||||
|
||||
func formatProtoFile(source []byte) ([]byte, error) {
|
||||
// TODO; Is there any protobuf formatter?
|
||||
return source, nil
|
||||
}
|
||||
|
||||
func assembleProtoFile(w io.Writer, f *generator.File) {
|
||||
w.Write(f.Header)
|
||||
|
||||
fmt.Fprint(w, "syntax = 'proto2';\n\n")
|
||||
|
||||
if len(f.PackageName) > 0 {
|
||||
fmt.Fprintf(w, "package %s;\n\n", f.PackageName)
|
||||
}
|
||||
|
||||
if len(f.Imports) > 0 {
|
||||
imports := []string{}
|
||||
for i := range f.Imports {
|
||||
imports = append(imports, i)
|
||||
}
|
||||
sort.Strings(imports)
|
||||
for _, s := range imports {
|
||||
fmt.Fprintf(w, "import %q;\n", s)
|
||||
}
|
||||
fmt.Fprint(w, "\n")
|
||||
}
|
||||
|
||||
if f.Vars.Len() > 0 {
|
||||
fmt.Fprintf(w, "%s\n", f.Vars.String())
|
||||
}
|
||||
|
||||
w.Write(f.Body.Bytes())
|
||||
}
|
||||
|
||||
func NewProtoFile() *generator.DefaultFileType {
|
||||
return &generator.DefaultFileType{
|
||||
Format: formatProtoFile,
|
||||
Assemble: assembleProtoFile,
|
||||
}
|
||||
}
|
50
vendor/k8s.io/gengo/examples/go-to-protobuf/protobuf/import_tracker.go
generated
vendored
Normal file
50
vendor/k8s.io/gengo/examples/go-to-protobuf/protobuf/import_tracker.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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 protobuf
|
||||
|
||||
import (
|
||||
"k8s.io/gengo/namer"
|
||||
"k8s.io/gengo/types"
|
||||
)
|
||||
|
||||
type ImportTracker struct {
|
||||
namer.DefaultImportTracker
|
||||
}
|
||||
|
||||
func NewImportTracker(local types.Name, typesToAdd ...*types.Type) *ImportTracker {
|
||||
tracker := namer.NewDefaultImportTracker(local)
|
||||
tracker.IsInvalidType = func(t *types.Type) bool { return t.Kind != types.Protobuf }
|
||||
tracker.LocalName = func(name types.Name) string { return name.Package }
|
||||
tracker.PrintImport = func(path, name string) string { return path }
|
||||
|
||||
tracker.AddTypes(typesToAdd...)
|
||||
return &ImportTracker{
|
||||
DefaultImportTracker: tracker,
|
||||
}
|
||||
}
|
||||
|
||||
// AddNullable ensures that support for the nullable Gogo-protobuf extension is added.
|
||||
func (tracker *ImportTracker) AddNullable() {
|
||||
tracker.AddType(&types.Type{
|
||||
Kind: types.Protobuf,
|
||||
Name: types.Name{
|
||||
Name: "nullable",
|
||||
Package: "gogoproto",
|
||||
Path: "github.com/gogo/protobuf/gogoproto/gogo.proto",
|
||||
},
|
||||
})
|
||||
}
|
186
vendor/k8s.io/gengo/examples/go-to-protobuf/protobuf/namer.go
generated
vendored
Normal file
186
vendor/k8s.io/gengo/examples/go-to-protobuf/protobuf/namer.go
generated
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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 protobuf
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"k8s.io/gengo/generator"
|
||||
"k8s.io/gengo/namer"
|
||||
"k8s.io/gengo/types"
|
||||
)
|
||||
|
||||
type localNamer struct {
|
||||
localPackage types.Name
|
||||
}
|
||||
|
||||
func (n localNamer) Name(t *types.Type) string {
|
||||
if t.Key != nil && t.Elem != nil {
|
||||
return fmt.Sprintf("map<%s, %s>", n.Name(t.Key), n.Name(t.Elem))
|
||||
}
|
||||
if len(n.localPackage.Package) != 0 && n.localPackage.Package == t.Name.Package {
|
||||
return t.Name.Name
|
||||
}
|
||||
return t.Name.String()
|
||||
}
|
||||
|
||||
type protobufNamer struct {
|
||||
packages []*protobufPackage
|
||||
packagesByPath map[string]*protobufPackage
|
||||
}
|
||||
|
||||
func NewProtobufNamer() *protobufNamer {
|
||||
return &protobufNamer{
|
||||
packagesByPath: make(map[string]*protobufPackage),
|
||||
}
|
||||
}
|
||||
|
||||
func (n *protobufNamer) Name(t *types.Type) string {
|
||||
if t.Kind == types.Map {
|
||||
return fmt.Sprintf("map<%s, %s>", n.Name(t.Key), n.Name(t.Elem))
|
||||
}
|
||||
return t.Name.String()
|
||||
}
|
||||
|
||||
func (n *protobufNamer) List() []generator.Package {
|
||||
packages := make([]generator.Package, 0, len(n.packages))
|
||||
for i := range n.packages {
|
||||
packages = append(packages, n.packages[i])
|
||||
}
|
||||
return packages
|
||||
}
|
||||
|
||||
func (n *protobufNamer) Add(p *protobufPackage) {
|
||||
if _, ok := n.packagesByPath[p.PackagePath]; !ok {
|
||||
n.packagesByPath[p.PackagePath] = p
|
||||
n.packages = append(n.packages, p)
|
||||
}
|
||||
}
|
||||
|
||||
func (n *protobufNamer) GoNameToProtoName(name types.Name) types.Name {
|
||||
if p, ok := n.packagesByPath[name.Package]; ok {
|
||||
return types.Name{
|
||||
Name: name.Name,
|
||||
Package: p.PackageName,
|
||||
Path: p.ImportPath(),
|
||||
}
|
||||
}
|
||||
for _, p := range n.packages {
|
||||
if _, ok := p.FilterTypes[name]; ok {
|
||||
return types.Name{
|
||||
Name: name.Name,
|
||||
Package: p.PackageName,
|
||||
Path: p.ImportPath(),
|
||||
}
|
||||
}
|
||||
}
|
||||
return types.Name{Name: name.Name}
|
||||
}
|
||||
|
||||
func protoSafePackage(name string) string {
|
||||
pkg := strings.Replace(name, "/", ".", -1)
|
||||
return strings.Replace(pkg, "-", "_", -1)
|
||||
}
|
||||
|
||||
type typeNameSet map[types.Name]*protobufPackage
|
||||
|
||||
// assignGoTypeToProtoPackage looks for Go and Protobuf types that are referenced by a type in
|
||||
// a package. It will not recurse into protobuf types.
|
||||
func assignGoTypeToProtoPackage(p *protobufPackage, t *types.Type, local, global typeNameSet, optional map[types.Name]struct{}) {
|
||||
newT, isProto := isFundamentalProtoType(t)
|
||||
if isProto {
|
||||
t = newT
|
||||
}
|
||||
if otherP, ok := global[t.Name]; ok {
|
||||
if _, ok := local[t.Name]; !ok {
|
||||
p.Imports.AddType(&types.Type{
|
||||
Kind: types.Protobuf,
|
||||
Name: otherP.ProtoTypeName(),
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
global[t.Name] = p
|
||||
if _, ok := local[t.Name]; ok {
|
||||
return
|
||||
}
|
||||
// don't recurse into existing proto types
|
||||
if isProto {
|
||||
p.Imports.AddType(t)
|
||||
return
|
||||
}
|
||||
|
||||
local[t.Name] = p
|
||||
for _, m := range t.Members {
|
||||
if namer.IsPrivateGoName(m.Name) {
|
||||
continue
|
||||
}
|
||||
field := &protoField{}
|
||||
tag := reflect.StructTag(m.Tags).Get("protobuf")
|
||||
if tag == "-" {
|
||||
continue
|
||||
}
|
||||
if err := protobufTagToField(tag, field, m, t, p.ProtoTypeName()); err == nil && field.Type != nil {
|
||||
assignGoTypeToProtoPackage(p, field.Type, local, global, optional)
|
||||
continue
|
||||
}
|
||||
assignGoTypeToProtoPackage(p, m.Type, local, global, optional)
|
||||
}
|
||||
// TODO: should methods be walked?
|
||||
if t.Elem != nil {
|
||||
assignGoTypeToProtoPackage(p, t.Elem, local, global, optional)
|
||||
}
|
||||
if t.Key != nil {
|
||||
assignGoTypeToProtoPackage(p, t.Key, local, global, optional)
|
||||
}
|
||||
if t.Underlying != nil {
|
||||
if t.Kind == types.Alias && isOptionalAlias(t) {
|
||||
optional[t.Name] = struct{}{}
|
||||
}
|
||||
assignGoTypeToProtoPackage(p, t.Underlying, local, global, optional)
|
||||
}
|
||||
}
|
||||
|
||||
func (n *protobufNamer) AssignTypesToPackages(c *generator.Context) error {
|
||||
global := make(typeNameSet)
|
||||
for _, p := range n.packages {
|
||||
local := make(typeNameSet)
|
||||
optional := make(map[types.Name]struct{})
|
||||
p.Imports = NewImportTracker(p.ProtoTypeName())
|
||||
for _, t := range c.Order {
|
||||
if t.Name.Package != p.PackagePath {
|
||||
continue
|
||||
}
|
||||
assignGoTypeToProtoPackage(p, t, local, global, optional)
|
||||
}
|
||||
p.FilterTypes = make(map[types.Name]struct{})
|
||||
p.LocalNames = make(map[string]struct{})
|
||||
p.OptionalTypeNames = make(map[string]struct{})
|
||||
for k, v := range local {
|
||||
if v == p {
|
||||
p.FilterTypes[k] = struct{}{}
|
||||
p.LocalNames[k.Name] = struct{}{}
|
||||
if _, ok := optional[k]; ok {
|
||||
p.OptionalTypeNames[k.Name] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
50
vendor/k8s.io/gengo/examples/go-to-protobuf/protobuf/namer_test.go
generated
vendored
Normal file
50
vendor/k8s.io/gengo/examples/go-to-protobuf/protobuf/namer_test.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 protobuf
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestProtoSafePackage(t *testing.T) {
|
||||
tests := []struct {
|
||||
pkg string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
pkg: "foo",
|
||||
expected: "foo",
|
||||
},
|
||||
{
|
||||
pkg: "foo/bar",
|
||||
expected: "foo.bar",
|
||||
},
|
||||
{
|
||||
pkg: "foo/bar/baz",
|
||||
expected: "foo.bar.baz",
|
||||
},
|
||||
{
|
||||
pkg: "foo/bar-baz/x/y-z/q",
|
||||
expected: "foo.bar_baz.x.y_z.q",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
actual := protoSafePackage(test.pkg)
|
||||
if e, a := test.expected, actual; e != a {
|
||||
t.Errorf("%s: expected %s, got %s", test.pkg, e, a)
|
||||
}
|
||||
}
|
||||
}
|
211
vendor/k8s.io/gengo/examples/go-to-protobuf/protobuf/package.go
generated
vendored
Normal file
211
vendor/k8s.io/gengo/examples/go-to-protobuf/protobuf/package.go
generated
vendored
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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 protobuf
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"k8s.io/gengo/generator"
|
||||
"k8s.io/gengo/types"
|
||||
)
|
||||
|
||||
func newProtobufPackage(packagePath, packageName string, generateAll bool, omitFieldTypes map[types.Name]struct{}) *protobufPackage {
|
||||
pkg := &protobufPackage{
|
||||
DefaultPackage: generator.DefaultPackage{
|
||||
// The protobuf package name (foo.bar.baz)
|
||||
PackageName: packageName,
|
||||
// A path segment relative to the GOPATH root (foo/bar/baz)
|
||||
PackagePath: packagePath,
|
||||
HeaderText: []byte(
|
||||
`
|
||||
// This file was autogenerated by go-to-protobuf. Do not edit it manually!
|
||||
|
||||
`),
|
||||
PackageDocumentation: []byte(fmt.Sprintf(
|
||||
`// Package %s is an autogenerated protobuf IDL.
|
||||
`, packageName)),
|
||||
},
|
||||
GenerateAll: generateAll,
|
||||
OmitFieldTypes: omitFieldTypes,
|
||||
}
|
||||
pkg.FilterFunc = pkg.filterFunc
|
||||
pkg.GeneratorFunc = pkg.generatorFunc
|
||||
return pkg
|
||||
}
|
||||
|
||||
// protobufPackage contains the protobuf implementation of Package.
|
||||
type protobufPackage struct {
|
||||
generator.DefaultPackage
|
||||
|
||||
// If true, generate protobuf serializations for all public types.
|
||||
// If false, only generate protobuf serializations for structs that
|
||||
// request serialization.
|
||||
GenerateAll bool
|
||||
|
||||
// A list of types to filter to; if not specified all types will be included.
|
||||
FilterTypes map[types.Name]struct{}
|
||||
|
||||
// If true, omit any gogoprotobuf extensions not defined as types.
|
||||
OmitGogo bool
|
||||
|
||||
// A list of field types that will be excluded from the output struct
|
||||
OmitFieldTypes map[types.Name]struct{}
|
||||
|
||||
// A list of names that this package exports
|
||||
LocalNames map[string]struct{}
|
||||
|
||||
// A list of type names in this package that will need marshaller rewriting
|
||||
// to remove synthetic protobuf fields.
|
||||
OptionalTypeNames map[string]struct{}
|
||||
|
||||
// A list of struct tags to generate onto named struct fields
|
||||
StructTags map[string]map[string]string
|
||||
|
||||
// An import tracker for this package
|
||||
Imports *ImportTracker
|
||||
}
|
||||
|
||||
func (p *protobufPackage) Clean(outputBase string) error {
|
||||
for _, s := range []string{p.ImportPath(), p.OutputPath()} {
|
||||
if err := os.Remove(filepath.Join(outputBase, s)); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *protobufPackage) ProtoTypeName() types.Name {
|
||||
return types.Name{
|
||||
Name: p.Path(), // the go path "foo/bar/baz"
|
||||
Package: p.Name(), // the protobuf package "foo.bar.baz"
|
||||
Path: p.ImportPath(), // the path of the import to get the proto
|
||||
}
|
||||
}
|
||||
|
||||
func (p *protobufPackage) filterFunc(c *generator.Context, t *types.Type) bool {
|
||||
switch t.Kind {
|
||||
case types.Func, types.Chan:
|
||||
return false
|
||||
case types.Struct:
|
||||
if t.Name.Name == "struct{}" {
|
||||
return false
|
||||
}
|
||||
case types.Builtin:
|
||||
return false
|
||||
case types.Alias:
|
||||
if !isOptionalAlias(t) {
|
||||
return false
|
||||
}
|
||||
case types.Slice, types.Array, types.Map:
|
||||
return false
|
||||
case types.Pointer:
|
||||
return false
|
||||
}
|
||||
if _, ok := isFundamentalProtoType(t); ok {
|
||||
return false
|
||||
}
|
||||
_, ok := p.FilterTypes[t.Name]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (p *protobufPackage) HasGoType(name string) bool {
|
||||
_, ok := p.LocalNames[name]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (p *protobufPackage) OptionalTypeName(name string) bool {
|
||||
_, ok := p.OptionalTypeNames[name]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (p *protobufPackage) ExtractGeneratedType(t *ast.TypeSpec) bool {
|
||||
if !p.HasGoType(t.Name.Name) {
|
||||
return false
|
||||
}
|
||||
|
||||
switch s := t.Type.(type) {
|
||||
case *ast.StructType:
|
||||
for i, f := range s.Fields.List {
|
||||
if len(f.Tag.Value) == 0 {
|
||||
continue
|
||||
}
|
||||
tag := strings.Trim(f.Tag.Value, "`")
|
||||
protobufTag := reflect.StructTag(tag).Get("protobuf")
|
||||
if len(protobufTag) == 0 {
|
||||
continue
|
||||
}
|
||||
if len(f.Names) > 1 {
|
||||
log.Printf("WARNING: struct %s field %d %s: defined multiple names but single protobuf tag", t.Name.Name, i, f.Names[0].Name)
|
||||
// TODO hard error?
|
||||
}
|
||||
if p.StructTags == nil {
|
||||
p.StructTags = make(map[string]map[string]string)
|
||||
}
|
||||
m := p.StructTags[t.Name.Name]
|
||||
if m == nil {
|
||||
m = make(map[string]string)
|
||||
p.StructTags[t.Name.Name] = m
|
||||
}
|
||||
m[f.Names[0].Name] = tag
|
||||
}
|
||||
default:
|
||||
log.Printf("WARNING: unexpected Go AST type definition: %#v", t)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *protobufPackage) generatorFunc(c *generator.Context) []generator.Generator {
|
||||
generators := []generator.Generator{}
|
||||
|
||||
p.Imports.AddNullable()
|
||||
|
||||
generators = append(generators, &genProtoIDL{
|
||||
DefaultGen: generator.DefaultGen{
|
||||
OptionalName: "generated",
|
||||
},
|
||||
localPackage: types.Name{Package: p.PackageName, Path: p.PackagePath},
|
||||
localGoPackage: types.Name{Package: p.PackagePath, Name: p.GoPackageName()},
|
||||
imports: p.Imports,
|
||||
generateAll: p.GenerateAll,
|
||||
omitGogo: p.OmitGogo,
|
||||
omitFieldTypes: p.OmitFieldTypes,
|
||||
})
|
||||
return generators
|
||||
}
|
||||
|
||||
func (p *protobufPackage) GoPackageName() string {
|
||||
return filepath.Base(p.PackagePath)
|
||||
}
|
||||
|
||||
func (p *protobufPackage) ImportPath() string {
|
||||
return filepath.Join(p.PackagePath, "generated.proto")
|
||||
}
|
||||
|
||||
func (p *protobufPackage) OutputPath() string {
|
||||
return filepath.Join(p.PackagePath, "generated.pb.go")
|
||||
}
|
||||
|
||||
var (
|
||||
_ = generator.Package(&protobufPackage{})
|
||||
)
|
452
vendor/k8s.io/gengo/examples/go-to-protobuf/protobuf/parser.go
generated
vendored
Normal file
452
vendor/k8s.io/gengo/examples/go-to-protobuf/protobuf/parser.go
generated
vendored
Normal file
@@ -0,0 +1,452 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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 protobuf
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/format"
|
||||
"go/parser"
|
||||
"go/printer"
|
||||
"go/token"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
customreflect "k8s.io/kubernetes/third_party/forked/golang/reflect"
|
||||
)
|
||||
|
||||
func rewriteFile(name string, header []byte, rewriteFn func(*token.FileSet, *ast.File) error) error {
|
||||
fset := token.NewFileSet()
|
||||
src, err := ioutil.ReadFile(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
file, err := parser.ParseFile(fset, name, src, parser.DeclarationErrors|parser.ParseComments)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := rewriteFn(fset, file); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := &bytes.Buffer{}
|
||||
b.Write(header)
|
||||
if err := printer.Fprint(b, fset, file); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
body, err := format.Source(b.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(name, os.O_WRONLY|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err := f.Write(body); err != nil {
|
||||
return err
|
||||
}
|
||||
return f.Close()
|
||||
}
|
||||
|
||||
// ExtractFunc extracts information from the provided TypeSpec and returns true if the type should be
|
||||
// removed from the destination file.
|
||||
type ExtractFunc func(*ast.TypeSpec) bool
|
||||
|
||||
// OptionalFunc returns true if the provided local name is a type that has protobuf.nullable=true
|
||||
// and should have its marshal functions adjusted to remove the 'Items' accessor.
|
||||
type OptionalFunc func(name string) bool
|
||||
|
||||
func RewriteGeneratedGogoProtobufFile(name string, extractFn ExtractFunc, optionalFn OptionalFunc, header []byte) error {
|
||||
return rewriteFile(name, header, func(fset *token.FileSet, file *ast.File) error {
|
||||
cmap := ast.NewCommentMap(fset, file, file.Comments)
|
||||
|
||||
// transform methods that point to optional maps or slices
|
||||
for _, d := range file.Decls {
|
||||
rewriteOptionalMethods(d, optionalFn)
|
||||
}
|
||||
|
||||
// remove types that are already declared
|
||||
decls := []ast.Decl{}
|
||||
for _, d := range file.Decls {
|
||||
if dropExistingTypeDeclarations(d, extractFn) {
|
||||
continue
|
||||
}
|
||||
if dropEmptyImportDeclarations(d) {
|
||||
continue
|
||||
}
|
||||
decls = append(decls, d)
|
||||
}
|
||||
file.Decls = decls
|
||||
|
||||
// remove unmapped comments
|
||||
file.Comments = cmap.Filter(file).Comments()
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// rewriteOptionalMethods makes specific mutations to marshaller methods that belong to types identified
|
||||
// as being "optional" (they may be nil on the wire). This allows protobuf to serialize a map or slice and
|
||||
// properly discriminate between empty and nil (which is not possible in protobuf).
|
||||
// TODO: move into upstream gogo-protobuf once https://github.com/gogo/protobuf/issues/181
|
||||
// has agreement
|
||||
func rewriteOptionalMethods(decl ast.Decl, isOptional OptionalFunc) {
|
||||
switch t := decl.(type) {
|
||||
case *ast.FuncDecl:
|
||||
ident, ptr, ok := receiver(t)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// correct initialization of the form `m.Field = &OptionalType{}` to
|
||||
// `m.Field = OptionalType{}`
|
||||
if t.Name.Name == "Unmarshal" {
|
||||
ast.Walk(optionalAssignmentVisitor{fn: isOptional}, t.Body)
|
||||
}
|
||||
|
||||
if !isOptional(ident.Name) {
|
||||
return
|
||||
}
|
||||
|
||||
switch t.Name.Name {
|
||||
case "Unmarshal":
|
||||
ast.Walk(&optionalItemsVisitor{}, t.Body)
|
||||
case "MarshalTo", "Size", "String":
|
||||
ast.Walk(&optionalItemsVisitor{}, t.Body)
|
||||
fallthrough
|
||||
case "Marshal":
|
||||
// if the method has a pointer receiver, set it back to a normal receiver
|
||||
if ptr {
|
||||
t.Recv.List[0].Type = ident
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type optionalAssignmentVisitor struct {
|
||||
fn OptionalFunc
|
||||
}
|
||||
|
||||
// Visit walks the provided node, transforming field initializations of the form
|
||||
// m.Field = &OptionalType{} -> m.Field = OptionalType{}
|
||||
func (v optionalAssignmentVisitor) Visit(n ast.Node) ast.Visitor {
|
||||
switch t := n.(type) {
|
||||
case *ast.AssignStmt:
|
||||
if len(t.Lhs) == 1 && len(t.Rhs) == 1 {
|
||||
if !isFieldSelector(t.Lhs[0], "m", "") {
|
||||
return nil
|
||||
}
|
||||
unary, ok := t.Rhs[0].(*ast.UnaryExpr)
|
||||
if !ok || unary.Op != token.AND {
|
||||
return nil
|
||||
}
|
||||
composite, ok := unary.X.(*ast.CompositeLit)
|
||||
if !ok || composite.Type == nil || len(composite.Elts) != 0 {
|
||||
return nil
|
||||
}
|
||||
if ident, ok := composite.Type.(*ast.Ident); ok && v.fn(ident.Name) {
|
||||
t.Rhs[0] = composite
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
type optionalItemsVisitor struct{}
|
||||
|
||||
// Visit walks the provided node, looking for specific patterns to transform that match
|
||||
// the effective outcome of turning struct{ map[x]y || []x } into map[x]y or []x.
|
||||
func (v *optionalItemsVisitor) Visit(n ast.Node) ast.Visitor {
|
||||
switch t := n.(type) {
|
||||
case *ast.RangeStmt:
|
||||
if isFieldSelector(t.X, "m", "Items") {
|
||||
t.X = &ast.Ident{Name: "m"}
|
||||
}
|
||||
case *ast.AssignStmt:
|
||||
if len(t.Lhs) == 1 && len(t.Rhs) == 1 {
|
||||
switch lhs := t.Lhs[0].(type) {
|
||||
case *ast.IndexExpr:
|
||||
if isFieldSelector(lhs.X, "m", "Items") {
|
||||
lhs.X = &ast.StarExpr{X: &ast.Ident{Name: "m"}}
|
||||
}
|
||||
default:
|
||||
if isFieldSelector(t.Lhs[0], "m", "Items") {
|
||||
t.Lhs[0] = &ast.StarExpr{X: &ast.Ident{Name: "m"}}
|
||||
}
|
||||
}
|
||||
switch rhs := t.Rhs[0].(type) {
|
||||
case *ast.CallExpr:
|
||||
if ident, ok := rhs.Fun.(*ast.Ident); ok && ident.Name == "append" {
|
||||
ast.Walk(v, rhs)
|
||||
if len(rhs.Args) > 0 {
|
||||
switch arg := rhs.Args[0].(type) {
|
||||
case *ast.Ident:
|
||||
if arg.Name == "m" {
|
||||
rhs.Args[0] = &ast.StarExpr{X: &ast.Ident{Name: "m"}}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
case *ast.IfStmt:
|
||||
switch cond := t.Cond.(type) {
|
||||
case *ast.BinaryExpr:
|
||||
if cond.Op == token.EQL {
|
||||
if isFieldSelector(cond.X, "m", "Items") && isIdent(cond.Y, "nil") {
|
||||
cond.X = &ast.StarExpr{X: &ast.Ident{Name: "m"}}
|
||||
}
|
||||
}
|
||||
}
|
||||
if t.Init != nil {
|
||||
// Find form:
|
||||
// if err := m[len(m.Items)-1].Unmarshal(data[iNdEx:postIndex]); err != nil {
|
||||
// return err
|
||||
// }
|
||||
switch s := t.Init.(type) {
|
||||
case *ast.AssignStmt:
|
||||
if call, ok := s.Rhs[0].(*ast.CallExpr); ok {
|
||||
if sel, ok := call.Fun.(*ast.SelectorExpr); ok {
|
||||
if x, ok := sel.X.(*ast.IndexExpr); ok {
|
||||
// m[] -> (*m)[]
|
||||
if sel2, ok := x.X.(*ast.SelectorExpr); ok {
|
||||
if ident, ok := sel2.X.(*ast.Ident); ok && ident.Name == "m" {
|
||||
x.X = &ast.StarExpr{X: &ast.Ident{Name: "m"}}
|
||||
}
|
||||
}
|
||||
// len(m.Items) -> len(*m)
|
||||
if bin, ok := x.Index.(*ast.BinaryExpr); ok {
|
||||
if call2, ok := bin.X.(*ast.CallExpr); ok && len(call2.Args) == 1 {
|
||||
if isFieldSelector(call2.Args[0], "m", "Items") {
|
||||
call2.Args[0] = &ast.StarExpr{X: &ast.Ident{Name: "m"}}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case *ast.IndexExpr:
|
||||
if isFieldSelector(t.X, "m", "Items") {
|
||||
t.X = &ast.Ident{Name: "m"}
|
||||
return nil
|
||||
}
|
||||
case *ast.CallExpr:
|
||||
changed := false
|
||||
for i := range t.Args {
|
||||
if isFieldSelector(t.Args[i], "m", "Items") {
|
||||
t.Args[i] = &ast.Ident{Name: "m"}
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
if changed {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func isFieldSelector(n ast.Expr, name, field string) bool {
|
||||
s, ok := n.(*ast.SelectorExpr)
|
||||
if !ok || s.Sel == nil || (field != "" && s.Sel.Name != field) {
|
||||
return false
|
||||
}
|
||||
return isIdent(s.X, name)
|
||||
}
|
||||
|
||||
func isIdent(n ast.Expr, value string) bool {
|
||||
ident, ok := n.(*ast.Ident)
|
||||
return ok && ident.Name == value
|
||||
}
|
||||
|
||||
func receiver(f *ast.FuncDecl) (ident *ast.Ident, pointer bool, ok bool) {
|
||||
if f.Recv == nil || len(f.Recv.List) != 1 {
|
||||
return nil, false, false
|
||||
}
|
||||
switch t := f.Recv.List[0].Type.(type) {
|
||||
case *ast.StarExpr:
|
||||
identity, ok := t.X.(*ast.Ident)
|
||||
if !ok {
|
||||
return nil, false, false
|
||||
}
|
||||
return identity, true, true
|
||||
case *ast.Ident:
|
||||
return t, false, true
|
||||
}
|
||||
return nil, false, false
|
||||
}
|
||||
|
||||
// dropExistingTypeDeclarations removes any type declaration for which extractFn returns true. The function
|
||||
// returns true if the entire declaration should be dropped.
|
||||
func dropExistingTypeDeclarations(decl ast.Decl, extractFn ExtractFunc) bool {
|
||||
switch t := decl.(type) {
|
||||
case *ast.GenDecl:
|
||||
if t.Tok != token.TYPE {
|
||||
return false
|
||||
}
|
||||
specs := []ast.Spec{}
|
||||
for _, s := range t.Specs {
|
||||
switch spec := s.(type) {
|
||||
case *ast.TypeSpec:
|
||||
if extractFn(spec) {
|
||||
continue
|
||||
}
|
||||
specs = append(specs, spec)
|
||||
}
|
||||
}
|
||||
if len(specs) == 0 {
|
||||
return true
|
||||
}
|
||||
t.Specs = specs
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// dropEmptyImportDeclarations strips any generated but no-op imports from the generated code
|
||||
// to prevent generation from being able to define side-effects. The function returns true
|
||||
// if the entire declaration should be dropped.
|
||||
func dropEmptyImportDeclarations(decl ast.Decl) bool {
|
||||
switch t := decl.(type) {
|
||||
case *ast.GenDecl:
|
||||
if t.Tok != token.IMPORT {
|
||||
return false
|
||||
}
|
||||
specs := []ast.Spec{}
|
||||
for _, s := range t.Specs {
|
||||
switch spec := s.(type) {
|
||||
case *ast.ImportSpec:
|
||||
if spec.Name != nil && spec.Name.Name == "_" {
|
||||
continue
|
||||
}
|
||||
specs = append(specs, spec)
|
||||
}
|
||||
}
|
||||
if len(specs) == 0 {
|
||||
return true
|
||||
}
|
||||
t.Specs = specs
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func RewriteTypesWithProtobufStructTags(name string, structTags map[string]map[string]string) error {
|
||||
return rewriteFile(name, []byte{}, func(fset *token.FileSet, file *ast.File) error {
|
||||
allErrs := []error{}
|
||||
|
||||
// set any new struct tags
|
||||
for _, d := range file.Decls {
|
||||
if errs := updateStructTags(d, structTags, []string{"protobuf"}); len(errs) > 0 {
|
||||
allErrs = append(allErrs, errs...)
|
||||
}
|
||||
}
|
||||
|
||||
if len(allErrs) > 0 {
|
||||
var s string
|
||||
for _, err := range allErrs {
|
||||
s += err.Error() + "\n"
|
||||
}
|
||||
return errors.New(s)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func updateStructTags(decl ast.Decl, structTags map[string]map[string]string, toCopy []string) []error {
|
||||
var errs []error
|
||||
t, ok := decl.(*ast.GenDecl)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
if t.Tok != token.TYPE {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, s := range t.Specs {
|
||||
spec, ok := s.(*ast.TypeSpec)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
typeName := spec.Name.Name
|
||||
fieldTags, ok := structTags[typeName]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
st, ok := spec.Type.(*ast.StructType)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
for i := range st.Fields.List {
|
||||
f := st.Fields.List[i]
|
||||
var name string
|
||||
if len(f.Names) == 0 {
|
||||
switch t := f.Type.(type) {
|
||||
case *ast.Ident:
|
||||
name = t.Name
|
||||
case *ast.SelectorExpr:
|
||||
name = t.Sel.Name
|
||||
default:
|
||||
errs = append(errs, fmt.Errorf("unable to get name for tag from struct %q, field %#v", spec.Name.Name, t))
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
name = f.Names[0].Name
|
||||
}
|
||||
value, ok := fieldTags[name]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
var tags customreflect.StructTags
|
||||
if f.Tag != nil {
|
||||
oldTags, err := customreflect.ParseStructTags(strings.Trim(f.Tag.Value, "`"))
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("unable to read struct tag from struct %q, field %q: %v", spec.Name.Name, name, err))
|
||||
continue
|
||||
}
|
||||
tags = oldTags
|
||||
}
|
||||
for _, name := range toCopy {
|
||||
// don't overwrite existing tags
|
||||
if tags.Has(name) {
|
||||
continue
|
||||
}
|
||||
// append new tags
|
||||
if v := reflect.StructTag(value).Get(name); len(v) > 0 {
|
||||
tags = append(tags, customreflect.StructTag{Name: name, Value: v})
|
||||
}
|
||||
}
|
||||
if len(tags) == 0 {
|
||||
continue
|
||||
}
|
||||
if f.Tag == nil {
|
||||
f.Tag = &ast.BasicLit{}
|
||||
}
|
||||
f.Tag.Value = tags.String()
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
33
vendor/k8s.io/gengo/examples/go-to-protobuf/protobuf/tags.go
generated
vendored
Normal file
33
vendor/k8s.io/gengo/examples/go-to-protobuf/protobuf/tags.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 protobuf
|
||||
|
||||
import (
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/gengo/types"
|
||||
)
|
||||
|
||||
// extractBoolTagOrDie gets the comment-tags for the key and asserts that, if
|
||||
// it exists, the value is boolean. If the tag did not exist, it returns
|
||||
// false.
|
||||
func extractBoolTagOrDie(key string, lines []string) bool {
|
||||
val, err := types.ExtractSingleBoolCommentTag("+", key, false, lines)
|
||||
if err != nil {
|
||||
glog.Fatalf(err.Error())
|
||||
}
|
||||
return val
|
||||
}
|
32
vendor/k8s.io/gengo/examples/go-to-protobuf/protoc-gen-gogo/main.go
generated
vendored
Normal file
32
vendor/k8s.io/gengo/examples/go-to-protobuf/protoc-gen-gogo/main.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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 main defines the protoc-gen-gogo binary we use to generate our proto go files,
|
||||
// as well as takes dependencies on the correct gogo/protobuf packages for godeps.
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gogo/protobuf/vanity/command"
|
||||
|
||||
// dependencies that are required for our packages
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
_ "github.com/gogo/protobuf/proto"
|
||||
_ "github.com/gogo/protobuf/sortkeys"
|
||||
)
|
||||
|
||||
func main() {
|
||||
command.Write(command.Generate(command.Read()))
|
||||
}
|
1
vendor/k8s.io/gengo/examples/import-boss/.gitignore
generated
vendored
Normal file
1
vendor/k8s.io/gengo/examples/import-boss/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import-boss
|
272
vendor/k8s.io/gengo/examples/import-boss/generators/import_restrict.go
generated
vendored
Normal file
272
vendor/k8s.io/gengo/examples/import-boss/generators/import_restrict.go
generated
vendored
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 generators has the generators for the import-boss utility.
|
||||
package generators
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/gengo/args"
|
||||
"k8s.io/gengo/generator"
|
||||
"k8s.io/gengo/namer"
|
||||
"k8s.io/gengo/types"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
const (
|
||||
importBossFileType = "import-boss"
|
||||
)
|
||||
|
||||
// NameSystems returns the name system used by the generators in this package.
|
||||
func NameSystems() namer.NameSystems {
|
||||
return namer.NameSystems{
|
||||
"raw": namer.NewRawNamer("", nil),
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultNameSystem returns the default name system for ordering the types to be
|
||||
// processed by the generators in this package.
|
||||
func DefaultNameSystem() string {
|
||||
return "raw"
|
||||
}
|
||||
|
||||
// Packages makes the import-boss package definition.
|
||||
func Packages(c *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
|
||||
pkgs := generator.Packages{}
|
||||
c.FileTypes = map[string]generator.FileType{
|
||||
importBossFileType: importRuleFile{},
|
||||
}
|
||||
|
||||
for _, p := range c.Universe {
|
||||
if !arguments.InputIncludes(p) {
|
||||
// Don't run on e.g. third party dependencies.
|
||||
continue
|
||||
}
|
||||
savedPackage := p
|
||||
pkgs = append(pkgs, &generator.DefaultPackage{
|
||||
PackageName: p.Name,
|
||||
PackagePath: p.Path,
|
||||
// GeneratorFunc returns a list of generators. Each generator makes a
|
||||
// single file.
|
||||
GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
|
||||
return []generator.Generator{&importRules{
|
||||
myPackage: savedPackage,
|
||||
}}
|
||||
},
|
||||
FilterFunc: func(c *generator.Context, t *types.Type) bool {
|
||||
return false
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return pkgs
|
||||
}
|
||||
|
||||
// A single import restriction rule.
|
||||
type Rule struct {
|
||||
// All import paths that match this regexp...
|
||||
SelectorRegexp string
|
||||
// ... must have one of these prefixes ...
|
||||
AllowedPrefixes []string
|
||||
// ... and must not have one of these prefixes.
|
||||
ForbiddenPrefixes []string
|
||||
}
|
||||
|
||||
type fileFormat struct {
|
||||
CurrentImports []string
|
||||
|
||||
Rules []Rule
|
||||
}
|
||||
|
||||
func readFile(path string) (*fileFormat, error) {
|
||||
currentBytes, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't read %v: %v", path, err)
|
||||
}
|
||||
|
||||
var current fileFormat
|
||||
err = json.Unmarshal(currentBytes, ¤t)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't unmarshal %v: %v", path, err)
|
||||
}
|
||||
return ¤t, nil
|
||||
}
|
||||
|
||||
func writeFile(path string, ff *fileFormat) error {
|
||||
raw, err := json.MarshalIndent(ff, "", "\t")
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't format data for file %v.\n%#v", path, ff)
|
||||
}
|
||||
f, err := os.Create(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't open %v for writing: %v", path, err)
|
||||
}
|
||||
defer f.Close()
|
||||
_, err = f.Write(raw)
|
||||
return err
|
||||
}
|
||||
|
||||
// This does the actual checking, since it knows the literal destination file.
|
||||
type importRuleFile struct{}
|
||||
|
||||
func (importRuleFile) AssembleFile(f *generator.File, path string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: make a flag to enable this, or expose this information in some other way.
|
||||
func (importRuleFile) listEntireImportTree(f *generator.File, path string) error {
|
||||
// If the file exists, populate its current imports. This is mostly to help
|
||||
// humans figure out what they need to fix.
|
||||
if _, err := os.Stat(path); err != nil {
|
||||
// Ignore packages which haven't opted in by adding an .import-restrictions file.
|
||||
return nil
|
||||
}
|
||||
|
||||
current, err := readFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
current.CurrentImports = []string{}
|
||||
for v := range f.Imports {
|
||||
current.CurrentImports = append(current.CurrentImports, v)
|
||||
}
|
||||
sort.Strings(current.CurrentImports)
|
||||
|
||||
return writeFile(path, current)
|
||||
}
|
||||
|
||||
// removeLastDir removes the last directory, but leaves the file name
|
||||
// unchanged. It returns the new path and the removed directory. So:
|
||||
// "a/b/c/file" -> ("a/b/file", "c")
|
||||
func removeLastDir(path string) (newPath, removedDir string) {
|
||||
dir, file := filepath.Split(path)
|
||||
dir = strings.TrimSuffix(dir, string(filepath.Separator))
|
||||
return filepath.Join(filepath.Dir(dir), file), filepath.Base(dir)
|
||||
}
|
||||
|
||||
// Keep going up a directory until we find an .import-restrictions file.
|
||||
func recursiveRead(path string) (*fileFormat, string, error) {
|
||||
for {
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
ff, err := readFile(path)
|
||||
return ff, path, err
|
||||
}
|
||||
|
||||
nextPath, removedDir := removeLastDir(path)
|
||||
if nextPath == path || removedDir == "src" {
|
||||
break
|
||||
}
|
||||
path = nextPath
|
||||
}
|
||||
return nil, "", nil
|
||||
}
|
||||
|
||||
func (importRuleFile) VerifyFile(f *generator.File, path string) error {
|
||||
rules, actualPath, err := recursiveRead(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error finding rules file: %v", err)
|
||||
}
|
||||
|
||||
if rules == nil {
|
||||
// No restrictions on this directory.
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, r := range rules.Rules {
|
||||
re, err := regexp.Compile(r.SelectorRegexp)
|
||||
if err != nil {
|
||||
return fmt.Errorf("regexp `%s` in file %q doesn't compile: %v", r.SelectorRegexp, actualPath, err)
|
||||
}
|
||||
for v := range f.Imports {
|
||||
glog.V(4).Infof("Checking %v matches %v: %v\n", r.SelectorRegexp, v, re.MatchString(v))
|
||||
if !re.MatchString(v) {
|
||||
continue
|
||||
}
|
||||
for _, forbidden := range r.ForbiddenPrefixes {
|
||||
glog.V(4).Infof("Checking %v against %v\n", v, forbidden)
|
||||
if strings.HasPrefix(v, forbidden) {
|
||||
return fmt.Errorf("import %v has forbidden prefix %v", v, forbidden)
|
||||
}
|
||||
}
|
||||
found := false
|
||||
for _, allowed := range r.AllowedPrefixes {
|
||||
glog.V(4).Infof("Checking %v against %v\n", v, allowed)
|
||||
if strings.HasPrefix(v, allowed) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return fmt.Errorf("import %v did not match any allowed prefix", v)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(rules.Rules) > 0 {
|
||||
glog.V(2).Infof("%v passes rules found in %v\n", path, actualPath)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// importRules produces a file with a set for a single type.
|
||||
type importRules struct {
|
||||
myPackage *types.Package
|
||||
imports namer.ImportTracker
|
||||
}
|
||||
|
||||
var (
|
||||
_ = generator.Generator(&importRules{})
|
||||
_ = generator.FileType(importRuleFile{})
|
||||
)
|
||||
|
||||
func (r *importRules) Name() string { return "import rules" }
|
||||
func (r *importRules) Filter(*generator.Context, *types.Type) bool { return false }
|
||||
func (r *importRules) Namers(*generator.Context) namer.NameSystems { return nil }
|
||||
func (r *importRules) PackageVars(*generator.Context) []string { return []string{} }
|
||||
func (r *importRules) PackageConsts(*generator.Context) []string { return []string{} }
|
||||
func (r *importRules) GenerateType(*generator.Context, *types.Type, io.Writer) error { return nil }
|
||||
func (r *importRules) Filename() string { return ".import-restrictions" }
|
||||
func (r *importRules) FileType() string { return importBossFileType }
|
||||
func (r *importRules) Init(c *generator.Context, w io.Writer) error { return nil }
|
||||
func (r *importRules) Finalize(*generator.Context, io.Writer) error { return nil }
|
||||
|
||||
func dfsImports(dest *[]string, seen map[string]bool, p *types.Package) {
|
||||
for _, p2 := range p.Imports {
|
||||
if seen[p2.Path] {
|
||||
continue
|
||||
}
|
||||
seen[p2.Path] = true
|
||||
dfsImports(dest, seen, p2)
|
||||
*dest = append(*dest, p2.Path)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *importRules) Imports(*generator.Context) []string {
|
||||
all := []string{}
|
||||
dfsImports(&all, map[string]bool{}, r.myPackage)
|
||||
return all
|
||||
}
|
39
vendor/k8s.io/gengo/examples/import-boss/generators/import_restrict_test.go
generated
vendored
Normal file
39
vendor/k8s.io/gengo/examples/import-boss/generators/import_restrict_test.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 generators
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRemoveLastDir(t *testing.T) {
|
||||
table := map[string]struct{ newPath, removedDir string }{
|
||||
"a/b/c": {"a/c", "b"},
|
||||
}
|
||||
for slashInput, expect := range table {
|
||||
input := filepath.FromSlash(slashInput)
|
||||
|
||||
gotPath, gotRemoved := removeLastDir(input)
|
||||
if e, a := filepath.FromSlash(expect.newPath), gotPath; e != a {
|
||||
t.Errorf("%v: wanted %v, got %v", input, e, a)
|
||||
}
|
||||
if e, a := filepath.FromSlash(expect.removedDir), gotRemoved; e != a {
|
||||
t.Errorf("%v: wanted %v, got %v", input, e, a)
|
||||
}
|
||||
}
|
||||
}
|
78
vendor/k8s.io/gengo/examples/import-boss/main.go
generated
vendored
Normal file
78
vendor/k8s.io/gengo/examples/import-boss/main.go
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// import-boss enforces import restrictions in a given repository.
|
||||
//
|
||||
// When a directory is verified, import-boss looks for a file called
|
||||
// ".import-restrictions". If this file is not found, parent directories will be
|
||||
// recursively searched.
|
||||
//
|
||||
// If an ".import-restrictions" file is found, then all imports of the package
|
||||
// are checked against each "rule" in the file. A rule consists of three parts:
|
||||
// * A SelectorRegexp, to select the import paths that the rule applies to.
|
||||
// * A list of AllowedPrefixes
|
||||
// * A list of ForbiddenPrefixes
|
||||
// An import is allowed if it matches at least one allowed prefix and does not
|
||||
// match any forbidden prefix. An example file looks like this:
|
||||
//
|
||||
// {
|
||||
// "Rules": [
|
||||
// {
|
||||
// "SelectorRegexp": "k8s[.]io",
|
||||
// "AllowedPrefixes": [
|
||||
// "k8s.io/gengo",
|
||||
// "k8s.io/kubernetes/third_party"
|
||||
// ],
|
||||
// "ForbiddenPrefixes": [
|
||||
// "k8s.io/kubernetes/pkg/third_party/deprecated"
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// "SelectorRegexp": "^unsafe$",
|
||||
// "AllowedPrefixes": [
|
||||
// ],
|
||||
// "ForbiddenPrefixes": [
|
||||
// ""
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
//
|
||||
// Note the secound block explicitly matches the unsafe package, and forbids it
|
||||
// ("" is a prefix of everything).
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"k8s.io/gengo/args"
|
||||
"k8s.io/gengo/examples/import-boss/generators"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
func main() {
|
||||
arguments := args.Default()
|
||||
if err := arguments.Execute(
|
||||
generators.NameSystems(),
|
||||
generators.DefaultNameSystem(),
|
||||
generators.Packages,
|
||||
); err != nil {
|
||||
glog.Errorf("Error: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
glog.V(2).Info("Completed successfully.")
|
||||
}
|
1
vendor/k8s.io/gengo/examples/set-gen/.gitignore
generated
vendored
Normal file
1
vendor/k8s.io/gengo/examples/set-gen/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
set-gen
|
15
vendor/k8s.io/gengo/examples/set-gen/Makefile
generated
vendored
Normal file
15
vendor/k8s.io/gengo/examples/set-gen/Makefile
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
TOOL=set-gen
|
||||
|
||||
test:
|
||||
@if ! git diff --quiet HEAD; then \
|
||||
echo "FAIL: git client is not clean"; \
|
||||
false; \
|
||||
fi
|
||||
@go build -o /tmp/$(TOOL)
|
||||
@PKGS=$$(go list ./sets/types | paste -sd' ' -); \
|
||||
/tmp/$(TOOL) --logtostderr --v=4 -i $$(echo $$PKGS | sed 's/ /,/g') -O zz_generated -o ./sets
|
||||
@if ! git diff --quiet HEAD; then \
|
||||
echo "FAIL: output files changed"; \
|
||||
git diff; \
|
||||
false; \
|
||||
fi
|
360
vendor/k8s.io/gengo/examples/set-gen/generators/sets.go
generated
vendored
Normal file
360
vendor/k8s.io/gengo/examples/set-gen/generators/sets.go
generated
vendored
Normal file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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 generators has the generators for the set-gen utility.
|
||||
package generators
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"k8s.io/gengo/args"
|
||||
"k8s.io/gengo/generator"
|
||||
"k8s.io/gengo/namer"
|
||||
"k8s.io/gengo/types"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// NameSystems returns the name system used by the generators in this package.
|
||||
func NameSystems() namer.NameSystems {
|
||||
return namer.NameSystems{
|
||||
"public": namer.NewPublicNamer(0),
|
||||
"private": namer.NewPrivateNamer(0),
|
||||
"raw": namer.NewRawNamer("", nil),
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultNameSystem returns the default name system for ordering the types to be
|
||||
// processed by the generators in this package.
|
||||
func DefaultNameSystem() string {
|
||||
return "public"
|
||||
}
|
||||
|
||||
// Packages makes the sets package definition.
|
||||
func Packages(_ *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
|
||||
boilerplate, err := arguments.LoadGoBoilerplate()
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed loading boilerplate: %v", err)
|
||||
}
|
||||
|
||||
return generator.Packages{&generator.DefaultPackage{
|
||||
PackageName: "sets",
|
||||
PackagePath: arguments.OutputPackagePath,
|
||||
HeaderText: boilerplate,
|
||||
PackageDocumentation: []byte(
|
||||
`// Package sets has auto-generated set types.
|
||||
`),
|
||||
// GeneratorFunc returns a list of generators. Each generator makes a
|
||||
// single file.
|
||||
GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
|
||||
generators = []generator.Generator{
|
||||
// Always generate a "doc.go" file.
|
||||
generator.DefaultGen{OptionalName: "doc"},
|
||||
// Make a separate file for the Empty type, since it's shared by every type.
|
||||
generator.DefaultGen{
|
||||
OptionalName: "empty",
|
||||
OptionalBody: []byte(emptyTypeDecl),
|
||||
},
|
||||
}
|
||||
// Since we want a file per type that we generate a set for, we
|
||||
// have to provide a function for this.
|
||||
for _, t := range c.Order {
|
||||
generators = append(generators, &genSet{
|
||||
DefaultGen: generator.DefaultGen{
|
||||
// Use the privatized version of the
|
||||
// type name as the file name.
|
||||
//
|
||||
// TODO: make a namer that converts
|
||||
// camelCase to '-' separation for file
|
||||
// names?
|
||||
OptionalName: c.Namers["private"].Name(t),
|
||||
},
|
||||
outputPackage: arguments.OutputPackagePath,
|
||||
typeToMatch: t,
|
||||
imports: generator.NewImportTracker(),
|
||||
})
|
||||
}
|
||||
return generators
|
||||
},
|
||||
FilterFunc: func(c *generator.Context, t *types.Type) bool {
|
||||
// It would be reasonable to filter by the type's package here.
|
||||
// It might be necessary if your input directory has a big
|
||||
// import graph.
|
||||
switch t.Kind {
|
||||
case types.Map, types.Slice, types.Pointer:
|
||||
// These types can't be keys in a map.
|
||||
return false
|
||||
case types.Builtin:
|
||||
return true
|
||||
case types.Struct:
|
||||
// Only some structs can be keys in a map. This is triggered by the line
|
||||
// // +genset
|
||||
// or
|
||||
// // +genset=true
|
||||
return extractBoolTagOrDie("genset", t.CommentLines) == true
|
||||
}
|
||||
return false
|
||||
},
|
||||
}}
|
||||
}
|
||||
|
||||
// genSet produces a file with a set for a single type.
|
||||
type genSet struct {
|
||||
generator.DefaultGen
|
||||
outputPackage string
|
||||
typeToMatch *types.Type
|
||||
imports namer.ImportTracker
|
||||
}
|
||||
|
||||
// Filter ignores all but one type because we're making a single file per type.
|
||||
func (g *genSet) Filter(c *generator.Context, t *types.Type) bool { return t == g.typeToMatch }
|
||||
|
||||
func (g *genSet) Namers(c *generator.Context) namer.NameSystems {
|
||||
return namer.NameSystems{
|
||||
"raw": namer.NewRawNamer(g.outputPackage, g.imports),
|
||||
}
|
||||
}
|
||||
|
||||
func (g *genSet) Imports(c *generator.Context) (imports []string) {
|
||||
return append(g.imports.ImportLines(), "reflect", "sort")
|
||||
}
|
||||
|
||||
// args constructs arguments for templates. Usage:
|
||||
// g.args(t, "key1", value1, "key2", value2, ...)
|
||||
//
|
||||
// 't' is loaded with the key 'type'.
|
||||
//
|
||||
// We could use t directly as the argument, but doing it this way makes it easy
|
||||
// to mix in additional parameters. This feature is not used in this set
|
||||
// generator, but is present as an example.
|
||||
func (g *genSet) args(t *types.Type, kv ...interface{}) interface{} {
|
||||
m := map[interface{}]interface{}{"type": t}
|
||||
for i := 0; i < len(kv)/2; i++ {
|
||||
m[kv[i*2]] = kv[i*2+1]
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// GenerateType makes the body of a file implementing a set for type t.
|
||||
func (g *genSet) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
|
||||
sw := generator.NewSnippetWriter(w, c, "$", "$")
|
||||
sw.Do(setCode, g.args(t))
|
||||
sw.Do("func less$.type|public$(lhs, rhs $.type|raw$) bool {\n", g.args(t))
|
||||
g.lessBody(sw, t)
|
||||
sw.Do("}\n", g.args(t))
|
||||
return sw.Error()
|
||||
}
|
||||
|
||||
func (g *genSet) lessBody(sw *generator.SnippetWriter, t *types.Type) {
|
||||
// TODO: make this recursive, handle pointers and multiple nested structs...
|
||||
switch t.Kind {
|
||||
case types.Struct:
|
||||
for _, m := range types.FlattenMembers(t.Members) {
|
||||
sw.Do("if lhs.$.Name$ < rhs.$.Name$ { return true }\n", m)
|
||||
sw.Do("if lhs.$.Name$ > rhs.$.Name$ { return false }\n", m)
|
||||
}
|
||||
sw.Do("return false\n", nil)
|
||||
default:
|
||||
sw.Do("return lhs < rhs\n", nil)
|
||||
}
|
||||
}
|
||||
|
||||
// written to the "empty.go" file.
|
||||
var emptyTypeDecl = `
|
||||
// Empty is public since it is used by some internal API objects for conversions between external
|
||||
// string arrays and internal sets, and conversion logic requires public types today.
|
||||
type Empty struct{}
|
||||
`
|
||||
|
||||
// Written for every type. If you've never used text/template before:
|
||||
// $.type$ refers to the source type; |public means to
|
||||
// call the function giving the public name, |raw the raw type name.
|
||||
var setCode = `// sets.$.type|public$ is a set of $.type|raw$s, implemented via map[$.type|raw$]struct{} for minimal memory consumption.
|
||||
type $.type|public$ map[$.type|raw$]Empty
|
||||
|
||||
// New$.type|public$ creates a $.type|public$ from a list of values.
|
||||
func New$.type|public$(items ...$.type|raw$) $.type|public$ {
|
||||
ss := $.type|public${}
|
||||
ss.Insert(items...)
|
||||
return ss
|
||||
}
|
||||
|
||||
// $.type|public$KeySet creates a $.type|public$ from a keys of a map[$.type|raw$](? extends interface{}).
|
||||
// If the value passed in is not actually a map, this will panic.
|
||||
func $.type|public$KeySet(theMap interface{}) $.type|public$ {
|
||||
v := reflect.ValueOf(theMap)
|
||||
ret := $.type|public${}
|
||||
|
||||
for _, keyValue := range v.MapKeys() {
|
||||
ret.Insert(keyValue.Interface().($.type|raw$))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Insert adds items to the set.
|
||||
func (s $.type|public$) Insert(items ...$.type|raw$) {
|
||||
for _, item := range items {
|
||||
s[item] = Empty{}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete removes all items from the set.
|
||||
func (s $.type|public$) Delete(items ...$.type|raw$) {
|
||||
for _, item := range items {
|
||||
delete(s, item)
|
||||
}
|
||||
}
|
||||
|
||||
// Has returns true if and only if item is contained in the set.
|
||||
func (s $.type|public$) Has(item $.type|raw$) bool {
|
||||
_, contained := s[item]
|
||||
return contained
|
||||
}
|
||||
|
||||
// HasAll returns true if and only if all items are contained in the set.
|
||||
func (s $.type|public$) HasAll(items ...$.type|raw$) bool {
|
||||
for _, item := range items {
|
||||
if !s.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// HasAny returns true if any items are contained in the set.
|
||||
func (s $.type|public$) HasAny(items ...$.type|raw$) bool {
|
||||
for _, item := range items {
|
||||
if s.Has(item) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Difference returns a set of objects that are not in s2
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.Difference(s2) = {a3}
|
||||
// s2.Difference(s1) = {a4, a5}
|
||||
func (s $.type|public$) Difference(s2 $.type|public$) $.type|public$ {
|
||||
result := New$.type|public$()
|
||||
for key := range s {
|
||||
if !s2.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Union returns a new set which includes items in either s1 or s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a3, a4}
|
||||
// s1.Union(s2) = {a1, a2, a3, a4}
|
||||
// s2.Union(s1) = {a1, a2, a3, a4}
|
||||
func (s1 $.type|public$) Union(s2 $.type|public$) $.type|public$ {
|
||||
result := New$.type|public$()
|
||||
for key := range s1 {
|
||||
result.Insert(key)
|
||||
}
|
||||
for key := range s2 {
|
||||
result.Insert(key)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Intersection returns a new set which includes the item in BOTH s1 and s2
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a2, a3}
|
||||
// s1.Intersection(s2) = {a2}
|
||||
func (s1 $.type|public$) Intersection(s2 $.type|public$) $.type|public$ {
|
||||
var walk, other $.type|public$
|
||||
result := New$.type|public$()
|
||||
if s1.Len() < s2.Len() {
|
||||
walk = s1
|
||||
other = s2
|
||||
} else {
|
||||
walk = s2
|
||||
other = s1
|
||||
}
|
||||
for key := range walk {
|
||||
if other.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// IsSuperset returns true if and only if s1 is a superset of s2.
|
||||
func (s1 $.type|public$) IsSuperset(s2 $.type|public$) bool {
|
||||
for item := range s2 {
|
||||
if !s1.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Equal returns true if and only if s1 is equal (as a set) to s2.
|
||||
// Two sets are equal if their membership is identical.
|
||||
// (In practice, this means same elements, order doesn't matter)
|
||||
func (s1 $.type|public$) Equal(s2 $.type|public$) bool {
|
||||
return len(s1) == len(s2) && s1.IsSuperset(s2)
|
||||
}
|
||||
|
||||
type sortableSliceOf$.type|public$ []$.type|raw$
|
||||
|
||||
func (s sortableSliceOf$.type|public$) Len() int { return len(s) }
|
||||
func (s sortableSliceOf$.type|public$) Less(i, j int) bool { return less$.type|public$(s[i], s[j]) }
|
||||
func (s sortableSliceOf$.type|public$) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// List returns the contents as a sorted $.type|raw$ slice.
|
||||
func (s $.type|public$) List() []$.type|raw$ {
|
||||
res := make(sortableSliceOf$.type|public$, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
sort.Sort(res)
|
||||
return []$.type|raw$(res)
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s $.type|public$) UnsortedList() []$.type|raw$ {
|
||||
res :=make([]$.type|raw$, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Returns a single element from the set.
|
||||
func (s $.type|public$) PopAny() ($.type|raw$, bool) {
|
||||
for key := range s {
|
||||
s.Delete(key)
|
||||
return key, true
|
||||
}
|
||||
var zeroValue $.type|raw$
|
||||
return zeroValue, false
|
||||
}
|
||||
|
||||
// Len returns the size of the set.
|
||||
func (s $.type|public$) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
`
|
33
vendor/k8s.io/gengo/examples/set-gen/generators/tags.go
generated
vendored
Normal file
33
vendor/k8s.io/gengo/examples/set-gen/generators/tags.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 generators
|
||||
|
||||
import (
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/gengo/types"
|
||||
)
|
||||
|
||||
// extractBoolTagOrDie gets the comment-tags for the key and asserts that, if
|
||||
// it exists, the value is boolean. If the tag did not exist, it returns
|
||||
// false.
|
||||
func extractBoolTagOrDie(key string, lines []string) bool {
|
||||
val, err := types.ExtractSingleBoolCommentTag("+", key, false, lines)
|
||||
if err != nil {
|
||||
glog.Fatalf(err.Error())
|
||||
}
|
||||
return val
|
||||
}
|
47
vendor/k8s.io/gengo/examples/set-gen/main.go
generated
vendored
Normal file
47
vendor/k8s.io/gengo/examples/set-gen/main.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// set-gen is an example usage of go2idl.
|
||||
//
|
||||
// Structs in the input directories with the below line in their comments will
|
||||
// have sets generated for them.
|
||||
// // +genset
|
||||
//
|
||||
// Any builtin type referenced anywhere in the input directories will have a
|
||||
// set generated for it.
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"k8s.io/gengo/args"
|
||||
"k8s.io/gengo/examples/set-gen/generators"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
func main() {
|
||||
arguments := args.Default()
|
||||
if err := arguments.Execute(
|
||||
generators.NameSystems(),
|
||||
generators.DefaultNameSystem(),
|
||||
generators.Packages,
|
||||
); err != nil {
|
||||
glog.Errorf("Error: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
glog.V(2).Info("Completed successfully.")
|
||||
}
|
203
vendor/k8s.io/gengo/examples/set-gen/sets/byte.go
generated
vendored
Normal file
203
vendor/k8s.io/gengo/examples/set-gen/sets/byte.go
generated
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by set-gen. DO NOT EDIT.
|
||||
|
||||
package sets
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// sets.Byte is a set of bytes, implemented via map[byte]struct{} for minimal memory consumption.
|
||||
type Byte map[byte]Empty
|
||||
|
||||
// NewByte creates a Byte from a list of values.
|
||||
func NewByte(items ...byte) Byte {
|
||||
ss := Byte{}
|
||||
ss.Insert(items...)
|
||||
return ss
|
||||
}
|
||||
|
||||
// ByteKeySet creates a Byte from a keys of a map[byte](? extends interface{}).
|
||||
// If the value passed in is not actually a map, this will panic.
|
||||
func ByteKeySet(theMap interface{}) Byte {
|
||||
v := reflect.ValueOf(theMap)
|
||||
ret := Byte{}
|
||||
|
||||
for _, keyValue := range v.MapKeys() {
|
||||
ret.Insert(keyValue.Interface().(byte))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Insert adds items to the set.
|
||||
func (s Byte) Insert(items ...byte) {
|
||||
for _, item := range items {
|
||||
s[item] = Empty{}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete removes all items from the set.
|
||||
func (s Byte) Delete(items ...byte) {
|
||||
for _, item := range items {
|
||||
delete(s, item)
|
||||
}
|
||||
}
|
||||
|
||||
// Has returns true if and only if item is contained in the set.
|
||||
func (s Byte) Has(item byte) bool {
|
||||
_, contained := s[item]
|
||||
return contained
|
||||
}
|
||||
|
||||
// HasAll returns true if and only if all items are contained in the set.
|
||||
func (s Byte) HasAll(items ...byte) bool {
|
||||
for _, item := range items {
|
||||
if !s.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// HasAny returns true if any items are contained in the set.
|
||||
func (s Byte) HasAny(items ...byte) bool {
|
||||
for _, item := range items {
|
||||
if s.Has(item) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Difference returns a set of objects that are not in s2
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.Difference(s2) = {a3}
|
||||
// s2.Difference(s1) = {a4, a5}
|
||||
func (s Byte) Difference(s2 Byte) Byte {
|
||||
result := NewByte()
|
||||
for key := range s {
|
||||
if !s2.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Union returns a new set which includes items in either s1 or s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a3, a4}
|
||||
// s1.Union(s2) = {a1, a2, a3, a4}
|
||||
// s2.Union(s1) = {a1, a2, a3, a4}
|
||||
func (s1 Byte) Union(s2 Byte) Byte {
|
||||
result := NewByte()
|
||||
for key := range s1 {
|
||||
result.Insert(key)
|
||||
}
|
||||
for key := range s2 {
|
||||
result.Insert(key)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Intersection returns a new set which includes the item in BOTH s1 and s2
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a2, a3}
|
||||
// s1.Intersection(s2) = {a2}
|
||||
func (s1 Byte) Intersection(s2 Byte) Byte {
|
||||
var walk, other Byte
|
||||
result := NewByte()
|
||||
if s1.Len() < s2.Len() {
|
||||
walk = s1
|
||||
other = s2
|
||||
} else {
|
||||
walk = s2
|
||||
other = s1
|
||||
}
|
||||
for key := range walk {
|
||||
if other.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// IsSuperset returns true if and only if s1 is a superset of s2.
|
||||
func (s1 Byte) IsSuperset(s2 Byte) bool {
|
||||
for item := range s2 {
|
||||
if !s1.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Equal returns true if and only if s1 is equal (as a set) to s2.
|
||||
// Two sets are equal if their membership is identical.
|
||||
// (In practice, this means same elements, order doesn't matter)
|
||||
func (s1 Byte) Equal(s2 Byte) bool {
|
||||
return len(s1) == len(s2) && s1.IsSuperset(s2)
|
||||
}
|
||||
|
||||
type sortableSliceOfByte []byte
|
||||
|
||||
func (s sortableSliceOfByte) Len() int { return len(s) }
|
||||
func (s sortableSliceOfByte) Less(i, j int) bool { return lessByte(s[i], s[j]) }
|
||||
func (s sortableSliceOfByte) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// List returns the contents as a sorted byte slice.
|
||||
func (s Byte) List() []byte {
|
||||
res := make(sortableSliceOfByte, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
sort.Sort(res)
|
||||
return []byte(res)
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s Byte) UnsortedList() []byte {
|
||||
res := make([]byte, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Returns a single element from the set.
|
||||
func (s Byte) PopAny() (byte, bool) {
|
||||
for key := range s {
|
||||
s.Delete(key)
|
||||
return key, true
|
||||
}
|
||||
var zeroValue byte
|
||||
return zeroValue, false
|
||||
}
|
||||
|
||||
// Len returns the size of the set.
|
||||
func (s Byte) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func lessByte(lhs, rhs byte) bool {
|
||||
return lhs < rhs
|
||||
}
|
20
vendor/k8s.io/gengo/examples/set-gen/sets/doc.go
generated
vendored
Normal file
20
vendor/k8s.io/gengo/examples/set-gen/sets/doc.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by set-gen. DO NOT EDIT.
|
||||
|
||||
// Package sets has auto-generated set types.
|
||||
package sets
|
23
vendor/k8s.io/gengo/examples/set-gen/sets/empty.go
generated
vendored
Normal file
23
vendor/k8s.io/gengo/examples/set-gen/sets/empty.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by set-gen. DO NOT EDIT.
|
||||
|
||||
package sets
|
||||
|
||||
// Empty is public since it is used by some internal API objects for conversions between external
|
||||
// string arrays and internal sets, and conversion logic requires public types today.
|
||||
type Empty struct{}
|
203
vendor/k8s.io/gengo/examples/set-gen/sets/int.go
generated
vendored
Normal file
203
vendor/k8s.io/gengo/examples/set-gen/sets/int.go
generated
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by set-gen. DO NOT EDIT.
|
||||
|
||||
package sets
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// sets.Int is a set of ints, implemented via map[int]struct{} for minimal memory consumption.
|
||||
type Int map[int]Empty
|
||||
|
||||
// NewInt creates a Int from a list of values.
|
||||
func NewInt(items ...int) Int {
|
||||
ss := Int{}
|
||||
ss.Insert(items...)
|
||||
return ss
|
||||
}
|
||||
|
||||
// IntKeySet creates a Int from a keys of a map[int](? extends interface{}).
|
||||
// If the value passed in is not actually a map, this will panic.
|
||||
func IntKeySet(theMap interface{}) Int {
|
||||
v := reflect.ValueOf(theMap)
|
||||
ret := Int{}
|
||||
|
||||
for _, keyValue := range v.MapKeys() {
|
||||
ret.Insert(keyValue.Interface().(int))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Insert adds items to the set.
|
||||
func (s Int) Insert(items ...int) {
|
||||
for _, item := range items {
|
||||
s[item] = Empty{}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete removes all items from the set.
|
||||
func (s Int) Delete(items ...int) {
|
||||
for _, item := range items {
|
||||
delete(s, item)
|
||||
}
|
||||
}
|
||||
|
||||
// Has returns true if and only if item is contained in the set.
|
||||
func (s Int) Has(item int) bool {
|
||||
_, contained := s[item]
|
||||
return contained
|
||||
}
|
||||
|
||||
// HasAll returns true if and only if all items are contained in the set.
|
||||
func (s Int) HasAll(items ...int) bool {
|
||||
for _, item := range items {
|
||||
if !s.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// HasAny returns true if any items are contained in the set.
|
||||
func (s Int) HasAny(items ...int) bool {
|
||||
for _, item := range items {
|
||||
if s.Has(item) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Difference returns a set of objects that are not in s2
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.Difference(s2) = {a3}
|
||||
// s2.Difference(s1) = {a4, a5}
|
||||
func (s Int) Difference(s2 Int) Int {
|
||||
result := NewInt()
|
||||
for key := range s {
|
||||
if !s2.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Union returns a new set which includes items in either s1 or s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a3, a4}
|
||||
// s1.Union(s2) = {a1, a2, a3, a4}
|
||||
// s2.Union(s1) = {a1, a2, a3, a4}
|
||||
func (s1 Int) Union(s2 Int) Int {
|
||||
result := NewInt()
|
||||
for key := range s1 {
|
||||
result.Insert(key)
|
||||
}
|
||||
for key := range s2 {
|
||||
result.Insert(key)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Intersection returns a new set which includes the item in BOTH s1 and s2
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a2, a3}
|
||||
// s1.Intersection(s2) = {a2}
|
||||
func (s1 Int) Intersection(s2 Int) Int {
|
||||
var walk, other Int
|
||||
result := NewInt()
|
||||
if s1.Len() < s2.Len() {
|
||||
walk = s1
|
||||
other = s2
|
||||
} else {
|
||||
walk = s2
|
||||
other = s1
|
||||
}
|
||||
for key := range walk {
|
||||
if other.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// IsSuperset returns true if and only if s1 is a superset of s2.
|
||||
func (s1 Int) IsSuperset(s2 Int) bool {
|
||||
for item := range s2 {
|
||||
if !s1.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Equal returns true if and only if s1 is equal (as a set) to s2.
|
||||
// Two sets are equal if their membership is identical.
|
||||
// (In practice, this means same elements, order doesn't matter)
|
||||
func (s1 Int) Equal(s2 Int) bool {
|
||||
return len(s1) == len(s2) && s1.IsSuperset(s2)
|
||||
}
|
||||
|
||||
type sortableSliceOfInt []int
|
||||
|
||||
func (s sortableSliceOfInt) Len() int { return len(s) }
|
||||
func (s sortableSliceOfInt) Less(i, j int) bool { return lessInt(s[i], s[j]) }
|
||||
func (s sortableSliceOfInt) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// List returns the contents as a sorted int slice.
|
||||
func (s Int) List() []int {
|
||||
res := make(sortableSliceOfInt, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
sort.Sort(res)
|
||||
return []int(res)
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s Int) UnsortedList() []int {
|
||||
res := make([]int, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Returns a single element from the set.
|
||||
func (s Int) PopAny() (int, bool) {
|
||||
for key := range s {
|
||||
s.Delete(key)
|
||||
return key, true
|
||||
}
|
||||
var zeroValue int
|
||||
return zeroValue, false
|
||||
}
|
||||
|
||||
// Len returns the size of the set.
|
||||
func (s Int) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func lessInt(lhs, rhs int) bool {
|
||||
return lhs < rhs
|
||||
}
|
203
vendor/k8s.io/gengo/examples/set-gen/sets/int64.go
generated
vendored
Normal file
203
vendor/k8s.io/gengo/examples/set-gen/sets/int64.go
generated
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by set-gen. DO NOT EDIT.
|
||||
|
||||
package sets
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// sets.Int64 is a set of int64s, implemented via map[int64]struct{} for minimal memory consumption.
|
||||
type Int64 map[int64]Empty
|
||||
|
||||
// NewInt64 creates a Int64 from a list of values.
|
||||
func NewInt64(items ...int64) Int64 {
|
||||
ss := Int64{}
|
||||
ss.Insert(items...)
|
||||
return ss
|
||||
}
|
||||
|
||||
// Int64KeySet creates a Int64 from a keys of a map[int64](? extends interface{}).
|
||||
// If the value passed in is not actually a map, this will panic.
|
||||
func Int64KeySet(theMap interface{}) Int64 {
|
||||
v := reflect.ValueOf(theMap)
|
||||
ret := Int64{}
|
||||
|
||||
for _, keyValue := range v.MapKeys() {
|
||||
ret.Insert(keyValue.Interface().(int64))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Insert adds items to the set.
|
||||
func (s Int64) Insert(items ...int64) {
|
||||
for _, item := range items {
|
||||
s[item] = Empty{}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete removes all items from the set.
|
||||
func (s Int64) Delete(items ...int64) {
|
||||
for _, item := range items {
|
||||
delete(s, item)
|
||||
}
|
||||
}
|
||||
|
||||
// Has returns true if and only if item is contained in the set.
|
||||
func (s Int64) Has(item int64) bool {
|
||||
_, contained := s[item]
|
||||
return contained
|
||||
}
|
||||
|
||||
// HasAll returns true if and only if all items are contained in the set.
|
||||
func (s Int64) HasAll(items ...int64) bool {
|
||||
for _, item := range items {
|
||||
if !s.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// HasAny returns true if any items are contained in the set.
|
||||
func (s Int64) HasAny(items ...int64) bool {
|
||||
for _, item := range items {
|
||||
if s.Has(item) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Difference returns a set of objects that are not in s2
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.Difference(s2) = {a3}
|
||||
// s2.Difference(s1) = {a4, a5}
|
||||
func (s Int64) Difference(s2 Int64) Int64 {
|
||||
result := NewInt64()
|
||||
for key := range s {
|
||||
if !s2.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Union returns a new set which includes items in either s1 or s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a3, a4}
|
||||
// s1.Union(s2) = {a1, a2, a3, a4}
|
||||
// s2.Union(s1) = {a1, a2, a3, a4}
|
||||
func (s1 Int64) Union(s2 Int64) Int64 {
|
||||
result := NewInt64()
|
||||
for key := range s1 {
|
||||
result.Insert(key)
|
||||
}
|
||||
for key := range s2 {
|
||||
result.Insert(key)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Intersection returns a new set which includes the item in BOTH s1 and s2
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a2, a3}
|
||||
// s1.Intersection(s2) = {a2}
|
||||
func (s1 Int64) Intersection(s2 Int64) Int64 {
|
||||
var walk, other Int64
|
||||
result := NewInt64()
|
||||
if s1.Len() < s2.Len() {
|
||||
walk = s1
|
||||
other = s2
|
||||
} else {
|
||||
walk = s2
|
||||
other = s1
|
||||
}
|
||||
for key := range walk {
|
||||
if other.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// IsSuperset returns true if and only if s1 is a superset of s2.
|
||||
func (s1 Int64) IsSuperset(s2 Int64) bool {
|
||||
for item := range s2 {
|
||||
if !s1.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Equal returns true if and only if s1 is equal (as a set) to s2.
|
||||
// Two sets are equal if their membership is identical.
|
||||
// (In practice, this means same elements, order doesn't matter)
|
||||
func (s1 Int64) Equal(s2 Int64) bool {
|
||||
return len(s1) == len(s2) && s1.IsSuperset(s2)
|
||||
}
|
||||
|
||||
type sortableSliceOfInt64 []int64
|
||||
|
||||
func (s sortableSliceOfInt64) Len() int { return len(s) }
|
||||
func (s sortableSliceOfInt64) Less(i, j int) bool { return lessInt64(s[i], s[j]) }
|
||||
func (s sortableSliceOfInt64) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// List returns the contents as a sorted int64 slice.
|
||||
func (s Int64) List() []int64 {
|
||||
res := make(sortableSliceOfInt64, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
sort.Sort(res)
|
||||
return []int64(res)
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s Int64) UnsortedList() []int64 {
|
||||
res := make([]int64, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Returns a single element from the set.
|
||||
func (s Int64) PopAny() (int64, bool) {
|
||||
for key := range s {
|
||||
s.Delete(key)
|
||||
return key, true
|
||||
}
|
||||
var zeroValue int64
|
||||
return zeroValue, false
|
||||
}
|
||||
|
||||
// Len returns the size of the set.
|
||||
func (s Int64) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func lessInt64(lhs, rhs int64) bool {
|
||||
return lhs < rhs
|
||||
}
|
270
vendor/k8s.io/gengo/examples/set-gen/sets/set_test.go
generated
vendored
Normal file
270
vendor/k8s.io/gengo/examples/set-gen/sets/set_test.go
generated
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
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 sets
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStringSet(t *testing.T) {
|
||||
s := String{}
|
||||
s2 := String{}
|
||||
if len(s) != 0 {
|
||||
t.Errorf("Expected len=0: %d", len(s))
|
||||
}
|
||||
s.Insert("a", "b")
|
||||
if len(s) != 2 {
|
||||
t.Errorf("Expected len=2: %d", len(s))
|
||||
}
|
||||
s.Insert("c")
|
||||
if s.Has("d") {
|
||||
t.Errorf("Unexpected contents: %#v", s)
|
||||
}
|
||||
if !s.Has("a") {
|
||||
t.Errorf("Missing contents: %#v", s)
|
||||
}
|
||||
s.Delete("a")
|
||||
if s.Has("a") {
|
||||
t.Errorf("Unexpected contents: %#v", s)
|
||||
}
|
||||
s.Insert("a")
|
||||
if s.HasAll("a", "b", "d") {
|
||||
t.Errorf("Unexpected contents: %#v", s)
|
||||
}
|
||||
if !s.HasAll("a", "b") {
|
||||
t.Errorf("Missing contents: %#v", s)
|
||||
}
|
||||
s2.Insert("a", "b", "d")
|
||||
if s.IsSuperset(s2) {
|
||||
t.Errorf("Unexpected contents: %#v", s)
|
||||
}
|
||||
s2.Delete("d")
|
||||
if !s.IsSuperset(s2) {
|
||||
t.Errorf("Missing contents: %#v", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringSetDeleteMultiples(t *testing.T) {
|
||||
s := String{}
|
||||
s.Insert("a", "b", "c")
|
||||
if len(s) != 3 {
|
||||
t.Errorf("Expected len=3: %d", len(s))
|
||||
}
|
||||
|
||||
s.Delete("a", "c")
|
||||
if len(s) != 1 {
|
||||
t.Errorf("Expected len=1: %d", len(s))
|
||||
}
|
||||
if s.Has("a") {
|
||||
t.Errorf("Unexpected contents: %#v", s)
|
||||
}
|
||||
if s.Has("c") {
|
||||
t.Errorf("Unexpected contents: %#v", s)
|
||||
}
|
||||
if !s.Has("b") {
|
||||
t.Errorf("Missing contents: %#v", s)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestNewStringSet(t *testing.T) {
|
||||
s := NewString("a", "b", "c")
|
||||
if len(s) != 3 {
|
||||
t.Errorf("Expected len=3: %d", len(s))
|
||||
}
|
||||
if !s.Has("a") || !s.Has("b") || !s.Has("c") {
|
||||
t.Errorf("Unexpected contents: %#v", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringSetList(t *testing.T) {
|
||||
s := NewString("z", "y", "x", "a")
|
||||
if !reflect.DeepEqual(s.List(), []string{"a", "x", "y", "z"}) {
|
||||
t.Errorf("List gave unexpected result: %#v", s.List())
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringSetDifference(t *testing.T) {
|
||||
a := NewString("1", "2", "3")
|
||||
b := NewString("1", "2", "4", "5")
|
||||
c := a.Difference(b)
|
||||
d := b.Difference(a)
|
||||
if len(c) != 1 {
|
||||
t.Errorf("Expected len=1: %d", len(c))
|
||||
}
|
||||
if !c.Has("3") {
|
||||
t.Errorf("Unexpected contents: %#v", c.List())
|
||||
}
|
||||
if len(d) != 2 {
|
||||
t.Errorf("Expected len=2: %d", len(d))
|
||||
}
|
||||
if !d.Has("4") || !d.Has("5") {
|
||||
t.Errorf("Unexpected contents: %#v", d.List())
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringSetHasAny(t *testing.T) {
|
||||
a := NewString("1", "2", "3")
|
||||
|
||||
if !a.HasAny("1", "4") {
|
||||
t.Errorf("expected true, got false")
|
||||
}
|
||||
|
||||
if a.HasAny("0", "4") {
|
||||
t.Errorf("expected false, got true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringSetEquals(t *testing.T) {
|
||||
// Simple case (order doesn't matter)
|
||||
a := NewString("1", "2")
|
||||
b := NewString("2", "1")
|
||||
if !a.Equal(b) {
|
||||
t.Errorf("Expected to be equal: %v vs %v", a, b)
|
||||
}
|
||||
|
||||
// It is a set; duplicates are ignored
|
||||
b = NewString("2", "2", "1")
|
||||
if !a.Equal(b) {
|
||||
t.Errorf("Expected to be equal: %v vs %v", a, b)
|
||||
}
|
||||
|
||||
// Edge cases around empty sets / empty strings
|
||||
a = NewString()
|
||||
b = NewString()
|
||||
if !a.Equal(b) {
|
||||
t.Errorf("Expected to be equal: %v vs %v", a, b)
|
||||
}
|
||||
|
||||
b = NewString("1", "2", "3")
|
||||
if a.Equal(b) {
|
||||
t.Errorf("Expected to be not-equal: %v vs %v", a, b)
|
||||
}
|
||||
|
||||
b = NewString("1", "2", "")
|
||||
if a.Equal(b) {
|
||||
t.Errorf("Expected to be not-equal: %v vs %v", a, b)
|
||||
}
|
||||
|
||||
// Check for equality after mutation
|
||||
a = NewString()
|
||||
a.Insert("1")
|
||||
if a.Equal(b) {
|
||||
t.Errorf("Expected to be not-equal: %v vs %v", a, b)
|
||||
}
|
||||
|
||||
a.Insert("2")
|
||||
if a.Equal(b) {
|
||||
t.Errorf("Expected to be not-equal: %v vs %v", a, b)
|
||||
}
|
||||
|
||||
a.Insert("")
|
||||
if !a.Equal(b) {
|
||||
t.Errorf("Expected to be equal: %v vs %v", a, b)
|
||||
}
|
||||
|
||||
a.Delete("")
|
||||
if a.Equal(b) {
|
||||
t.Errorf("Expected to be not-equal: %v vs %v", a, b)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringUnion(t *testing.T) {
|
||||
tests := []struct {
|
||||
s1 String
|
||||
s2 String
|
||||
expected String
|
||||
}{
|
||||
{
|
||||
NewString("1", "2", "3", "4"),
|
||||
NewString("3", "4", "5", "6"),
|
||||
NewString("1", "2", "3", "4", "5", "6"),
|
||||
},
|
||||
{
|
||||
NewString("1", "2", "3", "4"),
|
||||
NewString(),
|
||||
NewString("1", "2", "3", "4"),
|
||||
},
|
||||
{
|
||||
NewString(),
|
||||
NewString("1", "2", "3", "4"),
|
||||
NewString("1", "2", "3", "4"),
|
||||
},
|
||||
{
|
||||
NewString(),
|
||||
NewString(),
|
||||
NewString(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
union := test.s1.Union(test.s2)
|
||||
if union.Len() != test.expected.Len() {
|
||||
t.Errorf("Expected union.Len()=%d but got %d", test.expected.Len(), union.Len())
|
||||
}
|
||||
|
||||
if !union.Equal(test.expected) {
|
||||
t.Errorf("Expected union.Equal(expected) but not true. union:%v expected:%v", union.List(), test.expected.List())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringIntersection(t *testing.T) {
|
||||
tests := []struct {
|
||||
s1 String
|
||||
s2 String
|
||||
expected String
|
||||
}{
|
||||
{
|
||||
NewString("1", "2", "3", "4"),
|
||||
NewString("3", "4", "5", "6"),
|
||||
NewString("3", "4"),
|
||||
},
|
||||
{
|
||||
NewString("1", "2", "3", "4"),
|
||||
NewString("1", "2", "3", "4"),
|
||||
NewString("1", "2", "3", "4"),
|
||||
},
|
||||
{
|
||||
NewString("1", "2", "3", "4"),
|
||||
NewString(),
|
||||
NewString(),
|
||||
},
|
||||
{
|
||||
NewString(),
|
||||
NewString("1", "2", "3", "4"),
|
||||
NewString(),
|
||||
},
|
||||
{
|
||||
NewString(),
|
||||
NewString(),
|
||||
NewString(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
intersection := test.s1.Intersection(test.s2)
|
||||
if intersection.Len() != test.expected.Len() {
|
||||
t.Errorf("Expected intersection.Len()=%d but got %d", test.expected.Len(), intersection.Len())
|
||||
}
|
||||
|
||||
if !intersection.Equal(test.expected) {
|
||||
t.Errorf("Expected intersection.Equal(expected) but not true. intersection:%v expected:%v", intersection.List(), test.expected.List())
|
||||
}
|
||||
}
|
||||
}
|
203
vendor/k8s.io/gengo/examples/set-gen/sets/string.go
generated
vendored
Normal file
203
vendor/k8s.io/gengo/examples/set-gen/sets/string.go
generated
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by set-gen. DO NOT EDIT.
|
||||
|
||||
package sets
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// sets.String is a set of strings, implemented via map[string]struct{} for minimal memory consumption.
|
||||
type String map[string]Empty
|
||||
|
||||
// NewString creates a String from a list of values.
|
||||
func NewString(items ...string) String {
|
||||
ss := String{}
|
||||
ss.Insert(items...)
|
||||
return ss
|
||||
}
|
||||
|
||||
// StringKeySet creates a String from a keys of a map[string](? extends interface{}).
|
||||
// If the value passed in is not actually a map, this will panic.
|
||||
func StringKeySet(theMap interface{}) String {
|
||||
v := reflect.ValueOf(theMap)
|
||||
ret := String{}
|
||||
|
||||
for _, keyValue := range v.MapKeys() {
|
||||
ret.Insert(keyValue.Interface().(string))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Insert adds items to the set.
|
||||
func (s String) Insert(items ...string) {
|
||||
for _, item := range items {
|
||||
s[item] = Empty{}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete removes all items from the set.
|
||||
func (s String) Delete(items ...string) {
|
||||
for _, item := range items {
|
||||
delete(s, item)
|
||||
}
|
||||
}
|
||||
|
||||
// Has returns true if and only if item is contained in the set.
|
||||
func (s String) Has(item string) bool {
|
||||
_, contained := s[item]
|
||||
return contained
|
||||
}
|
||||
|
||||
// HasAll returns true if and only if all items are contained in the set.
|
||||
func (s String) HasAll(items ...string) bool {
|
||||
for _, item := range items {
|
||||
if !s.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// HasAny returns true if any items are contained in the set.
|
||||
func (s String) HasAny(items ...string) bool {
|
||||
for _, item := range items {
|
||||
if s.Has(item) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Difference returns a set of objects that are not in s2
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.Difference(s2) = {a3}
|
||||
// s2.Difference(s1) = {a4, a5}
|
||||
func (s String) Difference(s2 String) String {
|
||||
result := NewString()
|
||||
for key := range s {
|
||||
if !s2.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Union returns a new set which includes items in either s1 or s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a3, a4}
|
||||
// s1.Union(s2) = {a1, a2, a3, a4}
|
||||
// s2.Union(s1) = {a1, a2, a3, a4}
|
||||
func (s1 String) Union(s2 String) String {
|
||||
result := NewString()
|
||||
for key := range s1 {
|
||||
result.Insert(key)
|
||||
}
|
||||
for key := range s2 {
|
||||
result.Insert(key)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Intersection returns a new set which includes the item in BOTH s1 and s2
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a2, a3}
|
||||
// s1.Intersection(s2) = {a2}
|
||||
func (s1 String) Intersection(s2 String) String {
|
||||
var walk, other String
|
||||
result := NewString()
|
||||
if s1.Len() < s2.Len() {
|
||||
walk = s1
|
||||
other = s2
|
||||
} else {
|
||||
walk = s2
|
||||
other = s1
|
||||
}
|
||||
for key := range walk {
|
||||
if other.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// IsSuperset returns true if and only if s1 is a superset of s2.
|
||||
func (s1 String) IsSuperset(s2 String) bool {
|
||||
for item := range s2 {
|
||||
if !s1.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Equal returns true if and only if s1 is equal (as a set) to s2.
|
||||
// Two sets are equal if their membership is identical.
|
||||
// (In practice, this means same elements, order doesn't matter)
|
||||
func (s1 String) Equal(s2 String) bool {
|
||||
return len(s1) == len(s2) && s1.IsSuperset(s2)
|
||||
}
|
||||
|
||||
type sortableSliceOfString []string
|
||||
|
||||
func (s sortableSliceOfString) Len() int { return len(s) }
|
||||
func (s sortableSliceOfString) Less(i, j int) bool { return lessString(s[i], s[j]) }
|
||||
func (s sortableSliceOfString) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// List returns the contents as a sorted string slice.
|
||||
func (s String) List() []string {
|
||||
res := make(sortableSliceOfString, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
sort.Sort(res)
|
||||
return []string(res)
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s String) UnsortedList() []string {
|
||||
res := make([]string, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Returns a single element from the set.
|
||||
func (s String) PopAny() (string, bool) {
|
||||
for key := range s {
|
||||
s.Delete(key)
|
||||
return key, true
|
||||
}
|
||||
var zeroValue string
|
||||
return zeroValue, false
|
||||
}
|
||||
|
||||
// Len returns the size of the set.
|
||||
func (s String) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func lessString(lhs, rhs string) bool {
|
||||
return lhs < rhs
|
||||
}
|
30
vendor/k8s.io/gengo/examples/set-gen/sets/types/types.go
generated
vendored
Normal file
30
vendor/k8s.io/gengo/examples/set-gen/sets/types/types.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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 types just provides input types to the set generator. It also
|
||||
// contains a "go generate" block.
|
||||
// (You must first `go install k8s.io/gengo/examples/set-gen`)
|
||||
package types
|
||||
|
||||
//go:generate set-gen -i k8s.io/gengo/examples/set-gen/sets/types -o k8s.io/gengo/examples/set-gen/sets
|
||||
|
||||
type ReferenceSetTypes struct {
|
||||
// These types all cause files to be generated
|
||||
a int64
|
||||
b int
|
||||
c byte
|
||||
d string
|
||||
}
|
Reference in New Issue
Block a user