func getEnumAzureNameFunction(enumType TypeName) asFuncType {
	return func(f *objectFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl {
		receiverIdent := f.idFactory.CreateIdentifier(receiver.Name(), NotExported)
		receiverType := receiver.AsType(codeGenerationContext)
		fn := &astbuilder.FuncDetails{
			Name:          methodName,
			ReceiverIdent: receiverIdent,
			ReceiverType:  &dst.StarExpr{X: receiverType},
			Body: []dst.Stmt{
				&dst.ReturnStmt{
					Decs: dst.ReturnStmtDecorations{
						NodeDecs: dst.NodeDecs{
							Before: dst.NewLine,
						},
					},
					Results: []dst.Expr{
						&dst.CallExpr{
							Fun: dst.NewIdent("string"),
							Args: []dst.Expr{
								&dst.SelectorExpr{
									X: &dst.SelectorExpr{
										X:   dst.NewIdent(receiverIdent),
										Sel: dst.NewIdent("Spec"),
									},
									Sel: dst.NewIdent(AzureNameProperty),
								},
							},
						},
					},
				},
			},
		}
		fn.AddComments(fmt.Sprintf("returns the Azure name of the resource (string representation of %s)", enumType.String()))
		fn.AddReturns("string")
		return fn.DefineFunc()
	}
}
getEnumAzureNameFunction adds an AzureName() function that casts the AzureName property
with an enum value to a string
package astmodel
import (
	"fmt"
	"go/token"
	"strings"
	"github.com/Azure/k8s-infra/hack/generator/pkg/astbuilder"
	"github.com/dave/dst"
	"github.com/pkg/errors"
)
const (
	AzureNameProperty = "AzureName"
	SetAzureNameFunc  = "SetAzureName"
	OwnerProperty     = "Owner"
)
func AddKubernetesResourceInterfaceImpls(
	resourceName TypeName,
	r *ResourceType,
	idFactory IdentifierFactory,
	types Types) (*ResourceType, error) {
	resolvedSpec, err := types.FullyResolve(r.SpecType())
	if err != nil {
		return nil, errors.Wrapf(err, "unable to resolve resource spec type")
	}
	spec, ok := AsObjectType(resolvedSpec)
	if !ok {
		return nil, errors.Errorf("resource spec %q did not contain an object", r.SpecType().String())
	}
	ownerProperty := idFactory.CreatePropertyName(OwnerProperty, Exported)
	_, ok = spec.Property(ownerProperty)
	if !ok {
		return nil, errors.Errorf("resource spec doesn't have %q property", ownerProperty)
	}
	azureNameProp, ok := spec.Property(AzureNameProperty)
	if !ok {
		return nil, errors.Errorf("resource spec doesn't have %q property", AzureNameProperty)
	}
	getNameFunction, setNameFunction, err := getAzureNameFunctionsForType(&r, spec, azureNameProp.PropertyType(), types)
	if err != nil {
		return nil, err
	}
	getAzureNameProperty := &objectFunction{
		name:      AzureNameProperty,
		o:         spec,
		idFactory: idFactory,
		asFunc:    getNameFunction,
	}
	getOwnerProperty := &objectFunction{
		name:      OwnerProperty,
		o:         spec,
		idFactory: idFactory,
		asFunc:    ownerFunction,
	}
	r = r.WithInterface(NewInterfaceImplementation(
		MakeTypeName(GenRuntimeReference, "KubernetesResource"),
		getAzureNameProperty,
		getOwnerProperty))
	if setNameFunction != nil {
		spec := r.SpecType()
		spec, err = types.FullyResolve(spec)
		if err != nil {
			return nil, err
		}
		specObj := spec.(*ObjectType)
		r = r.WithSpec(specObj.WithFunction(
			&objectFunction{
				name:      SetAzureNameFunc,
				o:         specObj,
				idFactory: idFactory,
				asFunc:    setNameFunction,
			}))
	}
	if setNameFunction != nil {
		r = r.WithInterface(generateDefaulter(resourceName, spec, idFactory))
	}
	return r, nil
}
var admissionPackageReference PackageReference = MakeExternalPackageReference("sigs.k8s.io/controller-runtime/pkg/webhook/admission")
var DefaulterInterfaceName = MakeTypeName(admissionPackageReference, "Defaulter")
func generateDefaulter(resourceName TypeName, spec *ObjectType, idFactory IdentifierFactory) *InterfaceImplementation {
	lpr, _ := resourceName.PackageReference.AsLocalPackage()
	group := lpr.group               
	resource := resourceName.Name()  
	version := lpr.version           
	group = strings.ToLower(group + GroupSuffix)
	nonPluralResource := strings.ToLower(resource)
	resource = strings.ToLower(resourceName.Plural().Name())
	path := fmt.Sprintf("/mutate-%s-%s-%s", strings.ReplaceAll(group, ".", "-"), version, nonPluralResource)
	name := fmt.Sprintf("default.%s.%s.%s", version, resource, group)
	annotation := fmt.Sprintf(
		"+kubebuilder:webhook:path=%s,mutating=true,sideEffects=None,"+
			"matchPolicy=Exact,failurePolicy=fail,groups=%s,resources=%s,"+
			"verbs=create;update,versions=%s,name=%s,admissionReviewVersions=v1beta1",  
		path,
		group,
		resource,
		version,
		name)
	return NewInterfaceImplementation(
		DefaulterInterfaceName,
		&objectFunction{
			name:      "Default",
			o:         spec,
			idFactory: idFactory,
			asFunc:    defaultAzureNameFunction,
		}).WithAnnotation(annotation)
}
func getAzureNameFunctionsForType(r **ResourceType, spec *ObjectType, t Type, types Types) (asFuncType, asFuncType, error) {
	switch azureNamePropType := t.(type) {
	case *ValidatedType:
		if !azureNamePropType.ElementType().Equals(StringType) {
			return nil, nil, errors.Errorf("unable to handle non-string validated types in AzureName property")
		}
		validations := azureNamePropType.Validations().(StringValidations)
		if validations.Pattern != nil {
			if validations.Pattern.String() == "^.*/default$" {
				*r = (*r).WithSpec(spec.WithoutProperty(AzureNameProperty))
				return fixedValueGetAzureNameFunction("default"), nil, nil  
			} else {
				return getStringAzureNameFunction, setStringAzureNameFunction, nil
			}
		} else {
			return getStringAzureNameFunction, setStringAzureNameFunction, nil
		}
	case TypeName:
		resolvedPropType, err := types.FullyResolve(azureNamePropType)
		if err != nil {
			return nil, nil, errors.Wrapf(err, "unable to resolve type of resource Name property: %s", azureNamePropType.String())
		}
		if t, ok := resolvedPropType.(*EnumType); ok {
			if !t.BaseType().Equals(StringType) {
				return nil, nil, errors.Errorf("unable to handle non-string enum base type in Name property")
			}
			options := t.Options()
			if len(options) == 1 {
				*r = (*r).WithSpec(spec.WithoutProperty(AzureNameProperty))
				return fixedValueGetAzureNameFunction(options[0].Value), nil, nil  
			} else {
				return getEnumAzureNameFunction(azureNamePropType), setEnumAzureNameFunction(azureNamePropType), nil
			}
		} else {
			return nil, nil, errors.Errorf("unable to produce AzureName()/SetAzureName() for Name property with type %s", resolvedPropType.String())
		}
	case *PrimitiveType:
		if !azureNamePropType.Equals(StringType) {
			return nil, nil, errors.Errorf("cannot use type %s as type of AzureName property", azureNamePropType.String())
		}
		return getStringAzureNameFunction, setStringAzureNameFunction, nil
	default:
		return nil, nil, errors.Errorf("unsupported type for AzureName property: %s", azureNamePropType.String())
	}
}
type objectFunction struct {
	name      string
	o         *ObjectType
	idFactory IdentifierFactory
	asFunc    asFuncType
}
type asFuncType func(f *objectFunction, codeGenerationContext *CodeGenerationContext, receiver TypeName, methodName string) *dst.FuncDecl