github.com/crossplane/upjet@v1.3.0/pkg/types/reference.go (about) 1 // SPDX-FileCopyrightText: 2023 The Crossplane Authors <https://crossplane.io> 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 5 package types 6 7 import ( 8 "fmt" 9 "go/token" 10 "go/types" 11 "reflect" 12 "strings" 13 14 "k8s.io/utils/ptr" 15 16 "github.com/crossplane/upjet/pkg/types/comments" 17 "github.com/crossplane/upjet/pkg/types/markers" 18 "github.com/crossplane/upjet/pkg/types/name" 19 ) 20 21 const ( 22 // PackagePathXPCommonAPIs is the go path for the Crossplane Runtime package 23 // with common APIs 24 PackagePathXPCommonAPIs = "github.com/crossplane/crossplane-runtime/apis/common/v1" 25 ) 26 27 // Types to use from by reference generator. 28 var ( 29 typeReferenceField types.Type = types.NewNamed( 30 types.NewTypeName(token.NoPos, types.NewPackage(PackagePathXPCommonAPIs, "v1"), "Reference", nil), 31 types.NewStruct(nil, nil), 32 nil, 33 ) 34 typeSelectorField types.Type = types.NewNamed( 35 types.NewTypeName(token.NoPos, types.NewPackage(PackagePathXPCommonAPIs, "v1"), "Selector", nil), 36 types.NewStruct(nil, nil), 37 nil, 38 ) 39 typeSecretKeySelector types.Type = types.NewNamed( 40 types.NewTypeName(token.NoPos, types.NewPackage(PackagePathXPCommonAPIs, "v1"), "SecretKeySelector", nil), 41 types.NewStruct(nil, nil), 42 nil, 43 ) 44 typeSecretReference types.Type = types.NewNamed( 45 types.NewTypeName(token.NoPos, types.NewPackage(PackagePathXPCommonAPIs, "v1"), "SecretReference", nil), 46 types.NewStruct(nil, nil), 47 nil, 48 ) 49 commentOptional = &comments.Comment{ 50 Options: markers.Options{ 51 KubebuilderOptions: markers.KubebuilderOptions{ 52 Required: ptr.To(false), 53 }, 54 }, 55 } 56 ) 57 58 func (g *Builder) generateReferenceFields(t *types.TypeName, f *Field) (fields []*types.Var, tags []string) { 59 _, isSlice := f.FieldType.(*types.Slice) 60 61 rfn := name.ReferenceFieldName(f.Name, isSlice, f.Reference.RefFieldName) 62 sfn := name.SelectorFieldName(f.Name, f.Reference.SelectorFieldName) 63 64 refTag := fmt.Sprintf(`json:"%s,omitempty" tf:"-"`, rfn.LowerCamelComputed) 65 selTag := fmt.Sprintf(`json:"%s,omitempty" tf:"-"`, sfn.LowerCamelComputed) 66 67 var tr types.Type 68 tr = types.NewPointer(typeReferenceField) 69 refComment := fmt.Sprintf("// Reference to a %s to populate %s.\n%s", 70 friendlyTypeDescription(f.Reference.Type), f.Name.LowerCamelComputed, commentOptional.Build()) 71 selComment := fmt.Sprintf("// Selector for a %s to populate %s.\n%s", 72 friendlyTypeDescription(f.Reference.Type), f.Name.LowerCamelComputed, commentOptional.Build()) 73 if isSlice { 74 tr = types.NewSlice(typeReferenceField) 75 refComment = fmt.Sprintf("// References to %s to populate %s.\n%s", 76 friendlyTypeDescription(f.Reference.Type), f.Name.LowerCamelComputed, commentOptional.Build()) 77 selComment = fmt.Sprintf("// Selector for a list of %s to populate %s.\n%s", 78 friendlyTypeDescription(f.Reference.Type), f.Name.LowerCamelComputed, commentOptional.Build()) 79 } 80 ref := types.NewField(token.NoPos, g.Package, rfn.Camel, tr, false) 81 sel := types.NewField(token.NoPos, g.Package, sfn.Camel, types.NewPointer(typeSelectorField), false) 82 83 g.comments.AddFieldComment(t, rfn.Camel, refComment) 84 g.comments.AddFieldComment(t, sfn.Camel, selComment) 85 f.TransformedName = rfn.LowerCamelComputed 86 f.SelectorName = sfn.LowerCamelComputed 87 88 return []*types.Var{ref, sel}, []string{refTag, selTag} 89 } 90 91 // TypePath returns go package path for the input type. This is a helper 92 // function to be used whenever this information is needed, like configuring to 93 // reference to a type. Should not be used if the type is in the same package as 94 // the caller. 95 func TypePath(i any) string { 96 return reflect.TypeOf(i).PkgPath() + "." + reflect.TypeOf(i).Name() 97 } 98 99 func friendlyTypeDescription(path string) string { 100 if !strings.Contains(path, ".") { 101 return path 102 } 103 typeName := path[strings.LastIndex(path, ".")+1:] 104 dirs := strings.Split(path, "/") 105 groupName := dirs[len(dirs)-2] 106 return fmt.Sprintf("%s in %s", typeName, groupName) 107 }