rebase: bump the golang-dependencies group with 1 update

Bumps the golang-dependencies group with 1 update: [golang.org/x/crypto](https://github.com/golang/crypto).


Updates `golang.org/x/crypto` from 0.16.0 to 0.17.0
- [Commits](https://github.com/golang/crypto/compare/v0.16.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: golang-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2023-12-18 20:31:00 +00:00
committed by mergify[bot]
parent 1ad79314f9
commit e5d9b68d36
398 changed files with 33924 additions and 10753 deletions

View File

@ -22,9 +22,22 @@ import (
// parseErrors is a specialization of Errors.
type parseErrors struct {
*common.Errors
errs *common.Errors
}
// errorCount indicates the number of errors reported.
func (e *parseErrors) errorCount() int {
return len(e.errs.GetErrors())
}
func (e *parseErrors) internalError(message string) {
e.errs.ReportErrorAtID(0, common.NoLocation, message)
}
func (e *parseErrors) syntaxError(l common.Location, message string) {
e.ReportError(l, fmt.Sprintf("Syntax error: %s", message))
e.errs.ReportErrorAtID(0, l, fmt.Sprintf("Syntax error: %s", message))
}
func (e *parseErrors) reportErrorAtID(id int64, l common.Location, message string, args ...any) {
e.errs.ReportErrorAtID(id, l, message, args...)
}

View File

@ -193,15 +193,15 @@ func (p *parserHelper) newExpr(ctx any) *exprpb.Expr {
func (p *parserHelper) id(ctx any) int64 {
var location common.Location
switch ctx.(type) {
switch c := ctx.(type) {
case antlr.ParserRuleContext:
token := (ctx.(antlr.ParserRuleContext)).GetStart()
token := c.GetStart()
location = p.source.NewLocation(token.GetLine(), token.GetColumn())
case antlr.Token:
token := ctx.(antlr.Token)
token := c
location = p.source.NewLocation(token.GetLine(), token.GetColumn())
case common.Location:
location = ctx.(common.Location)
location = c
default:
// This should only happen if the ctx is nil
return -1
@ -297,67 +297,83 @@ func (p *parserHelper) addMacroCall(exprID int64, function string, target *exprp
}
}
// balancer performs tree balancing on operators whose arguments are of equal precedence.
// logicManager compacts logical trees into a more efficient structure which is semantically
// equivalent with how the logic graph is constructed by the ANTLR parser.
//
// The purpose of the balancer is to ensure a compact serialization format for the logical &&, ||
// The purpose of the logicManager is to ensure a compact serialization format for the logical &&, ||
// operators which have a tendency to create long DAGs which are skewed in one direction. Since the
// operators are commutative re-ordering the terms *must not* affect the evaluation result.
//
// Re-balancing the terms is a safe, if somewhat controversial choice. A better solution would be
// to make these functions variadic and update both the checker and interpreter to understand this;
// however, this is a more complex change.
//
// TODO: Consider replacing tree-balancing with variadic logical &&, || within the parser, checker,
// and interpreter.
type balancer struct {
helper *parserHelper
function string
terms []*exprpb.Expr
ops []int64
// The logic manager will either render the terms to N-chained && / || operators as a single logical
// call with N-terms, or will rebalance the tree. Rebalancing the terms is a safe, if somewhat
// controversial choice as it alters the traditional order of execution assumptions present in most
// expressions.
type logicManager struct {
helper *parserHelper
function string
terms []*exprpb.Expr
ops []int64
variadicASTs bool
}
// newBalancer creates a balancer instance bound to a specific function and its first term.
func newBalancer(h *parserHelper, function string, term *exprpb.Expr) *balancer {
return &balancer{
helper: h,
function: function,
terms: []*exprpb.Expr{term},
ops: []int64{},
// newVariadicLogicManager creates a logic manager instance bound to a specific function and its first term.
func newVariadicLogicManager(h *parserHelper, function string, term *exprpb.Expr) *logicManager {
return &logicManager{
helper: h,
function: function,
terms: []*exprpb.Expr{term},
ops: []int64{},
variadicASTs: true,
}
}
// newBalancingLogicManager creates a logic manager instance bound to a specific function and its first term.
func newBalancingLogicManager(h *parserHelper, function string, term *exprpb.Expr) *logicManager {
return &logicManager{
helper: h,
function: function,
terms: []*exprpb.Expr{term},
ops: []int64{},
variadicASTs: false,
}
}
// addTerm adds an operation identifier and term to the set of terms to be balanced.
func (b *balancer) addTerm(op int64, term *exprpb.Expr) {
b.terms = append(b.terms, term)
b.ops = append(b.ops, op)
func (l *logicManager) addTerm(op int64, term *exprpb.Expr) {
l.terms = append(l.terms, term)
l.ops = append(l.ops, op)
}
// balance creates a balanced tree from the sub-terms and returns the final Expr value.
func (b *balancer) balance() *exprpb.Expr {
if len(b.terms) == 1 {
return b.terms[0]
// toExpr renders the logic graph into an Expr value, either balancing a tree of logical
// operations or creating a variadic representation of the logical operator.
func (l *logicManager) toExpr() *exprpb.Expr {
if len(l.terms) == 1 {
return l.terms[0]
}
return b.balancedTree(0, len(b.ops)-1)
if l.variadicASTs {
return l.helper.newGlobalCall(l.ops[0], l.function, l.terms...)
}
return l.balancedTree(0, len(l.ops)-1)
}
// balancedTree recursively balances the terms provided to a commutative operator.
func (b *balancer) balancedTree(lo, hi int) *exprpb.Expr {
func (l *logicManager) balancedTree(lo, hi int) *exprpb.Expr {
mid := (lo + hi + 1) / 2
var left *exprpb.Expr
if mid == lo {
left = b.terms[mid]
left = l.terms[mid]
} else {
left = b.balancedTree(lo, mid-1)
left = l.balancedTree(lo, mid-1)
}
var right *exprpb.Expr
if mid == hi {
right = b.terms[mid+1]
right = l.terms[mid+1]
} else {
right = b.balancedTree(mid+1, hi)
right = l.balancedTree(mid+1, hi)
}
return b.helper.newGlobalCall(b.ops[mid], b.function, left, right)
return l.helper.newGlobalCall(l.ops[mid], l.function, left, right)
}
type exprHelper struct {
@ -370,7 +386,7 @@ func (e *exprHelper) nextMacroID() int64 {
}
// Copy implements the ExprHelper interface method by producing a copy of the input Expr value
// with a fresh set of numeric identifiers the Expr and all its descendents.
// with a fresh set of numeric identifiers the Expr and all its descendants.
func (e *exprHelper) Copy(expr *exprpb.Expr) *exprpb.Expr {
copy := e.parserHelper.newExpr(e.parserHelper.getLocation(expr.GetId()))
switch expr.GetExprKind().(type) {
@ -558,11 +574,22 @@ func (e *exprHelper) Select(operand *exprpb.Expr, field string) *exprpb.Expr {
// OffsetLocation implements the ExprHelper interface method.
func (e *exprHelper) OffsetLocation(exprID int64) common.Location {
offset := e.parserHelper.positions[exprID]
location, _ := e.parserHelper.source.OffsetLocation(offset)
offset, found := e.parserHelper.positions[exprID]
if !found {
return common.NoLocation
}
location, found := e.parserHelper.source.OffsetLocation(offset)
if !found {
return common.NoLocation
}
return location
}
// NewError associates an error message with a given expression id, populating the source offset location of the error if possible.
func (e *exprHelper) NewError(exprID int64, message string) *common.Error {
return common.NewError(exprID, message, e.OffsetLocation(exprID))
}
var (
// Thread-safe pool of ExprHelper values to minimize alloc overhead of ExprHelper creations.
exprHelperPool = &sync.Pool{

View File

@ -232,6 +232,9 @@ type ExprHelper interface {
// OffsetLocation returns the Location of the expression identifier.
OffsetLocation(exprID int64) common.Location
// NewError associates an error message with a given expression id.
NewError(exprID int64, message string) *common.Error
}
var (
@ -324,7 +327,7 @@ func MakeExistsOne(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*ex
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"}
return nil, eh.NewError(args[0].GetId(), "argument is not an identifier")
}
var fn *exprpb.Expr
@ -355,7 +358,7 @@ func MakeMap(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.E
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"}
return nil, eh.NewError(args[0].GetId(), "argument is not an identifier")
}
filter := args[1]
@ -372,17 +375,13 @@ func MakeHas(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.E
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"}
return nil, eh.NewError(args[0].GetId(), "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,
}
return nil, eh.NewError(args[0].GetId(), "argument must be a simple name")
}
var init *exprpb.Expr
@ -411,7 +410,7 @@ func makeQuantifier(kind quantifierKind, eh ExprHelper, target *exprpb.Expr, arg
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 nil, eh.NewError(args[0].GetId(), fmt.Sprintf("unrecognized quantifier '%v'", kind))
}
return eh.Fold(v, target, AccumulatorName, init, condition, step, result), nil
}

View File

@ -25,6 +25,7 @@ type options struct {
macros map[string]Macro
populateMacroCalls bool
enableOptionalSyntax bool
enableVariadicOperatorASTs bool
}
// Option configures the behavior of the parser.
@ -125,3 +126,15 @@ func EnableOptionalSyntax(optionalSyntax bool) Option {
return nil
}
}
// EnableVariadicOperatorASTs enables a compact representation of chained like-kind commutative
// operators. e.g. `a || b || c || d` -> `call(op='||', args=[a, b, c, d])`
//
// The benefit of enabling variadic operators ASTs is a more compact representation deeply nested
// logic graphs.
func EnableVariadicOperatorASTs(varArgASTs bool) Option {
return func(opts *options) error {
opts.enableVariadicOperatorASTs = varArgASTs
return nil
}
}

View File

@ -89,8 +89,9 @@ func mustNewParser(opts ...Option) *Parser {
// Parse parses the expression represented by source and returns the result.
func (p *Parser) Parse(source common.Source) (*exprpb.ParsedExpr, *common.Errors) {
errs := common.NewErrors(source)
impl := parser{
errors: &parseErrors{common.NewErrors(source)},
errors: &parseErrors{errs},
helper: newParserHelper(source),
macros: p.macros,
maxRecursionDepth: p.maxRecursionDepth,
@ -99,6 +100,7 @@ func (p *Parser) Parse(source common.Source) (*exprpb.ParsedExpr, *common.Errors
errorRecoveryLookaheadTokenLimit: p.errorRecoveryTokenLookaheadLimit,
populateMacroCalls: p.populateMacroCalls,
enableOptionalSyntax: p.enableOptionalSyntax,
enableVariadicOperatorASTs: p.enableVariadicOperatorASTs,
}
buf, ok := source.(runes.Buffer)
if !ok {
@ -115,7 +117,7 @@ func (p *Parser) Parse(source common.Source) (*exprpb.ParsedExpr, *common.Errors
return &exprpb.ParsedExpr{
Expr: e,
SourceInfo: impl.helper.getSourceInfo(),
}, impl.errors.Errors
}, errs
}
// reservedIds are not legal to use as variables. We exclude them post-parse, as they *are* valid
@ -295,6 +297,7 @@ type parser struct {
errorRecoveryLookaheadTokenLimit int
populateMacroCalls bool
enableOptionalSyntax bool
enableVariadicOperatorASTs bool
}
var (
@ -357,9 +360,9 @@ func (p *parser) parse(expr runes.Buffer, desc string) *exprpb.Expr {
if val := recover(); val != nil {
switch err := val.(type) {
case *lookaheadLimitError:
p.errors.ReportError(common.NoLocation, err.Error())
p.errors.internalError(err.Error())
case *recursionError:
p.errors.ReportError(common.NoLocation, err.Error())
p.errors.internalError(err.Error())
case *tooManyErrors:
// do nothing
case *recoveryLimitError:
@ -449,7 +452,7 @@ func (p *parser) Visit(tree antlr.ParseTree) any {
// Report at least one error if the parser reaches an unknown parse element.
// Typically, this happens if the parser has already encountered a syntax error elsewhere.
if len(p.errors.GetErrors()) == 0 {
if p.errors.errorCount() == 0 {
txt := "<<nil>>"
if t != nil {
txt = fmt.Sprintf("<<%T>>", t)
@ -480,7 +483,7 @@ func (p *parser) VisitExpr(ctx *gen.ExprContext) any {
// Visit a parse tree produced by CELParser#conditionalOr.
func (p *parser) VisitConditionalOr(ctx *gen.ConditionalOrContext) any {
result := p.Visit(ctx.GetE()).(*exprpb.Expr)
b := newBalancer(p.helper, operators.LogicalOr, result)
l := p.newLogicManager(operators.LogicalOr, result)
rest := ctx.GetE1()
for i, op := range ctx.GetOps() {
if i >= len(rest) {
@ -488,15 +491,15 @@ func (p *parser) VisitConditionalOr(ctx *gen.ConditionalOrContext) any {
}
next := p.Visit(rest[i]).(*exprpb.Expr)
opID := p.helper.id(op)
b.addTerm(opID, next)
l.addTerm(opID, next)
}
return b.balance()
return l.toExpr()
}
// Visit a parse tree produced by CELParser#conditionalAnd.
func (p *parser) VisitConditionalAnd(ctx *gen.ConditionalAndContext) any {
result := p.Visit(ctx.GetE()).(*exprpb.Expr)
b := newBalancer(p.helper, operators.LogicalAnd, result)
l := p.newLogicManager(operators.LogicalAnd, result)
rest := ctx.GetE1()
for i, op := range ctx.GetOps() {
if i >= len(rest) {
@ -504,9 +507,9 @@ func (p *parser) VisitConditionalAnd(ctx *gen.ConditionalAndContext) any {
}
next := p.Visit(rest[i]).(*exprpb.Expr)
opID := p.helper.id(op)
b.addTerm(opID, next)
l.addTerm(opID, next)
}
return b.balance()
return l.toExpr()
}
// Visit a parse tree produced by CELParser#relation.
@ -867,18 +870,24 @@ func (p *parser) unquote(ctx any, value string, isBytes bool) string {
return text
}
func (p *parser) newLogicManager(function string, term *exprpb.Expr) *logicManager {
if p.enableVariadicOperatorASTs {
return newVariadicLogicManager(p.helper, function, term)
}
return newBalancingLogicManager(p.helper, function, term)
}
func (p *parser) reportError(ctx any, format string, args ...any) *exprpb.Expr {
var location common.Location
switch ctx.(type) {
err := p.helper.newExpr(ctx)
switch c := ctx.(type) {
case common.Location:
location = ctx.(common.Location)
location = c
case antlr.Token, antlr.ParserRuleContext:
err := p.helper.newExpr(ctx)
location = p.helper.getLocation(err.GetId())
}
err := p.helper.newExpr(ctx)
// Provide arguments to the report error.
p.errors.ReportError(location, format, args...)
p.errors.reportErrorAtID(err.GetId(), location, format, args...)
return err
}