knative.dev/pkg@v0.0.0-20260602142205-ac97e43f6622/codegen/cmd/injection-gen/generators/informers/informer.go (about) 1 /* 2 Copyright 2019 The Knative Authors 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package informers 18 19 import ( 20 "io" 21 22 clientgentypes "k8s.io/code-generator/cmd/client-gen/types" 23 "k8s.io/gengo/v2/generator" 24 "k8s.io/gengo/v2/namer" 25 "k8s.io/gengo/v2/types" 26 "k8s.io/klog/v2" 27 28 gennamer "knative.dev/pkg/codegen/cmd/injection-gen/namer" 29 ) 30 31 // injectionTestGenerator produces a file of listers for a given GroupVersion and 32 // type. 33 type injectionGenerator struct { 34 generator.GoGenerator 35 outputPackage string 36 groupVersion clientgentypes.GroupVersion 37 groupGoName string 38 typeToGenerate *types.Type 39 imports namer.ImportTracker 40 typedInformerPackage string 41 groupInformerFactoryPackage string 42 disableInformerInit bool 43 } 44 45 var _ generator.Generator = (*injectionGenerator)(nil) 46 47 func (g *injectionGenerator) Filter(c *generator.Context, t *types.Type) bool { 48 // Only process the type for this informer generator. 49 return t == g.typeToGenerate 50 } 51 52 func (g *injectionGenerator) Namers(c *generator.Context) namer.NameSystems { 53 publicPluralNamer := &gennamer.ExceptionNamer{ 54 Exceptions: map[string]string{ 55 // these exceptions are used to deconflict the generated code 56 // you can put your fully qualified package like 57 // to generate a name that doesn't conflict with your group. 58 // "k8s.io/apis/events/v1beta1.Event": "EventResource" 59 }, 60 KeyFunc: func(t *types.Type) string { 61 return t.Name.Package + "." + t.Name.Name 62 }, 63 Delegate: namer.NewPublicPluralNamer(map[string]string{ 64 "Endpoints": "Endpoints", 65 }), 66 } 67 68 return namer.NameSystems{ 69 "raw": namer.NewRawNamer(g.outputPackage, g.imports), 70 "publicPlural": publicPluralNamer, 71 } 72 } 73 74 func (g *injectionGenerator) Imports(c *generator.Context) (imports []string) { 75 imports = append(imports, g.imports.ImportLines()...) 76 return imports 77 } 78 79 func (g *injectionGenerator) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { 80 sw := generator.NewSnippetWriter(w, c, "{{", "}}") 81 82 klog.V(5).Info("processing type ", t) 83 84 m := map[string]interface{}{ 85 "groupGoName": namer.IC(g.groupGoName), 86 "versionGoName": namer.IC(g.groupVersion.Version.String()), 87 "type": t, 88 "injectionRegisterInformer": c.Universe.Type(types.Name{Package: "knative.dev/pkg/injection", Name: "Default.RegisterInformer"}), 89 "controllerInformer": c.Universe.Type(types.Name{Package: "knative.dev/pkg/controller", Name: "Informer"}), 90 "informersTypedInformer": c.Universe.Type(types.Name{Package: g.typedInformerPackage, Name: t.Name.Name + "Informer"}), 91 "factoryGet": c.Universe.Type(types.Name{Package: g.groupInformerFactoryPackage, Name: "Get"}), 92 "loggingFromContext": c.Universe.Function(types.Name{ 93 Package: "knative.dev/pkg/logging", 94 Name: "FromContext", 95 }), 96 "contextContext": c.Universe.Type(types.Name{ 97 Package: "context", 98 Name: "Context", 99 }), 100 "contextWithValue": c.Universe.Function(types.Name{ 101 Package: "context", 102 Name: "WithValue", 103 }), 104 "disableInformerInit": g.disableInformerInit, 105 } 106 107 sw.Do(injectionInformer, m) 108 109 return sw.Error() 110 } 111 112 var injectionInformer = ` 113 {{ if not .disableInformerInit }} 114 func init() { 115 {{.injectionRegisterInformer|raw}}(withInformer) 116 } 117 {{ end }} 118 119 // Key is used for associating the Informer inside the context.Context. 120 type Key struct{} 121 122 {{ if .disableInformerInit }} func WithInformer {{ else }} func withInformer {{ end }} (ctx {{.contextContext|raw}}) ({{.contextContext|raw}}, {{.controllerInformer|raw}}) { 123 f := {{.factoryGet|raw}}(ctx) 124 inf := f.{{.groupGoName}}().{{.versionGoName}}().{{.type|publicPlural}}() 125 return {{ .contextWithValue|raw }}(ctx, Key{}, inf), inf.Informer() 126 } 127 128 // Get extracts the typed informer from the context. 129 func Get(ctx {{.contextContext|raw}}) {{.informersTypedInformer|raw}} { 130 untyped := ctx.Value(Key{}) 131 if untyped == nil { 132 {{.loggingFromContext|raw}}(ctx).Panic( 133 "Unable to fetch {{.informersTypedInformer}} from context.") 134 } 135 return untyped.({{.informersTypedInformer|raw}}) 136 } 137 `