mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 18:53:35 +00:00
rebase: update K8s packages to v0.32.1
Update K8s packages in go.mod to v0.32.1 Signed-off-by: Praveen M <m.praveen@ibm.com>
This commit is contained in:
33
vendor/github.com/google/cel-go/interpreter/activation.go
generated
vendored
33
vendor/github.com/google/cel-go/interpreter/activation.go
generated
vendored
@ -17,7 +17,6 @@ package interpreter
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
)
|
||||
@ -167,35 +166,3 @@ type partActivation struct {
|
||||
func (a *partActivation) UnknownAttributePatterns() []*AttributePattern {
|
||||
return a.unknowns
|
||||
}
|
||||
|
||||
// varActivation represents a single mutable variable binding.
|
||||
//
|
||||
// This activation type should only be used within folds as the fold loop controls the object
|
||||
// life-cycle.
|
||||
type varActivation struct {
|
||||
parent Activation
|
||||
name string
|
||||
val ref.Val
|
||||
}
|
||||
|
||||
// Parent implements the Activation interface method.
|
||||
func (v *varActivation) Parent() Activation {
|
||||
return v.parent
|
||||
}
|
||||
|
||||
// ResolveName implements the Activation interface method.
|
||||
func (v *varActivation) ResolveName(name string) (any, bool) {
|
||||
if name == v.name {
|
||||
return v.val, true
|
||||
}
|
||||
return v.parent.ResolveName(name)
|
||||
}
|
||||
|
||||
var (
|
||||
// pool of var activations to reduce allocations during folds.
|
||||
varActivationPool = &sync.Pool{
|
||||
New: func() any {
|
||||
return &varActivation{}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
6
vendor/github.com/google/cel-go/interpreter/attribute_patterns.go
generated
vendored
6
vendor/github.com/google/cel-go/interpreter/attribute_patterns.go
generated
vendored
@ -178,10 +178,8 @@ func numericValueEquals(value any, celValue ref.Val) bool {
|
||||
|
||||
// NewPartialAttributeFactory returns an AttributeFactory implementation capable of performing
|
||||
// AttributePattern matches with PartialActivation inputs.
|
||||
func NewPartialAttributeFactory(container *containers.Container,
|
||||
adapter types.Adapter,
|
||||
provider types.Provider) AttributeFactory {
|
||||
fac := NewAttributeFactory(container, adapter, provider)
|
||||
func NewPartialAttributeFactory(container *containers.Container, adapter types.Adapter, provider types.Provider, opts ...AttrFactoryOption) AttributeFactory {
|
||||
fac := NewAttributeFactory(container, adapter, provider, opts...)
|
||||
return &partialAttributeFactory{
|
||||
AttributeFactory: fac,
|
||||
container: container,
|
||||
|
236
vendor/github.com/google/cel-go/interpreter/attributes.go
generated
vendored
236
vendor/github.com/google/cel-go/interpreter/attributes.go
generated
vendored
@ -126,21 +126,39 @@ type NamespacedAttribute interface {
|
||||
Qualifiers() []Qualifier
|
||||
}
|
||||
|
||||
// AttrFactoryOption specifies a functional option for configuring an attribute factory.
|
||||
type AttrFactoryOption func(*attrFactory) *attrFactory
|
||||
|
||||
// EnableErrorOnBadPresenceTest error generation when a presence test or optional field selection
|
||||
// is performed on a primitive type.
|
||||
func EnableErrorOnBadPresenceTest(value bool) AttrFactoryOption {
|
||||
return func(fac *attrFactory) *attrFactory {
|
||||
fac.errorOnBadPresenceTest = value
|
||||
return fac
|
||||
}
|
||||
}
|
||||
|
||||
// NewAttributeFactory returns a default AttributeFactory which is produces Attribute values
|
||||
// capable of resolving types by simple names and qualify the values using the supported qualifier
|
||||
// types: bool, int, string, and uint.
|
||||
func NewAttributeFactory(cont *containers.Container, a types.Adapter, p types.Provider) AttributeFactory {
|
||||
return &attrFactory{
|
||||
func NewAttributeFactory(cont *containers.Container, a types.Adapter, p types.Provider, opts ...AttrFactoryOption) AttributeFactory {
|
||||
fac := &attrFactory{
|
||||
container: cont,
|
||||
adapter: a,
|
||||
provider: p,
|
||||
}
|
||||
for _, o := range opts {
|
||||
fac = o(fac)
|
||||
}
|
||||
return fac
|
||||
}
|
||||
|
||||
type attrFactory struct {
|
||||
container *containers.Container
|
||||
adapter types.Adapter
|
||||
provider types.Provider
|
||||
|
||||
errorOnBadPresenceTest bool
|
||||
}
|
||||
|
||||
// AbsoluteAttribute refers to a variable value and an optional qualifier path.
|
||||
@ -149,12 +167,13 @@ type attrFactory struct {
|
||||
// resolution rules.
|
||||
func (r *attrFactory) AbsoluteAttribute(id int64, names ...string) NamespacedAttribute {
|
||||
return &absoluteAttribute{
|
||||
id: id,
|
||||
namespaceNames: names,
|
||||
qualifiers: []Qualifier{},
|
||||
adapter: r.adapter,
|
||||
provider: r.provider,
|
||||
fac: r,
|
||||
id: id,
|
||||
namespaceNames: names,
|
||||
qualifiers: []Qualifier{},
|
||||
adapter: r.adapter,
|
||||
provider: r.provider,
|
||||
fac: r,
|
||||
errorOnBadPresenceTest: r.errorOnBadPresenceTest,
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,11 +207,12 @@ func (r *attrFactory) MaybeAttribute(id int64, name string) Attribute {
|
||||
// RelativeAttribute refers to an expression and an optional qualifier path.
|
||||
func (r *attrFactory) RelativeAttribute(id int64, operand Interpretable) Attribute {
|
||||
return &relativeAttribute{
|
||||
id: id,
|
||||
operand: operand,
|
||||
qualifiers: []Qualifier{},
|
||||
adapter: r.adapter,
|
||||
fac: r,
|
||||
id: id,
|
||||
operand: operand,
|
||||
qualifiers: []Qualifier{},
|
||||
adapter: r.adapter,
|
||||
fac: r,
|
||||
errorOnBadPresenceTest: r.errorOnBadPresenceTest,
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,7 +234,7 @@ func (r *attrFactory) NewQualifier(objType *types.Type, qualID int64, val any, o
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
return newQualifier(r.adapter, qualID, val, opt)
|
||||
return newQualifier(r.adapter, qualID, val, opt, r.errorOnBadPresenceTest)
|
||||
}
|
||||
|
||||
type absoluteAttribute struct {
|
||||
@ -226,6 +246,8 @@ type absoluteAttribute struct {
|
||||
adapter types.Adapter
|
||||
provider types.Provider
|
||||
fac AttributeFactory
|
||||
|
||||
errorOnBadPresenceTest bool
|
||||
}
|
||||
|
||||
// ID implements the Attribute interface method.
|
||||
@ -514,6 +536,8 @@ type relativeAttribute struct {
|
||||
qualifiers []Qualifier
|
||||
adapter types.Adapter
|
||||
fac AttributeFactory
|
||||
|
||||
errorOnBadPresenceTest bool
|
||||
}
|
||||
|
||||
// ID is an implementation of the Attribute interface method.
|
||||
@ -577,7 +601,7 @@ func (a *relativeAttribute) String() string {
|
||||
return fmt.Sprintf("id: %v, operand: %v", a.id, a.operand)
|
||||
}
|
||||
|
||||
func newQualifier(adapter types.Adapter, id int64, v any, opt bool) (Qualifier, error) {
|
||||
func newQualifier(adapter types.Adapter, id int64, v any, opt, errorOnBadPresenceTest bool) (Qualifier, error) {
|
||||
var qual Qualifier
|
||||
switch val := v.(type) {
|
||||
case Attribute:
|
||||
@ -592,71 +616,138 @@ func newQualifier(adapter types.Adapter, id int64, v any, opt bool) (Qualifier,
|
||||
}, nil
|
||||
case string:
|
||||
qual = &stringQualifier{
|
||||
id: id,
|
||||
value: val,
|
||||
celValue: types.String(val),
|
||||
adapter: adapter,
|
||||
optional: opt,
|
||||
id: id,
|
||||
value: val,
|
||||
celValue: types.String(val),
|
||||
adapter: adapter,
|
||||
optional: opt,
|
||||
errorOnBadPresenceTest: errorOnBadPresenceTest,
|
||||
}
|
||||
case int:
|
||||
qual = &intQualifier{
|
||||
id: id, value: int64(val), celValue: types.Int(val), adapter: adapter, optional: opt,
|
||||
id: id,
|
||||
value: int64(val),
|
||||
celValue: types.Int(val),
|
||||
adapter: adapter,
|
||||
optional: opt,
|
||||
errorOnBadPresenceTest: errorOnBadPresenceTest,
|
||||
}
|
||||
case int32:
|
||||
qual = &intQualifier{
|
||||
id: id, value: int64(val), celValue: types.Int(val), adapter: adapter, optional: opt,
|
||||
id: id,
|
||||
value: int64(val),
|
||||
celValue: types.Int(val),
|
||||
adapter: adapter,
|
||||
optional: opt,
|
||||
errorOnBadPresenceTest: errorOnBadPresenceTest,
|
||||
}
|
||||
case int64:
|
||||
qual = &intQualifier{
|
||||
id: id, value: val, celValue: types.Int(val), adapter: adapter, optional: opt,
|
||||
id: id,
|
||||
value: val,
|
||||
celValue: types.Int(val),
|
||||
adapter: adapter,
|
||||
optional: opt,
|
||||
errorOnBadPresenceTest: errorOnBadPresenceTest,
|
||||
}
|
||||
case uint:
|
||||
qual = &uintQualifier{
|
||||
id: id, value: uint64(val), celValue: types.Uint(val), adapter: adapter, optional: opt,
|
||||
id: id,
|
||||
value: uint64(val),
|
||||
celValue: types.Uint(val),
|
||||
adapter: adapter,
|
||||
optional: opt,
|
||||
errorOnBadPresenceTest: errorOnBadPresenceTest,
|
||||
}
|
||||
case uint32:
|
||||
qual = &uintQualifier{
|
||||
id: id, value: uint64(val), celValue: types.Uint(val), adapter: adapter, optional: opt,
|
||||
id: id,
|
||||
value: uint64(val),
|
||||
celValue: types.Uint(val),
|
||||
adapter: adapter,
|
||||
optional: opt,
|
||||
errorOnBadPresenceTest: errorOnBadPresenceTest,
|
||||
}
|
||||
case uint64:
|
||||
qual = &uintQualifier{
|
||||
id: id, value: val, celValue: types.Uint(val), adapter: adapter, optional: opt,
|
||||
id: id,
|
||||
value: val,
|
||||
celValue: types.Uint(val),
|
||||
adapter: adapter,
|
||||
optional: opt,
|
||||
errorOnBadPresenceTest: errorOnBadPresenceTest,
|
||||
}
|
||||
case bool:
|
||||
qual = &boolQualifier{
|
||||
id: id, value: val, celValue: types.Bool(val), adapter: adapter, optional: opt,
|
||||
id: id,
|
||||
value: val,
|
||||
celValue: types.Bool(val),
|
||||
adapter: adapter,
|
||||
optional: opt,
|
||||
errorOnBadPresenceTest: errorOnBadPresenceTest,
|
||||
}
|
||||
case float32:
|
||||
qual = &doubleQualifier{
|
||||
id: id,
|
||||
value: float64(val),
|
||||
celValue: types.Double(val),
|
||||
adapter: adapter,
|
||||
optional: opt,
|
||||
id: id,
|
||||
value: float64(val),
|
||||
celValue: types.Double(val),
|
||||
adapter: adapter,
|
||||
optional: opt,
|
||||
errorOnBadPresenceTest: errorOnBadPresenceTest,
|
||||
}
|
||||
case float64:
|
||||
qual = &doubleQualifier{
|
||||
id: id, value: val, celValue: types.Double(val), adapter: adapter, optional: opt,
|
||||
id: id,
|
||||
value: val,
|
||||
celValue: types.Double(val),
|
||||
adapter: adapter,
|
||||
optional: opt,
|
||||
errorOnBadPresenceTest: errorOnBadPresenceTest,
|
||||
}
|
||||
case types.String:
|
||||
qual = &stringQualifier{
|
||||
id: id, value: string(val), celValue: val, adapter: adapter, optional: opt,
|
||||
id: id,
|
||||
value: string(val),
|
||||
celValue: val,
|
||||
adapter: adapter,
|
||||
optional: opt,
|
||||
errorOnBadPresenceTest: errorOnBadPresenceTest,
|
||||
}
|
||||
case types.Int:
|
||||
qual = &intQualifier{
|
||||
id: id, value: int64(val), celValue: val, adapter: adapter, optional: opt,
|
||||
id: id,
|
||||
value: int64(val),
|
||||
celValue: val,
|
||||
adapter: adapter,
|
||||
optional: opt,
|
||||
errorOnBadPresenceTest: errorOnBadPresenceTest,
|
||||
}
|
||||
case types.Uint:
|
||||
qual = &uintQualifier{
|
||||
id: id, value: uint64(val), celValue: val, adapter: adapter, optional: opt,
|
||||
id: id,
|
||||
value: uint64(val),
|
||||
celValue: val,
|
||||
adapter: adapter,
|
||||
optional: opt,
|
||||
errorOnBadPresenceTest: errorOnBadPresenceTest,
|
||||
}
|
||||
case types.Bool:
|
||||
qual = &boolQualifier{
|
||||
id: id, value: bool(val), celValue: val, adapter: adapter, optional: opt,
|
||||
id: id,
|
||||
value: bool(val),
|
||||
celValue: val,
|
||||
adapter: adapter,
|
||||
optional: opt,
|
||||
errorOnBadPresenceTest: errorOnBadPresenceTest,
|
||||
}
|
||||
case types.Double:
|
||||
qual = &doubleQualifier{
|
||||
id: id, value: float64(val), celValue: val, adapter: adapter, optional: opt,
|
||||
id: id,
|
||||
value: float64(val),
|
||||
celValue: val,
|
||||
adapter: adapter,
|
||||
optional: opt,
|
||||
errorOnBadPresenceTest: errorOnBadPresenceTest,
|
||||
}
|
||||
case *types.Unknown:
|
||||
qual = &unknownQualifier{id: id, value: val}
|
||||
@ -687,11 +778,12 @@ func (q *attrQualifier) IsOptional() bool {
|
||||
}
|
||||
|
||||
type stringQualifier struct {
|
||||
id int64
|
||||
value string
|
||||
celValue ref.Val
|
||||
adapter types.Adapter
|
||||
optional bool
|
||||
id int64
|
||||
value string
|
||||
celValue ref.Val
|
||||
adapter types.Adapter
|
||||
optional bool
|
||||
errorOnBadPresenceTest bool
|
||||
}
|
||||
|
||||
// ID is an implementation of the Qualifier interface method.
|
||||
@ -774,7 +866,7 @@ func (q *stringQualifier) qualifyInternal(vars Activation, obj any, presenceTest
|
||||
return obj, true, nil
|
||||
}
|
||||
default:
|
||||
return refQualify(q.adapter, obj, q.celValue, presenceTest, presenceOnly)
|
||||
return refQualify(q.adapter, obj, q.celValue, presenceTest, presenceOnly, q.errorOnBadPresenceTest)
|
||||
}
|
||||
if presenceTest {
|
||||
return nil, false, nil
|
||||
@ -788,11 +880,12 @@ func (q *stringQualifier) Value() ref.Val {
|
||||
}
|
||||
|
||||
type intQualifier struct {
|
||||
id int64
|
||||
value int64
|
||||
celValue ref.Val
|
||||
adapter types.Adapter
|
||||
optional bool
|
||||
id int64
|
||||
value int64
|
||||
celValue ref.Val
|
||||
adapter types.Adapter
|
||||
optional bool
|
||||
errorOnBadPresenceTest bool
|
||||
}
|
||||
|
||||
// ID is an implementation of the Qualifier interface method.
|
||||
@ -898,7 +991,7 @@ func (q *intQualifier) qualifyInternal(vars Activation, obj any, presenceTest, p
|
||||
return o[i], true, nil
|
||||
}
|
||||
default:
|
||||
return refQualify(q.adapter, obj, q.celValue, presenceTest, presenceOnly)
|
||||
return refQualify(q.adapter, obj, q.celValue, presenceTest, presenceOnly, q.errorOnBadPresenceTest)
|
||||
}
|
||||
if presenceTest {
|
||||
return nil, false, nil
|
||||
@ -915,11 +1008,12 @@ func (q *intQualifier) Value() ref.Val {
|
||||
}
|
||||
|
||||
type uintQualifier struct {
|
||||
id int64
|
||||
value uint64
|
||||
celValue ref.Val
|
||||
adapter types.Adapter
|
||||
optional bool
|
||||
id int64
|
||||
value uint64
|
||||
celValue ref.Val
|
||||
adapter types.Adapter
|
||||
optional bool
|
||||
errorOnBadPresenceTest bool
|
||||
}
|
||||
|
||||
// ID is an implementation of the Qualifier interface method.
|
||||
@ -966,7 +1060,7 @@ func (q *uintQualifier) qualifyInternal(vars Activation, obj any, presenceTest,
|
||||
return obj, true, nil
|
||||
}
|
||||
default:
|
||||
return refQualify(q.adapter, obj, q.celValue, presenceTest, presenceOnly)
|
||||
return refQualify(q.adapter, obj, q.celValue, presenceTest, presenceOnly, q.errorOnBadPresenceTest)
|
||||
}
|
||||
if presenceTest {
|
||||
return nil, false, nil
|
||||
@ -980,11 +1074,12 @@ func (q *uintQualifier) Value() ref.Val {
|
||||
}
|
||||
|
||||
type boolQualifier struct {
|
||||
id int64
|
||||
value bool
|
||||
celValue ref.Val
|
||||
adapter types.Adapter
|
||||
optional bool
|
||||
id int64
|
||||
value bool
|
||||
celValue ref.Val
|
||||
adapter types.Adapter
|
||||
optional bool
|
||||
errorOnBadPresenceTest bool
|
||||
}
|
||||
|
||||
// ID is an implementation of the Qualifier interface method.
|
||||
@ -1017,7 +1112,7 @@ func (q *boolQualifier) qualifyInternal(vars Activation, obj any, presenceTest,
|
||||
return obj, true, nil
|
||||
}
|
||||
default:
|
||||
return refQualify(q.adapter, obj, q.celValue, presenceTest, presenceOnly)
|
||||
return refQualify(q.adapter, obj, q.celValue, presenceTest, presenceOnly, q.errorOnBadPresenceTest)
|
||||
}
|
||||
if presenceTest {
|
||||
return nil, false, nil
|
||||
@ -1092,11 +1187,12 @@ func (q *fieldQualifier) Value() ref.Val {
|
||||
// type may not be known ahead of time and may not conform to the standard types supported as valid
|
||||
// protobuf map key types.
|
||||
type doubleQualifier struct {
|
||||
id int64
|
||||
value float64
|
||||
celValue ref.Val
|
||||
adapter types.Adapter
|
||||
optional bool
|
||||
id int64
|
||||
value float64
|
||||
celValue ref.Val
|
||||
adapter types.Adapter
|
||||
optional bool
|
||||
errorOnBadPresenceTest bool
|
||||
}
|
||||
|
||||
// ID is an implementation of the Qualifier interface method.
|
||||
@ -1120,7 +1216,7 @@ func (q *doubleQualifier) QualifyIfPresent(vars Activation, obj any, presenceOnl
|
||||
}
|
||||
|
||||
func (q *doubleQualifier) qualifyInternal(vars Activation, obj any, presenceTest, presenceOnly bool) (any, bool, error) {
|
||||
return refQualify(q.adapter, obj, q.celValue, presenceTest, presenceOnly)
|
||||
return refQualify(q.adapter, obj, q.celValue, presenceTest, presenceOnly, q.errorOnBadPresenceTest)
|
||||
}
|
||||
|
||||
// Value implements the ConstantQualifier interface
|
||||
@ -1226,7 +1322,7 @@ func attrQualifyIfPresent(fac AttributeFactory, vars Activation, obj any, qualAt
|
||||
|
||||
// refQualify attempts to convert the value to a CEL value and then uses reflection methods to try and
|
||||
// apply the qualifier with the option to presence test field accesses before retrieving field values.
|
||||
func refQualify(adapter types.Adapter, obj any, idx ref.Val, presenceTest, presenceOnly bool) (ref.Val, bool, error) {
|
||||
func refQualify(adapter types.Adapter, obj any, idx ref.Val, presenceTest, presenceOnly, errorOnBadPresenceTest bool) (ref.Val, bool, error) {
|
||||
celVal := adapter.NativeToValue(obj)
|
||||
switch v := celVal.(type) {
|
||||
case *types.Unknown:
|
||||
@ -1283,7 +1379,7 @@ func refQualify(adapter types.Adapter, obj any, idx ref.Val, presenceTest, prese
|
||||
}
|
||||
return val, true, nil
|
||||
default:
|
||||
if presenceTest {
|
||||
if presenceTest && !errorOnBadPresenceTest {
|
||||
return nil, false, nil
|
||||
}
|
||||
return nil, false, missingKey(idx)
|
||||
|
273
vendor/github.com/google/cel-go/interpreter/interpretable.go
generated
vendored
273
vendor/github.com/google/cel-go/interpreter/interpretable.go
generated
vendored
@ -16,6 +16,7 @@ package interpreter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/google/cel-go/common/functions"
|
||||
"github.com/google/cel-go/common/operators"
|
||||
@ -96,7 +97,7 @@ type InterpretableCall interface {
|
||||
Args() []Interpretable
|
||||
}
|
||||
|
||||
// InterpretableConstructor interface for inspecting Interpretable instructions that initialize a list, map
|
||||
// InterpretableConstructor interface for inspecting Interpretable instructions that initialize a list, map
|
||||
// or struct.
|
||||
type InterpretableConstructor interface {
|
||||
Interpretable
|
||||
@ -720,24 +721,31 @@ func (o *evalObj) Eval(ctx Activation) ref.Val {
|
||||
return types.LabelErrNode(o.id, o.provider.NewValue(o.typeName, fieldVals))
|
||||
}
|
||||
|
||||
// InitVals implements the InterpretableConstructor interface method.
|
||||
func (o *evalObj) InitVals() []Interpretable {
|
||||
return o.vals
|
||||
}
|
||||
|
||||
// Type implements the InterpretableConstructor interface method.
|
||||
func (o *evalObj) Type() ref.Type {
|
||||
return types.NewObjectTypeValue(o.typeName)
|
||||
return types.NewObjectType(o.typeName)
|
||||
}
|
||||
|
||||
type evalFold struct {
|
||||
id int64
|
||||
accuVar string
|
||||
iterVar string
|
||||
iterRange Interpretable
|
||||
accu Interpretable
|
||||
cond Interpretable
|
||||
step Interpretable
|
||||
result Interpretable
|
||||
adapter types.Adapter
|
||||
id int64
|
||||
accuVar string
|
||||
iterVar string
|
||||
iterVar2 string
|
||||
iterRange Interpretable
|
||||
accu Interpretable
|
||||
cond Interpretable
|
||||
step Interpretable
|
||||
result Interpretable
|
||||
adapter types.Adapter
|
||||
|
||||
// note an exhaustive fold will ensure that all branches are evaluated
|
||||
// when using mutable values, these branches will mutate the final result
|
||||
// rather than make a throw-away computation.
|
||||
exhaustive bool
|
||||
interruptable bool
|
||||
}
|
||||
@ -749,64 +757,30 @@ func (fold *evalFold) ID() int64 {
|
||||
|
||||
// Eval implements the Interpretable interface method.
|
||||
func (fold *evalFold) Eval(ctx Activation) ref.Val {
|
||||
// Initialize the folder interface
|
||||
f := newFolder(fold, ctx)
|
||||
defer releaseFolder(f)
|
||||
|
||||
foldRange := fold.iterRange.Eval(ctx)
|
||||
if fold.iterVar2 != "" {
|
||||
var foldable traits.Foldable
|
||||
switch r := foldRange.(type) {
|
||||
case traits.Mapper:
|
||||
foldable = types.ToFoldableMap(r)
|
||||
case traits.Lister:
|
||||
foldable = types.ToFoldableList(r)
|
||||
default:
|
||||
return types.NewErrWithNodeID(fold.ID(), "unsupported comprehension range type: %T", foldRange)
|
||||
}
|
||||
foldable.Fold(f)
|
||||
return f.evalResult()
|
||||
}
|
||||
|
||||
if !foldRange.Type().HasTrait(traits.IterableType) {
|
||||
return types.ValOrErr(foldRange, "got '%T', expected iterable type", foldRange)
|
||||
}
|
||||
// Configure the fold activation with the accumulator initial value.
|
||||
accuCtx := varActivationPool.Get().(*varActivation)
|
||||
accuCtx.parent = ctx
|
||||
accuCtx.name = fold.accuVar
|
||||
accuCtx.val = fold.accu.Eval(ctx)
|
||||
// If the accumulator starts as an empty list, then the comprehension will build a list
|
||||
// so create a mutable list to optimize the cost of the inner loop.
|
||||
l, ok := accuCtx.val.(traits.Lister)
|
||||
buildingList := false
|
||||
if !fold.exhaustive && ok && l.Size() == types.IntZero {
|
||||
buildingList = true
|
||||
accuCtx.val = types.NewMutableList(fold.adapter)
|
||||
}
|
||||
iterCtx := varActivationPool.Get().(*varActivation)
|
||||
iterCtx.parent = accuCtx
|
||||
iterCtx.name = fold.iterVar
|
||||
|
||||
interrupted := false
|
||||
it := foldRange.(traits.Iterable).Iterator()
|
||||
for it.HasNext() == types.True {
|
||||
// Modify the iter var in the fold activation.
|
||||
iterCtx.val = it.Next()
|
||||
|
||||
// Evaluate the condition, terminate the loop if false.
|
||||
cond := fold.cond.Eval(iterCtx)
|
||||
condBool, ok := cond.(types.Bool)
|
||||
if !fold.exhaustive && ok && condBool != types.True {
|
||||
break
|
||||
}
|
||||
// Evaluate the evaluation step into accu var.
|
||||
accuCtx.val = fold.step.Eval(iterCtx)
|
||||
if fold.interruptable {
|
||||
if stop, found := ctx.ResolveName("#interrupted"); found && stop == true {
|
||||
interrupted = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
varActivationPool.Put(iterCtx)
|
||||
if interrupted {
|
||||
varActivationPool.Put(accuCtx)
|
||||
return types.NewErr("operation interrupted")
|
||||
}
|
||||
|
||||
// Compute the result.
|
||||
res := fold.result.Eval(accuCtx)
|
||||
varActivationPool.Put(accuCtx)
|
||||
// Convert a mutable list to an immutable one, if the comprehension has generated a list as a result.
|
||||
if !types.IsUnknownOrError(res) && buildingList {
|
||||
if _, ok := res.(traits.MutableLister); ok {
|
||||
res = res.(traits.MutableLister).ToImmutableList()
|
||||
}
|
||||
}
|
||||
return res
|
||||
iterable := foldRange.(traits.Iterable)
|
||||
return f.foldIterable(iterable)
|
||||
}
|
||||
|
||||
// Optional Interpretable implementations that specialize, subsume, or extend the core evaluation
|
||||
@ -1262,3 +1236,172 @@ func invalidOptionalEntryInit(field any, value ref.Val) ref.Val {
|
||||
func invalidOptionalElementInit(value ref.Val) ref.Val {
|
||||
return types.NewErr("cannot initialize optional list element from non-optional value %v", value)
|
||||
}
|
||||
|
||||
// newFolder creates or initializes a pooled folder instance.
|
||||
func newFolder(eval *evalFold, ctx Activation) *folder {
|
||||
f := folderPool.Get().(*folder)
|
||||
f.evalFold = eval
|
||||
f.Activation = ctx
|
||||
return f
|
||||
}
|
||||
|
||||
// releaseFolder resets and releases a pooled folder instance.
|
||||
func releaseFolder(f *folder) {
|
||||
f.reset()
|
||||
folderPool.Put(f)
|
||||
}
|
||||
|
||||
// folder tracks the state associated with folding a list or map with a comprehension v2 style macro.
|
||||
//
|
||||
// The folder embeds an interpreter.Activation and Interpretable evalFold value as well as implements
|
||||
// the traits.Folder interface methods.
|
||||
//
|
||||
// Instances of a folder are intended to be pooled to minimize allocation overhead with this temporary
|
||||
// bookkeeping object which supports lazy evaluation of the accumulator init expression which is useful
|
||||
// in preserving evaluation order semantics which might otherwise be disrupted through the use of
|
||||
// cel.bind or cel.@block.
|
||||
type folder struct {
|
||||
*evalFold
|
||||
Activation
|
||||
|
||||
// fold state objects.
|
||||
accuVal ref.Val
|
||||
iterVar1Val any
|
||||
iterVar2Val any
|
||||
|
||||
// bookkeeping flags to modify Activation and fold behaviors.
|
||||
initialized bool
|
||||
mutableValue bool
|
||||
interrupted bool
|
||||
computeResult bool
|
||||
}
|
||||
|
||||
func (f *folder) foldIterable(iterable traits.Iterable) ref.Val {
|
||||
it := iterable.Iterator()
|
||||
for it.HasNext() == types.True {
|
||||
f.iterVar1Val = it.Next()
|
||||
|
||||
cond := f.cond.Eval(f)
|
||||
condBool, ok := cond.(types.Bool)
|
||||
if f.interrupted || (!f.exhaustive && ok && condBool != types.True) {
|
||||
return f.evalResult()
|
||||
}
|
||||
|
||||
// Update the accumulation value and check for eval interuption.
|
||||
f.accuVal = f.step.Eval(f)
|
||||
f.initialized = true
|
||||
if f.interruptable && checkInterrupt(f.Activation) {
|
||||
f.interrupted = true
|
||||
return f.evalResult()
|
||||
}
|
||||
}
|
||||
return f.evalResult()
|
||||
}
|
||||
|
||||
// FoldEntry will either fold comprehension v1 style macros if iterVar2 is unset, or comprehension v2 style
|
||||
// macros if both the iterVar and iterVar2 are set to non-empty strings.
|
||||
func (f *folder) FoldEntry(key, val any) bool {
|
||||
// Default to referencing both values.
|
||||
f.iterVar1Val = key
|
||||
f.iterVar2Val = val
|
||||
|
||||
// Terminate evaluation if evaluation is interrupted or the condition is not true and exhaustive
|
||||
// eval is not enabled.
|
||||
cond := f.cond.Eval(f)
|
||||
condBool, ok := cond.(types.Bool)
|
||||
if f.interrupted || (!f.exhaustive && ok && condBool != types.True) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Update the accumulation value and check for eval interuption.
|
||||
f.accuVal = f.step.Eval(f)
|
||||
f.initialized = true
|
||||
if f.interruptable && checkInterrupt(f.Activation) {
|
||||
f.interrupted = true
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ResolveName overrides the default Activation lookup to perform lazy initialization of the accumulator
|
||||
// and specialized lookups of iteration values with consideration for whether the final result is being
|
||||
// computed and the iteration variables should be ignored.
|
||||
func (f *folder) ResolveName(name string) (any, bool) {
|
||||
if name == f.accuVar {
|
||||
if !f.initialized {
|
||||
f.initialized = true
|
||||
initVal := f.accu.Eval(f.Activation)
|
||||
if !f.exhaustive {
|
||||
if l, isList := initVal.(traits.Lister); isList && l.Size() == types.IntZero {
|
||||
initVal = types.NewMutableList(f.adapter)
|
||||
f.mutableValue = true
|
||||
}
|
||||
if m, isMap := initVal.(traits.Mapper); isMap && m.Size() == types.IntZero {
|
||||
initVal = types.NewMutableMap(f.adapter, map[ref.Val]ref.Val{})
|
||||
f.mutableValue = true
|
||||
}
|
||||
}
|
||||
f.accuVal = initVal
|
||||
}
|
||||
return f.accuVal, true
|
||||
}
|
||||
if !f.computeResult {
|
||||
if name == f.iterVar {
|
||||
f.iterVar1Val = f.adapter.NativeToValue(f.iterVar1Val)
|
||||
return f.iterVar1Val, true
|
||||
}
|
||||
if name == f.iterVar2 {
|
||||
f.iterVar2Val = f.adapter.NativeToValue(f.iterVar2Val)
|
||||
return f.iterVar2Val, true
|
||||
}
|
||||
}
|
||||
return f.Activation.ResolveName(name)
|
||||
}
|
||||
|
||||
// evalResult computes the final result of the fold after all entries have been folded and accumulated.
|
||||
func (f *folder) evalResult() ref.Val {
|
||||
f.computeResult = true
|
||||
if f.interrupted {
|
||||
return types.NewErr("operation interrupted")
|
||||
}
|
||||
res := f.result.Eval(f)
|
||||
// Convert a mutable list or map to an immutable one if the comprehension has generated a list or
|
||||
// map as a result.
|
||||
if !types.IsUnknownOrError(res) && f.mutableValue {
|
||||
if _, ok := res.(traits.MutableLister); ok {
|
||||
res = res.(traits.MutableLister).ToImmutableList()
|
||||
}
|
||||
if _, ok := res.(traits.MutableMapper); ok {
|
||||
res = res.(traits.MutableMapper).ToImmutableMap()
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// reset clears any state associated with folder evaluation.
|
||||
func (f *folder) reset() {
|
||||
f.evalFold = nil
|
||||
f.Activation = nil
|
||||
f.accuVal = nil
|
||||
f.iterVar1Val = nil
|
||||
f.iterVar2Val = nil
|
||||
|
||||
f.initialized = false
|
||||
f.mutableValue = false
|
||||
f.interrupted = false
|
||||
f.computeResult = false
|
||||
}
|
||||
|
||||
func checkInterrupt(a Activation) bool {
|
||||
stop, found := a.ResolveName("#interrupted")
|
||||
return found && stop == true
|
||||
}
|
||||
|
||||
var (
|
||||
// pool of var folders to reduce allocations during folds.
|
||||
folderPool = &sync.Pool{
|
||||
New: func() any {
|
||||
return &folder{}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
1
vendor/github.com/google/cel-go/interpreter/planner.go
generated
vendored
1
vendor/github.com/google/cel-go/interpreter/planner.go
generated
vendored
@ -603,6 +603,7 @@ func (p *planner) planComprehension(expr ast.Expr) (Interpretable, error) {
|
||||
accuVar: fold.AccuVar(),
|
||||
accu: accu,
|
||||
iterVar: fold.IterVar(),
|
||||
iterVar2: fold.IterVar2(),
|
||||
iterRange: iterRange,
|
||||
cond: cond,
|
||||
step: step,
|
||||
|
Reference in New Issue
Block a user