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:
254
vendor/github.com/google/cel-go/ext/bindings.go
generated
vendored
254
vendor/github.com/google/cel-go/ext/bindings.go
generated
vendored
@ -15,9 +15,19 @@
|
||||
package ext
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/google/cel-go/cel"
|
||||
"github.com/google/cel-go/common/ast"
|
||||
"github.com/google/cel-go/common/types"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/google/cel-go/common/types/traits"
|
||||
"github.com/google/cel-go/interpreter"
|
||||
)
|
||||
|
||||
// Bindings returns a cel.EnvOption to configure support for local variable
|
||||
@ -41,35 +51,120 @@ import (
|
||||
// [d, e, f].exists(elem, elem in valid_values))
|
||||
//
|
||||
// Local bindings are not guaranteed to be evaluated before use.
|
||||
func Bindings() cel.EnvOption {
|
||||
return cel.Lib(celBindings{})
|
||||
func Bindings(options ...BindingsOption) cel.EnvOption {
|
||||
b := &celBindings{version: math.MaxUint32}
|
||||
for _, o := range options {
|
||||
b = o(b)
|
||||
}
|
||||
return cel.Lib(b)
|
||||
}
|
||||
|
||||
const (
|
||||
celNamespace = "cel"
|
||||
bindMacro = "bind"
|
||||
blockFunc = "@block"
|
||||
unusedIterVar = "#unused"
|
||||
)
|
||||
|
||||
type celBindings struct{}
|
||||
// BindingsOption declares a functional operator for configuring the Bindings library behavior.
|
||||
type BindingsOption func(*celBindings) *celBindings
|
||||
|
||||
func (celBindings) LibraryName() string {
|
||||
// BindingsVersion sets the version of the bindings library to an explicit version.
|
||||
func BindingsVersion(version uint32) BindingsOption {
|
||||
return func(lib *celBindings) *celBindings {
|
||||
lib.version = version
|
||||
return lib
|
||||
}
|
||||
}
|
||||
|
||||
type celBindings struct {
|
||||
version uint32
|
||||
}
|
||||
|
||||
func (*celBindings) LibraryName() string {
|
||||
return "cel.lib.ext.cel.bindings"
|
||||
}
|
||||
|
||||
func (celBindings) CompileOptions() []cel.EnvOption {
|
||||
return []cel.EnvOption{
|
||||
func (lib *celBindings) CompileOptions() []cel.EnvOption {
|
||||
opts := []cel.EnvOption{
|
||||
cel.Macros(
|
||||
// cel.bind(var, <init>, <expr>)
|
||||
cel.ReceiverMacro(bindMacro, 3, celBind),
|
||||
),
|
||||
}
|
||||
if lib.version >= 1 {
|
||||
// The cel.@block signature takes a list of subexpressions and a typed expression which is
|
||||
// used as the output type.
|
||||
paramType := cel.TypeParamType("T")
|
||||
opts = append(opts,
|
||||
cel.Function("cel.@block",
|
||||
cel.Overload("cel_block_list",
|
||||
[]*cel.Type{cel.ListType(cel.DynType), paramType}, paramType)),
|
||||
)
|
||||
opts = append(opts, cel.ASTValidators(blockValidationExemption{}))
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
func (celBindings) ProgramOptions() []cel.ProgramOption {
|
||||
func (lib *celBindings) ProgramOptions() []cel.ProgramOption {
|
||||
if lib.version >= 1 {
|
||||
celBlockPlan := func(i interpreter.Interpretable) (interpreter.Interpretable, error) {
|
||||
call, ok := i.(interpreter.InterpretableCall)
|
||||
if !ok {
|
||||
return i, nil
|
||||
}
|
||||
switch call.Function() {
|
||||
case "cel.@block":
|
||||
args := call.Args()
|
||||
if len(args) != 2 {
|
||||
return nil, fmt.Errorf("cel.@block expects two arguments, but got %d", len(args))
|
||||
}
|
||||
expr := args[1]
|
||||
// Non-empty block
|
||||
if block, ok := args[0].(interpreter.InterpretableConstructor); ok {
|
||||
slotExprs := block.InitVals()
|
||||
return newDynamicBlock(slotExprs, expr), nil
|
||||
}
|
||||
// Constant valued block which can happen during runtime optimization.
|
||||
if cons, ok := args[0].(interpreter.InterpretableConst); ok {
|
||||
if cons.Value().Type() == types.ListType {
|
||||
l := cons.Value().(traits.Lister)
|
||||
if l.Size().Equal(types.IntZero) == types.True {
|
||||
return args[1], nil
|
||||
}
|
||||
return newConstantBlock(l, expr), nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("cel.@block expects a list constructor as the first argument")
|
||||
default:
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
return []cel.ProgramOption{cel.CustomDecorator(celBlockPlan)}
|
||||
}
|
||||
return []cel.ProgramOption{}
|
||||
}
|
||||
|
||||
type blockValidationExemption struct{}
|
||||
|
||||
// Name returns the name of the validator.
|
||||
func (blockValidationExemption) Name() string {
|
||||
return "cel.lib.ext.validate.functions.cel.block"
|
||||
}
|
||||
|
||||
// Configure implements the ASTValidatorConfigurer interface and augments the list of functions to skip
|
||||
// during homogeneous aggregate literal type-checks.
|
||||
func (blockValidationExemption) Configure(config cel.MutableValidatorConfig) error {
|
||||
functions := config.GetOrDefault(cel.HomogeneousAggregateLiteralExemptFunctions, []string{}).([]string)
|
||||
functions = append(functions, "cel.@block")
|
||||
return config.Set(cel.HomogeneousAggregateLiteralExemptFunctions, functions)
|
||||
}
|
||||
|
||||
// Validate is a no-op as the intent is to simply disable strong type-checks for list literals during
|
||||
// when they occur within cel.@block calls as the arg types have already been validated.
|
||||
func (blockValidationExemption) Validate(env *cel.Env, _ cel.ValidatorConfig, a *ast.AST, iss *cel.Issues) {
|
||||
}
|
||||
|
||||
func celBind(mef cel.MacroExprFactory, target ast.Expr, args []ast.Expr) (ast.Expr, *cel.Error) {
|
||||
if !macroTargetMatchesNamespace(celNamespace, target) {
|
||||
return nil, nil
|
||||
@ -94,3 +189,148 @@ func celBind(mef cel.MacroExprFactory, target ast.Expr, args []ast.Expr) (ast.Ex
|
||||
resultExpr,
|
||||
), nil
|
||||
}
|
||||
|
||||
func newDynamicBlock(slotExprs []interpreter.Interpretable, expr interpreter.Interpretable) interpreter.Interpretable {
|
||||
bs := &dynamicBlock{
|
||||
slotExprs: slotExprs,
|
||||
expr: expr,
|
||||
}
|
||||
bs.slotActivationPool = &sync.Pool{
|
||||
New: func() any {
|
||||
slotCount := len(slotExprs)
|
||||
sa := &dynamicSlotActivation{
|
||||
slotExprs: slotExprs,
|
||||
slotCount: slotCount,
|
||||
slotVals: make([]*slotVal, slotCount),
|
||||
}
|
||||
for i := 0; i < slotCount; i++ {
|
||||
sa.slotVals[i] = &slotVal{}
|
||||
}
|
||||
return sa
|
||||
},
|
||||
}
|
||||
return bs
|
||||
}
|
||||
|
||||
type dynamicBlock struct {
|
||||
slotExprs []interpreter.Interpretable
|
||||
expr interpreter.Interpretable
|
||||
slotActivationPool *sync.Pool
|
||||
}
|
||||
|
||||
// ID implements the Interpretable interface method.
|
||||
func (b *dynamicBlock) ID() int64 {
|
||||
return b.expr.ID()
|
||||
}
|
||||
|
||||
// Eval implements the Interpretable interface method.
|
||||
func (b *dynamicBlock) Eval(activation interpreter.Activation) ref.Val {
|
||||
sa := b.slotActivationPool.Get().(*dynamicSlotActivation)
|
||||
sa.Activation = activation
|
||||
defer b.clearSlots(sa)
|
||||
return b.expr.Eval(sa)
|
||||
}
|
||||
|
||||
func (b *dynamicBlock) clearSlots(sa *dynamicSlotActivation) {
|
||||
sa.reset()
|
||||
b.slotActivationPool.Put(sa)
|
||||
}
|
||||
|
||||
type slotVal struct {
|
||||
value *ref.Val
|
||||
visited bool
|
||||
}
|
||||
|
||||
type dynamicSlotActivation struct {
|
||||
interpreter.Activation
|
||||
slotExprs []interpreter.Interpretable
|
||||
slotCount int
|
||||
slotVals []*slotVal
|
||||
}
|
||||
|
||||
// ResolveName implements the Activation interface method but handles variables prefixed with `@index`
|
||||
// as special variables which exist within the slot-based memory of the cel.@block() where each slot
|
||||
// refers to an expression which must be computed only once.
|
||||
func (sa *dynamicSlotActivation) ResolveName(name string) (any, bool) {
|
||||
if idx, found := matchSlot(name, sa.slotCount); found {
|
||||
v := sa.slotVals[idx]
|
||||
if v.visited {
|
||||
// Return not found if the index expression refers to itself
|
||||
if v.value == nil {
|
||||
return nil, false
|
||||
}
|
||||
return *v.value, true
|
||||
}
|
||||
v.visited = true
|
||||
val := sa.slotExprs[idx].Eval(sa)
|
||||
v.value = &val
|
||||
return val, true
|
||||
}
|
||||
return sa.Activation.ResolveName(name)
|
||||
}
|
||||
|
||||
func (sa *dynamicSlotActivation) reset() {
|
||||
sa.Activation = nil
|
||||
for _, sv := range sa.slotVals {
|
||||
sv.visited = false
|
||||
sv.value = nil
|
||||
}
|
||||
}
|
||||
|
||||
func newConstantBlock(slots traits.Lister, expr interpreter.Interpretable) interpreter.Interpretable {
|
||||
count := slots.Size().(types.Int)
|
||||
return &constantBlock{slots: slots, slotCount: int(count), expr: expr}
|
||||
}
|
||||
|
||||
type constantBlock struct {
|
||||
slots traits.Lister
|
||||
slotCount int
|
||||
expr interpreter.Interpretable
|
||||
}
|
||||
|
||||
// ID implements the interpreter.Interpretable interface method.
|
||||
func (b *constantBlock) ID() int64 {
|
||||
return b.expr.ID()
|
||||
}
|
||||
|
||||
// Eval implements the interpreter.Interpretable interface method, and will proxy @index prefixed variable
|
||||
// lookups into a set of constant slots determined from the plan step.
|
||||
func (b *constantBlock) Eval(activation interpreter.Activation) ref.Val {
|
||||
vars := constantSlotActivation{Activation: activation, slots: b.slots, slotCount: b.slotCount}
|
||||
return b.expr.Eval(vars)
|
||||
}
|
||||
|
||||
type constantSlotActivation struct {
|
||||
interpreter.Activation
|
||||
slots traits.Lister
|
||||
slotCount int
|
||||
}
|
||||
|
||||
// ResolveName implements Activation interface method and proxies @index prefixed lookups into the slot
|
||||
// activation associated with the block scope.
|
||||
func (sa constantSlotActivation) ResolveName(name string) (any, bool) {
|
||||
if idx, found := matchSlot(name, sa.slotCount); found {
|
||||
return sa.slots.Get(types.Int(idx)), true
|
||||
}
|
||||
return sa.Activation.ResolveName(name)
|
||||
}
|
||||
|
||||
func matchSlot(name string, slotCount int) (int, bool) {
|
||||
if idx, found := strings.CutPrefix(name, indexPrefix); found {
|
||||
idx, err := strconv.Atoi(idx)
|
||||
// Return not found if the index is not numeric
|
||||
if err != nil {
|
||||
return -1, false
|
||||
}
|
||||
// Return not found if the index is not a valid slot
|
||||
if idx < 0 || idx >= slotCount {
|
||||
return -1, false
|
||||
}
|
||||
return idx, true
|
||||
}
|
||||
return -1, false
|
||||
}
|
||||
|
||||
var (
|
||||
indexPrefix = "@index"
|
||||
)
|
||||
|
Reference in New Issue
Block a user