func (g *genFakeForGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	const pkgTestingCore = "k8s.io/kubernetes/pkg/client/testing/core"
	m := map[string]interface{}{
		"group": g.group,
		"Group": namer.IC(g.group),
		"Fake":  c.Universe.Type(types.Name{Package: pkgTestingCore, Name: "Fake"}),
	}
	sw.Do(groupClientTemplate, m)
	for _, t := range g.types {
		wrapper := map[string]interface{}{
			"type":              t,
			"Group":             namer.IC(g.group),
			"realClientPackage": filepath.Base(g.realClientPath),
		}
		namespaced := !(types.ExtractCommentTags("+", t.SecondClosestCommentLines)["nonNamespaced"] == "true")
		if namespaced {
			sw.Do(getterImplNamespaced, wrapper)
		} else {
			sw.Do(getterImplNonNamespaced, wrapper)

		}
	}
	return sw.Error()
}
func (g *genClientset) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	// TODO: We actually don't need any type information to generate the clientset,
	// perhaps we can adapt the go2ild framework to this kind of usage.
	sw := generator.NewSnippetWriter(w, c, "$", "$")

	sw.Do(common, nil)

	sw.Do(checkImpl, nil)

	type arg struct {
		Group       string
		PackageName string
	}
	allGroups := []arg{}
	for _, gv := range g.groupVersions {
		group := normalization.Group(gv.Group)
		version := normalization.Version(gv.Version)
		allGroups = append(allGroups, arg{namer.IC(group), version + group})
	}

	for _, g := range allGroups {
		sw.Do(clientsetInterfaceImplTemplate, g)
	}

	return sw.Error()
}
Ejemplo n.º 3
0
// 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)
	}
}
Ejemplo n.º 4
0
func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	const pkgUnversioned = "k8s.io/kubernetes/pkg/client/unversioned"
	const pkgLatest = "k8s.io/kubernetes/pkg/api/latest"
	m := map[string]interface{}{
		"group":                      g.group,
		"Group":                      namer.IC(g.group),
		"types":                      g.types,
		"Config":                     c.Universe.Get(types.Name{Package: pkgUnversioned, Name: "Config"}),
		"DefaultKubernetesUserAgent": c.Universe.Get(types.Name{Package: pkgUnversioned, Name: "DefaultKubernetesUserAgent"}),
		"RESTClient":                 c.Universe.Get(types.Name{Package: pkgUnversioned, Name: "RESTClient"}),
		"RESTClientFor":              c.Universe.Get(types.Name{Package: pkgUnversioned, Name: "RESTClientFor"}),
		"latestGroup":                c.Universe.Get(types.Name{Package: pkgLatest, Name: "Group"}),
		"GroupOrDie":                 c.Universe.Get(types.Name{Package: pkgLatest, Name: "GroupOrDie"}),
	}
	sw.Do(groupInterfaceTemplate, m)
	sw.Do(groupClientTemplate, m)
	for _, t := range g.types {
		wrapper := map[string]interface{}{
			"type":  t,
			"Group": namer.IC(g.group),
		}
		sw.Do(namespacerImplTemplate, wrapper)
	}
	sw.Do(newClientTemplate, m)
	sw.Do(newClientOrDieTemplate, m)
	sw.Do(setClientDefaultsTemplate, m)

	return sw.Error()
}
Ejemplo n.º 5
0
func (g *genExpansion) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	for _, t := range g.types {
		sw.Do(expansionInterfaceTemplate, t)
	}
	return sw.Error()
}
Ejemplo n.º 6
0
func (g *genDeepCopy) Init(c *generator.Context, w io.Writer) error {
	cloner := c.Universe.Type(types.Name{Package: conversionPackagePath, Name: "Cloner"})
	g.imports.AddType(cloner)
	g.globalVariables = map[string]interface{}{
		"Cloner": cloner,
	}
	if !g.registerTypes {
		// TODO: We should come up with a solution to register all generated
		// deep-copy functions. However, for now, to avoid import cycles
		// we register only those explicitly requested.
		return nil
	}
	glog.V(5).Infof("registering types in pkg %q", g.targetPackage)

	scheme := c.Universe.Variable(types.Name{Package: apiPackagePath, Name: "Scheme"})
	g.imports.AddType(scheme)
	g.globalVariables["scheme"] = scheme

	sw := generator.NewSnippetWriter(w, c, "$", "$")
	sw.Do("func init() {\n", nil)
	sw.Do("if err := $.scheme|raw$.AddGeneratedDeepCopyFuncs(\n", map[string]interface{}{
		"scheme": scheme,
	})
	for _, t := range g.typesForInit {
		sw.Do(fmt.Sprintf("%s,\n", g.funcNameTmpl(t)), argsFromType(t))
	}
	sw.Do("); err != nil {\n", nil)
	sw.Do("// if one of the deep copy functions is malformed, detect it immediately.\n", nil)
	sw.Do("panic(err)\n", nil)
	sw.Do("}\n", nil)
	sw.Do("}\n\n", nil)
	return sw.Error()
}
Ejemplo n.º 7
0
func (g *genDeepCopy) Init(c *generator.Context, w io.Writer) error {
	cloner := c.Universe.Type(types.Name{Package: conversionPackagePath, Name: "Cloner"})
	g.imports.AddType(cloner)
	if !g.registerTypes {
		// TODO: We should come up with a solution to register all generated
		// deep-copy functions. However, for now, to avoid import cycles
		// we register only those explicitly requested.
		return nil
	}
	glog.V(5).Infof("registering types in pkg %q", g.targetPackage)

	sw := generator.NewSnippetWriter(w, c, "$", "$")
	sw.Do("func init() {\n", nil)
	sw.Do("SchemeBuilder.Register(RegisterDeepCopies)\n", nil)
	sw.Do("}\n\n", nil)

	scheme := c.Universe.Type(types.Name{Package: runtimePackagePath, Name: "Scheme"})
	schemePtr := &types.Type{
		Kind: types.Pointer,
		Elem: scheme,
	}
	sw.Do("// RegisterDeepCopies adds deep-copy functions to the given scheme. Public\n", nil)
	sw.Do("// to allow building arbitrary schemes.\n", nil)
	sw.Do("func RegisterDeepCopies(scheme $.|raw$) error {\n", schemePtr)
	sw.Do("return scheme.AddGeneratedDeepCopyFuncs(\n", nil)
	for _, t := range g.typesForInit {
		args := argsFromType(t).
			With("typeof", c.Universe.Package("reflect").Function("TypeOf"))
		sw.Do("conversion.GeneratedDeepCopyFunc{Fn: $.type|dcFnName$, InType: $.typeof|raw$(&$.type|raw${})},\n", args)
	}
	sw.Do(")\n", nil)
	sw.Do("}\n\n", nil)
	return sw.Error()
}
Ejemplo n.º 8
0
func (g *genConversion) Init(c *generator.Context, w io.Writer) error {
	scheme := c.Universe.Variable(types.Name{Package: apiPackagePath, Name: "Scheme"})
	g.imports.AddType(scheme)
	scope := c.Universe.Type(types.Name{Package: conversionPackagePath, Name: "Scope"})
	g.imports.AddType(scope)
	g.globalVariables = map[string]interface{}{
		"scheme": scheme,
		"Scope":  scope,
	}

	sw := generator.NewSnippetWriter(w, c, "$", "$")
	sw.Do("func init() {\n", nil)
	sw.Do("if err := $.scheme|raw$.AddGeneratedConversionFuncs(\n", map[string]interface{}{
		"scheme": scheme,
	})
	for _, conv := range g.typesForInit {
		funcName := g.funcNameTmpl(conv.inType, conv.outType)
		sw.Do(fmt.Sprintf("%s,\n", funcName), argsFromType(conv.inType, conv.outType))
	}
	sw.Do("); err != nil {\n", nil)
	sw.Do("// if one of the conversion functions is malformed, detect it immediately.\n", nil)
	sw.Do("panic(err)\n", nil)
	sw.Do("}\n", nil)
	sw.Do("}\n\n", nil)
	return sw.Error()
}
Ejemplo n.º 9
0
// GenerateType makes the body of a file implementing a set for type t.
func (g *genClientForType) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	pkg := filepath.Base(t.Name.Package)
	m := map[string]interface{}{
		"type":             t,
		"package":          pkg,
		"Package":          namer.IC(pkg),
		"Group":            namer.IC(g.group),
		"watchInterface":   c.Universe.Type(types.Name{Package: "k8s.io/kubernetes/pkg/watch", Name: "Interface"}),
		"apiDeleteOptions": c.Universe.Type(types.Name{Package: "k8s.io/kubernetes/pkg/api", Name: "DeleteOptions"}),
		"apiListOptions":   c.Universe.Type(types.Name{Package: "k8s.io/kubernetes/pkg/api", Name: "ListOptions"}),
	}
	sw.Do(namespacerTemplate, m)
	sw.Do(interfaceTemplate, m)
	sw.Do(structTemplate, m)
	sw.Do(newStructTemplate, m)
	sw.Do(createTemplate, m)
	sw.Do(updateTemplate, m)
	sw.Do(deleteTemplate, m)
	sw.Do(deleteCollectionTemplate, m)
	sw.Do(getTemplate, m)
	sw.Do(listTemplate, m)
	sw.Do(watchTemplate, m)

	return sw.Error()
}
func (g *genClientset) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	// TODO: We actually don't need any type information to generate the clientset,
	// perhaps we can adapt the go2ild framework to this kind of usage.
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	const pkgUnversioned = "k8s.io/kubernetes/pkg/client/unversioned"

	type arg struct {
		Group       string
		PackageName string
	}

	allGroups := []arg{}
	for _, gv := range g.groupVersions {
		group := normalizeGroup(gv.Group)
		version := normalizeVersion(gv.Version)
		allGroups = append(allGroups, arg{namer.IC(group), group + "_" + version})
	}

	m := map[string]interface{}{
		"allGroups":                  allGroups,
		"Config":                     c.Universe.Type(types.Name{Package: pkgUnversioned, Name: "Config"}),
		"DefaultKubernetesUserAgent": c.Universe.Function(types.Name{Package: pkgUnversioned, Name: "DefaultKubernetesUserAgent"}),
		"RESTClient":                 c.Universe.Type(types.Name{Package: pkgUnversioned, Name: "RESTClient"}),
	}
	sw.Do(clientsetInterfaceTemplate, m)
	sw.Do(clientsetTemplate, m)
	for _, g := range allGroups {
		sw.Do(clientsetInterfaceImplTemplate, g)
	}
	sw.Do(newClientsetForConfigTemplate, m)
	sw.Do(newClientsetForConfigOrDieTemplate, m)
	sw.Do(newClientsetForRESTClientTemplate, m)

	return sw.Error()
}
Ejemplo n.º 11
0
func (g *genConversion) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	glog.V(5).Infof("generating for type %v", t)
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	peerType := getPeerTypeFor(c, t, g.peerPackages)
	didForward, didBackward := false, false
	if isDirectlyConvertible(t, peerType, g.manualConversions) {
		didForward = true
		g.generateConversion(t, peerType, sw)
	}
	if isDirectlyConvertible(peerType, t, g.manualConversions) {
		didBackward = true
		g.generateConversion(peerType, t, sw)
	}
	if didForward != didBackward {
		glog.Fatalf("Could only generate one direction of conversion for %v <-> %v", t, peerType)
	}
	if !didForward && !didBackward {
		// TODO: This should be fatal but we have at least 8 types that
		// currently fail this.  The right thing to do is to figure out why they
		// can't be generated and mark those fields as
		// +k8s:conversion-gen=false, and ONLY do manual conversions for those
		// fields, with the manual Convert_...() calling autoConvert_...()
		// first.
		glog.Errorf("Warning: could not generate autoConvert functions for %v <-> %v", t, peerType)
	}
	return sw.Error()
}
Ejemplo n.º 12
0
// GenerateType makes the body of a file implementing the individual typed client for type t.
func (g *genClientForType) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	pkg := filepath.Base(t.Name.Package)
	namespaced := !(types.ExtractCommentTags("+", t.SecondClosestCommentLines)["nonNamespaced"] == "true")
	m := map[string]interface{}{
		"type":              t,
		"package":           pkg,
		"Package":           namer.IC(pkg),
		"Group":             namer.IC(g.group),
		"watchInterface":    c.Universe.Type(types.Name{Package: "k8s.io/kubernetes/pkg/watch", Name: "Interface"}),
		"apiDeleteOptions":  c.Universe.Type(types.Name{Package: "k8s.io/kubernetes/pkg/api", Name: "DeleteOptions"}),
		"apiListOptions":    c.Universe.Type(types.Name{Package: "k8s.io/kubernetes/pkg/api", Name: "ListOptions"}),
		"apiParameterCodec": c.Universe.Type(types.Name{Package: "k8s.io/kubernetes/pkg/api", Name: "ParameterCodec"}),
		"namespaced":        namespaced,
	}

	sw.Do(getterComment, m)
	if namespaced {
		sw.Do(getterNamesapced, m)
	} else {
		sw.Do(getterNonNamesapced, m)
	}
	noMethods := types.ExtractCommentTags("+", t.SecondClosestCommentLines)["noMethods"] == "true"

	sw.Do(interfaceTemplate1, m)
	if !noMethods {
		sw.Do(interfaceTemplate2, m)
		// Include the UpdateStatus method if the type has a status
		if hasStatus(t) {
			sw.Do(interfaceUpdateStatusTemplate, m)
		}
		sw.Do(interfaceTemplate3, m)
	}
	sw.Do(interfaceTemplate4, m)

	if namespaced {
		sw.Do(structNamespaced, m)
		sw.Do(newStructNamespaced, m)
	} else {
		sw.Do(structNonNamespaced, m)
		sw.Do(newStructNonNamespaced, m)
	}

	if !noMethods {
		sw.Do(createTemplate, m)
		sw.Do(updateTemplate, m)
		// Generate the UpdateStatus method if the type has a status
		if hasStatus(t) {
			sw.Do(updateStatusTemplate, m)
		}
		sw.Do(deleteTemplate, m)
		sw.Do(deleteCollectionTemplate, m)
		sw.Do(getTemplate, m)
		sw.Do(listTemplate, m)
		sw.Do(watchTemplate, m)
	}

	return sw.Error()
}
Ejemplo n.º 13
0
// GenerateType makes the body of a file implementing a set for type t.
func (g *genDeepCopy) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	sw.Do("func deepCopy_$.|public$(in $.|raw$, out *$.|raw$, c *conversion.Cloner) error {\n", t)
	g.generateFor(t, sw)
	sw.Do("return nil\n", nil)
	sw.Do("}\n\n", nil)
	return sw.Error()
}
Ejemplo n.º 14
0
// 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 *genExpansion) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	for _, t := range g.types {
		if _, err := os.Stat(filepath.Join(g.groupPath, strings.ToLower(t.Name.Name+"_expansion.go"))); os.IsNotExist(err) {
			sw.Do(expansionInterfaceTemplate, t)
		}
	}
	return sw.Error()
}
Ejemplo n.º 16
0
func (g *openAPIGen) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	glog.V(5).Infof("generating for type %v", t)
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	err := newOpenAPITypeWriter(sw).generate(t)
	if err != nil {
		return err
	}
	return sw.Error()
}
Ejemplo n.º 17
0
func (g *genDeepCopy) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	funcName := g.funcNameTmpl(t)
	sw.Do(fmt.Sprintf("func %s(in $.type|raw$, out *$.type|raw$, c *$.Cloner|raw$) error {\n", funcName), g.withGlobals(argsFromType(t)))
	g.generateFor(t, sw)
	sw.Do("return nil\n", nil)
	sw.Do("}\n\n", nil)
	return sw.Error()
}
Ejemplo n.º 18
0
func TestSnippetWriter(t *testing.T) {
	var structTest = map[string]string{
		"base/foo/proto/foo.go": `
package foo

// Blah is a test.
// A test, I tell you.
type Blah struct {
	// A is the first field.
	A int64 ` + "`" + `json:"a"` + "`" + `

	// B is the second field.
	// Multiline comments work.
	B string ` + "`" + `json:"b"` + "`" + `
}
`,
	}

	c := construct(t, structTest)
	b := &bytes.Buffer{}
	err := generator.NewSnippetWriter(b, c, "$", "$").
		Do("$.|public$$.|private$", c.Order[0]).
		Error()
	if err != nil {
		t.Errorf("Unexpected error %v", err)
	}
	if e, a := "Blahblah", b.String(); e != a {
		t.Errorf("Expected %q, got %q", e, a)
	}

	err = generator.NewSnippetWriter(b, c, "$", "$").
		Do("$.|public", c.Order[0]).
		Error()
	if err == nil {
		t.Errorf("expected error on invalid template")
	} else {
		// Dear reader, I apologize for making the worst change
		// detection test in the history of ever.
		if e, a := "unclosed action", err.Error(); !strings.Contains(a, e) {
			t.Errorf("Expected %q but didn't find it in %q", e, a)
		}
	}
}
func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	const pkgUnversioned = "k8s.io/kubernetes/pkg/client/unversioned"
	const pkgRegistered = "k8s.io/kubernetes/pkg/apimachinery/registered"
	const pkgAPI = "k8s.io/kubernetes/pkg/api"
	apiPath := func(group string) string {
		if group == "legacy" {
			return `"/api"`
		}
		return `"/apis"`
	}

	canonize := func(group string) string {
		if group == "legacy" {
			return ""
		}
		return group
	}

	m := map[string]interface{}{
		"group":                      g.group,
		"Group":                      namer.IC(g.group),
		"canonicalGroup":             canonize(g.group),
		"types":                      g.types,
		"Config":                     c.Universe.Type(types.Name{Package: pkgUnversioned, Name: "Config"}),
		"DefaultKubernetesUserAgent": c.Universe.Function(types.Name{Package: pkgUnversioned, Name: "DefaultKubernetesUserAgent"}),
		"RESTClient":                 c.Universe.Type(types.Name{Package: pkgUnversioned, Name: "RESTClient"}),
		"RESTClientFor":              c.Universe.Function(types.Name{Package: pkgUnversioned, Name: "RESTClientFor"}),
		"latestGroup":                c.Universe.Variable(types.Name{Package: pkgRegistered, Name: "Group"}),
		"GroupOrDie":                 c.Universe.Variable(types.Name{Package: pkgRegistered, Name: "GroupOrDie"}),
		"apiPath":                    apiPath(g.group),
		"codecs":                     c.Universe.Variable(types.Name{Package: pkgAPI, Name: "Codecs"}),
	}
	sw.Do(groupInterfaceTemplate, m)
	sw.Do(groupClientTemplate, m)
	for _, t := range g.types {
		wrapper := map[string]interface{}{
			"type":  t,
			"Group": namer.IC(g.group),
		}
		namespaced := !(types.ExtractCommentTags("+", t.SecondClosestCommentLines)["nonNamespaced"] == "true")
		if namespaced {
			sw.Do(getterImplNamespaced, wrapper)
		} else {
			sw.Do(getterImplNonNamespaced, wrapper)

		}
	}
	sw.Do(newClientForConfigTemplate, m)
	sw.Do(newClientForConfigOrDieTemplate, m)
	sw.Do(newClientForRESTClientTemplate, m)
	sw.Do(setClientDefaultsTemplate, m)

	return sw.Error()
}
Ejemplo n.º 20
0
func (g *genConversion) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	internalType, _ := getInternalTypeFor(c, t)
	if isDirectlyConvertible(t, internalType, g.preexisting) {
		g.generateConversion(t, internalType, sw)
	}
	if isDirectlyConvertible(internalType, t, g.preexisting) {
		g.generateConversion(internalType, t, sw)
	}
	return sw.Error()
}
Ejemplo n.º 21
0
func (g *genDeepCopy) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	funcName := g.funcNameTmpl(t)
	if g.targetPackage == conversionPackagePath {
		sw.Do(fmt.Sprintf("func %s(in $.type|raw$, out *$.type|raw$, c *Cloner) error {\n", funcName), argsFromType(t))
	} else {
		sw.Do(fmt.Sprintf("func %s(in $.type|raw$, out *$.type|raw$, c *conversion.Cloner) error {\n", funcName), argsFromType(t))
	}
	g.generateFor(t, sw)
	sw.Do("return nil\n", nil)
	sw.Do("}\n\n", nil)
	return sw.Error()
}
Ejemplo n.º 22
0
func (g *genDeepCopy) Init(c *generator.Context, w io.Writer) error {
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	sw.Do("func init() {\n", nil)
	sw.Do("if err := api.Scheme.AddGeneratedDeepCopyFuncs(\n", nil)
	for _, t := range g.typesForInit {
		sw.Do("deepCopy_$.|public$,\n", t)
	}
	sw.Do("); err != nil {\n", nil)
	sw.Do("// if one of the deep copy functions is malformed, detect it immediately.\n", nil)
	sw.Do("panic(err)\n", nil)
	sw.Do("}\n", nil)
	sw.Do("}\n\n", nil)
	return sw.Error()
}
Ejemplo n.º 23
0
// Returns all already existing conversion functions that we are able to find.
func existingConversionFunctions(context *generator.Context) conversions {
	scopeName := types.Name{Package: conversionPackagePath, Name: "Scope"}
	errorName := types.Name{Package: "", Name: "error"}
	buffer := &bytes.Buffer{}
	sw := generator.NewSnippetWriter(buffer, context, "$", "$")

	preexisting := make(conversions)
	for _, p := range context.Universe {
		for _, f := range p.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 conversion function.
			// Note that all of them have signature:
			// func Convert_inType_To_outType(inType, outType, conversion.Scope) error
			if signature.Receiver != nil {
				continue
			}
			if len(signature.Parameters) != 3 || signature.Parameters[2].Name != scopeName {
				continue
			}
			if len(signature.Results) != 1 || signature.Results[0].Name != errorName {
				continue
			}
			inType := signature.Parameters[0]
			outType := signature.Parameters[1]
			if inType.Kind != types.Pointer || outType.Kind != types.Pointer {
				continue
			}
			// Now check if the name satisfies the convention.
			args := argsFromType(inType.Elem, outType.Elem)
			sw.Do("Convert_$.inType|public$_To_$.outType|public$", args)
			if f.Name.Name == buffer.String() {
				key := conversionType{inType.Elem, outType.Elem}
				if v, ok := preexisting[key]; ok && v != nil {
					panic(fmt.Sprintf("duplicate static conversion defined: %#v", key))
				}
				preexisting[key] = f
			}
			buffer.Reset()
		}
	}
	return preexisting
}
Ejemplo n.º 24
0
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 for type %v", t)

	sw := generator.NewSnippetWriter(w, c, "$", "$")
	funcName := g.funcNameTmpl(t)
	sw.Do(fmt.Sprintf("func %s(in interface{}, out interface{}, c *$.Cloner|raw$) error {{\n", funcName), g.withGlobals(argsFromType(t)))
	sw.Do("in := in.(*$.type|raw$)\nout := out.(*$.type|raw$)\n", g.withGlobals(argsFromType(t)))
	g.generateFor(t, sw)
	sw.Do("return nil\n", nil)
	sw.Do("}}\n\n", nil)
	return sw.Error()
}
Ejemplo n.º 25
0
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 for type %v", t)

	sw := generator.NewSnippetWriter(w, c, "$", "$")
	args := argsFromType(t).
		With("clonerType", types.Ref(conversionPackagePath, "Cloner"))
	sw.Do("func $.type|dcFnName$(in interface{}, out interface{}, c *$.clonerType|raw$) error {{\n", args)
	sw.Do("in := in.(*$.type|raw$)\nout := out.(*$.type|raw$)\n", argsFromType(t))
	g.generateFor(t, sw)
	sw.Do("return nil\n", nil)
	sw.Do("}}\n\n", nil)
	return sw.Error()
}
Ejemplo n.º 26
0
// Returns all manually-defined conversion functions in the package.
func getManualConversionFunctions(context *generator.Context, pkg *types.Package, manualMap conversionFuncMap) {
	scopeName := types.Ref(conversionPackagePath, "Scope").Name
	errorName := types.Ref("", "error").Name
	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 conversion function.
		// Note that all of them have signature:
		// func Convert_inType_To_outType(inType, outType, conversion.Scope) error
		if signature.Receiver != nil {
			continue
		}
		if len(signature.Parameters) != 3 || signature.Parameters[2].Name != scopeName {
			continue
		}
		if len(signature.Results) != 1 || signature.Results[0].Name != errorName {
			continue
		}
		inType := signature.Parameters[0]
		outType := signature.Parameters[1]
		if inType.Kind != types.Pointer || outType.Kind != types.Pointer {
			continue
		}
		// Now check if the name satisfies the convention.
		args := argsFromType(inType.Elem, outType.Elem)
		sw.Do("Convert_$.inType|public$_To_$.outType|public$", args)
		if f.Name.Name == buffer.String() {
			key := conversionPair{inType.Elem, outType.Elem}
			// We might scan the same package twice, and that's OK.
			if v, ok := manualMap[key]; ok && v != nil && v.Name.Package != pkg.Path {
				panic(fmt.Sprintf("duplicate static conversion defined: %#v", key))
			}
			manualMap[key] = f
		}
		buffer.Reset()
	}
}
Ejemplo n.º 27
0
func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	const pkgUnversioned = "k8s.io/kubernetes/pkg/client/unversioned"
	const pkgLatest = "k8s.io/kubernetes/pkg/api/latest"
	prefix := func(group string) string {
		if group == "legacy" {
			return `"/api"`
		}
		return `"/apis"`
	}

	canonize := func(group string) string {
		if group == "legacy" {
			return ""
		}
		return group
	}

	m := map[string]interface{}{
		"group":                      g.group,
		"Group":                      namer.IC(g.group),
		"canonicalGroup":             canonize(g.group),
		"types":                      g.types,
		"Config":                     c.Universe.Type(types.Name{Package: pkgUnversioned, Name: "Config"}),
		"DefaultKubernetesUserAgent": c.Universe.Function(types.Name{Package: pkgUnversioned, Name: "DefaultKubernetesUserAgent"}),
		"RESTClient":                 c.Universe.Type(types.Name{Package: pkgUnversioned, Name: "RESTClient"}),
		"RESTClientFor":              c.Universe.Function(types.Name{Package: pkgUnversioned, Name: "RESTClientFor"}),
		"latestGroup":                c.Universe.Variable(types.Name{Package: pkgLatest, Name: "Group"}),
		"GroupOrDie":                 c.Universe.Variable(types.Name{Package: pkgLatest, Name: "GroupOrDie"}),
		"prefix":                     prefix(g.group),
	}
	sw.Do(groupInterfaceTemplate, m)
	sw.Do(groupClientTemplate, m)
	for _, t := range g.types {
		wrapper := map[string]interface{}{
			"type":  t,
			"Group": namer.IC(g.group),
		}
		sw.Do(namespacerImplTemplate, wrapper)
	}
	sw.Do(newClientForConfigTemplate, m)
	sw.Do(newClientForConfigOrDieTemplate, m)
	sw.Do(newClientForRESTClientTemplate, m)
	sw.Do(setClientDefaultsTemplate, m)

	return sw.Error()
}
Ejemplo n.º 28
0
// Returns all already existing defaulting functions that we are able to find.
func existingDefaultingFunctions(context *generator.Context) defaulters {
	buffer := &bytes.Buffer{}
	sw := generator.NewSnippetWriter(buffer, context, "$", "$")

	preexisting := make(defaulters)
	for _, p := range context.Universe {
		for _, f := range p.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 conversion function.
			// Note that all of them have signature:
			// func Convert_inType_To_outType(inType, outType, conversion.Scope) error
			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
			}
			// Now check if the name satisfies the convention.
			args := defaultingArgsFromType(inType.Elem)
			sw.Do("$.inType|defaultfn$", args)
			if f.Name.Name == buffer.String() {
				key := inType.Elem
				if v, ok := preexisting[key]; ok && v != nil {
					panic(fmt.Sprintf("duplicate static defaulter defined: %#v", key))
				}
				preexisting[key] = f
			}
			buffer.Reset()
		}
	}
	return preexisting
}
Ejemplo n.º 29
0
func (g *genDeepCopy) Init(c *generator.Context, w io.Writer) error {
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	sw.Do("func init() {\n", nil)
	if g.targetPackage == apiPackagePath {
		sw.Do("if err := Scheme.AddGeneratedDeepCopyFuncs(\n", nil)
	} else {
		sw.Do("if err := api.Scheme.AddGeneratedDeepCopyFuncs(\n", nil)
	}
	for _, t := range g.typesForInit {
		sw.Do(fmt.Sprintf("%s,\n", g.funcNameTmpl(t)), argsFromType(t))
	}
	sw.Do("); err != nil {\n", nil)
	sw.Do("// if one of the deep copy functions is malformed, detect it immediately.\n", nil)
	sw.Do("panic(err)\n", nil)
	sw.Do("}\n", nil)
	sw.Do("}\n\n", nil)
	return sw.Error()
}
Ejemplo n.º 30
0
func (g *genConversion) Init(c *generator.Context, w io.Writer) error {
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	sw.Do("func init() {\n", nil)
	if g.targetPackage == apiPackagePath {
		sw.Do("if err := Scheme.AddGeneratedConversionFuncs(\n", nil)
	} else {
		sw.Do("if err := api.Scheme.AddGeneratedConversionFuncs(\n", nil)
	}
	for _, conv := range g.typesForInit {
		funcName := g.funcNameTmpl(conv.inType, conv.outType)
		sw.Do(fmt.Sprintf("%s,\n", funcName), argsFromType(conv.inType, conv.outType))
	}
	sw.Do("); err != nil {\n", nil)
	sw.Do("// if one of the conversion functions is malformed, detect it immediately.\n", nil)
	sw.Do("panic(err)\n", nil)
	sw.Do("}\n", nil)
	sw.Do("}\n\n", nil)
	return sw.Error()
}