Bump cel-go to v0.12.0
This commit is contained in:
209
vendor/github.com/google/cel-go/parser/macro.go
generated
vendored
209
vendor/github.com/google/cel-go/parser/macro.go
generated
vendored
@@ -23,8 +23,6 @@ import (
|
||||
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
||||
)
|
||||
|
||||
// TODO: Consider moving macros to common.
|
||||
|
||||
// NewGlobalMacro creates a Macro for a global function with the specified arg count.
|
||||
func NewGlobalMacro(function string, argCount int, expander MacroExpander) Macro {
|
||||
return ¯o{
|
||||
@@ -50,8 +48,7 @@ func NewGlobalVarArgMacro(function string, expander MacroExpander) Macro {
|
||||
varArgStyle: true}
|
||||
}
|
||||
|
||||
// NewReceiverVarArgMacro creates a Macro for a receiver function matching a variable arg
|
||||
// count.
|
||||
// NewReceiverVarArgMacro creates a Macro for a receiver function matching a variable arg count.
|
||||
func NewReceiverVarArgMacro(function string, expander MacroExpander) Macro {
|
||||
return ¯o{
|
||||
function: function,
|
||||
@@ -135,9 +132,13 @@ func makeVarArgMacroKey(name string, receiverStyle bool) string {
|
||||
return fmt.Sprintf("%s:*:%v", name, receiverStyle)
|
||||
}
|
||||
|
||||
// MacroExpander converts the target and args of a function call that matches a Macro.
|
||||
// MacroExpander converts a call and its associated arguments into a new CEL abstract syntax tree, or an error
|
||||
// if the input arguments are not suitable for the expansion requirements for the macro in question.
|
||||
//
|
||||
// Note: when the Macros.IsReceiverStyle() is true, the target argument will be nil.
|
||||
// The MacroExpander accepts as arguments a MacroExprHelper as well as the arguments used in the function call
|
||||
// and produces as output an Expr ast node.
|
||||
//
|
||||
// Note: when the Macro.IsReceiverStyle() method returns true, the target argument will be nil.
|
||||
type MacroExpander func(eh ExprHelper,
|
||||
target *exprpb.Expr,
|
||||
args []*exprpb.Expr) (*exprpb.Expr, *common.Error)
|
||||
@@ -208,6 +209,9 @@ type ExprHelper interface {
|
||||
// Ident creates an identifier Expr value.
|
||||
Ident(name string) *exprpb.Expr
|
||||
|
||||
// AccuIdent returns an accumulator identifier for use with comprehension results.
|
||||
AccuIdent() *exprpb.Expr
|
||||
|
||||
// GlobalCall creates a function call Expr value for a global (free) function.
|
||||
GlobalCall(function string, args ...*exprpb.Expr) *exprpb.Expr
|
||||
|
||||
@@ -225,34 +229,44 @@ type ExprHelper interface {
|
||||
}
|
||||
|
||||
var (
|
||||
// HasMacro expands "has(m.f)" which tests the presence of a field, avoiding the need to
|
||||
// specify the field as a string.
|
||||
HasMacro = NewGlobalMacro(operators.Has, 1, MakeHas)
|
||||
|
||||
// AllMacro expands "range.all(var, predicate)" into a comprehension which ensures that all
|
||||
// elements in the range satisfy the predicate.
|
||||
AllMacro = NewReceiverMacro(operators.All, 2, MakeAll)
|
||||
|
||||
// ExistsMacro expands "range.exists(var, predicate)" into a comprehension which ensures that
|
||||
// some element in the range satisfies the predicate.
|
||||
ExistsMacro = NewReceiverMacro(operators.Exists, 2, MakeExists)
|
||||
|
||||
// ExistsOneMacro expands "range.exists_one(var, predicate)", which is true if for exactly one
|
||||
// element in range the predicate holds.
|
||||
ExistsOneMacro = NewReceiverMacro(operators.ExistsOne, 2, MakeExistsOne)
|
||||
|
||||
// MapMacro expands "range.map(var, function)" into a comprehension which applies the function
|
||||
// to each element in the range to produce a new list.
|
||||
MapMacro = NewReceiverMacro(operators.Map, 2, MakeMap)
|
||||
|
||||
// MapFilterMacro expands "range.map(var, predicate, function)" into a comprehension which
|
||||
// first filters the elements in the range by the predicate, then applies the transform function
|
||||
// to produce a new list.
|
||||
MapFilterMacro = NewReceiverMacro(operators.Map, 3, MakeMap)
|
||||
|
||||
// FilterMacro expands "range.filter(var, predicate)" into a comprehension which filters
|
||||
// elements in the range, producing a new list from the elements that satisfy the predicate.
|
||||
FilterMacro = NewReceiverMacro(operators.Filter, 2, MakeFilter)
|
||||
|
||||
// AllMacros includes the list of all spec-supported macros.
|
||||
AllMacros = []Macro{
|
||||
// The macro "has(m.f)" which tests the presence of a field, avoiding the need to specify
|
||||
// the field as a string.
|
||||
NewGlobalMacro(operators.Has, 1, makeHas),
|
||||
|
||||
// The macro "range.all(var, predicate)", which is true if for all elements in range the
|
||||
// predicate holds.
|
||||
NewReceiverMacro(operators.All, 2, makeAll),
|
||||
|
||||
// The macro "range.exists(var, predicate)", which is true if for at least one element in
|
||||
// range the predicate holds.
|
||||
NewReceiverMacro(operators.Exists, 2, makeExists),
|
||||
|
||||
// The macro "range.exists_one(var, predicate)", which is true if for exactly one element
|
||||
// in range the predicate holds.
|
||||
NewReceiverMacro(operators.ExistsOne, 2, makeExistsOne),
|
||||
|
||||
// The macro "range.map(var, function)", applies the function to the vars in the range.
|
||||
NewReceiverMacro(operators.Map, 2, makeMap),
|
||||
|
||||
// The macro "range.map(var, predicate, function)", applies the function to the vars in
|
||||
// the range for which the predicate holds true. The other variables are filtered out.
|
||||
NewReceiverMacro(operators.Map, 3, makeMap),
|
||||
|
||||
// The macro "range.filter(var, predicate)", filters out the variables for which the
|
||||
// predicate is false.
|
||||
NewReceiverMacro(operators.Filter, 2, makeFilter),
|
||||
HasMacro,
|
||||
AllMacro,
|
||||
ExistsMacro,
|
||||
ExistsOneMacro,
|
||||
MapMacro,
|
||||
MapFilterMacro,
|
||||
FilterMacro,
|
||||
}
|
||||
|
||||
// NoMacros list.
|
||||
@@ -270,62 +284,36 @@ const (
|
||||
quantifierExistsOne
|
||||
)
|
||||
|
||||
func makeAll(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
|
||||
// MakeExists expands the input call arguments into a comprehension that returns true if all of the
|
||||
// elements in the range match the predicate expressions:
|
||||
// <iterRange>.all(<iterVar>, <predicate>)
|
||||
func MakeAll(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
|
||||
return makeQuantifier(quantifierAll, eh, target, args)
|
||||
}
|
||||
|
||||
func makeExists(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
|
||||
// MakeExists expands the input call arguments into a comprehension that returns true if any of the
|
||||
// elements in the range match the predicate expressions:
|
||||
// <iterRange>.exists(<iterVar>, <predicate>)
|
||||
func MakeExists(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
|
||||
return makeQuantifier(quantifierExists, eh, target, args)
|
||||
}
|
||||
|
||||
func makeExistsOne(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
|
||||
// MakeExistsOne expands the input call arguments into a comprehension that returns true if exactly
|
||||
// one of the elements in the range match the predicate expressions:
|
||||
// <iterRange>.exists_one(<iterVar>, <predicate>)
|
||||
func MakeExistsOne(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
|
||||
return makeQuantifier(quantifierExistsOne, eh, target, args)
|
||||
}
|
||||
|
||||
func makeQuantifier(kind quantifierKind, eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
|
||||
v, found := extractIdent(args[0])
|
||||
if !found {
|
||||
location := eh.OffsetLocation(args[0].GetId())
|
||||
return nil, &common.Error{
|
||||
Message: "argument must be a simple name",
|
||||
Location: location}
|
||||
}
|
||||
accuIdent := func() *exprpb.Expr {
|
||||
return eh.Ident(AccumulatorName)
|
||||
}
|
||||
|
||||
var init *exprpb.Expr
|
||||
var condition *exprpb.Expr
|
||||
var step *exprpb.Expr
|
||||
var result *exprpb.Expr
|
||||
switch kind {
|
||||
case quantifierAll:
|
||||
init = eh.LiteralBool(true)
|
||||
condition = eh.GlobalCall(operators.NotStrictlyFalse, accuIdent())
|
||||
step = eh.GlobalCall(operators.LogicalAnd, accuIdent(), args[1])
|
||||
result = accuIdent()
|
||||
case quantifierExists:
|
||||
init = eh.LiteralBool(false)
|
||||
condition = eh.GlobalCall(
|
||||
operators.NotStrictlyFalse,
|
||||
eh.GlobalCall(operators.LogicalNot, accuIdent()))
|
||||
step = eh.GlobalCall(operators.LogicalOr, accuIdent(), args[1])
|
||||
result = accuIdent()
|
||||
case quantifierExistsOne:
|
||||
zeroExpr := eh.LiteralInt(0)
|
||||
oneExpr := eh.LiteralInt(1)
|
||||
init = zeroExpr
|
||||
condition = eh.LiteralBool(true)
|
||||
step = eh.GlobalCall(operators.Conditional, args[1],
|
||||
eh.GlobalCall(operators.Add, accuIdent(), oneExpr), accuIdent())
|
||||
result = eh.GlobalCall(operators.Equals, accuIdent(), oneExpr)
|
||||
default:
|
||||
return nil, &common.Error{Message: fmt.Sprintf("unrecognized quantifier '%v'", kind)}
|
||||
}
|
||||
return eh.Fold(v, target, AccumulatorName, init, condition, step, result), nil
|
||||
}
|
||||
|
||||
func makeMap(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
|
||||
// MakeMap expands the input call arguments into a comprehension that transforms each element in the
|
||||
// input to produce an output list.
|
||||
//
|
||||
// There are two call patterns supported by map:
|
||||
// <iterRange>.map(<iterVar>, <transform>)
|
||||
// <iterRange>.map(<iterVar>, <predicate>, <transform>)
|
||||
// In the second form only iterVar values which return true when provided to the predicate expression
|
||||
// are transformed.
|
||||
func MakeMap(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
|
||||
v, found := extractIdent(args[0])
|
||||
if !found {
|
||||
return nil, &common.Error{Message: "argument is not an identifier"}
|
||||
@@ -345,7 +333,6 @@ func makeMap(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.E
|
||||
accuExpr := eh.Ident(AccumulatorName)
|
||||
init := eh.NewList()
|
||||
condition := eh.LiteralBool(true)
|
||||
// TODO: use compiler internal method for faster, stateful add.
|
||||
step := eh.GlobalCall(operators.Add, accuExpr, eh.NewList(fn))
|
||||
|
||||
if filter != nil {
|
||||
@@ -354,7 +341,10 @@ func makeMap(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.E
|
||||
return eh.Fold(v, target, AccumulatorName, init, condition, step, accuExpr), nil
|
||||
}
|
||||
|
||||
func makeFilter(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
|
||||
// MakeFilter expands the input call arguments into a comprehension which produces a list which contains
|
||||
// only elements which match the provided predicate expression:
|
||||
// <iterRange>.filter(<iterVar>, <predicate>)
|
||||
func MakeFilter(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
|
||||
v, found := extractIdent(args[0])
|
||||
if !found {
|
||||
return nil, &common.Error{Message: "argument is not an identifier"}
|
||||
@@ -364,12 +354,60 @@ func makeFilter(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprp
|
||||
accuExpr := eh.Ident(AccumulatorName)
|
||||
init := eh.NewList()
|
||||
condition := eh.LiteralBool(true)
|
||||
// TODO: use compiler internal method for faster, stateful add.
|
||||
step := eh.GlobalCall(operators.Add, accuExpr, eh.NewList(args[0]))
|
||||
step = eh.GlobalCall(operators.Conditional, filter, step, accuExpr)
|
||||
return eh.Fold(v, target, AccumulatorName, init, condition, step, accuExpr), nil
|
||||
}
|
||||
|
||||
// MakeHas expands the input call arguments into a presence test, e.g. has(<operand>.field)
|
||||
func MakeHas(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
|
||||
if s, ok := args[0].ExprKind.(*exprpb.Expr_SelectExpr); ok {
|
||||
return eh.PresenceTest(s.SelectExpr.GetOperand(), s.SelectExpr.GetField()), nil
|
||||
}
|
||||
return nil, &common.Error{Message: "invalid argument to has() macro"}
|
||||
}
|
||||
|
||||
func makeQuantifier(kind quantifierKind, eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
|
||||
v, found := extractIdent(args[0])
|
||||
if !found {
|
||||
location := eh.OffsetLocation(args[0].GetId())
|
||||
return nil, &common.Error{
|
||||
Message: "argument must be a simple name",
|
||||
Location: location,
|
||||
}
|
||||
}
|
||||
|
||||
var init *exprpb.Expr
|
||||
var condition *exprpb.Expr
|
||||
var step *exprpb.Expr
|
||||
var result *exprpb.Expr
|
||||
switch kind {
|
||||
case quantifierAll:
|
||||
init = eh.LiteralBool(true)
|
||||
condition = eh.GlobalCall(operators.NotStrictlyFalse, eh.AccuIdent())
|
||||
step = eh.GlobalCall(operators.LogicalAnd, eh.AccuIdent(), args[1])
|
||||
result = eh.AccuIdent()
|
||||
case quantifierExists:
|
||||
init = eh.LiteralBool(false)
|
||||
condition = eh.GlobalCall(
|
||||
operators.NotStrictlyFalse,
|
||||
eh.GlobalCall(operators.LogicalNot, eh.AccuIdent()))
|
||||
step = eh.GlobalCall(operators.LogicalOr, eh.AccuIdent(), args[1])
|
||||
result = eh.AccuIdent()
|
||||
case quantifierExistsOne:
|
||||
zeroExpr := eh.LiteralInt(0)
|
||||
oneExpr := eh.LiteralInt(1)
|
||||
init = zeroExpr
|
||||
condition = eh.LiteralBool(true)
|
||||
step = eh.GlobalCall(operators.Conditional, args[1],
|
||||
eh.GlobalCall(operators.Add, eh.AccuIdent(), oneExpr), eh.AccuIdent())
|
||||
result = eh.GlobalCall(operators.Equals, eh.AccuIdent(), oneExpr)
|
||||
default:
|
||||
return nil, &common.Error{Message: fmt.Sprintf("unrecognized quantifier '%v'", kind)}
|
||||
}
|
||||
return eh.Fold(v, target, AccumulatorName, init, condition, step, result), nil
|
||||
}
|
||||
|
||||
func extractIdent(e *exprpb.Expr) (string, bool) {
|
||||
switch e.ExprKind.(type) {
|
||||
case *exprpb.Expr_IdentExpr:
|
||||
@@ -377,10 +415,3 @@ func extractIdent(e *exprpb.Expr) (string, bool) {
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
func makeHas(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
|
||||
if s, ok := args[0].ExprKind.(*exprpb.Expr_SelectExpr); ok {
|
||||
return eh.PresenceTest(s.SelectExpr.GetOperand(), s.SelectExpr.GetField()), nil
|
||||
}
|
||||
return nil, &common.Error{Message: "invalid argument to has() macro"}
|
||||
}
|
||||
|
Reference in New Issue
Block a user