Repository: kubernetes/kubernetes
File: staging/src/k8s.io/apiserver/pkg/admission/plugin/cel/composition.go (Go)

Code before:

	compositionEnv *CompositionEnv
}

// CompositedEvaluator provides evaluation of a single expression with variable composition.
// The types that may returned by the expression is determined at compilation time.
type CompositedEvaluator struct {
	MutatingEvaluator

	compositionEnv *CompositionEnv
}

func NewCompositedCompiler(envSet *environment.EnvSet) (*CompositedCompiler, error) {
	compositionContext, err := NewCompositionEnv(VariablesTypeName, envSet)
	if err != nil {
		return nil, err
	}
	return NewCompositedCompilerFromTemplate(compositionContext), nil
}

func NewCompositedCompilerFromTemplate(context *CompositionEnv) *CompositedCompiler {
	// shallow copy the MapType
	newMapType := *context.MapType

	// We are making fields empty similar to CompiledVariables.
	// In all combinations fields are always empty when initializing from a template.
	newMapType.Fields = map[string]*apiservercel.DeclField{}

	// Create a NEW environment from the BASE environment.
	// We cannot extend context.EnvSet because it already has 'variables' defined, which causes a conflict.
	// Instead, we extend the original baseEnvSet with our NEW MapType.
	newEnvSet, err := context.baseEnvSet.Extend(environment.VersionedOptions{
		IntroducedVersion: version.MajorMinor(1, 0),
		EnvOptions: []cel.EnvOption{
			cel.Variable("variables", newMapType.CelType()),
		},
		DeclTypes: []*apiservercel.DeclType{
			&newMapType,
		},
	})
	if err != nil {
		panic(fmt.Errorf("failed to extend environment for composition: %w", err))
	}

	newContext := &CompositionEnv{
		MapType:           &newMapType,
		EnvSet:            newEnvSet,
		baseEnvSet:        context.baseEnvSet,
		CompiledVariables: map[string]CompilationResult{},
	}


Review comment (suggestion):
I agree that this error condition seems impossible in the code as it is currently written. I think this would be a bit cleaner if we created a `MustExtend` function (or maybe `mustExtend` since it's probably only used in this package) that makes it more clear that this operation is expected to be infallible.

Code after:
	state *compositionState
}

// CompositedEvaluator provides evaluation of a single expression with variable composition.
// The types that may returned by the expression is determined at compilation time.
type CompositedEvaluator struct {
	MutatingEvaluator

	state *compositionState
}

func NewCompositedCompiler(envSet *environment.EnvSet) (*CompositedCompiler, error) {
	newMapType := apiservercel.NewObjectType(variablesTypeName, map[string]*apiservercel.DeclField{})

	newEnvSet, err := envSet.Extend(environment.VersionedOptions{
		IntroducedVersion: version.MajorMinor(1, 0),
		EnvOptions: []cel.EnvOption{
			cel.Variable("variables", newMapType.CelType()),
		},
		DeclTypes: []*apiservercel.DeclType{
			newMapType,
		},
	})
	if err != nil {
		return nil, err
	}

	state := &compositionState{
		mapType:           newMapType,
		EnvSet:            newEnvSet,
		compiledVariables: map[string]CompilationResult{},
	}

	compiler := NewCompiler(state.EnvSet)
	conditionCompiler := &conditionCompiler{compiler}
	mutation := &mutatingCompiler{compiler}
	return &CompositedCompiler{
		Compiler:          compiler,
		ConditionCompiler: conditionCompiler,
		MutatingCompiler:  mutation,
		state:             state,
	}, nil
}

// NewCompositedCompilerForTypeChecking creates a CompositedCompiler for type checking.
// It initializes the composition state but leaves the Compilers nil, as they are expected
// to be replaced by the caller (who is doing type checking).
func NewCompositedCompilerForTypeChecking(envSet *environment.EnvSet) (*CompositedCompiler, error) {
	newMapType := apiservercel.NewObjectType(variablesTypeName, map[string]*apiservercel.DeclField{})

	newEnvSet, err := envSet.Extend(environment.VersionedOptions{