func (t *DeclType) ExprType() *exprpb.Type {
	return t.exprType
}
ExprType returns the CEL expression type of this declaration.
package model
import (
	"fmt"
	"k8s.io/kube-openapi/pkg/validation/spec"
	"time"
	"github.com/google/cel-go/cel"
	"github.com/google/cel-go/checker/decls"
	"github.com/google/cel-go/common/types"
	"github.com/google/cel-go/common/types/ref"
	"github.com/google/cel-go/common/types/traits"
	"google.golang.org/protobuf/proto"
	exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
)
func NewListType(elem *DeclType) *DeclType {
	return &DeclType{
		name:         "list",
		ElemType:     elem,
		exprType:     decls.NewListType(elem.ExprType()),
		defaultValue: NewListValue(),
	}
}
func NewMapType(key, elem *DeclType) *DeclType {
	return &DeclType{
		name:         "map",
		KeyType:      key,
		ElemType:     elem,
		exprType:     decls.NewMapType(key.ExprType(), elem.ExprType()),
		defaultValue: NewMapValue(),
	}
}
func NewObjectType(name string, fields map[string]*DeclField) *DeclType {
	t := &DeclType{
		name:      name,
		Fields:    fields,
		exprType:  decls.NewObjectType(name),
		traitMask: traits.FieldTesterType | traits.IndexerType,
	}
	t.defaultValue = NewObjectValue(t)
	return t
}
func NewObjectTypeRef(name string) *DeclType {
	t := &DeclType{
		name:      name,
		exprType:  decls.NewObjectType(name),
		traitMask: traits.FieldTesterType | traits.IndexerType,
	}
	return t
}
func NewTypeParam(name string) *DeclType {
	return &DeclType{
		name:      name,
		TypeParam: true,
		exprType:  decls.NewTypeParamType(name),
	}
}
func newSimpleType(name string, exprType *exprpb.Type, zeroVal ref.Val) *DeclType {
	return &DeclType{
		name:         name,
		exprType:     exprType,
		defaultValue: zeroVal,
	}
}
type DeclType struct {
	fmt.Stringer
	name      string
	Fields    map[string]*DeclField
	KeyType   *DeclType
	ElemType  *DeclType
	TypeParam bool
	Metadata  map[string]string
	exprType     *exprpb.Type
	traitMask    int
	defaultValue ref.Val
}
func (t *DeclType) MaybeAssignTypeName(name string) *DeclType {
	if t.IsObject() {
		objUpdated := false
		if t.name != "object" {
			name = t.name
		} else {
			objUpdated = true
		}
		fieldMap := make(map[string]*DeclField, len(t.Fields))
		for fieldName, field := range t.Fields {
			fieldType := field.Type
			fieldTypeName := fmt.Sprintf("%s.%s", name, fieldName)
			updated := fieldType.MaybeAssignTypeName(fieldTypeName)
			if updated == fieldType {
				fieldMap[fieldName] = field
				continue
			}
			objUpdated = true
			fieldMap[fieldName] = &DeclField{
				Name:         fieldName,
				Type:         updated,
				Required:     field.Required,
				enumValues:   field.enumValues,
				defaultValue: field.defaultValue,
			}
		}
		if !objUpdated {
			return t
		}
		return &DeclType{
			name:         name,
			Fields:       fieldMap,
			KeyType:      t.KeyType,
			ElemType:     t.ElemType,
			TypeParam:    t.TypeParam,
			Metadata:     t.Metadata,
			exprType:     decls.NewObjectType(name),
			traitMask:    t.traitMask,
			defaultValue: t.defaultValue,
		}
	}
	if t.IsMap() {
		elemTypeName := fmt.Sprintf("%s.@elem", name)
		updated := t.ElemType.MaybeAssignTypeName(elemTypeName)
		if updated == t.ElemType {
			return t
		}
		return NewMapType(t.KeyType, updated)
	}
	if t.IsList() {
		elemTypeName := fmt.Sprintf("%s.@idx", name)
		updated := t.ElemType.MaybeAssignTypeName(elemTypeName)
		if updated == t.ElemType {
			return t
		}
		return NewListType(updated)
	}
	return t
}