From f0d1c53510d38ff8790d0cb71b5463308d9f572d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Aug 2023 21:17:13 +0000 Subject: [PATCH] Bump github.com/google/cel-go from 0.13.0 to 0.17.6 Bumps [github.com/google/cel-go](https://github.com/google/cel-go) from 0.13.0 to 0.17.6. - [Release notes](https://github.com/google/cel-go/releases) - [Commits](https://github.com/google/cel-go/compare/v0.13.0...v0.17.6) --- updated-dependencies: - dependency-name: github.com/google/cel-go dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 5 +- go.sum | 10 +- .../antlr4/runtime/Go/antlr/{ => v4}/LICENSE | 0 .../antlr4/runtime/Go/antlr/v4/antlrdoc.go | 68 + .../antlr4/runtime/Go/antlr/{ => v4}/atn.go | 27 +- .../runtime/Go/antlr/{ => v4}/atn_config.go | 54 +- .../Go/antlr/{ => v4}/atn_config_set.go | 80 +- .../{ => v4}/atn_deserialization_options.go | 2 +- .../Go/antlr/{ => v4}/atn_deserializer.go | 2 +- .../Go/antlr/{ => v4}/atn_simulator.go | 2 +- .../runtime/Go/antlr/{ => v4}/atn_state.go | 9 +- .../runtime/Go/antlr/{ => v4}/atn_type.go | 2 +- .../runtime/Go/antlr/{ => v4}/char_stream.go | 2 +- .../Go/antlr/{ => v4}/common_token_factory.go | 2 +- .../Go/antlr/{ => v4}/common_token_stream.go | 6 +- .../antlr4/runtime/Go/antlr/v4/comparators.go | 147 ++ .../antlr4/runtime/Go/antlr/{ => v4}/dfa.go | 54 +- .../Go/antlr/{ => v4}/dfa_serializer.go | 2 +- .../runtime/Go/antlr/{ => v4}/dfa_state.go | 54 +- .../{ => v4}/diagnostic_error_listener.go | 4 +- .../Go/antlr/{ => v4}/error_listener.go | 6 +- .../Go/antlr/{ => v4}/error_strategy.go | 38 +- .../runtime/Go/antlr/{ => v4}/errors.go | 5 +- .../runtime/Go/antlr/{ => v4}/file_stream.go | 2 +- .../runtime/Go/antlr/{ => v4}/input_stream.go | 2 +- .../runtime/Go/antlr/{ => v4}/int_stream.go | 2 +- .../runtime/Go/antlr/{ => v4}/interval_set.go | 6 +- .../antlr4/runtime/Go/antlr/v4/jcollect.go | 198 +++ .../antlr4/runtime/Go/antlr/{ => v4}/lexer.go | 6 +- .../runtime/Go/antlr/{ => v4}/lexer_action.go | 44 +- .../antlr/{ => v4}/lexer_action_executor.go | 27 +- .../Go/antlr/{ => v4}/lexer_atn_simulator.go | 17 +- .../runtime/Go/antlr/{ => v4}/ll1_analyzer.go | 30 +- .../runtime/Go/antlr/{ => v4}/parser.go | 14 +- .../Go/antlr/{ => v4}/parser_atn_simulator.go | 153 +- .../Go/antlr/{ => v4}/parser_rule_context.go | 4 +- .../Go/antlr/{ => v4}/prediction_context.go | 161 ++- .../Go/antlr/{ => v4}/prediction_mode.go | 48 +- .../runtime/Go/antlr/{ => v4}/recognizer.go | 19 +- .../runtime/Go/antlr/{ => v4}/rule_context.go | 2 +- .../Go/antlr/{ => v4}/semantic_context.go | 81 +- .../antlr4/runtime/Go/antlr/{ => v4}/token.go | 3 +- .../runtime/Go/antlr/{ => v4}/token_source.go | 2 +- .../runtime/Go/antlr/{ => v4}/token_stream.go | 2 +- .../Go/antlr/{ => v4}/tokenstream_rewriter.go | 420 +++--- .../Go/antlr/{ => v4}/trace_listener.go | 2 +- .../runtime/Go/antlr/{ => v4}/transition.go | 2 +- .../antlr4/runtime/Go/antlr/{ => v4}/tree.go | 5 +- .../antlr4/runtime/Go/antlr/{ => v4}/trees.go | 9 +- .../antlr4/runtime/Go/antlr/{ => v4}/utils.go | 21 +- .../runtime/Go/antlr/{ => v4}/utils_set.go | 34 +- .../github.com/google/cel-go/cel/BUILD.bazel | 12 +- vendor/github.com/google/cel-go/cel/decls.go | 1088 ++------------ vendor/github.com/google/cel-go/cel/env.go | 421 ++++-- vendor/github.com/google/cel-go/cel/io.go | 46 +- .../github.com/google/cel-go/cel/library.go | 299 +++- vendor/github.com/google/cel-go/cel/macro.go | 11 +- .../github.com/google/cel-go/cel/options.go | 169 ++- .../github.com/google/cel-go/cel/program.go | 81 +- .../github.com/google/cel-go/cel/validator.go | 388 +++++ .../google/cel-go/checker/BUILD.bazel | 10 +- .../google/cel-go/checker/checker.go | 433 +++--- .../github.com/google/cel-go/checker/cost.go | 129 +- .../google/cel-go/checker/decls/BUILD.bazel | 3 +- .../github.com/google/cel-go/checker/env.go | 239 +-- .../google/cel-go/checker/errors.go | 94 +- .../google/cel-go/checker/format.go | 216 +++ .../google/cel-go/checker/mapping.go | 14 +- .../google/cel-go/checker/options.go | 13 +- .../google/cel-go/checker/printer.go | 3 + .../cel-go/checker/{decls => }/scopes.go | 38 +- .../google/cel-go/checker/standard.go | 481 +------ .../github.com/google/cel-go/checker/types.go | 404 ++---- .../google/cel-go/common/BUILD.bazel | 2 +- .../google/cel-go/common/ast/BUILD.bazel | 52 + .../google/cel-go/common/ast/ast.go | 226 +++ .../google/cel-go/common/ast/expr.go | 709 +++++++++ .../cel-go/common/containers/BUILD.bazel | 4 +- .../google/cel-go/common/debug/BUILD.bazel | 2 +- .../google/cel-go/common/decls/BUILD.bazel | 39 + .../google/cel-go/common/decls/decls.go | 844 +++++++++++ .../github.com/google/cel-go/common/error.go | 8 +- .../github.com/google/cel-go/common/errors.go | 16 +- .../cel-go/common/functions/BUILD.bazel | 17 + .../functions/functions.go | 5 +- .../cel-go/common/overloads/overloads.go | 10 + .../github.com/google/cel-go/common/source.go | 3 - .../functions => common/stdlib}/BUILD.bazel | 11 +- .../google/cel-go/common/stdlib/standard.go | 661 +++++++++ .../google/cel-go/common/types/BUILD.bazel | 11 +- .../google/cel-go/common/types/bool.go | 6 - .../google/cel-go/common/types/bytes.go | 7 - .../google/cel-go/common/types/double.go | 14 +- .../google/cel-go/common/types/duration.go | 76 +- .../google/cel-go/common/types/err.go | 17 +- .../google/cel-go/common/types/int.go | 25 +- .../google/cel-go/common/types/iterator.go | 2 +- .../google/cel-go/common/types/list.go | 90 +- .../google/cel-go/common/types/map.go | 87 +- .../google/cel-go/common/types/null.go | 2 - .../google/cel-go/common/types/object.go | 18 +- .../google/cel-go/common/types/optional.go | 2 +- .../google/cel-go/common/types/pb/BUILD.bazel | 2 +- .../google/cel-go/common/types/pb/type.go | 23 +- .../google/cel-go/common/types/provider.go | 244 +++- .../cel-go/common/types/ref/BUILD.bazel | 2 +- .../cel-go/common/types/ref/provider.go | 37 +- .../cel-go/common/types/ref/reference.go | 11 +- .../google/cel-go/common/types/string.go | 44 +- .../google/cel-go/common/types/timestamp.go | 20 +- .../google/cel-go/common/types/type.go | 102 -- .../google/cel-go/common/types/types.go | 806 +++++++++++ .../google/cel-go/common/types/uint.go | 22 +- .../google/cel-go/common/types/unknown.go | 290 +++- .../google/cel-go/common/types/util.go | 2 +- .../google/cel-go/interpreter/BUILD.bazel | 15 +- .../google/cel-go/interpreter/activation.go | 2 +- .../cel-go/interpreter/attribute_patterns.go | 42 +- .../google/cel-go/interpreter/attributes.go | 198 +-- .../google/cel-go/interpreter/coster.go | 35 - .../google/cel-go/interpreter/decorators.go | 21 +- .../google/cel-go/interpreter/dispatcher.go | 2 +- .../google/cel-go/interpreter/evalstate.go | 6 +- .../google/cel-go/interpreter/formatting.go | 383 +++++ .../cel-go/interpreter/functions/standard.go | 270 ---- .../cel-go/interpreter/interpretable.go | 680 +++++---- .../google/cel-go/interpreter/interpreter.go | 28 +- .../google/cel-go/interpreter/planner.go | 125 +- .../google/cel-go/interpreter/prune.go | 374 ++++- .../google/cel-go/interpreter/runtimecost.go | 72 +- .../google/cel-go/parser/BUILD.bazel | 6 +- .../github.com/google/cel-go/parser/errors.go | 17 +- .../google/cel-go/parser/gen/BUILD.bazel | 2 +- .../google/cel-go/parser/gen/CEL.g4 | 28 +- .../google/cel-go/parser/gen/CEL.interp | 9 +- .../google/cel-go/parser/gen/CEL.tokens | 132 +- .../google/cel-go/parser/gen/CELLexer.interp | 8 +- .../google/cel-go/parser/gen/CELLexer.tokens | 132 +- .../cel-go/parser/gen/cel_base_listener.go | 18 +- .../cel-go/parser/gen/cel_base_visitor.go | 10 +- .../google/cel-go/parser/gen/cel_lexer.go | 483 +++---- .../google/cel-go/parser/gen/cel_listener.go | 18 +- .../google/cel-go/parser/gen/cel_parser.go | 1276 +++++++++++------ .../google/cel-go/parser/gen/cel_visitor.go | 11 +- .../google/cel-go/parser/gen/generate.sh | 2 +- .../github.com/google/cel-go/parser/helper.go | 127 +- .../github.com/google/cel-go/parser/input.go | 2 +- .../github.com/google/cel-go/parser/macro.go | 17 +- .../google/cel-go/parser/options.go | 29 +- .../github.com/google/cel-go/parser/parser.go | 118 +- .../google/cel-go/parser/unparser.go | 56 +- vendor/golang.org/x/exp/LICENSE | 27 + vendor/golang.org/x/exp/PATENTS | 22 + .../x/exp/constraints/constraints.go | 50 + vendor/golang.org/x/exp/slices/slices.go | 218 +++ vendor/golang.org/x/exp/slices/sort.go | 127 ++ vendor/golang.org/x/exp/slices/zsortfunc.go | 479 +++++++ .../golang.org/x/exp/slices/zsortordered.go | 481 +++++++ vendor/modules.txt | 17 +- 159 files changed, 11628 insertions(+), 5607 deletions(-) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/LICENSE (100%) create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/antlrdoc.go rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/atn.go (72%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/atn_config.go (84%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/atn_config_set.go (81%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/atn_deserialization_options.go (96%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/atn_deserializer.go (99%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/atn_simulator.go (94%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/atn_state.go (97%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/atn_type.go (79%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/char_stream.go (82%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/common_token_factory.go (96%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/common_token_stream.go (98%) create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/comparators.go rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/dfa.go (80%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/dfa_serializer.go (97%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/dfa_state.go (90%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/diagnostic_error_listener.go (98%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/error_listener.go (98%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/error_strategy.go (99%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/errors.go (98%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/file_stream.go (92%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/input_stream.go (96%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/int_stream.go (82%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/interval_set.go (98%) create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/jcollect.go rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/lexer.go (98%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/lexer_action.go (91%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/lexer_action_executor.go (88%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/lexer_atn_simulator.go (98%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/ll1_analyzer.go (87%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/parser.go (99%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/parser_atn_simulator.go (94%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/parser_rule_context.go (98%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/prediction_context.go (81%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/prediction_mode.go (95%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/recognizer.go (92%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/rule_context.go (97%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/semantic_context.go (85%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/token.go (98%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/token_source.go (85%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/token_stream.go (87%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/tokenstream_rewriter.go (58%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/trace_listener.go (93%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/transition.go (99%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/tree.go (98%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/trees.go (93%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/utils.go (94%) rename vendor/github.com/antlr/antlr4/runtime/Go/antlr/{ => v4}/utils_set.go (80%) create mode 100644 vendor/github.com/google/cel-go/cel/validator.go create mode 100644 vendor/github.com/google/cel-go/checker/format.go rename vendor/github.com/google/cel-go/checker/{decls => }/scopes.go (81%) create mode 100644 vendor/github.com/google/cel-go/common/ast/BUILD.bazel create mode 100644 vendor/github.com/google/cel-go/common/ast/ast.go create mode 100644 vendor/github.com/google/cel-go/common/ast/expr.go create mode 100644 vendor/github.com/google/cel-go/common/decls/BUILD.bazel create mode 100644 vendor/github.com/google/cel-go/common/decls/decls.go create mode 100644 vendor/github.com/google/cel-go/common/functions/BUILD.bazel rename vendor/github.com/google/cel-go/{interpreter => common}/functions/functions.go (95%) rename vendor/github.com/google/cel-go/{interpreter/functions => common/stdlib}/BUILD.bazel (56%) create mode 100644 vendor/github.com/google/cel-go/common/stdlib/standard.go delete mode 100644 vendor/github.com/google/cel-go/common/types/type.go create mode 100644 vendor/github.com/google/cel-go/common/types/types.go delete mode 100644 vendor/github.com/google/cel-go/interpreter/coster.go create mode 100644 vendor/github.com/google/cel-go/interpreter/formatting.go delete mode 100644 vendor/github.com/google/cel-go/interpreter/functions/standard.go create mode 100644 vendor/golang.org/x/exp/LICENSE create mode 100644 vendor/golang.org/x/exp/PATENTS create mode 100644 vendor/golang.org/x/exp/constraints/constraints.go create mode 100644 vendor/golang.org/x/exp/slices/slices.go create mode 100644 vendor/golang.org/x/exp/slices/sort.go create mode 100644 vendor/golang.org/x/exp/slices/zsortfunc.go create mode 100644 vendor/golang.org/x/exp/slices/zsortordered.go diff --git a/go.mod b/go.mod index 1d47bdd04..447df03a9 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/fatih/color v1.15.0 github.com/golang-jwt/jwt/v4 v4.5.0 github.com/golang/protobuf v1.5.3 - github.com/google/cel-go v0.13.0 + github.com/google/cel-go v0.17.6 github.com/google/go-cmp v0.5.9 github.com/google/go-replayers/httpreplay v1.1.1 github.com/google/uuid v1.3.0 @@ -67,7 +67,7 @@ require ( github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect - github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect + github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.11 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.8 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.38 // indirect @@ -199,6 +199,7 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.12.0 // indirect + golang.org/x/exp v0.0.0-20220823124025-807a23277127 // indirect golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.11.0 // indirect golang.org/x/term v0.11.0 // indirect diff --git a/go.sum b/go.sum index 256f52492..fa71b1c8d 100644 --- a/go.sum +++ b/go.sum @@ -210,8 +210,8 @@ github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8V github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves= -github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= +github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18= +github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -837,8 +837,8 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/cel-go v0.13.0 h1:z+8OBOcmh7IeKyqwT/6IlnMvy621fYUqnTVPEdegGlU= -github.com/google/cel-go v0.13.0/go.mod h1:K2hpQgEjDp18J76a2DKFRlPBPpgRZgi6EbnpDgIhJ8s= +github.com/google/cel-go v0.17.6 h1:QDvHTIJunIsbgN8yVukx0HGnsqVLSY6xGqo+17IjIyM= +github.com/google/cel-go v0.17.6/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= @@ -1853,6 +1853,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20220823124025-807a23277127 h1:S4NrSKDfihhl3+4jSTgwoIevKxX9p7Iv9x++OEIptDo= +golang.org/x/exp v0.0.0-20220823124025-807a23277127/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/LICENSE b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/LICENSE similarity index 100% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/LICENSE rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/LICENSE diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/antlrdoc.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/antlrdoc.go new file mode 100644 index 000000000..ab5121267 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/antlrdoc.go @@ -0,0 +1,68 @@ +/* +Package antlr implements the Go version of the ANTLR 4 runtime. + +# The ANTLR Tool + +ANTLR (ANother Tool for Language Recognition) is a powerful parser generator for reading, processing, executing, +or translating structured text or binary files. It's widely used to build languages, tools, and frameworks. +From a grammar, ANTLR generates a parser that can build parse trees and also generates a listener interface +(or visitor) that makes it easy to respond to the recognition of phrases of interest. + +# Code Generation + +ANTLR supports the generation of code in a number of [target languages], and the generated code is supported by a +runtime library, written specifically to support the generated code in the target language. This library is the +runtime for the Go target. + +To generate code for the go target, it is generally recommended to place the source grammar files in a package of +their own, and use the `.sh` script method of generating code, using the go generate directive. In that same directory +it is usual, though not required, to place the antlr tool that should be used to generate the code. That does mean +that the antlr tool JAR file will be checked in to your source code control though, so you are free to use any other +way of specifying the version of the ANTLR tool to use, such as aliasing in `.zshrc` or equivalent, or a profile in +your IDE, or configuration in your CI system. + +Here is a general template for an ANTLR based recognizer in Go: + + . + ├── myproject + ├── parser + │ ├── mygrammar.g4 + │ ├── antlr-4.12.0-complete.jar + │ ├── error_listeners.go + │ ├── generate.go + │ ├── generate.sh + ├── go.mod + ├── go.sum + ├── main.go + └── main_test.go + +Make sure that the package statement in your grammar file(s) reflects the go package they exist in. +The generate.go file then looks like this: + + package parser + + //go:generate ./generate.sh + +And the generate.sh file will look similar to this: + + #!/bin/sh + + alias antlr4='java -Xmx500M -cp "./antlr4-4.12.0-complete.jar:$CLASSPATH" org.antlr.v4.Tool' + antlr4 -Dlanguage=Go -no-visitor -package parser *.g4 + +depending on whether you want visitors or listeners or any other ANTLR options. + +From the command line at the root of your package “myproject” you can then simply issue the command: + + go generate ./... + +# Copyright Notice + +Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. + +Use of this file is governed by the BSD 3-clause license, which can be found in the [LICENSE.txt] file in the project root. + +[target languages]: https://github.com/antlr/antlr4/tree/master/runtime +[LICENSE.txt]: https://github.com/antlr/antlr4/blob/master/LICENSE.txt +*/ +package antlr diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn.go similarity index 72% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn.go index a4e2079e6..98010d2e6 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -6,11 +6,24 @@ package antlr import "sync" +// ATNInvalidAltNumber is used to represent an ALT number that has yet to be calculated or +// which is invalid for a particular struct such as [*antlr.BaseRuleContext] var ATNInvalidAltNumber int +// ATN represents an “[Augmented Transition Network]”, though general in ANTLR the term +// “Augmented Recursive Transition Network” though there are some descriptions of “[Recursive Transition Network]” +// in existence. +// +// ATNs represent the main networks in the system and are serialized by the code generator and support [ALL(*)]. +// +// [Augmented Transition Network]: https://en.wikipedia.org/wiki/Augmented_transition_network +// [ALL(*)]: https://www.antlr.org/papers/allstar-techreport.pdf +// [Recursive Transition Network]: https://en.wikipedia.org/wiki/Recursive_transition_network type ATN struct { // DecisionToState is the decision points for all rules, subrules, optional - // blocks, ()+, ()*, etc. Used to build DFA predictors for them. + // blocks, ()+, ()*, etc. Each subrule/rule is a decision point, and we must track them so we + // can go back later and build DFA predictors for them. This includes + // all the rules, subrules, optional blocks, ()+, ()* etc... DecisionToState []DecisionState // grammarType is the ATN type and is used for deserializing ATNs from strings. @@ -45,6 +58,8 @@ type ATN struct { edgeMu sync.RWMutex } +// NewATN returns a new ATN struct representing the given grammarType and is used +// for runtime deserialization of ATNs from the code generated by the ANTLR tool func NewATN(grammarType int, maxTokenType int) *ATN { return &ATN{ grammarType: grammarType, @@ -53,7 +68,7 @@ func NewATN(grammarType int, maxTokenType int) *ATN { } } -// NextTokensInContext computes the set of valid tokens that can occur starting +// NextTokensInContext computes and returns the set of valid tokens that can occur starting // in state s. If ctx is nil, the set of tokens will not include what can follow // the rule surrounding s. In other words, the set will be restricted to tokens // reachable staying within the rule of s. @@ -61,8 +76,8 @@ func (a *ATN) NextTokensInContext(s ATNState, ctx RuleContext) *IntervalSet { return NewLL1Analyzer(a).Look(s, nil, ctx) } -// NextTokensNoContext computes the set of valid tokens that can occur starting -// in s and staying in same rule. Token.EPSILON is in set if we reach end of +// NextTokensNoContext computes and returns the set of valid tokens that can occur starting +// in state s and staying in same rule. [antlr.Token.EPSILON] is in set if we reach end of // rule. func (a *ATN) NextTokensNoContext(s ATNState) *IntervalSet { a.mu.Lock() @@ -76,6 +91,8 @@ func (a *ATN) NextTokensNoContext(s ATNState) *IntervalSet { return iset } +// NextTokens computes and returns the set of valid tokens starting in state s, by +// calling either [NextTokensNoContext] (ctx == nil) or [NextTokensInContext] (ctx != nil). func (a *ATN) NextTokens(s ATNState, ctx RuleContext) *IntervalSet { if ctx == nil { return a.NextTokensNoContext(s) diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_config.go similarity index 84% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_config.go index 97ba417f7..7619fa172 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_config.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -8,19 +8,14 @@ import ( "fmt" ) -type comparable interface { - equals(other interface{}) bool -} - // ATNConfig is a tuple: (ATN state, predicted alt, syntactic, semantic // context). The syntactic context is a graph-structured stack node whose // path(s) to the root is the rule invocation(s) chain used to arrive at the // state. The semantic context is the tree of semantic predicates encountered // before reaching an ATN state. type ATNConfig interface { - comparable - - hash() int + Equals(o Collectable[ATNConfig]) bool + Hash() int GetState() ATNState GetAlt() int @@ -47,7 +42,7 @@ type BaseATNConfig struct { reachesIntoOuterContext int } -func NewBaseATNConfig7(old *BaseATNConfig) *BaseATNConfig { // TODO: Dup +func NewBaseATNConfig7(old *BaseATNConfig) ATNConfig { // TODO: Dup return &BaseATNConfig{ state: old.state, alt: old.alt, @@ -135,11 +130,16 @@ func (b *BaseATNConfig) SetReachesIntoOuterContext(v int) { b.reachesIntoOuterContext = v } +// Equals is the default comparison function for an ATNConfig when no specialist implementation is required +// for a collection. +// // An ATN configuration is equal to another if both have the same state, they // predict the same alternative, and syntactic/semantic contexts are the same. -func (b *BaseATNConfig) equals(o interface{}) bool { +func (b *BaseATNConfig) Equals(o Collectable[ATNConfig]) bool { if b == o { return true + } else if o == nil { + return false } var other, ok = o.(*BaseATNConfig) @@ -153,30 +153,32 @@ func (b *BaseATNConfig) equals(o interface{}) bool { if b.context == nil { equal = other.context == nil } else { - equal = b.context.equals(other.context) + equal = b.context.Equals(other.context) } var ( nums = b.state.GetStateNumber() == other.state.GetStateNumber() alts = b.alt == other.alt - cons = b.semanticContext.equals(other.semanticContext) + cons = b.semanticContext.Equals(other.semanticContext) sups = b.precedenceFilterSuppressed == other.precedenceFilterSuppressed ) return nums && alts && cons && sups && equal } -func (b *BaseATNConfig) hash() int { +// Hash is the default hash function for BaseATNConfig, when no specialist hash function +// is required for a collection +func (b *BaseATNConfig) Hash() int { var c int if b.context != nil { - c = b.context.hash() + c = b.context.Hash() } h := murmurInit(7) h = murmurUpdate(h, b.state.GetStateNumber()) h = murmurUpdate(h, b.alt) h = murmurUpdate(h, c) - h = murmurUpdate(h, b.semanticContext.hash()) + h = murmurUpdate(h, b.semanticContext.Hash()) return murmurFinish(h, 4) } @@ -243,7 +245,9 @@ func NewLexerATNConfig1(state ATNState, alt int, context PredictionContext) *Lex return &LexerATNConfig{BaseATNConfig: NewBaseATNConfig5(state, alt, context, SemanticContextNone)} } -func (l *LexerATNConfig) hash() int { +// Hash is the default hash function for LexerATNConfig objects, it can be used directly or via +// the default comparator [ObjEqComparator]. +func (l *LexerATNConfig) Hash() int { var f int if l.passedThroughNonGreedyDecision { f = 1 @@ -253,15 +257,20 @@ func (l *LexerATNConfig) hash() int { h := murmurInit(7) h = murmurUpdate(h, l.state.GetStateNumber()) h = murmurUpdate(h, l.alt) - h = murmurUpdate(h, l.context.hash()) - h = murmurUpdate(h, l.semanticContext.hash()) + h = murmurUpdate(h, l.context.Hash()) + h = murmurUpdate(h, l.semanticContext.Hash()) h = murmurUpdate(h, f) - h = murmurUpdate(h, l.lexerActionExecutor.hash()) + h = murmurUpdate(h, l.lexerActionExecutor.Hash()) h = murmurFinish(h, 6) return h } -func (l *LexerATNConfig) equals(other interface{}) bool { +// Equals is the default comparison function for LexerATNConfig objects, it can be used directly or via +// the default comparator [ObjEqComparator]. +func (l *LexerATNConfig) Equals(other Collectable[ATNConfig]) bool { + if l == other { + return true + } var othert, ok = other.(*LexerATNConfig) if l == other { @@ -275,7 +284,7 @@ func (l *LexerATNConfig) equals(other interface{}) bool { var b bool if l.lexerActionExecutor != nil { - b = !l.lexerActionExecutor.equals(othert.lexerActionExecutor) + b = !l.lexerActionExecutor.Equals(othert.lexerActionExecutor) } else { b = othert.lexerActionExecutor != nil } @@ -284,10 +293,9 @@ func (l *LexerATNConfig) equals(other interface{}) bool { return false } - return l.BaseATNConfig.equals(othert.BaseATNConfig) + return l.BaseATNConfig.Equals(othert.BaseATNConfig) } - func checkNonGreedyDecision(source *LexerATNConfig, target ATNState) bool { var ds, ok = target.(DecisionState) diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config_set.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_config_set.go similarity index 81% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config_set.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_config_set.go index 49ad4a719..43e9b33f3 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config_set.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_config_set.go @@ -1,24 +1,25 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. package antlr -import "fmt" +import ( + "fmt" +) type ATNConfigSet interface { - hash() int + Hash() int + Equals(o Collectable[ATNConfig]) bool Add(ATNConfig, *DoubleDict) bool AddAll([]ATNConfig) bool - GetStates() Set + GetStates() *JStore[ATNState, Comparator[ATNState]] GetPredicates() []SemanticContext GetItems() []ATNConfig OptimizeConfigs(interpreter *BaseATNSimulator) - Equals(other interface{}) bool - Length() int IsEmpty() bool Contains(ATNConfig) bool @@ -57,7 +58,7 @@ type BaseATNConfigSet struct { // effectively doubles the number of objects associated with ATNConfigs. All // keys are hashed by (s, i, _, pi), not including the context. Wiped out when // read-only because a set becomes a DFA state. - configLookup Set + configLookup *JStore[ATNConfig, Comparator[ATNConfig]] // configs is the added elements. configs []ATNConfig @@ -83,7 +84,7 @@ type BaseATNConfigSet struct { // readOnly is whether it is read-only. Do not // allow any code to manipulate the set if true because DFA states will point at - // sets and those must not change. It not protect other fields; conflictingAlts + // sets and those must not change. It not, protect other fields; conflictingAlts // in particular, which is assigned after readOnly. readOnly bool @@ -104,7 +105,7 @@ func (b *BaseATNConfigSet) Alts() *BitSet { func NewBaseATNConfigSet(fullCtx bool) *BaseATNConfigSet { return &BaseATNConfigSet{ cachedHash: -1, - configLookup: newArray2DHashSetWithCap(hashATNConfig, equalATNConfigs, 16, 2), + configLookup: NewJStore[ATNConfig, Comparator[ATNConfig]](aConfCompInst), fullCtx: fullCtx, } } @@ -126,9 +127,11 @@ func (b *BaseATNConfigSet) Add(config ATNConfig, mergeCache *DoubleDict) bool { b.dipsIntoOuterContext = true } - existing := b.configLookup.Add(config).(ATNConfig) + existing, present := b.configLookup.Put(config) - if existing == config { + // The config was not already in the set + // + if !present { b.cachedHash = -1 b.configs = append(b.configs, config) // Track order here return true @@ -154,11 +157,14 @@ func (b *BaseATNConfigSet) Add(config ATNConfig, mergeCache *DoubleDict) bool { return true } -func (b *BaseATNConfigSet) GetStates() Set { - states := newArray2DHashSet(nil, nil) +func (b *BaseATNConfigSet) GetStates() *JStore[ATNState, Comparator[ATNState]] { + + // states uses the standard comparator provided by the ATNState instance + // + states := NewJStore[ATNState, Comparator[ATNState]](aStateEqInst) for i := 0; i < len(b.configs); i++ { - states.Add(b.configs[i].GetState()) + states.Put(b.configs[i].GetState()) } return states @@ -214,7 +220,34 @@ func (b *BaseATNConfigSet) AddAll(coll []ATNConfig) bool { return false } -func (b *BaseATNConfigSet) Equals(other interface{}) bool { +// Compare is a hack function just to verify that adding DFAstares to the known +// set works, so long as comparison of ATNConfigSet s works. For that to work, we +// need to make sure that the set of ATNConfigs in two sets are equivalent. We can't +// know the order, so we do this inefficient hack. If this proves the point, then +// we can change the config set to a better structure. +func (b *BaseATNConfigSet) Compare(bs *BaseATNConfigSet) bool { + if len(b.configs) != len(bs.configs) { + return false + } + + for _, c := range b.configs { + found := false + for _, c2 := range bs.configs { + if c.Equals(c2) { + found = true + break + } + } + + if !found { + return false + } + + } + return true +} + +func (b *BaseATNConfigSet) Equals(other Collectable[ATNConfig]) bool { if b == other { return true } else if _, ok := other.(*BaseATNConfigSet); !ok { @@ -224,15 +257,15 @@ func (b *BaseATNConfigSet) Equals(other interface{}) bool { other2 := other.(*BaseATNConfigSet) return b.configs != nil && - // TODO: b.configs.equals(other2.configs) && // TODO: Is b necessary? b.fullCtx == other2.fullCtx && b.uniqueAlt == other2.uniqueAlt && b.conflictingAlts == other2.conflictingAlts && b.hasSemanticContext == other2.hasSemanticContext && - b.dipsIntoOuterContext == other2.dipsIntoOuterContext + b.dipsIntoOuterContext == other2.dipsIntoOuterContext && + b.Compare(other2) } -func (b *BaseATNConfigSet) hash() int { +func (b *BaseATNConfigSet) Hash() int { if b.readOnly { if b.cachedHash == -1 { b.cachedHash = b.hashCodeConfigs() @@ -247,7 +280,7 @@ func (b *BaseATNConfigSet) hash() int { func (b *BaseATNConfigSet) hashCodeConfigs() int { h := 1 for _, config := range b.configs { - h = 31*h + config.hash() + h = 31*h + config.Hash() } return h } @@ -283,7 +316,7 @@ func (b *BaseATNConfigSet) Clear() { b.configs = make([]ATNConfig, 0) b.cachedHash = -1 - b.configLookup = newArray2DHashSet(nil, equalATNConfigs) + b.configLookup = NewJStore[ATNConfig, Comparator[ATNConfig]](atnConfCompInst) } func (b *BaseATNConfigSet) FullContext() bool { @@ -365,7 +398,8 @@ type OrderedATNConfigSet struct { func NewOrderedATNConfigSet() *OrderedATNConfigSet { b := NewBaseATNConfigSet(false) - b.configLookup = newArray2DHashSet(nil, nil) + // This set uses the standard Hash() and Equals() from ATNConfig + b.configLookup = NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst) return &OrderedATNConfigSet{BaseATNConfigSet: b} } @@ -375,7 +409,7 @@ func hashATNConfig(i interface{}) int { hash := 7 hash = 31*hash + o.GetState().GetStateNumber() hash = 31*hash + o.GetAlt() - hash = 31*hash + o.GetSemanticContext().hash() + hash = 31*hash + o.GetSemanticContext().Hash() return hash } @@ -403,5 +437,5 @@ func equalATNConfigs(a, b interface{}) bool { return false } - return ai.GetSemanticContext().equals(bi.GetSemanticContext()) + return ai.GetSemanticContext().Equals(bi.GetSemanticContext()) } diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserialization_options.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_deserialization_options.go similarity index 96% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserialization_options.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_deserialization_options.go index cb8eafb0b..3c975ec7b 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserialization_options.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_deserialization_options.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserializer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_deserializer.go similarity index 99% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserializer.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_deserializer.go index aea9bbfa9..3888856b4 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserializer.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_deserializer.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_simulator.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_simulator.go similarity index 94% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_simulator.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_simulator.go index d5454d6d5..41529115f 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_simulator.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_simulator.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_state.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_state.go similarity index 97% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_state.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_state.go index 3835bb2e9..1f2a56bc3 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_state.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_state.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -49,7 +49,8 @@ type ATNState interface { AddTransition(Transition, int) String() string - hash() int + Hash() int + Equals(Collectable[ATNState]) bool } type BaseATNState struct { @@ -123,7 +124,7 @@ func (as *BaseATNState) SetNextTokenWithinRule(v *IntervalSet) { as.NextTokenWithinRule = v } -func (as *BaseATNState) hash() int { +func (as *BaseATNState) Hash() int { return as.stateNumber } @@ -131,7 +132,7 @@ func (as *BaseATNState) String() string { return strconv.Itoa(as.stateNumber) } -func (as *BaseATNState) equals(other interface{}) bool { +func (as *BaseATNState) Equals(other Collectable[ATNState]) bool { if ot, ok := other.(ATNState); ok { return as.stateNumber == ot.GetStateNumber() } diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_type.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_type.go similarity index 79% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_type.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_type.go index a7b48976b..3a515a145 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_type.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_type.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/char_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/char_stream.go similarity index 82% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/char_stream.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/char_stream.go index 70c1207f7..c33f0adb5 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/char_stream.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/char_stream.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_factory.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/common_token_factory.go similarity index 96% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_factory.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/common_token_factory.go index 330ff8f31..1bb0314ea 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_factory.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/common_token_factory.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/common_token_stream.go similarity index 98% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_stream.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/common_token_stream.go index c90e9b890..c6c9485a2 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_stream.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/common_token_stream.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -331,10 +331,12 @@ func (c *CommonTokenStream) GetTextFromRuleContext(interval RuleContext) string func (c *CommonTokenStream) GetTextFromInterval(interval *Interval) string { c.lazyInit() - c.Fill() if interval == nil { + c.Fill() interval = NewInterval(0, len(c.tokens)-1) + } else { + c.Sync(interval.Stop) } start := interval.Start diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/comparators.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/comparators.go new file mode 100644 index 000000000..9ea320053 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/comparators.go @@ -0,0 +1,147 @@ +package antlr + +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. +// Use of this file is governed by the BSD 3-clause license that +// can be found in the LICENSE.txt file in the project root. + +// This file contains all the implementations of custom comparators used for generic collections when the +// Hash() and Equals() funcs supplied by the struct objects themselves need to be overridden. Normally, we would +// put the comparators in the source file for the struct themselves, but given the organization of this code is +// sorta kinda based upon the Java code, I found it confusing trying to find out which comparator was where and used by +// which instantiation of a collection. For instance, an Array2DHashSet in the Java source, when used with ATNConfig +// collections requires three different comparators depending on what the collection is being used for. Collecting - pun intended - +// all the comparators here, makes it much easier to see which implementation of hash and equals is used by which collection. +// It also makes it easy to verify that the Hash() and Equals() functions marry up with the Java implementations. + +// ObjEqComparator is the equivalent of the Java ObjectEqualityComparator, which is the default instance of +// Equality comparator. We do not have inheritance in Go, only interfaces, so we use generics to enforce some +// type safety and avoid having to implement this for every type that we want to perform comparison on. +// +// This comparator works by using the standard Hash() and Equals() methods of the type T that is being compared. Which +// allows us to use it in any collection instance that does nto require a special hash or equals implementation. +type ObjEqComparator[T Collectable[T]] struct{} + +var ( + aStateEqInst = &ObjEqComparator[ATNState]{} + aConfEqInst = &ObjEqComparator[ATNConfig]{} + aConfCompInst = &ATNConfigComparator[ATNConfig]{} + atnConfCompInst = &BaseATNConfigComparator[ATNConfig]{} + dfaStateEqInst = &ObjEqComparator[*DFAState]{} + semctxEqInst = &ObjEqComparator[SemanticContext]{} + atnAltCfgEqInst = &ATNAltConfigComparator[ATNConfig]{} +) + +// Equals2 delegates to the Equals() method of type T +func (c *ObjEqComparator[T]) Equals2(o1, o2 T) bool { + return o1.Equals(o2) +} + +// Hash1 delegates to the Hash() method of type T +func (c *ObjEqComparator[T]) Hash1(o T) int { + + return o.Hash() +} + +type SemCComparator[T Collectable[T]] struct{} + +// ATNConfigComparator is used as the compartor for the configLookup field of an ATNConfigSet +// and has a custom Equals() and Hash() implementation, because equality is not based on the +// standard Hash() and Equals() methods of the ATNConfig type. +type ATNConfigComparator[T Collectable[T]] struct { +} + +// Equals2 is a custom comparator for ATNConfigs specifically for configLookup +func (c *ATNConfigComparator[T]) Equals2(o1, o2 ATNConfig) bool { + + // Same pointer, must be equal, even if both nil + // + if o1 == o2 { + return true + + } + + // If either are nil, but not both, then the result is false + // + if o1 == nil || o2 == nil { + return false + } + + return o1.GetState().GetStateNumber() == o2.GetState().GetStateNumber() && + o1.GetAlt() == o2.GetAlt() && + o1.GetSemanticContext().Equals(o2.GetSemanticContext()) +} + +// Hash1 is custom hash implementation for ATNConfigs specifically for configLookup +func (c *ATNConfigComparator[T]) Hash1(o ATNConfig) int { + hash := 7 + hash = 31*hash + o.GetState().GetStateNumber() + hash = 31*hash + o.GetAlt() + hash = 31*hash + o.GetSemanticContext().Hash() + return hash +} + +// ATNAltConfigComparator is used as the comparator for mapping configs to Alt Bitsets +type ATNAltConfigComparator[T Collectable[T]] struct { +} + +// Equals2 is a custom comparator for ATNConfigs specifically for configLookup +func (c *ATNAltConfigComparator[T]) Equals2(o1, o2 ATNConfig) bool { + + // Same pointer, must be equal, even if both nil + // + if o1 == o2 { + return true + + } + + // If either are nil, but not both, then the result is false + // + if o1 == nil || o2 == nil { + return false + } + + return o1.GetState().GetStateNumber() == o2.GetState().GetStateNumber() && + o1.GetContext().Equals(o2.GetContext()) +} + +// Hash1 is custom hash implementation for ATNConfigs specifically for configLookup +func (c *ATNAltConfigComparator[T]) Hash1(o ATNConfig) int { + h := murmurInit(7) + h = murmurUpdate(h, o.GetState().GetStateNumber()) + h = murmurUpdate(h, o.GetContext().Hash()) + return murmurFinish(h, 2) +} + +// BaseATNConfigComparator is used as the comparator for the configLookup field of a BaseATNConfigSet +// and has a custom Equals() and Hash() implementation, because equality is not based on the +// standard Hash() and Equals() methods of the ATNConfig type. +type BaseATNConfigComparator[T Collectable[T]] struct { +} + +// Equals2 is a custom comparator for ATNConfigs specifically for baseATNConfigSet +func (c *BaseATNConfigComparator[T]) Equals2(o1, o2 ATNConfig) bool { + + // Same pointer, must be equal, even if both nil + // + if o1 == o2 { + return true + + } + + // If either are nil, but not both, then the result is false + // + if o1 == nil || o2 == nil { + return false + } + + return o1.GetState().GetStateNumber() == o2.GetState().GetStateNumber() && + o1.GetAlt() == o2.GetAlt() && + o1.GetSemanticContext().Equals(o2.GetSemanticContext()) +} + +// Hash1 is custom hash implementation for ATNConfigs specifically for configLookup, but in fact just +// delegates to the standard Hash() method of the ATNConfig type. +func (c *BaseATNConfigComparator[T]) Hash1(o ATNConfig) int { + + return o.Hash() +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa.go similarity index 80% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa.go index d55a2a87d..bfd43e1f7 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa.go @@ -1,13 +1,9 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. package antlr -import ( - "sort" -) - type DFA struct { // atnStartState is the ATN state in which this was created atnStartState DecisionState @@ -15,8 +11,15 @@ type DFA struct { decision int // states is all the DFA states. Use Map to get the old state back; Set can only - // indicate whether it is there. - states map[int]*DFAState + // indicate whether it is there. Go maps implement key hash collisions and so on and are very + // good, but the DFAState is an object and can't be used directly as the key as it can in say JAva + // amd C#, whereby if the hashcode is the same for two objects, then Equals() is called against them + // to see if they really are the same object. + // + // + states *JStore[*DFAState, *ObjEqComparator[*DFAState]] + + numstates int s0 *DFAState @@ -29,7 +32,7 @@ func NewDFA(atnStartState DecisionState, decision int) *DFA { dfa := &DFA{ atnStartState: atnStartState, decision: decision, - states: make(map[int]*DFAState), + states: NewJStore[*DFAState, *ObjEqComparator[*DFAState]](dfaStateEqInst), } if s, ok := atnStartState.(*StarLoopEntryState); ok && s.precedenceRuleDecision { dfa.precedenceDfa = true @@ -92,7 +95,8 @@ func (d *DFA) getPrecedenceDfa() bool { // true or nil otherwise, and d.precedenceDfa is updated. func (d *DFA) setPrecedenceDfa(precedenceDfa bool) { if d.getPrecedenceDfa() != precedenceDfa { - d.setStates(make(map[int]*DFAState)) + d.states = NewJStore[*DFAState, *ObjEqComparator[*DFAState]](dfaStateEqInst) + d.numstates = 0 if precedenceDfa { precedenceState := NewDFAState(-1, NewBaseATNConfigSet(false)) @@ -117,38 +121,12 @@ func (d *DFA) setS0(s *DFAState) { d.s0 = s } -func (d *DFA) getState(hash int) (*DFAState, bool) { - s, ok := d.states[hash] - return s, ok -} - -func (d *DFA) setStates(states map[int]*DFAState) { - d.states = states -} - -func (d *DFA) setState(hash int, state *DFAState) { - d.states[hash] = state -} - -func (d *DFA) numStates() int { - return len(d.states) -} - -type dfaStateList []*DFAState - -func (d dfaStateList) Len() int { return len(d) } -func (d dfaStateList) Less(i, j int) bool { return d[i].stateNumber < d[j].stateNumber } -func (d dfaStateList) Swap(i, j int) { d[i], d[j] = d[j], d[i] } - // sortedStates returns the states in d sorted by their state number. func (d *DFA) sortedStates() []*DFAState { - vs := make([]*DFAState, 0, len(d.states)) - - for _, v := range d.states { - vs = append(vs, v) - } - sort.Sort(dfaStateList(vs)) + vs := d.states.SortedSlice(func(i, j *DFAState) bool { + return i.stateNumber < j.stateNumber + }) return vs } diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_serializer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa_serializer.go similarity index 97% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_serializer.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa_serializer.go index bf2ccc06c..84d0a31e5 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_serializer.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa_serializer.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_state.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa_state.go similarity index 90% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_state.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa_state.go index 970ed1986..c90dec55c 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_state.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa_state.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -90,16 +90,16 @@ func NewDFAState(stateNumber int, configs ATNConfigSet) *DFAState { } // GetAltSet gets the set of all alts mentioned by all ATN configurations in d. -func (d *DFAState) GetAltSet() Set { - alts := newArray2DHashSet(nil, nil) +func (d *DFAState) GetAltSet() []int { + var alts []int if d.configs != nil { for _, c := range d.configs.GetItems() { - alts.Add(c.GetAlt()) + alts = append(alts, c.GetAlt()) } } - if alts.Len() == 0 { + if len(alts) == 0 { return nil } @@ -130,27 +130,6 @@ func (d *DFAState) setPrediction(v int) { d.prediction = v } -// equals returns whether d equals other. Two DFAStates are equal if their ATN -// configuration sets are the same. This method is used to see if a state -// already exists. -// -// Because the number of alternatives and number of ATN configurations are -// finite, there is a finite number of DFA states that can be processed. This is -// necessary to show that the algorithm terminates. -// -// Cannot test the DFA state numbers here because in -// ParserATNSimulator.addDFAState we need to know if any other state exists that -// has d exact set of ATN configurations. The stateNumber is irrelevant. -func (d *DFAState) equals(other interface{}) bool { - if d == other { - return true - } else if _, ok := other.(*DFAState); !ok { - return false - } - - return d.configs.Equals(other.(*DFAState).configs) -} - func (d *DFAState) String() string { var s string if d.isAcceptState { @@ -164,8 +143,27 @@ func (d *DFAState) String() string { return fmt.Sprintf("%d:%s%s", d.stateNumber, fmt.Sprint(d.configs), s) } -func (d *DFAState) hash() int { +func (d *DFAState) Hash() int { h := murmurInit(7) - h = murmurUpdate(h, d.configs.hash()) + h = murmurUpdate(h, d.configs.Hash()) return murmurFinish(h, 1) } + +// Equals returns whether d equals other. Two DFAStates are equal if their ATN +// configuration sets are the same. This method is used to see if a state +// already exists. +// +// Because the number of alternatives and number of ATN configurations are +// finite, there is a finite number of DFA states that can be processed. This is +// necessary to show that the algorithm terminates. +// +// Cannot test the DFA state numbers here because in +// ParserATNSimulator.addDFAState we need to know if any other state exists that +// has d exact set of ATN configurations. The stateNumber is irrelevant. +func (d *DFAState) Equals(o Collectable[*DFAState]) bool { + if d == o { + return true + } + + return d.configs.Equals(o.(*DFAState).configs) +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/diagnostic_error_listener.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/diagnostic_error_listener.go similarity index 98% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/diagnostic_error_listener.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/diagnostic_error_listener.go index 1fec43d9d..c55bcc19b 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/diagnostic_error_listener.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/diagnostic_error_listener.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -87,7 +87,6 @@ func (d *DiagnosticErrorListener) getDecisionDescription(recognizer Parser, dfa return strconv.Itoa(decision) + " (" + ruleName + ")" } -// // Computes the set of conflicting or ambiguous alternatives from a // configuration set, if that information was not already provided by the // parser. @@ -97,7 +96,6 @@ func (d *DiagnosticErrorListener) getDecisionDescription(recognizer Parser, dfa // @param configs The conflicting or ambiguous configuration set. // @return Returns {@code ReportedAlts} if it is not {@code nil}, otherwise // returns the set of alternatives represented in {@code configs}. -// func (d *DiagnosticErrorListener) getConflictingAlts(ReportedAlts *BitSet, set ATNConfigSet) *BitSet { if ReportedAlts != nil { return ReportedAlts diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_listener.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/error_listener.go similarity index 98% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_listener.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/error_listener.go index 028e1a9d7..f679f0dcd 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_listener.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/error_listener.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -48,12 +48,9 @@ func NewConsoleErrorListener() *ConsoleErrorListener { return new(ConsoleErrorListener) } -// // Provides a default instance of {@link ConsoleErrorListener}. -// var ConsoleErrorListenerINSTANCE = NewConsoleErrorListener() -// // {@inheritDoc} // //

@@ -64,7 +61,6 @@ var ConsoleErrorListenerINSTANCE = NewConsoleErrorListener() //

 // line line:charPositionInLine msg
 // 
-// func (c *ConsoleErrorListener) SyntaxError(recognizer Recognizer, offendingSymbol interface{}, line, column int, msg string, e RecognitionException) { fmt.Fprintln(os.Stderr, "line "+strconv.Itoa(line)+":"+strconv.Itoa(column)+" "+msg) } diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_strategy.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/error_strategy.go similarity index 99% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_strategy.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/error_strategy.go index c4080dbfd..5c0a637ba 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_strategy.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/error_strategy.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -23,7 +23,6 @@ type ErrorStrategy interface { // This is the default implementation of {@link ANTLRErrorStrategy} used for // error Reporting and recovery in ANTLR parsers. -// type DefaultErrorStrategy struct { errorRecoveryMode bool lastErrorIndex int @@ -61,12 +60,10 @@ func (d *DefaultErrorStrategy) reset(recognizer Parser) { d.endErrorCondition(recognizer) } -// // This method is called to enter error recovery mode when a recognition // exception is Reported. // // @param recognizer the parser instance -// func (d *DefaultErrorStrategy) beginErrorCondition(recognizer Parser) { d.errorRecoveryMode = true } @@ -75,28 +72,23 @@ func (d *DefaultErrorStrategy) InErrorRecoveryMode(recognizer Parser) bool { return d.errorRecoveryMode } -// // This method is called to leave error recovery mode after recovering from // a recognition exception. // // @param recognizer -// func (d *DefaultErrorStrategy) endErrorCondition(recognizer Parser) { d.errorRecoveryMode = false d.lastErrorStates = nil d.lastErrorIndex = -1 } -// // {@inheritDoc} // //

The default implementation simply calls {@link //endErrorCondition}.

-// func (d *DefaultErrorStrategy) ReportMatch(recognizer Parser) { d.endErrorCondition(recognizer) } -// // {@inheritDoc} // //

The default implementation returns immediately if the handler is already @@ -114,7 +106,6 @@ func (d *DefaultErrorStrategy) ReportMatch(recognizer Parser) { //

  • All other types: calls {@link Parser//NotifyErrorListeners} to Report // the exception
  • // -// func (d *DefaultErrorStrategy) ReportError(recognizer Parser, e RecognitionException) { // if we've already Reported an error and have not Matched a token // yet successfully, don't Report any errors. @@ -142,7 +133,6 @@ func (d *DefaultErrorStrategy) ReportError(recognizer Parser, e RecognitionExcep //

    The default implementation reSynchronizes the parser by consuming tokens // until we find one in the reSynchronization set--loosely the set of tokens // that can follow the current rule.

    -// func (d *DefaultErrorStrategy) Recover(recognizer Parser, e RecognitionException) { if d.lastErrorIndex == recognizer.GetInputStream().Index() && @@ -206,7 +196,6 @@ func (d *DefaultErrorStrategy) Recover(recognizer Parser, e RecognitionException // compare token set at the start of the loop and at each iteration. If for // some reason speed is suffering for you, you can turn off d // functionality by simply overriding d method as a blank { }.

    -// func (d *DefaultErrorStrategy) Sync(recognizer Parser) { // If already recovering, don't try to Sync if d.InErrorRecoveryMode(recognizer) { @@ -247,7 +236,6 @@ func (d *DefaultErrorStrategy) Sync(recognizer Parser) { // // @param recognizer the parser instance // @param e the recognition exception -// func (d *DefaultErrorStrategy) ReportNoViableAlternative(recognizer Parser, e *NoViableAltException) { tokens := recognizer.GetTokenStream() var input string @@ -264,7 +252,6 @@ func (d *DefaultErrorStrategy) ReportNoViableAlternative(recognizer Parser, e *N recognizer.NotifyErrorListeners(msg, e.offendingToken, e) } -// // This is called by {@link //ReportError} when the exception is an // {@link InputMisMatchException}. // @@ -272,14 +259,12 @@ func (d *DefaultErrorStrategy) ReportNoViableAlternative(recognizer Parser, e *N // // @param recognizer the parser instance // @param e the recognition exception -// func (this *DefaultErrorStrategy) ReportInputMisMatch(recognizer Parser, e *InputMisMatchException) { msg := "mismatched input " + this.GetTokenErrorDisplay(e.offendingToken) + " expecting " + e.getExpectedTokens().StringVerbose(recognizer.GetLiteralNames(), recognizer.GetSymbolicNames(), false) recognizer.NotifyErrorListeners(msg, e.offendingToken, e) } -// // This is called by {@link //ReportError} when the exception is a // {@link FailedPredicateException}. // @@ -287,7 +272,6 @@ func (this *DefaultErrorStrategy) ReportInputMisMatch(recognizer Parser, e *Inpu // // @param recognizer the parser instance // @param e the recognition exception -// func (d *DefaultErrorStrategy) ReportFailedPredicate(recognizer Parser, e *FailedPredicateException) { ruleName := recognizer.GetRuleNames()[recognizer.GetParserRuleContext().GetRuleIndex()] msg := "rule " + ruleName + " " + e.message @@ -310,7 +294,6 @@ func (d *DefaultErrorStrategy) ReportFailedPredicate(recognizer Parser, e *Faile // {@link Parser//NotifyErrorListeners}.

    // // @param recognizer the parser instance -// func (d *DefaultErrorStrategy) ReportUnwantedToken(recognizer Parser) { if d.InErrorRecoveryMode(recognizer) { return @@ -339,7 +322,6 @@ func (d *DefaultErrorStrategy) ReportUnwantedToken(recognizer Parser) { // {@link Parser//NotifyErrorListeners}.

    // // @param recognizer the parser instance -// func (d *DefaultErrorStrategy) ReportMissingToken(recognizer Parser) { if d.InErrorRecoveryMode(recognizer) { return @@ -392,15 +374,14 @@ func (d *DefaultErrorStrategy) ReportMissingToken(recognizer Parser) { // derivation: // //
    -// => ID '=' '(' INT ')' ('+' atom)* ''
    +// => ID '=' '(' INT ')' ('+' atom)* ”
     // ^
     // 
    // -// The attempt to Match {@code ')'} will fail when it sees {@code ''} and -// call {@link //recoverInline}. To recover, it sees that {@code LA(1)==''} +// The attempt to Match {@code ')'} will fail when it sees {@code ”} and +// call {@link //recoverInline}. To recover, it sees that {@code LA(1)==”} // is in the set of tokens that can follow the {@code ')'} token reference // in rule {@code atom}. It can assume that you forgot the {@code ')'}. -// func (d *DefaultErrorStrategy) RecoverInline(recognizer Parser) Token { // SINGLE TOKEN DELETION MatchedSymbol := d.SingleTokenDeletion(recognizer) @@ -418,7 +399,6 @@ func (d *DefaultErrorStrategy) RecoverInline(recognizer Parser) Token { panic(NewInputMisMatchException(recognizer)) } -// // This method implements the single-token insertion inline error recovery // strategy. It is called by {@link //recoverInline} if the single-token // deletion strategy fails to recover from the mismatched input. If this @@ -434,7 +414,6 @@ func (d *DefaultErrorStrategy) RecoverInline(recognizer Parser) Token { // @param recognizer the parser instance // @return {@code true} if single-token insertion is a viable recovery // strategy for the current mismatched input, otherwise {@code false} -// func (d *DefaultErrorStrategy) SingleTokenInsertion(recognizer Parser) bool { currentSymbolType := recognizer.GetTokenStream().LA(1) // if current token is consistent with what could come after current @@ -469,7 +448,6 @@ func (d *DefaultErrorStrategy) SingleTokenInsertion(recognizer Parser) bool { // @return the successfully Matched {@link Token} instance if single-token // deletion successfully recovers from the mismatched input, otherwise // {@code nil} -// func (d *DefaultErrorStrategy) SingleTokenDeletion(recognizer Parser) Token { NextTokenType := recognizer.GetTokenStream().LA(2) expecting := d.GetExpectedTokens(recognizer) @@ -507,7 +485,6 @@ func (d *DefaultErrorStrategy) SingleTokenDeletion(recognizer Parser) Token { // a CommonToken of the appropriate type. The text will be the token. // If you change what tokens must be created by the lexer, // override d method to create the appropriate tokens. -// func (d *DefaultErrorStrategy) GetMissingSymbol(recognizer Parser) Token { currentSymbol := recognizer.GetCurrentToken() expecting := d.GetExpectedTokens(recognizer) @@ -546,7 +523,6 @@ func (d *DefaultErrorStrategy) GetExpectedTokens(recognizer Parser) *IntervalSet // the token). This is better than forcing you to override a method in // your token objects because you don't have to go modify your lexer // so that it creates a NewJava type. -// func (d *DefaultErrorStrategy) GetTokenErrorDisplay(t Token) string { if t == nil { return "" @@ -578,7 +554,7 @@ func (d *DefaultErrorStrategy) escapeWSAndQuote(s string) string { // from within the rule i.e., the FIRST computation done by // ANTLR stops at the end of a rule. // -// EXAMPLE +// # EXAMPLE // // When you find a "no viable alt exception", the input is not // consistent with any of the alternatives for rule r. The best @@ -597,7 +573,6 @@ func (d *DefaultErrorStrategy) escapeWSAndQuote(s string) string { // c : ID // | INT // -// // At each rule invocation, the set of tokens that could follow // that rule is pushed on a stack. Here are the various // context-sensitive follow sets: @@ -660,7 +635,6 @@ func (d *DefaultErrorStrategy) escapeWSAndQuote(s string) string { // // Like Grosch I implement context-sensitive FOLLOW sets that are combined // at run-time upon error to avoid overhead during parsing. -// func (d *DefaultErrorStrategy) getErrorRecoverySet(recognizer Parser) *IntervalSet { atn := recognizer.GetInterpreter().atn ctx := recognizer.GetParserRuleContext() @@ -733,7 +707,6 @@ func NewBailErrorStrategy() *BailErrorStrategy { // in a {@link ParseCancellationException} so it is not caught by the // rule func catches. Use {@link Exception//getCause()} to get the // original {@link RecognitionException}. -// func (b *BailErrorStrategy) Recover(recognizer Parser, e RecognitionException) { context := recognizer.GetParserRuleContext() for context != nil { @@ -749,7 +722,6 @@ func (b *BailErrorStrategy) Recover(recognizer Parser, e RecognitionException) { // Make sure we don't attempt to recover inline if the parser // successfully recovers, it won't panic an exception. -// func (b *BailErrorStrategy) RecoverInline(recognizer Parser) Token { b.Recover(recognizer, NewInputMisMatchException(recognizer)) diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/errors.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/errors.go similarity index 98% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/errors.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/errors.go index 2ef74926e..3954c1378 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/errors.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/errors.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -74,7 +74,6 @@ func (b *BaseRecognitionException) GetInputStream() IntStream { //

    If the state number is not known, b method returns -1.

    -// // Gets the set of input symbols which could potentially follow the // previously Matched symbol at the time b exception was panicn. // @@ -136,7 +135,6 @@ type NoViableAltException struct { // to take based upon the remaining input. It tracks the starting token // of the offending input and also knows where the parser was // in the various paths when the error. Reported by ReportNoViableAlternative() -// func NewNoViableAltException(recognizer Parser, input TokenStream, startToken Token, offendingToken Token, deadEndConfigs ATNConfigSet, ctx ParserRuleContext) *NoViableAltException { if ctx == nil { @@ -177,7 +175,6 @@ type InputMisMatchException struct { // This signifies any kind of mismatched input exceptions such as // when the current input does not Match the expected token. -// func NewInputMisMatchException(recognizer Parser) *InputMisMatchException { i := new(InputMisMatchException) diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/file_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/file_stream.go similarity index 92% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/file_stream.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/file_stream.go index 842170c08..bd6ad5efe 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/file_stream.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/file_stream.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/input_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/input_stream.go similarity index 96% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/input_stream.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/input_stream.go index 5ff270f53..a8b889ced 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/input_stream.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/input_stream.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/int_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/int_stream.go similarity index 82% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/int_stream.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/int_stream.go index 438e0ea6e..4778878bd 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/int_stream.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/int_stream.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/interval_set.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/interval_set.go similarity index 98% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/interval_set.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/interval_set.go index 1e9393adb..c1e155e81 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/interval_set.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/interval_set.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -223,6 +223,10 @@ func (i *IntervalSet) StringVerbose(literalNames []string, symbolicNames []strin return i.toIndexString() } +func (i *IntervalSet) GetIntervals() []*Interval { + return i.intervals +} + func (i *IntervalSet) toCharString() string { names := make([]string, len(i.intervals)) diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/jcollect.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/jcollect.go new file mode 100644 index 000000000..e5a74f0c6 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/jcollect.go @@ -0,0 +1,198 @@ +package antlr + +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. +// Use of this file is governed by the BSD 3-clause license that +// can be found in the LICENSE.txt file in the project root. + +import ( + "sort" +) + +// Collectable is an interface that a struct should implement if it is to be +// usable as a key in these collections. +type Collectable[T any] interface { + Hash() int + Equals(other Collectable[T]) bool +} + +type Comparator[T any] interface { + Hash1(o T) int + Equals2(T, T) bool +} + +// JStore implements a container that allows the use of a struct to calculate the key +// for a collection of values akin to map. This is not meant to be a full-blown HashMap but just +// serve the needs of the ANTLR Go runtime. +// +// For ease of porting the logic of the runtime from the master target (Java), this collection +// operates in a similar way to Java, in that it can use any struct that supplies a Hash() and Equals() +// function as the key. The values are stored in a standard go map which internally is a form of hashmap +// itself, the key for the go map is the hash supplied by the key object. The collection is able to deal with +// hash conflicts by using a simple slice of values associated with the hash code indexed bucket. That isn't +// particularly efficient, but it is simple, and it works. As this is specifically for the ANTLR runtime, and +// we understand the requirements, then this is fine - this is not a general purpose collection. +type JStore[T any, C Comparator[T]] struct { + store map[int][]T + len int + comparator Comparator[T] +} + +func NewJStore[T any, C Comparator[T]](comparator Comparator[T]) *JStore[T, C] { + + if comparator == nil { + panic("comparator cannot be nil") + } + + s := &JStore[T, C]{ + store: make(map[int][]T, 1), + comparator: comparator, + } + return s +} + +// Put will store given value in the collection. Note that the key for storage is generated from +// the value itself - this is specifically because that is what ANTLR needs - this would not be useful +// as any kind of general collection. +// +// If the key has a hash conflict, then the value will be added to the slice of values associated with the +// hash, unless the value is already in the slice, in which case the existing value is returned. Value equivalence is +// tested by calling the equals() method on the key. +// +// # If the given value is already present in the store, then the existing value is returned as v and exists is set to true +// +// If the given value is not present in the store, then the value is added to the store and returned as v and exists is set to false. +func (s *JStore[T, C]) Put(value T) (v T, exists bool) { //nolint:ireturn + + kh := s.comparator.Hash1(value) + + for _, v1 := range s.store[kh] { + if s.comparator.Equals2(value, v1) { + return v1, true + } + } + s.store[kh] = append(s.store[kh], value) + s.len++ + return value, false +} + +// Get will return the value associated with the key - the type of the key is the same type as the value +// which would not generally be useful, but this is a specific thing for ANTLR where the key is +// generated using the object we are going to store. +func (s *JStore[T, C]) Get(key T) (T, bool) { //nolint:ireturn + + kh := s.comparator.Hash1(key) + + for _, v := range s.store[kh] { + if s.comparator.Equals2(key, v) { + return v, true + } + } + return key, false +} + +// Contains returns true if the given key is present in the store +func (s *JStore[T, C]) Contains(key T) bool { //nolint:ireturn + + _, present := s.Get(key) + return present +} + +func (s *JStore[T, C]) SortedSlice(less func(i, j T) bool) []T { + vs := make([]T, 0, len(s.store)) + for _, v := range s.store { + vs = append(vs, v...) + } + sort.Slice(vs, func(i, j int) bool { + return less(vs[i], vs[j]) + }) + + return vs +} + +func (s *JStore[T, C]) Each(f func(T) bool) { + for _, e := range s.store { + for _, v := range e { + f(v) + } + } +} + +func (s *JStore[T, C]) Len() int { + return s.len +} + +func (s *JStore[T, C]) Values() []T { + vs := make([]T, 0, len(s.store)) + for _, e := range s.store { + for _, v := range e { + vs = append(vs, v) + } + } + return vs +} + +type entry[K, V any] struct { + key K + val V +} + +type JMap[K, V any, C Comparator[K]] struct { + store map[int][]*entry[K, V] + len int + comparator Comparator[K] +} + +func NewJMap[K, V any, C Comparator[K]](comparator Comparator[K]) *JMap[K, V, C] { + return &JMap[K, V, C]{ + store: make(map[int][]*entry[K, V], 1), + comparator: comparator, + } +} + +func (m *JMap[K, V, C]) Put(key K, val V) { + kh := m.comparator.Hash1(key) + + m.store[kh] = append(m.store[kh], &entry[K, V]{key, val}) + m.len++ +} + +func (m *JMap[K, V, C]) Values() []V { + vs := make([]V, 0, len(m.store)) + for _, e := range m.store { + for _, v := range e { + vs = append(vs, v.val) + } + } + return vs +} + +func (m *JMap[K, V, C]) Get(key K) (V, bool) { + + var none V + kh := m.comparator.Hash1(key) + for _, e := range m.store[kh] { + if m.comparator.Equals2(e.key, key) { + return e.val, true + } + } + return none, false +} + +func (m *JMap[K, V, C]) Len() int { + return len(m.store) +} + +func (m *JMap[K, V, C]) Delete(key K) { + kh := m.comparator.Hash1(key) + for i, e := range m.store[kh] { + if m.comparator.Equals2(e.key, key) { + m.store[kh] = append(m.store[kh][:i], m.store[kh][i+1:]...) + m.len-- + return + } + } +} + +func (m *JMap[K, V, C]) Clear() { + m.store = make(map[int][]*entry[K, V]) +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer.go similarity index 98% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer.go index b04f04572..6533f0516 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -232,8 +232,6 @@ func (b *BaseLexer) NextToken() Token { } return b.token } - - return nil } // Instruct the lexer to Skip creating a token for current lexer rule @@ -342,7 +340,7 @@ func (b *BaseLexer) GetCharIndex() int { } // Return the text Matched so far for the current token or any text override. -//Set the complete text of l token it wipes any previous changes to the text. +// Set the complete text of l token it wipes any previous changes to the text. func (b *BaseLexer) GetText() string { if b.text != "" { return b.text diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_action.go similarity index 91% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_action.go index 5a325be13..111656c29 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_action.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -21,8 +21,8 @@ type LexerAction interface { getActionType() int getIsPositionDependent() bool execute(lexer Lexer) - hash() int - equals(other LexerAction) bool + Hash() int + Equals(other LexerAction) bool } type BaseLexerAction struct { @@ -51,15 +51,14 @@ func (b *BaseLexerAction) getIsPositionDependent() bool { return b.isPositionDependent } -func (b *BaseLexerAction) hash() int { +func (b *BaseLexerAction) Hash() int { return b.actionType } -func (b *BaseLexerAction) equals(other LexerAction) bool { +func (b *BaseLexerAction) Equals(other LexerAction) bool { return b == other } -// // Implements the {@code Skip} lexer action by calling {@link Lexer//Skip}. // //

    The {@code Skip} command does not have any parameters, so l action is @@ -85,7 +84,8 @@ func (l *LexerSkipAction) String() string { return "skip" } -// Implements the {@code type} lexer action by calling {@link Lexer//setType} +// Implements the {@code type} lexer action by calling {@link Lexer//setType} +// // with the assigned type. type LexerTypeAction struct { *BaseLexerAction @@ -104,14 +104,14 @@ func (l *LexerTypeAction) execute(lexer Lexer) { lexer.SetType(l.thetype) } -func (l *LexerTypeAction) hash() int { +func (l *LexerTypeAction) Hash() int { h := murmurInit(0) h = murmurUpdate(h, l.actionType) h = murmurUpdate(h, l.thetype) return murmurFinish(h, 2) } -func (l *LexerTypeAction) equals(other LexerAction) bool { +func (l *LexerTypeAction) Equals(other LexerAction) bool { if l == other { return true } else if _, ok := other.(*LexerTypeAction); !ok { @@ -148,14 +148,14 @@ func (l *LexerPushModeAction) execute(lexer Lexer) { lexer.PushMode(l.mode) } -func (l *LexerPushModeAction) hash() int { +func (l *LexerPushModeAction) Hash() int { h := murmurInit(0) h = murmurUpdate(h, l.actionType) h = murmurUpdate(h, l.mode) return murmurFinish(h, 2) } -func (l *LexerPushModeAction) equals(other LexerAction) bool { +func (l *LexerPushModeAction) Equals(other LexerAction) bool { if l == other { return true } else if _, ok := other.(*LexerPushModeAction); !ok { @@ -245,14 +245,14 @@ func (l *LexerModeAction) execute(lexer Lexer) { lexer.SetMode(l.mode) } -func (l *LexerModeAction) hash() int { +func (l *LexerModeAction) Hash() int { h := murmurInit(0) h = murmurUpdate(h, l.actionType) h = murmurUpdate(h, l.mode) return murmurFinish(h, 2) } -func (l *LexerModeAction) equals(other LexerAction) bool { +func (l *LexerModeAction) Equals(other LexerAction) bool { if l == other { return true } else if _, ok := other.(*LexerModeAction); !ok { @@ -303,7 +303,7 @@ func (l *LexerCustomAction) execute(lexer Lexer) { lexer.Action(nil, l.ruleIndex, l.actionIndex) } -func (l *LexerCustomAction) hash() int { +func (l *LexerCustomAction) Hash() int { h := murmurInit(0) h = murmurUpdate(h, l.actionType) h = murmurUpdate(h, l.ruleIndex) @@ -311,13 +311,14 @@ func (l *LexerCustomAction) hash() int { return murmurFinish(h, 3) } -func (l *LexerCustomAction) equals(other LexerAction) bool { +func (l *LexerCustomAction) Equals(other LexerAction) bool { if l == other { return true } else if _, ok := other.(*LexerCustomAction); !ok { return false } else { - return l.ruleIndex == other.(*LexerCustomAction).ruleIndex && l.actionIndex == other.(*LexerCustomAction).actionIndex + return l.ruleIndex == other.(*LexerCustomAction).ruleIndex && + l.actionIndex == other.(*LexerCustomAction).actionIndex } } @@ -344,14 +345,14 @@ func (l *LexerChannelAction) execute(lexer Lexer) { lexer.SetChannel(l.channel) } -func (l *LexerChannelAction) hash() int { +func (l *LexerChannelAction) Hash() int { h := murmurInit(0) h = murmurUpdate(h, l.actionType) h = murmurUpdate(h, l.channel) return murmurFinish(h, 2) } -func (l *LexerChannelAction) equals(other LexerAction) bool { +func (l *LexerChannelAction) Equals(other LexerAction) bool { if l == other { return true } else if _, ok := other.(*LexerChannelAction); !ok { @@ -412,10 +413,10 @@ func (l *LexerIndexedCustomAction) execute(lexer Lexer) { l.lexerAction.execute(lexer) } -func (l *LexerIndexedCustomAction) hash() int { +func (l *LexerIndexedCustomAction) Hash() int { h := murmurInit(0) h = murmurUpdate(h, l.offset) - h = murmurUpdate(h, l.lexerAction.hash()) + h = murmurUpdate(h, l.lexerAction.Hash()) return murmurFinish(h, 2) } @@ -425,6 +426,7 @@ func (l *LexerIndexedCustomAction) equals(other LexerAction) bool { } else if _, ok := other.(*LexerIndexedCustomAction); !ok { return false } else { - return l.offset == other.(*LexerIndexedCustomAction).offset && l.lexerAction == other.(*LexerIndexedCustomAction).lexerAction + return l.offset == other.(*LexerIndexedCustomAction).offset && + l.lexerAction.Equals(other.(*LexerIndexedCustomAction).lexerAction) } } diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action_executor.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_action_executor.go similarity index 88% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action_executor.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_action_executor.go index 056941dd6..be1ba7a7e 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action_executor.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_action_executor.go @@ -1,9 +1,11 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. package antlr +import "golang.org/x/exp/slices" + // Represents an executor for a sequence of lexer actions which traversed during // the Matching operation of a lexer rule (token). // @@ -12,8 +14,8 @@ package antlr // not cause bloating of the {@link DFA} created for the lexer.

    type LexerActionExecutor struct { - lexerActions []LexerAction - cachedHash int + lexerActions []LexerAction + cachedHash int } func NewLexerActionExecutor(lexerActions []LexerAction) *LexerActionExecutor { @@ -30,7 +32,7 @@ func NewLexerActionExecutor(lexerActions []LexerAction) *LexerActionExecutor { // of the performance-critical {@link LexerATNConfig//hashCode} operation. l.cachedHash = murmurInit(57) for _, a := range lexerActions { - l.cachedHash = murmurUpdate(l.cachedHash, a.hash()) + l.cachedHash = murmurUpdate(l.cachedHash, a.Hash()) } return l @@ -151,14 +153,17 @@ func (l *LexerActionExecutor) execute(lexer Lexer, input CharStream, startIndex } } -func (l *LexerActionExecutor) hash() int { +func (l *LexerActionExecutor) Hash() int { if l == nil { + // TODO: Why is this here? l should not be nil return 61 } + + // TODO: This is created from the action itself when the struct is created - will this be an issue at some point? Java uses the runtime assign hashcode return l.cachedHash } -func (l *LexerActionExecutor) equals(other interface{}) bool { +func (l *LexerActionExecutor) Equals(other interface{}) bool { if l == other { return true } @@ -169,5 +174,13 @@ func (l *LexerActionExecutor) equals(other interface{}) bool { if othert == nil { return false } - return l.cachedHash == othert.cachedHash && &l.lexerActions == &othert.lexerActions + if l.cachedHash != othert.cachedHash { + return false + } + if len(l.lexerActions) != len(othert.lexerActions) { + return false + } + return slices.EqualFunc(l.lexerActions, othert.lexerActions, func(i, j LexerAction) bool { + return i.Equals(j) + }) } diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_atn_simulator.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_atn_simulator.go similarity index 98% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_atn_simulator.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_atn_simulator.go index dc05153ea..c573b7521 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_atn_simulator.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_atn_simulator.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -591,19 +591,24 @@ func (l *LexerATNSimulator) addDFAState(configs ATNConfigSet, suppressEdge bool) proposed.lexerActionExecutor = firstConfigWithRuleStopState.(*LexerATNConfig).lexerActionExecutor proposed.setPrediction(l.atn.ruleToTokenType[firstConfigWithRuleStopState.GetState().GetRuleIndex()]) } - hash := proposed.hash() dfa := l.decisionToDFA[l.mode] l.atn.stateMu.Lock() defer l.atn.stateMu.Unlock() - existing, ok := dfa.getState(hash) - if ok { + existing, present := dfa.states.Get(proposed) + if present { + + // This state was already present, so just return it. + // proposed = existing } else { - proposed.stateNumber = dfa.numStates() + + // We need to add the new state + // + proposed.stateNumber = dfa.states.Len() configs.SetReadOnly(true) proposed.configs = configs - dfa.setState(hash, proposed) + dfa.states.Put(proposed) } if !suppressEdge { dfa.setS0(proposed) diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/ll1_analyzer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/ll1_analyzer.go similarity index 87% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/ll1_analyzer.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/ll1_analyzer.go index 6ffb37de6..76689615a 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/ll1_analyzer.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/ll1_analyzer.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -14,14 +14,15 @@ func NewLL1Analyzer(atn *ATN) *LL1Analyzer { return la } -//* Special value added to the lookahead sets to indicate that we hit -// a predicate during analysis if {@code seeThruPreds==false}. -/// +// - Special value added to the lookahead sets to indicate that we hit +// a predicate during analysis if {@code seeThruPreds==false}. +// +// / const ( LL1AnalyzerHitPred = TokenInvalidType ) -//* +// * // Calculates the SLL(1) expected lookahead set for each outgoing transition // of an {@link ATNState}. The returned array has one element for each // outgoing transition in {@code s}. If the closure from transition @@ -38,7 +39,7 @@ func (la *LL1Analyzer) getDecisionLookahead(s ATNState) []*IntervalSet { look := make([]*IntervalSet, count) for alt := 0; alt < count; alt++ { look[alt] = NewIntervalSet() - lookBusy := newArray2DHashSet(nil, nil) + lookBusy := NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst) seeThruPreds := false // fail to get lookahead upon pred la.look1(s.GetTransitions()[alt].getTarget(), nil, BasePredictionContextEMPTY, look[alt], lookBusy, NewBitSet(), seeThruPreds, false) // Wipe out lookahead for la alternative if we found nothing @@ -50,7 +51,7 @@ func (la *LL1Analyzer) getDecisionLookahead(s ATNState) []*IntervalSet { return look } -//* +// * // Compute set of tokens that can follow {@code s} in the ATN in the // specified {@code ctx}. // @@ -67,7 +68,7 @@ func (la *LL1Analyzer) getDecisionLookahead(s ATNState) []*IntervalSet { // // @return The set of tokens that can follow {@code s} in the ATN in the // specified {@code ctx}. -/// +// / func (la *LL1Analyzer) Look(s, stopState ATNState, ctx RuleContext) *IntervalSet { r := NewIntervalSet() seeThruPreds := true // ignore preds get all lookahead @@ -75,7 +76,7 @@ func (la *LL1Analyzer) Look(s, stopState ATNState, ctx RuleContext) *IntervalSet if ctx != nil { lookContext = predictionContextFromRuleContext(s.GetATN(), ctx) } - la.look1(s, stopState, lookContext, r, newArray2DHashSet(nil, nil), NewBitSet(), seeThruPreds, true) + la.look1(s, stopState, lookContext, r, NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst), NewBitSet(), seeThruPreds, true) return r } @@ -109,14 +110,14 @@ func (la *LL1Analyzer) Look(s, stopState ATNState, ctx RuleContext) *IntervalSet // outermost context is reached. This parameter has no effect if {@code ctx} // is {@code nil}. -func (la *LL1Analyzer) look2(s, stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy Set, calledRuleStack *BitSet, seeThruPreds, addEOF bool, i int) { +func (la *LL1Analyzer) look2(s, stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy *JStore[ATNConfig, Comparator[ATNConfig]], calledRuleStack *BitSet, seeThruPreds, addEOF bool, i int) { returnState := la.atn.states[ctx.getReturnState(i)] la.look1(returnState, stopState, ctx.GetParent(i), look, lookBusy, calledRuleStack, seeThruPreds, addEOF) } -func (la *LL1Analyzer) look1(s, stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy Set, calledRuleStack *BitSet, seeThruPreds, addEOF bool) { +func (la *LL1Analyzer) look1(s, stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy *JStore[ATNConfig, Comparator[ATNConfig]], calledRuleStack *BitSet, seeThruPreds, addEOF bool) { c := NewBaseATNConfig6(s, 0, ctx) @@ -124,8 +125,11 @@ func (la *LL1Analyzer) look1(s, stopState ATNState, ctx PredictionContext, look return } - lookBusy.Add(c) + _, present := lookBusy.Put(c) + if present { + return + } if s == stopState { if ctx == nil { look.addOne(TokenEpsilon) @@ -198,7 +202,7 @@ func (la *LL1Analyzer) look1(s, stopState ATNState, ctx PredictionContext, look } } -func (la *LL1Analyzer) look3(stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy Set, calledRuleStack *BitSet, seeThruPreds, addEOF bool, t1 *RuleTransition) { +func (la *LL1Analyzer) look3(stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy *JStore[ATNConfig, Comparator[ATNConfig]], calledRuleStack *BitSet, seeThruPreds, addEOF bool, t1 *RuleTransition) { newContext := SingletonBasePredictionContextCreate(ctx, t1.followState.GetStateNumber()) diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser.go similarity index 99% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser.go index 2ab2f5605..d26bf0639 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -91,7 +91,6 @@ func NewBaseParser(input TokenStream) *BaseParser { // bypass alternatives. // // @see ATNDeserializationOptions//isGenerateRuleBypassTransitions() -// var bypassAltsAtnCache = make(map[string]int) // reset the parser's state// @@ -230,7 +229,6 @@ func (p *BaseParser) GetParseListeners() []ParseTreeListener { // @param listener the listener to add // // @panics nilPointerException if {@code} listener is {@code nil} -// func (p *BaseParser) AddParseListener(listener ParseTreeListener) { if listener == nil { panic("listener") @@ -241,13 +239,11 @@ func (p *BaseParser) AddParseListener(listener ParseTreeListener) { p.parseListeners = append(p.parseListeners, listener) } -// // Remove {@code listener} from the list of parse listeners. // //

    If {@code listener} is {@code nil} or has not been added as a parse // listener, p.method does nothing.

    // @param listener the listener to remove -// func (p *BaseParser) RemoveParseListener(listener ParseTreeListener) { if p.parseListeners != nil { @@ -289,11 +285,9 @@ func (p *BaseParser) TriggerEnterRuleEvent() { } } -// // Notify any parse listeners of an exit rule event. // // @see //addParseListener -// func (p *BaseParser) TriggerExitRuleEvent() { if p.parseListeners != nil { // reverse order walk of listeners @@ -330,7 +324,6 @@ func (p *BaseParser) setTokenFactory(factory TokenFactory) { // // @panics UnsupportedOperationException if the current parser does not // implement the {@link //getSerializedATN()} method. -// func (p *BaseParser) GetATNWithBypassAlts() { // TODO @@ -402,7 +395,6 @@ func (p *BaseParser) SetTokenStream(input TokenStream) { // Match needs to return the current input symbol, which gets put // into the label for the associated token ref e.g., x=ID. -// func (p *BaseParser) GetCurrentToken() Token { return p.input.LT(1) } @@ -624,7 +616,6 @@ func (p *BaseParser) IsExpectedToken(symbol int) bool { // respectively. // // @see ATN//getExpectedTokens(int, RuleContext) -// func (p *BaseParser) GetExpectedTokens() *IntervalSet { return p.Interpreter.atn.getExpectedTokens(p.state, p.ctx) } @@ -686,7 +677,7 @@ func (p *BaseParser) GetDFAStrings() string { func (p *BaseParser) DumpDFA() { seenOne := false for _, dfa := range p.Interpreter.decisionToDFA { - if dfa.numStates() > 0 { + if dfa.states.Len() > 0 { if seenOne { fmt.Println() } @@ -703,7 +694,6 @@ func (p *BaseParser) GetSourceName() string { // During a parse is sometimes useful to listen in on the rule entry and exit // events as well as token Matches. p.is for quick and dirty debugging. -// func (p *BaseParser) SetTrace(trace *TraceListener) { if trace == nil { p.RemoveParseListener(p.tracer) diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_atn_simulator.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser_atn_simulator.go similarity index 94% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_atn_simulator.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser_atn_simulator.go index 888d51297..8bcc46a0d 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_atn_simulator.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser_atn_simulator.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -11,11 +11,11 @@ import ( ) var ( - ParserATNSimulatorDebug = false - ParserATNSimulatorListATNDecisions = false - ParserATNSimulatorDFADebug = false - ParserATNSimulatorRetryDebug = false - TurnOffLRLoopEntryBranchOpt = false + ParserATNSimulatorDebug = false + ParserATNSimulatorTraceATNSim = false + ParserATNSimulatorDFADebug = false + ParserATNSimulatorRetryDebug = false + TurnOffLRLoopEntryBranchOpt = false ) type ParserATNSimulator struct { @@ -70,8 +70,8 @@ func (p *ParserATNSimulator) reset() { } func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, outerContext ParserRuleContext) int { - if ParserATNSimulatorDebug || ParserATNSimulatorListATNDecisions { - fmt.Println("AdaptivePredict decision " + strconv.Itoa(decision) + + if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim { + fmt.Println("adaptivePredict decision " + strconv.Itoa(decision) + " exec LA(1)==" + p.getLookaheadName(input) + " line " + strconv.Itoa(input.LT(1).GetLine()) + ":" + strconv.Itoa(input.LT(1).GetColumn())) @@ -111,15 +111,15 @@ func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, ou if s0 == nil { if outerContext == nil { - outerContext = RuleContextEmpty + outerContext = ParserRuleContextEmpty } - if ParserATNSimulatorDebug || ParserATNSimulatorListATNDecisions { + if ParserATNSimulatorDebug { fmt.Println("predictATN decision " + strconv.Itoa(dfa.decision) + " exec LA(1)==" + p.getLookaheadName(input) + ", outerContext=" + outerContext.String(p.parser.GetRuleNames(), nil)) } fullCtx := false - s0Closure := p.computeStartState(dfa.atnStartState, RuleContextEmpty, fullCtx) + s0Closure := p.computeStartState(dfa.atnStartState, ParserRuleContextEmpty, fullCtx) p.atn.stateMu.Lock() if dfa.getPrecedenceDfa() { @@ -174,17 +174,18 @@ func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, ou // Reporting insufficient predicates // cover these cases: -// dead end -// single alt -// single alt + preds -// conflict -// conflict + preds // +// dead end +// single alt +// single alt + preds +// conflict +// conflict + preds func (p *ParserATNSimulator) execATN(dfa *DFA, s0 *DFAState, input TokenStream, startIndex int, outerContext ParserRuleContext) int { - if ParserATNSimulatorDebug || ParserATNSimulatorListATNDecisions { + if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim { fmt.Println("execATN decision " + strconv.Itoa(dfa.decision) + - " exec LA(1)==" + p.getLookaheadName(input) + + ", DFA state " + s0.String() + + ", LA(1)==" + p.getLookaheadName(input) + " line " + strconv.Itoa(input.LT(1).GetLine()) + ":" + strconv.Itoa(input.LT(1).GetColumn())) } @@ -277,8 +278,6 @@ func (p *ParserATNSimulator) execATN(dfa *DFA, s0 *DFAState, input TokenStream, t = input.LA(1) } } - - panic("Should not have reached p state") } // Get an existing target state for an edge in the DFA. If the target state @@ -384,7 +383,7 @@ func (p *ParserATNSimulator) predicateDFAState(dfaState *DFAState, decisionState // comes back with reach.uniqueAlt set to a valid alt func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 ATNConfigSet, input TokenStream, startIndex int, outerContext ParserRuleContext) int { - if ParserATNSimulatorDebug || ParserATNSimulatorListATNDecisions { + if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim { fmt.Println("execATNWithFullContext " + s0.String()) } @@ -492,9 +491,6 @@ func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 AT } func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCtx bool) ATNConfigSet { - if ParserATNSimulatorDebug { - fmt.Println("in computeReachSet, starting closure: " + closure.String()) - } if p.mergeCache == nil { p.mergeCache = NewDoubleDict() } @@ -570,7 +566,7 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt // if reach == nil { reach = NewBaseATNConfigSet(fullCtx) - closureBusy := newArray2DHashSet(nil, nil) + closureBusy := NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst) treatEOFAsEpsilon := t == TokenEOF amount := len(intermediate.configs) for k := 0; k < amount; k++ { @@ -610,6 +606,11 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt reach.Add(skippedStopStates[l], p.mergeCache) } } + + if ParserATNSimulatorTraceATNSim { + fmt.Println("computeReachSet " + closure.String() + " -> " + reach.String()) + } + if len(reach.GetItems()) == 0 { return nil } @@ -617,7 +618,6 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt return reach } -// // Return a configuration set containing only the configurations from // {@code configs} which are in a {@link RuleStopState}. If all // configurations in {@code configs} are already in a rule stop state, p @@ -636,7 +636,6 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt // @return {@code configs} if all configurations in {@code configs} are in a // rule stop state, otherwise return a Newconfiguration set containing only // the configurations from {@code configs} which are in a rule stop state -// func (p *ParserATNSimulator) removeAllConfigsNotInRuleStopState(configs ATNConfigSet, lookToEndOfRule bool) ATNConfigSet { if PredictionModeallConfigsInRuleStopStates(configs) { return configs @@ -662,16 +661,20 @@ func (p *ParserATNSimulator) computeStartState(a ATNState, ctx RuleContext, full // always at least the implicit call to start rule initialContext := predictionContextFromRuleContext(p.atn, ctx) configs := NewBaseATNConfigSet(fullCtx) + if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim { + fmt.Println("computeStartState from ATN state " + a.String() + + " initialContext=" + initialContext.String()) + } + for i := 0; i < len(a.GetTransitions()); i++ { target := a.GetTransitions()[i].getTarget() c := NewBaseATNConfig6(target, i+1, initialContext) - closureBusy := newArray2DHashSet(nil, nil) + closureBusy := NewJStore[ATNConfig, Comparator[ATNConfig]](atnConfCompInst) p.closure(c, configs, closureBusy, true, fullCtx, false) } return configs } -// // This method transforms the start state computed by // {@link //computeStartState} to the special start state used by a // precedence DFA for a particular precedence value. The transformation @@ -726,7 +729,6 @@ func (p *ParserATNSimulator) computeStartState(a ATNState, ctx RuleContext, full // @return The transformed configuration set representing the start state // for a precedence DFA at a particular precedence level (determined by // calling {@link Parser//getPrecedence}). -// func (p *ParserATNSimulator) applyPrecedenceFilter(configs ATNConfigSet) ATNConfigSet { statesFromAlt1 := make(map[int]PredictionContext) @@ -760,7 +762,7 @@ func (p *ParserATNSimulator) applyPrecedenceFilter(configs ATNConfigSet) ATNConf // (basically a graph subtraction algorithm). if !config.getPrecedenceFilterSuppressed() { context := statesFromAlt1[config.GetState().GetStateNumber()] - if context != nil && context.equals(config.GetContext()) { + if context != nil && context.Equals(config.GetContext()) { // eliminated continue } @@ -824,7 +826,6 @@ func (p *ParserATNSimulator) getPredicatePredictions(ambigAlts *BitSet, altToPre return pairs } -// // This method is used to improve the localization of error messages by // choosing an alternative rather than panicing a // {@link NoViableAltException} in particular prediction scenarios where the @@ -869,7 +870,6 @@ func (p *ParserATNSimulator) getPredicatePredictions(ambigAlts *BitSet, altToPre // @return The value to return from {@link //AdaptivePredict}, or // {@link ATN//INVALID_ALT_NUMBER} if a suitable alternative was not // identified and {@link //AdaptivePredict} should Report an error instead. -// func (p *ParserATNSimulator) getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(configs ATNConfigSet, outerContext ParserRuleContext) int { cfgs := p.splitAccordingToSemanticValidity(configs, outerContext) semValidConfigs := cfgs[0] @@ -938,11 +938,11 @@ func (p *ParserATNSimulator) splitAccordingToSemanticValidity(configs ATNConfigS } // Look through a list of predicate/alt pairs, returning alts for the -// pairs that win. A {@code NONE} predicate indicates an alt containing an -// unpredicated config which behaves as "always true." If !complete -// then we stop at the first predicate that evaluates to true. This -// includes pairs with nil predicates. // +// pairs that win. A {@code NONE} predicate indicates an alt containing an +// unpredicated config which behaves as "always true." If !complete +// then we stop at the first predicate that evaluates to true. This +// includes pairs with nil predicates. func (p *ParserATNSimulator) evalSemanticContext(predPredictions []*PredPrediction, outerContext ParserRuleContext, complete bool) *BitSet { predictions := NewBitSet() for i := 0; i < len(predPredictions); i++ { @@ -972,16 +972,16 @@ func (p *ParserATNSimulator) evalSemanticContext(predPredictions []*PredPredicti return predictions } -func (p *ParserATNSimulator) closure(config ATNConfig, configs ATNConfigSet, closureBusy Set, collectPredicates, fullCtx, treatEOFAsEpsilon bool) { +func (p *ParserATNSimulator) closure(config ATNConfig, configs ATNConfigSet, closureBusy *JStore[ATNConfig, Comparator[ATNConfig]], collectPredicates, fullCtx, treatEOFAsEpsilon bool) { initialDepth := 0 p.closureCheckingStopState(config, configs, closureBusy, collectPredicates, fullCtx, initialDepth, treatEOFAsEpsilon) } -func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs ATNConfigSet, closureBusy Set, collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) { - if ParserATNSimulatorDebug { +func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs ATNConfigSet, closureBusy *JStore[ATNConfig, Comparator[ATNConfig]], collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) { + if ParserATNSimulatorTraceATNSim { fmt.Println("closure(" + config.String() + ")") - fmt.Println("configs(" + configs.String() + ")") + //fmt.Println("configs(" + configs.String() + ")") if config.GetReachesIntoOuterContext() > 50 { panic("problem") } @@ -1031,7 +1031,7 @@ func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs } // Do the actual work of walking epsilon edges// -func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, closureBusy Set, collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) { +func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, closureBusy *JStore[ATNConfig, Comparator[ATNConfig]], collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) { state := config.GetState() // optimization if !state.GetEpsilonOnlyTransitions() { @@ -1066,7 +1066,8 @@ func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, c.SetReachesIntoOuterContext(c.GetReachesIntoOuterContext() + 1) - if closureBusy.Add(c) != c { + _, present := closureBusy.Put(c) + if present { // avoid infinite recursion for right-recursive rules continue } @@ -1077,9 +1078,13 @@ func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, fmt.Println("dips into outer ctx: " + c.String()) } } else { - if !t.getIsEpsilon() && closureBusy.Add(c) != c { - // avoid infinite recursion for EOF* and EOF+ - continue + + if !t.getIsEpsilon() { + _, present := closureBusy.Put(c) + if present { + // avoid infinite recursion for EOF* and EOF+ + continue + } } if _, ok := t.(*RuleTransition); ok { // latch when newDepth goes negative - once we step out of the entry context we can't return @@ -1104,7 +1109,16 @@ func (p *ParserATNSimulator) canDropLoopEntryEdgeInLeftRecursiveRule(config ATNC // left-recursion elimination. For efficiency, also check if // the context has an empty stack case. If so, it would mean // global FOLLOW so we can't perform optimization - if startLoop, ok := _p.(StarLoopEntryState); !ok || !startLoop.precedenceRuleDecision || config.GetContext().isEmpty() || config.GetContext().hasEmptyPath() { + if _p.GetStateType() != ATNStateStarLoopEntry { + return false + } + startLoop, ok := _p.(*StarLoopEntryState) + if !ok { + return false + } + if !startLoop.precedenceRuleDecision || + config.GetContext().isEmpty() || + config.GetContext().hasEmptyPath() { return false } @@ -1117,8 +1131,8 @@ func (p *ParserATNSimulator) canDropLoopEntryEdgeInLeftRecursiveRule(config ATNC return false } } - - decisionStartState := _p.(BlockStartState).GetTransitions()[0].getTarget().(BlockStartState) + x := _p.GetTransitions()[0].getTarget() + decisionStartState := x.(BlockStartState) blockEndStateNum := decisionStartState.getEndState().stateNumber blockEndState := p.atn.states[blockEndStateNum].(*BlockEndState) @@ -1355,13 +1369,12 @@ func (p *ParserATNSimulator) GetTokenName(t int) string { return "EOF" } - if p.parser != nil && p.parser.GetLiteralNames() != nil { - if t >= len(p.parser.GetLiteralNames()) { - fmt.Println(strconv.Itoa(t) + " ttype out of range: " + strings.Join(p.parser.GetLiteralNames(), ",")) - // fmt.Println(p.parser.GetInputStream().(TokenStream).GetAllText()) // p seems incorrect - } else { - return p.parser.GetLiteralNames()[t] + "<" + strconv.Itoa(t) + ">" - } + if p.parser != nil && p.parser.GetLiteralNames() != nil && t < len(p.parser.GetLiteralNames()) { + return p.parser.GetLiteralNames()[t] + "<" + strconv.Itoa(t) + ">" + } + + if p.parser != nil && p.parser.GetLiteralNames() != nil && t < len(p.parser.GetSymbolicNames()) { + return p.parser.GetSymbolicNames()[t] + "<" + strconv.Itoa(t) + ">" } return strconv.Itoa(t) @@ -1372,9 +1385,9 @@ func (p *ParserATNSimulator) getLookaheadName(input TokenStream) string { } // Used for debugging in AdaptivePredict around execATN but I cut -// it out for clarity now that alg. works well. We can leave p -// "dead" code for a bit. // +// it out for clarity now that alg. works well. We can leave p +// "dead" code for a bit. func (p *ParserATNSimulator) dumpDeadEndConfigs(nvae *NoViableAltException) { panic("Not implemented") @@ -1421,7 +1434,6 @@ func (p *ParserATNSimulator) getUniqueAlt(configs ATNConfigSet) int { return alt } -// // Add an edge to the DFA, if possible. This method calls // {@link //addDFAState} to ensure the {@code to} state is present in the // DFA. If {@code from} is {@code nil}, or if {@code t} is outside the @@ -1440,7 +1452,6 @@ func (p *ParserATNSimulator) getUniqueAlt(configs ATNConfigSet) int { // @return If {@code to} is {@code nil}, p method returns {@code nil} // otherwise p method returns the result of calling {@link //addDFAState} // on {@code to} -// func (p *ParserATNSimulator) addDFAEdge(dfa *DFA, from *DFAState, t int, to *DFAState) *DFAState { if ParserATNSimulatorDebug { fmt.Println("EDGE " + from.String() + " -> " + to.String() + " upon " + p.GetTokenName(t)) @@ -1472,7 +1483,6 @@ func (p *ParserATNSimulator) addDFAEdge(dfa *DFA, from *DFAState, t int, to *DFA return to } -// // Add state {@code D} to the DFA if it is not already present, and return // the actual instance stored in the DFA. If a state equivalent to {@code D} // is already in the DFA, the existing state is returned. Otherwise p @@ -1486,25 +1496,30 @@ func (p *ParserATNSimulator) addDFAEdge(dfa *DFA, from *DFAState, t int, to *DFA // @return The state stored in the DFA. This will be either the existing // state if {@code D} is already in the DFA, or {@code D} itself if the // state was not already present. -// func (p *ParserATNSimulator) addDFAState(dfa *DFA, d *DFAState) *DFAState { if d == ATNSimulatorError { return d } - hash := d.hash() - existing, ok := dfa.getState(hash) - if ok { + existing, present := dfa.states.Get(d) + if present { + if ParserATNSimulatorTraceATNSim { + fmt.Print("addDFAState " + d.String() + " exists") + } return existing } - d.stateNumber = dfa.numStates() + + // The state was not present, so update it with configs + // + d.stateNumber = dfa.states.Len() if !d.configs.ReadOnly() { d.configs.OptimizeConfigs(p.BaseATNSimulator) d.configs.SetReadOnly(true) } - dfa.setState(hash, d) - if ParserATNSimulatorDebug { - fmt.Println("adding NewDFA state: " + d.String()) + dfa.states.Put(d) + if ParserATNSimulatorTraceATNSim { + fmt.Println("addDFAState new " + d.String()) } + return d } diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_rule_context.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser_rule_context.go similarity index 98% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_rule_context.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser_rule_context.go index 49cd10c5f..1c8cee747 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_rule_context.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser_rule_context.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -340,7 +340,7 @@ func (prc *BaseParserRuleContext) String(ruleNames []string, stop RuleContext) s return s } -var RuleContextEmpty = NewBaseParserRuleContext(nil, -1) +var ParserRuleContextEmpty = NewBaseParserRuleContext(nil, -1) type InterpreterRuleContext interface { ParserRuleContext diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_context.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/prediction_context.go similarity index 81% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_context.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/prediction_context.go index 9fdfd52b2..ba62af361 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_context.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/prediction_context.go @@ -1,10 +1,12 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. package antlr import ( + "fmt" + "golang.org/x/exp/slices" "strconv" ) @@ -26,10 +28,10 @@ var ( ) type PredictionContext interface { - hash() int + Hash() int + Equals(interface{}) bool GetParent(int) PredictionContext getReturnState(int) int - equals(PredictionContext) bool length() int isEmpty() bool hasEmptyPath() bool @@ -53,7 +55,7 @@ func (b *BasePredictionContext) isEmpty() bool { func calculateHash(parent PredictionContext, returnState int) int { h := murmurInit(1) - h = murmurUpdate(h, parent.hash()) + h = murmurUpdate(h, parent.Hash()) h = murmurUpdate(h, returnState) return murmurFinish(h, 2) } @@ -86,7 +88,6 @@ func NewPredictionContextCache() *PredictionContextCache { // Add a context to the cache and return it. If the context already exists, // return that one instead and do not add a Newcontext to the cache. // Protect shared cache from unsafe thread access. -// func (p *PredictionContextCache) add(ctx PredictionContext) PredictionContext { if ctx == BasePredictionContextEMPTY { return BasePredictionContextEMPTY @@ -160,28 +161,28 @@ func (b *BaseSingletonPredictionContext) hasEmptyPath() bool { return b.returnState == BasePredictionContextEmptyReturnState } -func (b *BaseSingletonPredictionContext) equals(other PredictionContext) bool { +func (b *BaseSingletonPredictionContext) Hash() int { + return b.cachedHash +} + +func (b *BaseSingletonPredictionContext) Equals(other interface{}) bool { if b == other { return true - } else if _, ok := other.(*BaseSingletonPredictionContext); !ok { + } + if _, ok := other.(*BaseSingletonPredictionContext); !ok { return false - } else if b.hash() != other.hash() { - return false // can't be same if hash is different } otherP := other.(*BaseSingletonPredictionContext) - if b.returnState != other.getReturnState(0) { + if b.returnState != otherP.getReturnState(0) { return false - } else if b.parentCtx == nil { + } + if b.parentCtx == nil { return otherP.parentCtx == nil } - return b.parentCtx.equals(otherP.parentCtx) -} - -func (b *BaseSingletonPredictionContext) hash() int { - return b.cachedHash + return b.parentCtx.Equals(otherP.parentCtx) } func (b *BaseSingletonPredictionContext) String() string { @@ -215,7 +216,7 @@ func NewEmptyPredictionContext() *EmptyPredictionContext { p := new(EmptyPredictionContext) p.BaseSingletonPredictionContext = NewBaseSingletonPredictionContext(nil, BasePredictionContextEmptyReturnState) - + p.cachedHash = calculateEmptyHash() return p } @@ -231,7 +232,11 @@ func (e *EmptyPredictionContext) getReturnState(index int) int { return e.returnState } -func (e *EmptyPredictionContext) equals(other PredictionContext) bool { +func (e *EmptyPredictionContext) Hash() int { + return e.cachedHash +} + +func (e *EmptyPredictionContext) Equals(other interface{}) bool { return e == other } @@ -254,7 +259,7 @@ func NewArrayPredictionContext(parents []PredictionContext, returnStates []int) hash := murmurInit(1) for _, parent := range parents { - hash = murmurUpdate(hash, parent.hash()) + hash = murmurUpdate(hash, parent.Hash()) } for _, returnState := range returnStates { @@ -298,18 +303,31 @@ func (a *ArrayPredictionContext) getReturnState(index int) int { return a.returnStates[index] } -func (a *ArrayPredictionContext) equals(other PredictionContext) bool { - if _, ok := other.(*ArrayPredictionContext); !ok { +// Equals is the default comparison function for ArrayPredictionContext when no specialized +// implementation is needed for a collection +func (a *ArrayPredictionContext) Equals(o interface{}) bool { + if a == o { + return true + } + other, ok := o.(*ArrayPredictionContext) + if !ok { return false - } else if a.cachedHash != other.hash() { + } + if a.cachedHash != other.Hash() { return false // can't be same if hash is different - } else { - otherP := other.(*ArrayPredictionContext) - return &a.returnStates == &otherP.returnStates && &a.parents == &otherP.parents } + + // Must compare the actual array elements and not just the array address + // + return slices.Equal(a.returnStates, other.returnStates) && + slices.EqualFunc(a.parents, other.parents, func(x, y PredictionContext) bool { + return x.Equals(y) + }) } -func (a *ArrayPredictionContext) hash() int { +// Hash is the default hash function for ArrayPredictionContext when no specialized +// implementation is needed for a collection +func (a *ArrayPredictionContext) Hash() int { return a.BasePredictionContext.cachedHash } @@ -343,11 +361,11 @@ func (a *ArrayPredictionContext) String() string { // / func predictionContextFromRuleContext(a *ATN, outerContext RuleContext) PredictionContext { if outerContext == nil { - outerContext = RuleContextEmpty + outerContext = ParserRuleContextEmpty } // if we are in RuleContext of start rule, s, then BasePredictionContext // is EMPTY. Nobody called us. (if we are empty, return empty) - if outerContext.GetParent() == nil || outerContext == RuleContextEmpty { + if outerContext.GetParent() == nil || outerContext == ParserRuleContextEmpty { return BasePredictionContextEMPTY } // If we have a parent, convert it to a BasePredictionContext graph @@ -359,11 +377,20 @@ func predictionContextFromRuleContext(a *ATN, outerContext RuleContext) Predicti } func merge(a, b PredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) PredictionContext { - // share same graph if both same - if a == b { + + // Share same graph if both same + // + if a == b || a.Equals(b) { return a } + // In Java, EmptyPredictionContext inherits from SingletonPredictionContext, and so the test + // in java for SingletonPredictionContext will succeed and a new ArrayPredictionContext will be created + // from it. + // In go, EmptyPredictionContext does not equate to SingletonPredictionContext and so that conversion + // will fail. We need to test for both Empty and Singleton and create an ArrayPredictionContext from + // either of them. + ac, ok1 := a.(*BaseSingletonPredictionContext) bc, ok2 := b.(*BaseSingletonPredictionContext) @@ -380,17 +407,32 @@ func merge(a, b PredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) return b } } - // convert singleton so both are arrays to normalize - if _, ok := a.(*BaseSingletonPredictionContext); ok { - a = NewArrayPredictionContext([]PredictionContext{a.GetParent(0)}, []int{a.getReturnState(0)}) + + // Convert Singleton or Empty so both are arrays to normalize - We should not use the existing parameters + // here. + // + // TODO: I think that maybe the Prediction Context structs should be redone as there is a chance we will see this mess again - maybe redo the logic here + + var arp, arb *ArrayPredictionContext + var ok bool + if arp, ok = a.(*ArrayPredictionContext); ok { + } else if _, ok = a.(*BaseSingletonPredictionContext); ok { + arp = NewArrayPredictionContext([]PredictionContext{a.GetParent(0)}, []int{a.getReturnState(0)}) + } else if _, ok = a.(*EmptyPredictionContext); ok { + arp = NewArrayPredictionContext([]PredictionContext{}, []int{}) } - if _, ok := b.(*BaseSingletonPredictionContext); ok { - b = NewArrayPredictionContext([]PredictionContext{b.GetParent(0)}, []int{b.getReturnState(0)}) + + if arb, ok = b.(*ArrayPredictionContext); ok { + } else if _, ok = b.(*BaseSingletonPredictionContext); ok { + arb = NewArrayPredictionContext([]PredictionContext{b.GetParent(0)}, []int{b.getReturnState(0)}) + } else if _, ok = b.(*EmptyPredictionContext); ok { + arb = NewArrayPredictionContext([]PredictionContext{}, []int{}) } - return mergeArrays(a.(*ArrayPredictionContext), b.(*ArrayPredictionContext), rootIsWildcard, mergeCache) + + // Both arp and arb + return mergeArrays(arp, arb, rootIsWildcard, mergeCache) } -// // Merge two {@link SingletonBasePredictionContext} instances. // //

    Stack tops equal, parents merge is same return left graph.
    @@ -423,11 +465,11 @@ func merge(a, b PredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) // / func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) PredictionContext { if mergeCache != nil { - previous := mergeCache.Get(a.hash(), b.hash()) + previous := mergeCache.Get(a.Hash(), b.Hash()) if previous != nil { return previous.(PredictionContext) } - previous = mergeCache.Get(b.hash(), a.hash()) + previous = mergeCache.Get(b.Hash(), a.Hash()) if previous != nil { return previous.(PredictionContext) } @@ -436,7 +478,7 @@ func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool, rootMerge := mergeRoot(a, b, rootIsWildcard) if rootMerge != nil { if mergeCache != nil { - mergeCache.set(a.hash(), b.hash(), rootMerge) + mergeCache.set(a.Hash(), b.Hash(), rootMerge) } return rootMerge } @@ -456,7 +498,7 @@ func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool, // Newjoined parent so create Newsingleton pointing to it, a' spc := SingletonBasePredictionContextCreate(parent, a.returnState) if mergeCache != nil { - mergeCache.set(a.hash(), b.hash(), spc) + mergeCache.set(a.Hash(), b.Hash(), spc) } return spc } @@ -478,7 +520,7 @@ func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool, parents := []PredictionContext{singleParent, singleParent} apc := NewArrayPredictionContext(parents, payloads) if mergeCache != nil { - mergeCache.set(a.hash(), b.hash(), apc) + mergeCache.set(a.Hash(), b.Hash(), apc) } return apc } @@ -494,12 +536,11 @@ func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool, } apc := NewArrayPredictionContext(parents, payloads) if mergeCache != nil { - mergeCache.set(a.hash(), b.hash(), apc) + mergeCache.set(a.Hash(), b.Hash(), apc) } return apc } -// // Handle case where at least one of {@code a} or {@code b} is // {@link //EMPTY}. In the following diagrams, the symbol {@code $} is used // to represent {@link //EMPTY}. @@ -561,7 +602,6 @@ func mergeRoot(a, b SingletonPredictionContext, rootIsWildcard bool) PredictionC return nil } -// // Merge two {@link ArrayBasePredictionContext} instances. // //

    Different tops, different parents.
    @@ -583,12 +623,18 @@ func mergeRoot(a, b SingletonPredictionContext, rootIsWildcard bool) PredictionC // / func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) PredictionContext { if mergeCache != nil { - previous := mergeCache.Get(a.hash(), b.hash()) + previous := mergeCache.Get(a.Hash(), b.Hash()) if previous != nil { + if ParserATNSimulatorTraceATNSim { + fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> previous") + } return previous.(PredictionContext) } - previous = mergeCache.Get(b.hash(), a.hash()) + previous = mergeCache.Get(b.Hash(), a.Hash()) if previous != nil { + if ParserATNSimulatorTraceATNSim { + fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> previous") + } return previous.(PredictionContext) } } @@ -608,7 +654,7 @@ func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache * payload := a.returnStates[i] // $+$ = $ bothDollars := payload == BasePredictionContextEmptyReturnState && aParent == nil && bParent == nil - axAX := (aParent != nil && bParent != nil && aParent == bParent) // ax+ax + axAX := aParent != nil && bParent != nil && aParent == bParent // ax+ax // -> // ax if bothDollars || axAX { @@ -651,7 +697,7 @@ func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache * if k == 1 { // for just one merged element, return singleton top pc := SingletonBasePredictionContextCreate(mergedParents[0], mergedReturnStates[0]) if mergeCache != nil { - mergeCache.set(a.hash(), b.hash(), pc) + mergeCache.set(a.Hash(), b.Hash(), pc) } return pc } @@ -663,27 +709,36 @@ func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache * // if we created same array as a or b, return that instead // TODO: track whether this is possible above during merge sort for speed + // TODO: In go, I do not think we can just do M == xx as M is a brand new allocation. This could be causing allocation problems if M == a { if mergeCache != nil { - mergeCache.set(a.hash(), b.hash(), a) + mergeCache.set(a.Hash(), b.Hash(), a) + } + if ParserATNSimulatorTraceATNSim { + fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> a") } return a } if M == b { if mergeCache != nil { - mergeCache.set(a.hash(), b.hash(), b) + mergeCache.set(a.Hash(), b.Hash(), b) + } + if ParserATNSimulatorTraceATNSim { + fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> b") } return b } combineCommonParents(mergedParents) if mergeCache != nil { - mergeCache.set(a.hash(), b.hash(), M) + mergeCache.set(a.Hash(), b.Hash(), M) + } + if ParserATNSimulatorTraceATNSim { + fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> " + M.String()) } return M } -// // Make pass over all M {@code parents} merge any {@code equals()} // ones. // / diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_mode.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/prediction_mode.go similarity index 95% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_mode.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/prediction_mode.go index 15718f912..7b9b72fab 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_mode.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/prediction_mode.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -70,7 +70,6 @@ const ( PredictionModeLLExactAmbigDetection = 2 ) -// // Computes the SLL prediction termination condition. // //

    @@ -108,9 +107,9 @@ const ( // The single-alt-state thing lets prediction continue upon rules like // (otherwise, it would admit defeat too soon):

    // -//

    {@code [12|1|[], 6|2|[], 12|2|[]]. s : (ID | ID ID?) '' }

    +//

    {@code [12|1|[], 6|2|[], 12|2|[]]. s : (ID | ID ID?) ” }

    // -//

    When the ATN simulation reaches the state before {@code ''}, it has a +//

    When the ATN simulation reaches the state before {@code ”}, it has a // DFA state that looks like: {@code [12|1|[], 6|2|[], 12|2|[]]}. Naturally // {@code 12|1|[]} and {@code 12|2|[]} conflict, but we cannot stop // processing this node because alternative to has another way to continue, @@ -152,16 +151,15 @@ const ( // //

    Before testing these configurations against others, we have to merge // {@code x} and {@code x'} (without modifying the existing configurations). -// For example, we test {@code (x+x')==x''} when looking for conflicts in +// For example, we test {@code (x+x')==x”} when looking for conflicts in // the following configurations.

    // -//

    {@code (s, 1, x, {}), (s, 1, x', {p}), (s, 2, x'', {})}

    +//

    {@code (s, 1, x, {}), (s, 1, x', {p}), (s, 2, x”, {})}

    // //

    If the configuration set has predicates (as indicated by // {@link ATNConfigSet//hasSemanticContext}), this algorithm makes a copy of // the configurations to strip out all of the predicates so that a standard // {@link ATNConfigSet} will merge everything ignoring predicates.

    -// func PredictionModehasSLLConflictTerminatingPrediction(mode int, configs ATNConfigSet) bool { // Configs in rule stop states indicate reaching the end of the decision // rule (local context) or end of start rule (full context). If all @@ -229,7 +227,6 @@ func PredictionModeallConfigsInRuleStopStates(configs ATNConfigSet) bool { return true } -// // Full LL prediction termination. // //

    Can we stop looking ahead during ATN simulation or is there some @@ -334,7 +331,7 @@ func PredictionModeallConfigsInRuleStopStates(configs ATNConfigSet) bool { // // //

  • {@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 1, y)}, -// {@code (s', 2, y)}, {@code (s'', 1, z)} yields non-conflicting set +// {@code (s', 2, y)}, {@code (s”, 1, z)} yields non-conflicting set // {@code {1}} U conflicting sets {@code min({1,2})} U {@code min({1,2})} = // {@code {1}} => stop and predict 1
  • // @@ -369,31 +366,26 @@ func PredictionModeallConfigsInRuleStopStates(configs ATNConfigSet) bool { // two or one and three so we keep going. We can only stop prediction when // we need exact ambiguity detection when the sets look like // {@code A={{1,2}}} or {@code {{1,2},{1,2}}}, etc...

    -// func PredictionModeresolvesToJustOneViableAlt(altsets []*BitSet) int { return PredictionModegetSingleViableAlt(altsets) } -// // Determines if every alternative subset in {@code altsets} contains more // than one alternative. // // @param altsets a collection of alternative subsets // @return {@code true} if every {@link BitSet} in {@code altsets} has // {@link BitSet//cardinality cardinality} > 1, otherwise {@code false} -// func PredictionModeallSubsetsConflict(altsets []*BitSet) bool { return !PredictionModehasNonConflictingAltSet(altsets) } -// // Determines if any single alternative subset in {@code altsets} contains // exactly one alternative. // // @param altsets a collection of alternative subsets // @return {@code true} if {@code altsets} contains a {@link BitSet} with // {@link BitSet//cardinality cardinality} 1, otherwise {@code false} -// func PredictionModehasNonConflictingAltSet(altsets []*BitSet) bool { for i := 0; i < len(altsets); i++ { alts := altsets[i] @@ -404,14 +396,12 @@ func PredictionModehasNonConflictingAltSet(altsets []*BitSet) bool { return false } -// // Determines if any single alternative subset in {@code altsets} contains // more than one alternative. // // @param altsets a collection of alternative subsets // @return {@code true} if {@code altsets} contains a {@link BitSet} with // {@link BitSet//cardinality cardinality} > 1, otherwise {@code false} -// func PredictionModehasConflictingAltSet(altsets []*BitSet) bool { for i := 0; i < len(altsets); i++ { alts := altsets[i] @@ -422,13 +412,11 @@ func PredictionModehasConflictingAltSet(altsets []*BitSet) bool { return false } -// // Determines if every alternative subset in {@code altsets} is equivalent. // // @param altsets a collection of alternative subsets // @return {@code true} if every member of {@code altsets} is equal to the // others, otherwise {@code false} -// func PredictionModeallSubsetsEqual(altsets []*BitSet) bool { var first *BitSet @@ -444,13 +432,11 @@ func PredictionModeallSubsetsEqual(altsets []*BitSet) bool { return true } -// // Returns the unique alternative predicted by all alternative subsets in // {@code altsets}. If no such alternative exists, this method returns // {@link ATN//INVALID_ALT_NUMBER}. // // @param altsets a collection of alternative subsets -// func PredictionModegetUniqueAlt(altsets []*BitSet) int { all := PredictionModeGetAlts(altsets) if all.length() == 1 { @@ -466,7 +452,6 @@ func PredictionModegetUniqueAlt(altsets []*BitSet) int { // // @param altsets a collection of alternative subsets // @return the set of represented alternatives in {@code altsets} -// func PredictionModeGetAlts(altsets []*BitSet) *BitSet { all := NewBitSet() for _, alts := range altsets { @@ -475,44 +460,35 @@ func PredictionModeGetAlts(altsets []*BitSet) *BitSet { return all } -// -// This func gets the conflicting alt subsets from a configuration set. +// PredictionModegetConflictingAltSubsets gets the conflicting alt subsets from a configuration set. // For each configuration {@code c} in {@code configs}: // //
     // map[c] U= c.{@link ATNConfig//alt alt} // map hash/equals uses s and x, not
     // alt and not pred
     // 
    -// func PredictionModegetConflictingAltSubsets(configs ATNConfigSet) []*BitSet { - configToAlts := make(map[int]*BitSet) + configToAlts := NewJMap[ATNConfig, *BitSet, *ATNAltConfigComparator[ATNConfig]](atnAltCfgEqInst) for _, c := range configs.GetItems() { - key := 31 * c.GetState().GetStateNumber() + c.GetContext().hash() - alts, ok := configToAlts[key] + alts, ok := configToAlts.Get(c) if !ok { alts = NewBitSet() - configToAlts[key] = alts + configToAlts.Put(c, alts) } alts.add(c.GetAlt()) } - values := make([]*BitSet, 0, 10) - for _, v := range configToAlts { - values = append(values, v) - } - return values + return configToAlts.Values() } -// -// Get a map from state to alt subset from a configuration set. For each +// PredictionModeGetStateToAltMap gets a map from state to alt subset from a configuration set. For each // configuration {@code c} in {@code configs}: // //
     // map[c.{@link ATNConfig//state state}] U= c.{@link ATNConfig//alt alt}
     // 
    -// func PredictionModeGetStateToAltMap(configs ATNConfigSet) *AltDict { m := NewAltDict() diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/recognizer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/recognizer.go similarity index 92% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/recognizer.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/recognizer.go index 93efcf355..bfe542d09 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/recognizer.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/recognizer.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -49,7 +49,7 @@ var tokenTypeMapCache = make(map[string]int) var ruleIndexMapCache = make(map[string]int) func (b *BaseRecognizer) checkVersion(toolVersion string) { - runtimeVersion := "4.10.1" + runtimeVersion := "4.12.0" if runtimeVersion != toolVersion { fmt.Println("ANTLR runtime and generated code versions disagree: " + runtimeVersion + "!=" + toolVersion) } @@ -108,7 +108,6 @@ func (b *BaseRecognizer) SetState(v int) { // Get a map from rule names to rule indexes. // //

    Used for XPath and tree pattern compilation.

    -// func (b *BaseRecognizer) GetRuleIndexMap() map[string]int { panic("Method not defined!") @@ -171,18 +170,18 @@ func (b *BaseRecognizer) GetErrorHeader(e RecognitionException) string { } // How should a token be displayed in an error message? The default -// is to display just the text, but during development you might -// want to have a lot of information spit out. Override in that case -// to use t.String() (which, for CommonToken, dumps everything about -// the token). This is better than forcing you to override a method in -// your token objects because you don't have to go modify your lexer -// so that it creates a NewJava type. +// +// is to display just the text, but during development you might +// want to have a lot of information spit out. Override in that case +// to use t.String() (which, for CommonToken, dumps everything about +// the token). This is better than forcing you to override a method in +// your token objects because you don't have to go modify your lexer +// so that it creates a NewJava type. // // @deprecated This method is not called by the ANTLR 4 Runtime. Specific // implementations of {@link ANTLRErrorStrategy} may provide a similar // feature when necessary. For example, see // {@link DefaultErrorStrategy//GetTokenErrorDisplay}. -// func (b *BaseRecognizer) GetTokenErrorDisplay(t Token) string { if t == nil { return "" diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/rule_context.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/rule_context.go similarity index 97% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/rule_context.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/rule_context.go index 600cf8c06..210699ba2 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/rule_context.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/rule_context.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/semantic_context.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/semantic_context.go similarity index 85% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/semantic_context.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/semantic_context.go index 9ada43077..a702e99de 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/semantic_context.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/semantic_context.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -18,12 +18,12 @@ import ( // type SemanticContext interface { - comparable + Equals(other Collectable[SemanticContext]) bool + Hash() int evaluate(parser Recognizer, outerContext RuleContext) bool evalPrecedence(parser Recognizer, outerContext RuleContext) SemanticContext - hash() int String() string } @@ -78,7 +78,7 @@ func NewPredicate(ruleIndex, predIndex int, isCtxDependent bool) *Predicate { //The default {@link SemanticContext}, which is semantically equivalent to //a predicate of the form {@code {true}?}. -var SemanticContextNone SemanticContext = NewPredicate(-1, -1, false) +var SemanticContextNone = NewPredicate(-1, -1, false) func (p *Predicate) evalPrecedence(parser Recognizer, outerContext RuleContext) SemanticContext { return p @@ -95,7 +95,7 @@ func (p *Predicate) evaluate(parser Recognizer, outerContext RuleContext) bool { return parser.Sempred(localctx, p.ruleIndex, p.predIndex) } -func (p *Predicate) equals(other interface{}) bool { +func (p *Predicate) Equals(other Collectable[SemanticContext]) bool { if p == other { return true } else if _, ok := other.(*Predicate); !ok { @@ -107,7 +107,7 @@ func (p *Predicate) equals(other interface{}) bool { } } -func (p *Predicate) hash() int { +func (p *Predicate) Hash() int { h := murmurInit(0) h = murmurUpdate(h, p.ruleIndex) h = murmurUpdate(h, p.predIndex) @@ -151,17 +151,22 @@ func (p *PrecedencePredicate) compareTo(other *PrecedencePredicate) int { return p.precedence - other.precedence } -func (p *PrecedencePredicate) equals(other interface{}) bool { - if p == other { - return true - } else if _, ok := other.(*PrecedencePredicate); !ok { +func (p *PrecedencePredicate) Equals(other Collectable[SemanticContext]) bool { + + var op *PrecedencePredicate + var ok bool + if op, ok = other.(*PrecedencePredicate); !ok { return false - } else { - return p.precedence == other.(*PrecedencePredicate).precedence } + + if p == op { + return true + } + + return p.precedence == other.(*PrecedencePredicate).precedence } -func (p *PrecedencePredicate) hash() int { +func (p *PrecedencePredicate) Hash() int { h := uint32(1) h = 31*h + uint32(p.precedence) return int(h) @@ -171,10 +176,10 @@ func (p *PrecedencePredicate) String() string { return "{" + strconv.Itoa(p.precedence) + ">=prec}?" } -func PrecedencePredicatefilterPrecedencePredicates(set Set) []*PrecedencePredicate { +func PrecedencePredicatefilterPrecedencePredicates(set *JStore[SemanticContext, Comparator[SemanticContext]]) []*PrecedencePredicate { result := make([]*PrecedencePredicate, 0) - set.Each(func(v interface{}) bool { + set.Each(func(v SemanticContext) bool { if c2, ok := v.(*PrecedencePredicate); ok { result = append(result, c2) } @@ -193,21 +198,21 @@ type AND struct { func NewAND(a, b SemanticContext) *AND { - operands := newArray2DHashSet(nil, nil) + operands := NewJStore[SemanticContext, Comparator[SemanticContext]](semctxEqInst) if aa, ok := a.(*AND); ok { for _, o := range aa.opnds { - operands.Add(o) + operands.Put(o) } } else { - operands.Add(a) + operands.Put(a) } if ba, ok := b.(*AND); ok { for _, o := range ba.opnds { - operands.Add(o) + operands.Put(o) } } else { - operands.Add(b) + operands.Put(b) } precedencePredicates := PrecedencePredicatefilterPrecedencePredicates(operands) if len(precedencePredicates) > 0 { @@ -220,7 +225,7 @@ func NewAND(a, b SemanticContext) *AND { } } - operands.Add(reduced) + operands.Put(reduced) } vs := operands.Values() @@ -235,14 +240,15 @@ func NewAND(a, b SemanticContext) *AND { return and } -func (a *AND) equals(other interface{}) bool { +func (a *AND) Equals(other Collectable[SemanticContext]) bool { if a == other { return true - } else if _, ok := other.(*AND); !ok { + } + if _, ok := other.(*AND); !ok { return false } else { for i, v := range other.(*AND).opnds { - if !a.opnds[i].equals(v) { + if !a.opnds[i].Equals(v) { return false } } @@ -250,13 +256,11 @@ func (a *AND) equals(other interface{}) bool { } } -// // {@inheritDoc} // //

    // The evaluation of predicates by a context is short-circuiting, but // unordered.

    -// func (a *AND) evaluate(parser Recognizer, outerContext RuleContext) bool { for i := 0; i < len(a.opnds); i++ { if !a.opnds[i].evaluate(parser, outerContext) { @@ -304,18 +308,18 @@ func (a *AND) evalPrecedence(parser Recognizer, outerContext RuleContext) Semant return result } -func (a *AND) hash() int { +func (a *AND) Hash() int { h := murmurInit(37) // Init with a value different from OR for _, op := range a.opnds { - h = murmurUpdate(h, op.hash()) + h = murmurUpdate(h, op.Hash()) } return murmurFinish(h, len(a.opnds)) } -func (a *OR) hash() int { +func (a *OR) Hash() int { h := murmurInit(41) // Init with a value different from AND for _, op := range a.opnds { - h = murmurUpdate(h, op.hash()) + h = murmurUpdate(h, op.Hash()) } return murmurFinish(h, len(a.opnds)) } @@ -345,21 +349,21 @@ type OR struct { func NewOR(a, b SemanticContext) *OR { - operands := newArray2DHashSet(nil, nil) + operands := NewJStore[SemanticContext, Comparator[SemanticContext]](semctxEqInst) if aa, ok := a.(*OR); ok { for _, o := range aa.opnds { - operands.Add(o) + operands.Put(o) } } else { - operands.Add(a) + operands.Put(a) } if ba, ok := b.(*OR); ok { for _, o := range ba.opnds { - operands.Add(o) + operands.Put(o) } } else { - operands.Add(b) + operands.Put(b) } precedencePredicates := PrecedencePredicatefilterPrecedencePredicates(operands) if len(precedencePredicates) > 0 { @@ -372,7 +376,7 @@ func NewOR(a, b SemanticContext) *OR { } } - operands.Add(reduced) + operands.Put(reduced) } vs := operands.Values() @@ -388,14 +392,14 @@ func NewOR(a, b SemanticContext) *OR { return o } -func (o *OR) equals(other interface{}) bool { +func (o *OR) Equals(other Collectable[SemanticContext]) bool { if o == other { return true } else if _, ok := other.(*OR); !ok { return false } else { for i, v := range other.(*OR).opnds { - if !o.opnds[i].equals(v) { + if !o.opnds[i].Equals(v) { return false } } @@ -406,7 +410,6 @@ func (o *OR) equals(other interface{}) bool { //

    // The evaluation of predicates by o context is short-circuiting, but // unordered.

    -// func (o *OR) evaluate(parser Recognizer, outerContext RuleContext) bool { for i := 0; i < len(o.opnds); i++ { if o.opnds[i].evaluate(parser, outerContext) { diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token.go similarity index 98% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/token.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token.go index 2d8e99095..f73b06bc6 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. @@ -158,7 +158,6 @@ func NewCommonToken(source *TokenSourceCharStreamPair, tokenType, channel, start // {@link Token//GetInputStream}.

    // // @param oldToken The token to copy. -// func (c *CommonToken) clone() *CommonToken { t := NewCommonToken(c.source, c.tokenType, c.channel, c.start, c.stop) t.tokenIndex = c.GetTokenIndex() diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_source.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token_source.go similarity index 85% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_source.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token_source.go index e023978fe..a3f36eaa6 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_source.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token_source.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token_stream.go similarity index 87% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_stream.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token_stream.go index df92c8147..1527d43f6 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_stream.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token_stream.go @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/tokenstream_rewriter.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/tokenstream_rewriter.go similarity index 58% rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/tokenstream_rewriter.go rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/tokenstream_rewriter.go index 96a03f02a..b3e38af34 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/tokenstream_rewriter.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/tokenstream_rewriter.go @@ -1,15 +1,15 @@ -// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. // Use of this file is governed by the BSD 3-clause license that // can be found in the LICENSE.txt file in the project root. + package antlr import ( -"bytes" -"fmt" + "bytes" + "fmt" ) - -// +// // Useful for rewriting out a buffered input token stream after doing some // augmentation or other manipulations on it. @@ -85,12 +85,10 @@ import ( // If you don't use named rewrite streams, a "default" stream is used as the // first example shows.

    - - -const( +const ( Default_Program_Name = "default" - Program_Init_Size = 100 - Min_Token_Index = 0 + Program_Init_Size = 100 + Min_Token_Index = 0 ) // Define the rewrite operation hierarchy @@ -98,13 +96,13 @@ const( type RewriteOperation interface { // Execute the rewrite operation by possibly adding to the buffer. // Return the index of the next token to operate on. - Execute(buffer *bytes.Buffer) int - String() string - GetInstructionIndex() int - GetIndex() int - GetText() string - GetOpName() string - GetTokens() TokenStream + Execute(buffer *bytes.Buffer) int + String() string + GetInstructionIndex() int + GetIndex() int + GetText() string + GetOpName() string + GetTokens() TokenStream SetInstructionIndex(val int) SetIndex(int) SetText(string) @@ -114,63 +112,62 @@ type RewriteOperation interface { type BaseRewriteOperation struct { //Current index of rewrites list - instruction_index int + instruction_index int //Token buffer index - index int + index int //Substitution text - text string + text string //Actual operation name - op_name string + op_name string //Pointer to token steam - tokens TokenStream + tokens TokenStream } -func (op *BaseRewriteOperation)GetInstructionIndex() int{ +func (op *BaseRewriteOperation) GetInstructionIndex() int { return op.instruction_index } -func (op *BaseRewriteOperation)GetIndex() int{ +func (op *BaseRewriteOperation) GetIndex() int { return op.index } -func (op *BaseRewriteOperation)GetText() string{ +func (op *BaseRewriteOperation) GetText() string { return op.text } -func (op *BaseRewriteOperation)GetOpName() string{ +func (op *BaseRewriteOperation) GetOpName() string { return op.op_name } -func (op *BaseRewriteOperation)GetTokens() TokenStream{ +func (op *BaseRewriteOperation) GetTokens() TokenStream { return op.tokens } -func (op *BaseRewriteOperation)SetInstructionIndex(val int){ +func (op *BaseRewriteOperation) SetInstructionIndex(val int) { op.instruction_index = val } -func (op *BaseRewriteOperation)SetIndex(val int) { +func (op *BaseRewriteOperation) SetIndex(val int) { op.index = val } -func (op *BaseRewriteOperation)SetText(val string){ +func (op *BaseRewriteOperation) SetText(val string) { op.text = val } -func (op *BaseRewriteOperation)SetOpName(val string){ +func (op *BaseRewriteOperation) SetOpName(val string) { op.op_name = val } -func (op *BaseRewriteOperation)SetTokens(val TokenStream) { +func (op *BaseRewriteOperation) SetTokens(val TokenStream) { op.tokens = val } - -func (op *BaseRewriteOperation) Execute(buffer *bytes.Buffer) int{ +func (op *BaseRewriteOperation) Execute(buffer *bytes.Buffer) int { return op.index } -func (op *BaseRewriteOperation) String() string { +func (op *BaseRewriteOperation) String() string { return fmt.Sprintf("<%s@%d:\"%s\">", op.op_name, op.tokens.Get(op.GetIndex()), @@ -179,26 +176,25 @@ func (op *BaseRewriteOperation) String() string { } - type InsertBeforeOp struct { BaseRewriteOperation } -func NewInsertBeforeOp(index int, text string, stream TokenStream) *InsertBeforeOp{ - return &InsertBeforeOp{BaseRewriteOperation:BaseRewriteOperation{ - index:index, - text:text, - op_name:"InsertBeforeOp", - tokens:stream, +func NewInsertBeforeOp(index int, text string, stream TokenStream) *InsertBeforeOp { + return &InsertBeforeOp{BaseRewriteOperation: BaseRewriteOperation{ + index: index, + text: text, + op_name: "InsertBeforeOp", + tokens: stream, }} } -func (op *InsertBeforeOp) Execute(buffer *bytes.Buffer) int{ +func (op *InsertBeforeOp) Execute(buffer *bytes.Buffer) int { buffer.WriteString(op.text) - if op.tokens.Get(op.index).GetTokenType() != TokenEOF{ + if op.tokens.Get(op.index).GetTokenType() != TokenEOF { buffer.WriteString(op.tokens.Get(op.index).GetText()) } - return op.index+1 + return op.index + 1 } func (op *InsertBeforeOp) String() string { @@ -213,20 +209,20 @@ type InsertAfterOp struct { BaseRewriteOperation } -func NewInsertAfterOp(index int, text string, stream TokenStream) *InsertAfterOp{ - return &InsertAfterOp{BaseRewriteOperation:BaseRewriteOperation{ - index:index+1, - text:text, - tokens:stream, +func NewInsertAfterOp(index int, text string, stream TokenStream) *InsertAfterOp { + return &InsertAfterOp{BaseRewriteOperation: BaseRewriteOperation{ + index: index + 1, + text: text, + tokens: stream, }} } func (op *InsertAfterOp) Execute(buffer *bytes.Buffer) int { buffer.WriteString(op.text) - if op.tokens.Get(op.index).GetTokenType() != TokenEOF{ + if op.tokens.Get(op.index).GetTokenType() != TokenEOF { buffer.WriteString(op.tokens.Get(op.index).GetText()) } - return op.index+1 + return op.index + 1 } func (op *InsertAfterOp) String() string { @@ -235,28 +231,28 @@ func (op *InsertAfterOp) String() string { // I'm going to try replacing range from x..y with (y-x)+1 ReplaceOp // instructions. -type ReplaceOp struct{ +type ReplaceOp struct { BaseRewriteOperation LastIndex int } -func NewReplaceOp(from, to int, text string, stream TokenStream)*ReplaceOp { +func NewReplaceOp(from, to int, text string, stream TokenStream) *ReplaceOp { return &ReplaceOp{ - BaseRewriteOperation:BaseRewriteOperation{ - index:from, - text:text, - op_name:"ReplaceOp", - tokens:stream, + BaseRewriteOperation: BaseRewriteOperation{ + index: from, + text: text, + op_name: "ReplaceOp", + tokens: stream, }, - LastIndex:to, + LastIndex: to, } } -func (op *ReplaceOp)Execute(buffer *bytes.Buffer) int{ - if op.text != ""{ +func (op *ReplaceOp) Execute(buffer *bytes.Buffer) int { + if op.text != "" { buffer.WriteString(op.text) } - return op.LastIndex +1 + return op.LastIndex + 1 } func (op *ReplaceOp) String() string { @@ -268,54 +264,54 @@ func (op *ReplaceOp) String() string { op.tokens.Get(op.index), op.tokens.Get(op.LastIndex), op.text) } - type TokenStreamRewriter struct { //Our source stream - tokens TokenStream + tokens TokenStream // You may have multiple, named streams of rewrite operations. // I'm calling these things "programs." // Maps String (name) → rewrite (List) - programs map[string][]RewriteOperation - last_rewrite_token_indexes map[string]int + programs map[string][]RewriteOperation + last_rewrite_token_indexes map[string]int } -func NewTokenStreamRewriter(tokens TokenStream) *TokenStreamRewriter{ +func NewTokenStreamRewriter(tokens TokenStream) *TokenStreamRewriter { return &TokenStreamRewriter{ - tokens: tokens, - programs: map[string][]RewriteOperation{ - Default_Program_Name:make([]RewriteOperation,0, Program_Init_Size), + tokens: tokens, + programs: map[string][]RewriteOperation{ + Default_Program_Name: make([]RewriteOperation, 0, Program_Init_Size), }, - last_rewrite_token_indexes: map[string]int{}, + last_rewrite_token_indexes: map[string]int{}, } } -func (tsr *TokenStreamRewriter) GetTokenStream() TokenStream{ +func (tsr *TokenStreamRewriter) GetTokenStream() TokenStream { return tsr.tokens } -// Rollback the instruction stream for a program so that -// the indicated instruction (via instructionIndex) is no -// longer in the stream. UNTESTED! -func (tsr *TokenStreamRewriter) Rollback(program_name string, instruction_index int){ - is, ok := tsr.programs[program_name] - if ok{ +// Rollback the instruction stream for a program so that +// the indicated instruction (via instructionIndex) is no +// longer in the stream. UNTESTED! +func (tsr *TokenStreamRewriter) Rollback(program_name string, instruction_index int) { + is, ok := tsr.programs[program_name] + if ok { tsr.programs[program_name] = is[Min_Token_Index:instruction_index] } } -func (tsr *TokenStreamRewriter) RollbackDefault(instruction_index int){ +func (tsr *TokenStreamRewriter) RollbackDefault(instruction_index int) { tsr.Rollback(Default_Program_Name, instruction_index) } -//Reset the program so that no instructions exist -func (tsr *TokenStreamRewriter) DeleteProgram(program_name string){ + +// Reset the program so that no instructions exist +func (tsr *TokenStreamRewriter) DeleteProgram(program_name string) { tsr.Rollback(program_name, Min_Token_Index) //TODO: double test on that cause lower bound is not included } -func (tsr *TokenStreamRewriter) DeleteProgramDefault(){ +func (tsr *TokenStreamRewriter) DeleteProgramDefault() { tsr.DeleteProgram(Default_Program_Name) } -func (tsr *TokenStreamRewriter) InsertAfter(program_name string, index int, text string){ +func (tsr *TokenStreamRewriter) InsertAfter(program_name string, index int, text string) { // to insert after, just insert before next index (even if past end) var op RewriteOperation = NewInsertAfterOp(index, text, tsr.tokens) rewrites := tsr.GetProgram(program_name) @@ -323,31 +319,31 @@ func (tsr *TokenStreamRewriter) InsertAfter(program_name string, index int, text tsr.AddToProgram(program_name, op) } -func (tsr *TokenStreamRewriter) InsertAfterDefault(index int, text string){ +func (tsr *TokenStreamRewriter) InsertAfterDefault(index int, text string) { tsr.InsertAfter(Default_Program_Name, index, text) } -func (tsr *TokenStreamRewriter) InsertAfterToken(program_name string, token Token, text string){ +func (tsr *TokenStreamRewriter) InsertAfterToken(program_name string, token Token, text string) { tsr.InsertAfter(program_name, token.GetTokenIndex(), text) } -func (tsr* TokenStreamRewriter) InsertBefore(program_name string, index int, text string){ +func (tsr *TokenStreamRewriter) InsertBefore(program_name string, index int, text string) { var op RewriteOperation = NewInsertBeforeOp(index, text, tsr.tokens) rewrites := tsr.GetProgram(program_name) op.SetInstructionIndex(len(rewrites)) tsr.AddToProgram(program_name, op) } -func (tsr *TokenStreamRewriter) InsertBeforeDefault(index int, text string){ +func (tsr *TokenStreamRewriter) InsertBeforeDefault(index int, text string) { tsr.InsertBefore(Default_Program_Name, index, text) } -func (tsr *TokenStreamRewriter) InsertBeforeToken(program_name string,token Token, text string){ +func (tsr *TokenStreamRewriter) InsertBeforeToken(program_name string, token Token, text string) { tsr.InsertBefore(program_name, token.GetTokenIndex(), text) } -func (tsr *TokenStreamRewriter) Replace(program_name string, from, to int, text string){ - if from > to || from < 0 || to < 0 || to >= tsr.tokens.Size(){ +func (tsr *TokenStreamRewriter) Replace(program_name string, from, to int, text string) { + if from > to || from < 0 || to < 0 || to >= tsr.tokens.Size() { panic(fmt.Sprintf("replace: range invalid: %d..%d(size=%d)", from, to, tsr.tokens.Size())) } @@ -357,207 +353,216 @@ func (tsr *TokenStreamRewriter) Replace(program_name string, from, to int, text tsr.AddToProgram(program_name, op) } -func (tsr *TokenStreamRewriter)ReplaceDefault(from, to int, text string) { +func (tsr *TokenStreamRewriter) ReplaceDefault(from, to int, text string) { tsr.Replace(Default_Program_Name, from, to, text) } -func (tsr *TokenStreamRewriter)ReplaceDefaultPos(index int, text string){ +func (tsr *TokenStreamRewriter) ReplaceDefaultPos(index int, text string) { tsr.ReplaceDefault(index, index, text) } -func (tsr *TokenStreamRewriter)ReplaceToken(program_name string, from, to Token, text string){ +func (tsr *TokenStreamRewriter) ReplaceToken(program_name string, from, to Token, text string) { tsr.Replace(program_name, from.GetTokenIndex(), to.GetTokenIndex(), text) } -func (tsr *TokenStreamRewriter)ReplaceTokenDefault(from, to Token, text string){ +func (tsr *TokenStreamRewriter) ReplaceTokenDefault(from, to Token, text string) { tsr.ReplaceToken(Default_Program_Name, from, to, text) } -func (tsr *TokenStreamRewriter)ReplaceTokenDefaultPos(index Token, text string){ +func (tsr *TokenStreamRewriter) ReplaceTokenDefaultPos(index Token, text string) { tsr.ReplaceTokenDefault(index, index, text) } -func (tsr *TokenStreamRewriter)Delete(program_name string, from, to int){ - tsr.Replace(program_name, from, to, "" ) +func (tsr *TokenStreamRewriter) Delete(program_name string, from, to int) { + tsr.Replace(program_name, from, to, "") } -func (tsr *TokenStreamRewriter)DeleteDefault(from, to int){ +func (tsr *TokenStreamRewriter) DeleteDefault(from, to int) { tsr.Delete(Default_Program_Name, from, to) } -func (tsr *TokenStreamRewriter)DeleteDefaultPos(index int){ - tsr.DeleteDefault(index,index) +func (tsr *TokenStreamRewriter) DeleteDefaultPos(index int) { + tsr.DeleteDefault(index, index) } -func (tsr *TokenStreamRewriter)DeleteToken(program_name string, from, to Token) { +func (tsr *TokenStreamRewriter) DeleteToken(program_name string, from, to Token) { tsr.ReplaceToken(program_name, from, to, "") } -func (tsr *TokenStreamRewriter)DeleteTokenDefault(from,to Token){ +func (tsr *TokenStreamRewriter) DeleteTokenDefault(from, to Token) { tsr.DeleteToken(Default_Program_Name, from, to) } -func (tsr *TokenStreamRewriter)GetLastRewriteTokenIndex(program_name string)int { +func (tsr *TokenStreamRewriter) GetLastRewriteTokenIndex(program_name string) int { i, ok := tsr.last_rewrite_token_indexes[program_name] - if !ok{ + if !ok { return -1 } return i } -func (tsr *TokenStreamRewriter)GetLastRewriteTokenIndexDefault()int{ +func (tsr *TokenStreamRewriter) GetLastRewriteTokenIndexDefault() int { return tsr.GetLastRewriteTokenIndex(Default_Program_Name) } -func (tsr *TokenStreamRewriter)SetLastRewriteTokenIndex(program_name string, i int){ +func (tsr *TokenStreamRewriter) SetLastRewriteTokenIndex(program_name string, i int) { tsr.last_rewrite_token_indexes[program_name] = i } -func (tsr *TokenStreamRewriter)InitializeProgram(name string)[]RewriteOperation{ +func (tsr *TokenStreamRewriter) InitializeProgram(name string) []RewriteOperation { is := make([]RewriteOperation, 0, Program_Init_Size) tsr.programs[name] = is return is } -func (tsr *TokenStreamRewriter)AddToProgram(name string, op RewriteOperation){ +func (tsr *TokenStreamRewriter) AddToProgram(name string, op RewriteOperation) { is := tsr.GetProgram(name) is = append(is, op) tsr.programs[name] = is } -func (tsr *TokenStreamRewriter)GetProgram(name string) []RewriteOperation { +func (tsr *TokenStreamRewriter) GetProgram(name string) []RewriteOperation { is, ok := tsr.programs[name] - if !ok{ + if !ok { is = tsr.InitializeProgram(name) } return is } -// Return the text from the original tokens altered per the -// instructions given to this rewriter. -func (tsr *TokenStreamRewriter)GetTextDefault() string{ + +// Return the text from the original tokens altered per the +// instructions given to this rewriter. +func (tsr *TokenStreamRewriter) GetTextDefault() string { return tsr.GetText( Default_Program_Name, NewInterval(0, tsr.tokens.Size()-1)) } -// Return the text from the original tokens altered per the -// instructions given to this rewriter. -func (tsr *TokenStreamRewriter)GetText(program_name string, interval *Interval) string { + +// Return the text from the original tokens altered per the +// instructions given to this rewriter. +func (tsr *TokenStreamRewriter) GetText(program_name string, interval *Interval) string { rewrites := tsr.programs[program_name] start := interval.Start - stop := interval.Stop + stop := interval.Stop // ensure start/end are in range stop = min(stop, tsr.tokens.Size()-1) - start = max(start,0) - if rewrites == nil || len(rewrites) == 0{ + start = max(start, 0) + if rewrites == nil || len(rewrites) == 0 { return tsr.tokens.GetTextFromInterval(interval) // no instructions to execute } buf := bytes.Buffer{} // First, optimize instruction stream indexToOp := reduceToSingleOperationPerIndex(rewrites) // Walk buffer, executing instructions and emitting tokens - for i:=start; i<=stop && i= tsr.tokens.Size()-1 {buf.WriteString(op.GetText())} + for _, op := range indexToOp { + if op.GetIndex() >= tsr.tokens.Size()-1 { + buf.WriteString(op.GetText()) + } } } return buf.String() } -// We need to combine operations and report invalid operations (like -// overlapping replaces that are not completed nested). Inserts to -// same index need to be combined etc... Here are the cases: +// We need to combine operations and report invalid operations (like +// overlapping replaces that are not completed nested). Inserts to +// same index need to be combined etc... Here are the cases: // -// I.i.u I.j.v leave alone, nonoverlapping -// I.i.u I.i.v combine: Iivu +// I.i.u I.j.v leave alone, nonoverlapping +// I.i.u I.i.v combine: Iivu // -// R.i-j.u R.x-y.v | i-j in x-y delete first R -// R.i-j.u R.i-j.v delete first R -// R.i-j.u R.x-y.v | x-y in i-j ERROR -// R.i-j.u R.x-y.v | boundaries overlap ERROR +// R.i-j.u R.x-y.v | i-j in x-y delete first R +// R.i-j.u R.i-j.v delete first R +// R.i-j.u R.x-y.v | x-y in i-j ERROR +// R.i-j.u R.x-y.v | boundaries overlap ERROR // -// Delete special case of replace (text==null): -// D.i-j.u D.x-y.v | boundaries overlap combine to max(min)..max(right) +// Delete special case of replace (text==null): +// D.i-j.u D.x-y.v | boundaries overlap combine to max(min)..max(right) // -// I.i.u R.x-y.v | i in (x+1)-y delete I (since insert before -// we're not deleting i) -// I.i.u R.x-y.v | i not in (x+1)-y leave alone, nonoverlapping -// R.x-y.v I.i.u | i in x-y ERROR -// R.x-y.v I.x.u R.x-y.uv (combine, delete I) -// R.x-y.v I.i.u | i not in x-y leave alone, nonoverlapping +// I.i.u R.x-y.v | i in (x+1)-y delete I (since insert before +// we're not deleting i) +// I.i.u R.x-y.v | i not in (x+1)-y leave alone, nonoverlapping +// R.x-y.v I.i.u | i in x-y ERROR +// R.x-y.v I.x.u R.x-y.uv (combine, delete I) +// R.x-y.v I.i.u | i not in x-y leave alone, nonoverlapping // -// I.i.u = insert u before op @ index i -// R.x-y.u = replace x-y indexed tokens with u +// I.i.u = insert u before op @ index i +// R.x-y.u = replace x-y indexed tokens with u // -// First we need to examine replaces. For any replace op: +// First we need to examine replaces. For any replace op: // -// 1. wipe out any insertions before op within that range. -// 2. Drop any replace op before that is contained completely within -// that range. -// 3. Throw exception upon boundary overlap with any previous replace. +// 1. wipe out any insertions before op within that range. +// 2. Drop any replace op before that is contained completely within +// that range. +// 3. Throw exception upon boundary overlap with any previous replace. // -// Then we can deal with inserts: +// Then we can deal with inserts: // -// 1. for any inserts to same index, combine even if not adjacent. -// 2. for any prior replace with same left boundary, combine this -// insert with replace and delete this replace. -// 3. throw exception if index in same range as previous replace +// 1. for any inserts to same index, combine even if not adjacent. +// 2. for any prior replace with same left boundary, combine this +// insert with replace and delete this replace. +// 3. throw exception if index in same range as previous replace // -// Don't actually delete; make op null in list. Easier to walk list. -// Later we can throw as we add to index → op map. +// Don't actually delete; make op null in list. Easier to walk list. +// Later we can throw as we add to index → op map. // -// Note that I.2 R.2-2 will wipe out I.2 even though, technically, the -// inserted stuff would be before the replace range. But, if you -// add tokens in front of a method body '{' and then delete the method -// body, I think the stuff before the '{' you added should disappear too. +// Note that I.2 R.2-2 will wipe out I.2 even though, technically, the +// inserted stuff would be before the replace range. But, if you +// add tokens in front of a method body '{' and then delete the method +// body, I think the stuff before the '{' you added should disappear too. // -// Return a map from token index to operation. -// -func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]RewriteOperation{ +// Return a map from token index to operation. +func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]RewriteOperation { // WALK REPLACES - for i:=0; i < len(rewrites); i++{ + for i := 0; i < len(rewrites); i++ { op := rewrites[i] - if op == nil{continue} + if op == nil { + continue + } rop, ok := op.(*ReplaceOp) - if !ok{continue} + if !ok { + continue + } // Wipe prior inserts within range - for j:=0; j rop.index && iop.index <=rop.LastIndex{ + } else if iop.index > rop.index && iop.index <= rop.LastIndex { // delete insert as it's a no-op. rewrites[iop.instruction_index] = nil } } } // Drop any prior replaces contained within - for j:=0; j=rop.index && prevop.LastIndex <= rop.LastIndex{ + for j := 0; j < i && j < len(rewrites); j++ { + if prevop, ok := rewrites[j].(*ReplaceOp); ok { + if prevop.index >= rop.index && prevop.LastIndex <= rop.LastIndex { // delete replace as it's a no-op. rewrites[prevop.instruction_index] = nil continue @@ -566,61 +571,67 @@ func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]Rewrit disjoint := prevop.LastIndex < rop.index || prevop.index > rop.LastIndex // Delete special case of replace (text==null): // D.i-j.u D.x-y.v | boundaries overlap combine to max(min)..max(right) - if prevop.text == "" && rop.text == "" && !disjoint{ + if prevop.text == "" && rop.text == "" && !disjoint { rewrites[prevop.instruction_index] = nil rop.index = min(prevop.index, rop.index) rop.LastIndex = max(prevop.LastIndex, rop.LastIndex) println("new rop" + rop.String()) //TODO: remove console write, taken from Java version - }else if !disjoint{ + } else if !disjoint { panic("replace op boundaries of " + rop.String() + " overlap with previous " + prevop.String()) } } } } // WALK INSERTS - for i:=0; i < len(rewrites); i++ { + for i := 0; i < len(rewrites); i++ { op := rewrites[i] - if op == nil{continue} + if op == nil { + continue + } //hack to replicate inheritance in composition _, iok := rewrites[i].(*InsertBeforeOp) _, aok := rewrites[i].(*InsertAfterOp) - if !iok && !aok{continue} + if !iok && !aok { + continue + } iop := rewrites[i] // combine current insert with prior if any at same index // deviating a bit from TokenStreamRewriter.java - hard to incorporate inheritance logic - for j:=0; j= rop.index && iop.GetIndex() <= rop.LastIndex{ - panic("insert op "+iop.String()+" within boundaries of previous "+rop.String()) + if iop.GetIndex() >= rop.index && iop.GetIndex() <= rop.LastIndex { + panic("insert op " + iop.String() + " within boundaries of previous " + rop.String()) } } } } m := map[int]RewriteOperation{} - for i:=0; i < len(rewrites); i++{ + for i := 0; i < len(rewrites); i++ { op := rewrites[i] - if op == nil {continue} - if _, ok := m[op.GetIndex()]; ok{ + if op == nil { + continue + } + if _, ok := m[op.GetIndex()]; ok { panic("should only be one op per index") } m[op.GetIndex()] = op @@ -628,22 +639,21 @@ func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]Rewrit return m } - /* Quick fixing Go lack of overloads - */ +*/ -func max(a,b int)int{ - if a>b{ +func max(a, b int) int { + if a > b { return a - }else { + } else { return b } } -func min(a,b int)int{ - if a as.threshold { as.expand() } @@ -98,7 +96,7 @@ func (as *array2DHashSet) expand() { b := as.getBuckets(o) bucketLength := newBucketLengths[b] - var newBucket []interface{} + var newBucket []Collectable[any] if bucketLength == 0 { // new bucket newBucket = as.createBucket(as.initialBucketCapacity) @@ -107,7 +105,7 @@ func (as *array2DHashSet) expand() { newBucket = newTable[b] if bucketLength == len(newBucket) { // expand - newBucketCopy := make([]interface{}, len(newBucket)<<1) + newBucketCopy := make([]Collectable[any], len(newBucket)<<1) copy(newBucketCopy[:bucketLength], newBucket) newBucket = newBucketCopy newTable[b] = newBucket @@ -124,7 +122,7 @@ func (as *array2DHashSet) Len() int { return as.n } -func (as *array2DHashSet) Get(o interface{}) interface{} { +func (as *array2DHashSet) Get(o Collectable[any]) interface{} { if o == nil { return nil } @@ -147,7 +145,7 @@ func (as *array2DHashSet) Get(o interface{}) interface{} { return nil } -func (as *array2DHashSet) innerAdd(o interface{}) interface{} { +func (as *array2DHashSet) innerAdd(o Collectable[any]) interface{} { b := as.getBuckets(o) bucket := as.buckets[b] @@ -178,7 +176,7 @@ func (as *array2DHashSet) innerAdd(o interface{}) interface{} { // full bucket, expand and add to end oldLength := len(bucket) - bucketCopy := make([]interface{}, oldLength<<1) + bucketCopy := make([]Collectable[any], oldLength<<1) copy(bucketCopy[:oldLength], bucket) bucket = bucketCopy as.buckets[b] = bucket @@ -187,22 +185,22 @@ func (as *array2DHashSet) innerAdd(o interface{}) interface{} { return o } -func (as *array2DHashSet) getBuckets(value interface{}) int { +func (as *array2DHashSet) getBuckets(value Collectable[any]) int { hash := as.hashcodeFunction(value) return hash & (len(as.buckets) - 1) } -func (as *array2DHashSet) createBuckets(cap int) [][]interface{} { - return make([][]interface{}, cap) +func (as *array2DHashSet) createBuckets(cap int) [][]Collectable[any] { + return make([][]Collectable[any], cap) } -func (as *array2DHashSet) createBucket(cap int) []interface{} { - return make([]interface{}, cap) +func (as *array2DHashSet) createBucket(cap int) []Collectable[any] { + return make([]Collectable[any], cap) } func newArray2DHashSetWithCap( hashcodeFunction func(interface{}) int, - equalsFunction func(interface{}, interface{}) bool, + equalsFunction func(Collectable[any], Collectable[any]) bool, initCap int, initBucketCap int, ) *array2DHashSet { @@ -231,7 +229,7 @@ func newArray2DHashSetWithCap( func newArray2DHashSet( hashcodeFunction func(interface{}) int, - equalsFunction func(interface{}, interface{}) bool, + equalsFunction func(Collectable[any], Collectable[any]) bool, ) *array2DHashSet { return newArray2DHashSetWithCap(hashcodeFunction, equalsFunction, _initalCapacity, _initalBucketCapacity) } diff --git a/vendor/github.com/google/cel-go/cel/BUILD.bazel b/vendor/github.com/google/cel-go/cel/BUILD.bazel index ddddbd280..0905f6353 100644 --- a/vendor/github.com/google/cel-go/cel/BUILD.bazel +++ b/vendor/github.com/google/cel-go/cel/BUILD.bazel @@ -15,6 +15,7 @@ go_library( "macro.go", "options.go", "program.go", + "validator.go", ], importpath = "github.com/google/cel-go/cel", visibility = ["//visibility:public"], @@ -22,17 +23,20 @@ go_library( "//checker:go_default_library", "//checker/decls:go_default_library", "//common:go_default_library", + "//common/ast:go_default_library", "//common/containers:go_default_library", + "//common/decls:go_default_library", + "//common/functions:go_default_library", "//common/operators:go_default_library", "//common/overloads:go_default_library", + "//common/stdlib:go_default_library", "//common/types:go_default_library", "//common/types/pb:go_default_library", "//common/types/ref:go_default_library", "//common/types/traits:go_default_library", "//interpreter:go_default_library", - "//interpreter/functions:go_default_library", "//parser:go_default_library", - "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//reflect/protodesc:go_default_library", "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", @@ -70,8 +74,10 @@ go_test( "//test/proto2pb:go_default_library", "//test/proto3pb:go_default_library", "@io_bazel_rules_go//proto/wkt:descriptor_go_proto", - "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", + "@org_golang_google_protobuf//encoding/prototext:go_default_library", "@org_golang_google_protobuf//types/known/structpb:go_default_library", + "@org_golang_google_protobuf//types/known/wrapperspb:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/cel/decls.go b/vendor/github.com/google/cel-go/cel/decls.go index 8ff690b11..0f9501341 100644 --- a/vendor/github.com/google/cel-go/cel/decls.go +++ b/vendor/github.com/google/cel-go/cel/decls.go @@ -16,341 +16,133 @@ package cel import ( "fmt" - "strings" - "github.com/google/cel-go/checker/decls" + "github.com/google/cel-go/common/ast" + "github.com/google/cel-go/common/decls" + "github.com/google/cel-go/common/functions" "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/functions" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) // Kind indicates a CEL type's kind which is used to differentiate quickly between simple and complex types. -type Kind uint +type Kind = types.Kind const ( // DynKind represents a dynamic type. This kind only exists at type-check time. - DynKind Kind = iota + DynKind Kind = types.DynKind // AnyKind represents a google.protobuf.Any type. This kind only exists at type-check time. - AnyKind + AnyKind = types.AnyKind // BoolKind represents a boolean type. - BoolKind + BoolKind = types.BoolKind // BytesKind represents a bytes type. - BytesKind + BytesKind = types.BytesKind // DoubleKind represents a double type. - DoubleKind + DoubleKind = types.DoubleKind // DurationKind represents a CEL duration type. - DurationKind + DurationKind = types.DurationKind // IntKind represents an integer type. - IntKind + IntKind = types.IntKind // ListKind represents a list type. - ListKind + ListKind = types.ListKind // MapKind represents a map type. - MapKind + MapKind = types.MapKind // NullTypeKind represents a null type. - NullTypeKind + NullTypeKind = types.NullTypeKind // OpaqueKind represents an abstract type which has no accessible fields. - OpaqueKind + OpaqueKind = types.OpaqueKind // StringKind represents a string type. - StringKind + StringKind = types.StringKind // StructKind represents a structured object with typed fields. - StructKind + StructKind = types.StructKind // TimestampKind represents a a CEL time type. - TimestampKind + TimestampKind = types.TimestampKind // TypeKind represents the CEL type. - TypeKind + TypeKind = types.TypeKind // TypeParamKind represents a parameterized type whose type name will be resolved at type-check time, if possible. - TypeParamKind + TypeParamKind = types.TypeParamKind // UintKind represents a uint type. - UintKind + UintKind = types.UintKind ) var ( // AnyType represents the google.protobuf.Any type. - AnyType = &Type{ - kind: AnyKind, - runtimeType: types.NewTypeValue("google.protobuf.Any"), - } + AnyType = types.AnyType // BoolType represents the bool type. - BoolType = &Type{ - kind: BoolKind, - runtimeType: types.BoolType, - } + BoolType = types.BoolType // BytesType represents the bytes type. - BytesType = &Type{ - kind: BytesKind, - runtimeType: types.BytesType, - } + BytesType = types.BytesType // DoubleType represents the double type. - DoubleType = &Type{ - kind: DoubleKind, - runtimeType: types.DoubleType, - } + DoubleType = types.DoubleType // DurationType represents the CEL duration type. - DurationType = &Type{ - kind: DurationKind, - runtimeType: types.DurationType, - } + DurationType = types.DurationType // DynType represents a dynamic CEL type whose type will be determined at runtime from context. - DynType = &Type{ - kind: DynKind, - runtimeType: types.NewTypeValue("dyn"), - } + DynType = types.DynType // IntType represents the int type. - IntType = &Type{ - kind: IntKind, - runtimeType: types.IntType, - } + IntType = types.IntType // NullType represents the type of a null value. - NullType = &Type{ - kind: NullTypeKind, - runtimeType: types.NullType, - } + NullType = types.NullType // StringType represents the string type. - StringType = &Type{ - kind: StringKind, - runtimeType: types.StringType, - } + StringType = types.StringType // TimestampType represents the time type. - TimestampType = &Type{ - kind: TimestampKind, - runtimeType: types.TimestampType, - } + TimestampType = types.TimestampType // TypeType represents a CEL type - TypeType = &Type{ - kind: TypeKind, - runtimeType: types.TypeType, - } - //UintType represents a uint type. - UintType = &Type{ - kind: UintKind, - runtimeType: types.UintType, - } + TypeType = types.TypeType + // UintType represents a uint type. + UintType = types.UintType + + // function references for instantiating new types. + + // ListType creates an instances of a list type value with the provided element type. + ListType = types.NewListType + // MapType creates an instance of a map type value with the provided key and value types. + MapType = types.NewMapType + // NullableType creates an instance of a nullable type with the provided wrapped type. + // + // Note: only primitive types are supported as wrapped types. + NullableType = types.NewNullableType + // OptionalType creates an abstract parameterized type instance corresponding to CEL's notion of optional. + OptionalType = types.NewOptionalType + // OpaqueType creates an abstract parameterized type with a given name. + OpaqueType = types.NewOpaqueType + // ObjectType creates a type references to an externally defined type, e.g. a protobuf message type. + ObjectType = types.NewObjectType + // TypeParamType creates a parameterized type instance. + TypeParamType = types.NewTypeParamType ) // Type holds a reference to a runtime type with an optional type-checked set of type parameters. -type Type struct { - // kind indicates general category of the type. - kind Kind - - // runtimeType is the runtime type of the declaration. - runtimeType ref.Type - - // parameters holds the optional type-checked set of type parameters that are used during static analysis. - parameters []*Type - - // isAssignableType function determines whether one type is assignable to this type. - // A nil value for the isAssignableType function falls back to equality of kind, runtimeType, and parameters. - isAssignableType func(other *Type) bool - - // isAssignableRuntimeType function determines whether the runtime type (with erasure) is assignable to this type. - // A nil value for the isAssignableRuntimeType function falls back to the equality of the type or type name. - isAssignableRuntimeType func(other ref.Val) bool -} - -// IsAssignableType determines whether the current type is type-check assignable from the input fromType. -func (t *Type) IsAssignableType(fromType *Type) bool { - if t.isAssignableType != nil { - return t.isAssignableType(fromType) - } - return t.defaultIsAssignableType(fromType) -} - -// IsAssignableRuntimeType determines whether the current type is runtime assignable from the input runtimeType. -// -// At runtime, parameterized types are erased and so a function which type-checks to support a map(string, string) -// will have a runtime assignable type of a map. -func (t *Type) IsAssignableRuntimeType(val ref.Val) bool { - if t.isAssignableRuntimeType != nil { - return t.isAssignableRuntimeType(val) - } - return t.defaultIsAssignableRuntimeType(val) -} - -// String returns a human-readable definition of the type name. -func (t *Type) String() string { - if len(t.parameters) == 0 { - return t.runtimeType.TypeName() - } - params := make([]string, len(t.parameters)) - for i, p := range t.parameters { - params[i] = p.String() - } - return fmt.Sprintf("%s(%s)", t.runtimeType.TypeName(), strings.Join(params, ", ")) -} - -// isDyn indicates whether the type is dynamic in any way. -func (t *Type) isDyn() bool { - return t.kind == DynKind || t.kind == AnyKind || t.kind == TypeParamKind -} +type Type = types.Type -// equals indicates whether two types have the same kind, type name, and parameters. -func (t *Type) equals(other *Type) bool { - if t.kind != other.kind || - t.runtimeType.TypeName() != other.runtimeType.TypeName() || - len(t.parameters) != len(other.parameters) { - return false - } - for i, p := range t.parameters { - if !p.equals(other.parameters[i]) { - return false - } - } - return true -} - -// defaultIsAssignableType provides the standard definition of what it means for one type to be assignable to another -// where any of the following may return a true result: -// - The from types are the same instance -// - The target type is dynamic -// - The fromType has the same kind and type name as the target type, and all parameters of the target type -// -// are IsAssignableType() from the parameters of the fromType. -func (t *Type) defaultIsAssignableType(fromType *Type) bool { - if t == fromType || t.isDyn() { - return true - } - if t.kind != fromType.kind || - t.runtimeType.TypeName() != fromType.runtimeType.TypeName() || - len(t.parameters) != len(fromType.parameters) { - return false - } - for i, tp := range t.parameters { - fp := fromType.parameters[i] - if !tp.IsAssignableType(fp) { - return false - } - } - return true -} - -// defaultIsAssignableRuntimeType inspects the type and in the case of list and map elements, the key and element types -// to determine whether a ref.Val is assignable to the declared type for a function signature. -func (t *Type) defaultIsAssignableRuntimeType(val ref.Val) bool { - valType := val.Type() - if !(t.runtimeType == valType || t.isDyn() || t.runtimeType.TypeName() == valType.TypeName()) { - return false - } - switch t.runtimeType { - case types.ListType: - elemType := t.parameters[0] - l := val.(traits.Lister) - if l.Size() == types.IntZero { - return true - } - it := l.Iterator() - for it.HasNext() == types.True { - elemVal := it.Next() - return elemType.IsAssignableRuntimeType(elemVal) - } - case types.MapType: - keyType := t.parameters[0] - elemType := t.parameters[1] - m := val.(traits.Mapper) - if m.Size() == types.IntZero { - return true - } - it := m.Iterator() - for it.HasNext() == types.True { - keyVal := it.Next() - elemVal := m.Get(keyVal) - return keyType.IsAssignableRuntimeType(keyVal) && elemType.IsAssignableRuntimeType(elemVal) - } - } - return true -} - -// ListType creates an instances of a list type value with the provided element type. -func ListType(elemType *Type) *Type { - return &Type{ - kind: ListKind, - runtimeType: types.ListType, - parameters: []*Type{elemType}, - } -} - -// MapType creates an instance of a map type value with the provided key and value types. -func MapType(keyType, valueType *Type) *Type { - return &Type{ - kind: MapKind, - runtimeType: types.MapType, - parameters: []*Type{keyType, valueType}, - } -} - -// NullableType creates an instance of a nullable type with the provided wrapped type. -// -// Note: only primitive types are supported as wrapped types. -func NullableType(wrapped *Type) *Type { - return &Type{ - kind: wrapped.kind, - runtimeType: wrapped.runtimeType, - parameters: wrapped.parameters, - isAssignableType: func(other *Type) bool { - return NullType.IsAssignableType(other) || wrapped.IsAssignableType(other) - }, - isAssignableRuntimeType: func(other ref.Val) bool { - return NullType.IsAssignableRuntimeType(other) || wrapped.IsAssignableRuntimeType(other) - }, - } -} - -// OptionalType creates an abstract parameterized type instance corresponding to CEL's notion of optional. -func OptionalType(param *Type) *Type { - return OpaqueType("optional", param) -} - -// OpaqueType creates an abstract parameterized type with a given name. -func OpaqueType(name string, params ...*Type) *Type { - return &Type{ - kind: OpaqueKind, - runtimeType: types.NewTypeValue(name), - parameters: params, - } -} - -// ObjectType creates a type references to an externally defined type, e.g. a protobuf message type. -func ObjectType(typeName string) *Type { - return &Type{ - kind: StructKind, - runtimeType: types.NewObjectTypeValue(typeName), - } -} - -// TypeParamType creates a parameterized type instance. -func TypeParamType(paramName string) *Type { - return &Type{ - kind: TypeParamKind, - runtimeType: types.NewTypeValue(paramName), +// Constant creates an instances of an identifier declaration with a variable name, type, and value. +func Constant(name string, t *Type, v ref.Val) EnvOption { + return func(e *Env) (*Env, error) { + e.variables = append(e.variables, decls.NewConstant(name, t, v)) + return e, nil } } // Variable creates an instance of a variable declaration with a variable name and type. func Variable(name string, t *Type) EnvOption { return func(e *Env) (*Env, error) { - et, err := TypeToExprType(t) - if err != nil { - return nil, err - } - e.declarations = append(e.declarations, decls.NewVar(name, et)) + e.variables = append(e.variables, decls.NewVariable(name, t)) return e, nil } } @@ -386,53 +178,30 @@ func Variable(name string, t *Type) EnvOption { // overload as CEL can only make inferences by type-name regarding such types. func Function(name string, opts ...FunctionOpt) EnvOption { return func(e *Env) (*Env, error) { - fn := &functionDecl{ - name: name, - overloads: []*overloadDecl{}, - options: opts, - } - err := fn.init() + fn, err := decls.NewFunction(name, opts...) if err != nil { return nil, err } - _, err = functionDeclToExprDecl(fn) - if err != nil { - return nil, err - } - if existing, found := e.functions[fn.name]; found { - fn, err = existing.merge(fn) + if existing, found := e.functions[fn.Name()]; found { + fn, err = existing.Merge(fn) if err != nil { return nil, err } } - e.functions[name] = fn + e.functions[fn.Name()] = fn return e, nil } } // FunctionOpt defines a functional option for configuring a function declaration. -type FunctionOpt func(*functionDecl) (*functionDecl, error) +type FunctionOpt = decls.FunctionOpt -// SingletonUnaryBinding creates a singleton function defintion to be used for all function overloads. +// SingletonUnaryBinding creates a singleton function definition to be used for all function overloads. // // Note, this approach works well if operand is expected to have a specific trait which it implements, // e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings. func SingletonUnaryBinding(fn functions.UnaryOp, traits ...int) FunctionOpt { - trait := 0 - for _, t := range traits { - trait = trait | t - } - return func(f *functionDecl) (*functionDecl, error) { - if f.singleton != nil { - return nil, fmt.Errorf("function already has a singleton binding: %s", f.name) - } - f.singleton = &functions.Overload{ - Operator: f.name, - Unary: fn, - OperandTrait: trait, - } - return f, nil - } + return decls.SingletonUnaryBinding(fn, traits...) } // SingletonBinaryImpl creates a singleton function definition to be used with all function overloads. @@ -442,7 +211,7 @@ func SingletonUnaryBinding(fn functions.UnaryOp, traits ...int) FunctionOpt { // // Deprecated: use SingletonBinaryBinding func SingletonBinaryImpl(fn functions.BinaryOp, traits ...int) FunctionOpt { - return SingletonBinaryBinding(fn, traits...) + return decls.SingletonBinaryBinding(fn, traits...) } // SingletonBinaryBinding creates a singleton function definition to be used with all function overloads. @@ -450,21 +219,7 @@ func SingletonBinaryImpl(fn functions.BinaryOp, traits ...int) FunctionOpt { // Note, this approach works well if operand is expected to have a specific trait which it implements, // e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings. func SingletonBinaryBinding(fn functions.BinaryOp, traits ...int) FunctionOpt { - trait := 0 - for _, t := range traits { - trait = trait | t - } - return func(f *functionDecl) (*functionDecl, error) { - if f.singleton != nil { - return nil, fmt.Errorf("function already has a singleton binding: %s", f.name) - } - f.singleton = &functions.Overload{ - Operator: f.name, - Binary: fn, - OperandTrait: trait, - } - return f, nil - } + return decls.SingletonBinaryBinding(fn, traits...) } // SingletonFunctionImpl creates a singleton function definition to be used with all function overloads. @@ -474,7 +229,7 @@ func SingletonBinaryBinding(fn functions.BinaryOp, traits ...int) FunctionOpt { // // Deprecated: use SingletonFunctionBinding func SingletonFunctionImpl(fn functions.FunctionOp, traits ...int) FunctionOpt { - return SingletonFunctionBinding(fn, traits...) + return decls.SingletonFunctionBinding(fn, traits...) } // SingletonFunctionBinding creates a singleton function definition to be used with all function overloads. @@ -482,21 +237,13 @@ func SingletonFunctionImpl(fn functions.FunctionOp, traits ...int) FunctionOpt { // Note, this approach works well if operand is expected to have a specific trait which it implements, // e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings. func SingletonFunctionBinding(fn functions.FunctionOp, traits ...int) FunctionOpt { - trait := 0 - for _, t := range traits { - trait = trait | t - } - return func(f *functionDecl) (*functionDecl, error) { - if f.singleton != nil { - return nil, fmt.Errorf("function already has a singleton binding: %s", f.name) - } - f.singleton = &functions.Overload{ - Operator: f.name, - Function: fn, - OperandTrait: trait, - } - return f, nil - } + return decls.SingletonFunctionBinding(fn, traits...) +} + +// DisableDeclaration disables the function signatures, effectively removing them from the type-check +// environment while preserving the runtime bindings. +func DisableDeclaration(value bool) FunctionOpt { + return decls.DisableDeclaration(value) } // Overload defines a new global overload with an overload id, argument types, and result type. Through the @@ -506,7 +253,7 @@ func SingletonFunctionBinding(fn functions.FunctionOp, traits ...int) FunctionOp // Note: function bindings should be commonly configured with Overload instances whereas operand traits and // strict-ness should be rare occurrences. func Overload(overloadID string, args []*Type, resultType *Type, opts ...OverloadOpt) FunctionOpt { - return newOverload(overloadID, false, args, resultType, opts...) + return decls.Overload(overloadID, args, resultType, opts...) } // MemberOverload defines a new receiver-style overload (or member function) with an overload id, argument types, @@ -516,610 +263,51 @@ func Overload(overloadID string, args []*Type, resultType *Type, opts ...Overloa // Note: function bindings should be commonly configured with Overload instances whereas operand traits and // strict-ness should be rare occurrences. func MemberOverload(overloadID string, args []*Type, resultType *Type, opts ...OverloadOpt) FunctionOpt { - return newOverload(overloadID, true, args, resultType, opts...) + return decls.MemberOverload(overloadID, args, resultType, opts...) } // OverloadOpt is a functional option for configuring a function overload. -type OverloadOpt func(*overloadDecl) (*overloadDecl, error) +type OverloadOpt = decls.OverloadOpt // UnaryBinding provides the implementation of a unary overload. The provided function is protected by a runtime // type-guard which ensures runtime type agreement between the overload signature and runtime argument types. func UnaryBinding(binding functions.UnaryOp) OverloadOpt { - return func(o *overloadDecl) (*overloadDecl, error) { - if o.hasBinding() { - return nil, fmt.Errorf("overload already has a binding: %s", o.id) - } - if len(o.argTypes) != 1 { - return nil, fmt.Errorf("unary function bound to non-unary overload: %s", o.id) - } - o.unaryOp = binding - return o, nil - } + return decls.UnaryBinding(binding) } // BinaryBinding provides the implementation of a binary overload. The provided function is protected by a runtime // type-guard which ensures runtime type agreement between the overload signature and runtime argument types. func BinaryBinding(binding functions.BinaryOp) OverloadOpt { - return func(o *overloadDecl) (*overloadDecl, error) { - if o.hasBinding() { - return nil, fmt.Errorf("overload already has a binding: %s", o.id) - } - if len(o.argTypes) != 2 { - return nil, fmt.Errorf("binary function bound to non-binary overload: %s", o.id) - } - o.binaryOp = binding - return o, nil - } + return decls.BinaryBinding(binding) } // FunctionBinding provides the implementation of a variadic overload. The provided function is protected by a runtime // type-guard which ensures runtime type agreement between the overload signature and runtime argument types. func FunctionBinding(binding functions.FunctionOp) OverloadOpt { - return func(o *overloadDecl) (*overloadDecl, error) { - if o.hasBinding() { - return nil, fmt.Errorf("overload already has a binding: %s", o.id) - } - o.functionOp = binding - return o, nil - } + return decls.FunctionBinding(binding) } // OverloadIsNonStrict enables the function to be called with error and unknown argument values. // // Note: do not use this option unless absoluately necessary as it should be an uncommon feature. func OverloadIsNonStrict() OverloadOpt { - return func(o *overloadDecl) (*overloadDecl, error) { - o.nonStrict = true - return o, nil - } + return decls.OverloadIsNonStrict() } // OverloadOperandTrait configures a set of traits which the first argument to the overload must implement in order to be // successfully invoked. func OverloadOperandTrait(trait int) OverloadOpt { - return func(o *overloadDecl) (*overloadDecl, error) { - o.operandTrait = trait - return o, nil - } -} - -type functionDecl struct { - name string - overloads []*overloadDecl - options []FunctionOpt - singleton *functions.Overload - initialized bool -} - -// init ensures that a function's options have been applied. -// -// This function is used in both the environment configuration and internally for function merges. -func (f *functionDecl) init() error { - if f.initialized { - return nil - } - f.initialized = true - - var err error - for _, opt := range f.options { - f, err = opt(f) - if err != nil { - return err - } - } - if len(f.overloads) == 0 { - return fmt.Errorf("function %s must have at least one overload", f.name) - } - return nil -} - -// bindings produces a set of function bindings, if any are defined. -func (f *functionDecl) bindings() ([]*functions.Overload, error) { - overloads := []*functions.Overload{} - nonStrict := false - for _, o := range f.overloads { - if o.hasBinding() { - overload := &functions.Overload{ - Operator: o.id, - Unary: o.guardedUnaryOp(f.name), - Binary: o.guardedBinaryOp(f.name), - Function: o.guardedFunctionOp(f.name), - OperandTrait: o.operandTrait, - NonStrict: o.nonStrict, - } - overloads = append(overloads, overload) - nonStrict = nonStrict || o.nonStrict - } - } - if f.singleton != nil { - if len(overloads) != 0 { - return nil, fmt.Errorf("singleton function incompatible with specialized overloads: %s", f.name) - } - return []*functions.Overload{ - { - Operator: f.name, - Unary: f.singleton.Unary, - Binary: f.singleton.Binary, - Function: f.singleton.Function, - OperandTrait: f.singleton.OperandTrait, - }, - }, nil - } - if len(overloads) == 0 { - return overloads, nil - } - // Single overload. Replicate an entry for it using the function name as well. - if len(overloads) == 1 { - if overloads[0].Operator == f.name { - return overloads, nil - } - return append(overloads, &functions.Overload{ - Operator: f.name, - Unary: overloads[0].Unary, - Binary: overloads[0].Binary, - Function: overloads[0].Function, - NonStrict: overloads[0].NonStrict, - OperandTrait: overloads[0].OperandTrait, - }), nil - } - // All of the defined overloads are wrapped into a top-level function which - // performs dynamic dispatch to the proper overload based on the argument types. - bindings := append([]*functions.Overload{}, overloads...) - funcDispatch := func(args ...ref.Val) ref.Val { - for _, o := range f.overloads { - if !o.matchesRuntimeSignature(args...) { - continue - } - switch len(args) { - case 1: - if o.unaryOp != nil { - return o.unaryOp(args[0]) - } - case 2: - if o.binaryOp != nil { - return o.binaryOp(args[0], args[1]) - } - } - if o.functionOp != nil { - return o.functionOp(args...) - } - // eventually this will fall through to the noSuchOverload below. - } - return noSuchOverload(f.name, args...) - } - function := &functions.Overload{ - Operator: f.name, - Function: funcDispatch, - NonStrict: nonStrict, - } - return append(bindings, function), nil -} - -// merge one function declaration with another. -// -// If a function is extended, by say adding new overloads to an existing function, then it is merged with the -// prior definition of the function at which point its overloads must not collide with pre-existing overloads -// and its bindings (singleton, or per-overload) must not conflict with previous definitions either. -func (f *functionDecl) merge(other *functionDecl) (*functionDecl, error) { - if f.name != other.name { - return nil, fmt.Errorf("cannot merge unrelated functions. %s and %s", f.name, other.name) - } - err := f.init() - if err != nil { - return nil, err - } - err = other.init() - if err != nil { - return nil, err - } - merged := &functionDecl{ - name: f.name, - overloads: make([]*overloadDecl, len(f.overloads)), - options: []FunctionOpt{}, - initialized: true, - singleton: f.singleton, - } - copy(merged.overloads, f.overloads) - for _, o := range other.overloads { - err := merged.addOverload(o) - if err != nil { - return nil, fmt.Errorf("function declaration merge failed: %v", err) - } - } - if other.singleton != nil { - if merged.singleton != nil { - return nil, fmt.Errorf("function already has a binding: %s", f.name) - } - merged.singleton = other.singleton - } - return merged, nil -} - -// addOverload ensures that the new overload does not collide with an existing overload signature; -// however, if the function signatures are identical, the implementation may be rewritten as its -// difficult to compare functions by object identity. -func (f *functionDecl) addOverload(overload *overloadDecl) error { - for index, o := range f.overloads { - if o.id != overload.id && o.signatureOverlaps(overload) { - return fmt.Errorf("overload signature collision in function %s: %s collides with %s", f.name, o.id, overload.id) - } - if o.id == overload.id { - if o.signatureEquals(overload) && o.nonStrict == overload.nonStrict { - // Allow redefinition of an overload implementation so long as the signatures match. - f.overloads[index] = overload - return nil - } else { - return fmt.Errorf("overload redefinition in function. %s: %s has multiple definitions", f.name, o.id) - } - } - } - f.overloads = append(f.overloads, overload) - return nil -} - -func noSuchOverload(funcName string, args ...ref.Val) ref.Val { - argTypes := make([]string, len(args)) - for i, arg := range args { - argTypes[i] = arg.Type().TypeName() - } - signature := strings.Join(argTypes, ", ") - return types.NewErr("no such overload: %s(%s)", funcName, signature) -} - -// overloadDecl contains all of the relevant information regarding a specific function overload. -type overloadDecl struct { - id string - argTypes []*Type - resultType *Type - memberFunction bool - - // binding options, optional but encouraged. - unaryOp functions.UnaryOp - binaryOp functions.BinaryOp - functionOp functions.FunctionOp - - // behavioral options, uncommon - nonStrict bool - operandTrait int -} - -func (o *overloadDecl) hasBinding() bool { - return o.unaryOp != nil || o.binaryOp != nil || o.functionOp != nil -} - -// guardedUnaryOp creates an invocation guard around the provided unary operator, if one is defined. -func (o *overloadDecl) guardedUnaryOp(funcName string) functions.UnaryOp { - if o.unaryOp == nil { - return nil - } - return func(arg ref.Val) ref.Val { - if !o.matchesRuntimeUnarySignature(arg) { - return noSuchOverload(funcName, arg) - } - return o.unaryOp(arg) - } -} - -// guardedBinaryOp creates an invocation guard around the provided binary operator, if one is defined. -func (o *overloadDecl) guardedBinaryOp(funcName string) functions.BinaryOp { - if o.binaryOp == nil { - return nil - } - return func(arg1, arg2 ref.Val) ref.Val { - if !o.matchesRuntimeBinarySignature(arg1, arg2) { - return noSuchOverload(funcName, arg1, arg2) - } - return o.binaryOp(arg1, arg2) - } -} - -// guardedFunctionOp creates an invocation guard around the provided variadic function binding, if one is provided. -func (o *overloadDecl) guardedFunctionOp(funcName string) functions.FunctionOp { - if o.functionOp == nil { - return nil - } - return func(args ...ref.Val) ref.Val { - if !o.matchesRuntimeSignature(args...) { - return noSuchOverload(funcName, args...) - } - return o.functionOp(args...) - } -} - -// matchesRuntimeUnarySignature indicates whether the argument type is runtime assiganble to the overload's expected argument. -func (o *overloadDecl) matchesRuntimeUnarySignature(arg ref.Val) bool { - if o.nonStrict && types.IsUnknownOrError(arg) { - return true - } - return o.argTypes[0].IsAssignableRuntimeType(arg) && (o.operandTrait == 0 || arg.Type().HasTrait(o.operandTrait)) -} - -// matchesRuntimeBinarySignature indicates whether the argument types are runtime assiganble to the overload's expected arguments. -func (o *overloadDecl) matchesRuntimeBinarySignature(arg1, arg2 ref.Val) bool { - if o.nonStrict { - if types.IsUnknownOrError(arg1) { - return types.IsUnknownOrError(arg2) || o.argTypes[1].IsAssignableRuntimeType(arg2) - } - } else if !o.argTypes[1].IsAssignableRuntimeType(arg2) { - return false - } - return o.argTypes[0].IsAssignableRuntimeType(arg1) && (o.operandTrait == 0 || arg1.Type().HasTrait(o.operandTrait)) -} - -// matchesRuntimeSignature indicates whether the argument types are runtime assiganble to the overload's expected arguments. -func (o *overloadDecl) matchesRuntimeSignature(args ...ref.Val) bool { - if len(args) != len(o.argTypes) { - return false - } - if len(args) == 0 { - return true - } - allArgsMatch := true - for i, arg := range args { - if o.nonStrict && types.IsUnknownOrError(arg) { - continue - } - allArgsMatch = allArgsMatch && o.argTypes[i].IsAssignableRuntimeType(arg) - } - - arg := args[0] - return allArgsMatch && (o.operandTrait == 0 || (o.nonStrict && types.IsUnknownOrError(arg)) || arg.Type().HasTrait(o.operandTrait)) -} - -// signatureEquals indicates whether one overload has an identical signature to another overload. -// -// Providing a duplicate signature is not an issue, but an overloapping signature is problematic. -func (o *overloadDecl) signatureEquals(other *overloadDecl) bool { - if o.id != other.id || o.memberFunction != other.memberFunction || len(o.argTypes) != len(other.argTypes) { - return false - } - for i, at := range o.argTypes { - oat := other.argTypes[i] - if !at.equals(oat) { - return false - } - } - return o.resultType.equals(other.resultType) -} - -// signatureOverlaps indicates whether one overload has an overlapping signature with another overload. -// -// The 'other' overload must first be checked for equality before determining whether it overlaps in order to be completely accurate. -func (o *overloadDecl) signatureOverlaps(other *overloadDecl) bool { - if o.memberFunction != other.memberFunction || len(o.argTypes) != len(other.argTypes) { - return false - } - argsOverlap := true - for i, argType := range o.argTypes { - otherArgType := other.argTypes[i] - argsOverlap = argsOverlap && - (argType.IsAssignableType(otherArgType) || - otherArgType.IsAssignableType(argType)) - } - return argsOverlap -} - -func newOverload(overloadID string, memberFunction bool, args []*Type, resultType *Type, opts ...OverloadOpt) FunctionOpt { - return func(f *functionDecl) (*functionDecl, error) { - overload := &overloadDecl{ - id: overloadID, - argTypes: args, - resultType: resultType, - memberFunction: memberFunction, - } - var err error - for _, opt := range opts { - overload, err = opt(overload) - if err != nil { - return nil, err - } - } - err = f.addOverload(overload) - if err != nil { - return nil, err - } - return f, nil - } -} - -func maybeWrapper(t *Type, pbType *exprpb.Type) *exprpb.Type { - if t.IsAssignableType(NullType) { - return decls.NewWrapperType(pbType) - } - return pbType + return decls.OverloadOperandTrait(trait) } // TypeToExprType converts a CEL-native type representation to a protobuf CEL Type representation. func TypeToExprType(t *Type) (*exprpb.Type, error) { - switch t.kind { - case AnyKind: - return decls.Any, nil - case BoolKind: - return maybeWrapper(t, decls.Bool), nil - case BytesKind: - return maybeWrapper(t, decls.Bytes), nil - case DoubleKind: - return maybeWrapper(t, decls.Double), nil - case DurationKind: - return decls.Duration, nil - case DynKind: - return decls.Dyn, nil - case IntKind: - return maybeWrapper(t, decls.Int), nil - case ListKind: - et, err := TypeToExprType(t.parameters[0]) - if err != nil { - return nil, err - } - return decls.NewListType(et), nil - case MapKind: - kt, err := TypeToExprType(t.parameters[0]) - if err != nil { - return nil, err - } - vt, err := TypeToExprType(t.parameters[1]) - if err != nil { - return nil, err - } - return decls.NewMapType(kt, vt), nil - case NullTypeKind: - return decls.Null, nil - case OpaqueKind: - params := make([]*exprpb.Type, len(t.parameters)) - for i, p := range t.parameters { - pt, err := TypeToExprType(p) - if err != nil { - return nil, err - } - params[i] = pt - } - return decls.NewAbstractType(t.runtimeType.TypeName(), params...), nil - case StringKind: - return maybeWrapper(t, decls.String), nil - case StructKind: - switch t.runtimeType.TypeName() { - case "google.protobuf.Any": - return decls.Any, nil - case "google.protobuf.Duration": - return decls.Duration, nil - case "google.protobuf.Timestamp": - return decls.Timestamp, nil - case "google.protobuf.Value": - return decls.Dyn, nil - case "google.protobuf.ListValue": - return decls.NewListType(decls.Dyn), nil - case "google.protobuf.Struct": - return decls.NewMapType(decls.String, decls.Dyn), nil - case "google.protobuf.BoolValue": - return decls.NewWrapperType(decls.Bool), nil - case "google.protobuf.BytesValue": - return decls.NewWrapperType(decls.Bytes), nil - case "google.protobuf.DoubleValue", "google.protobuf.FloatValue": - return decls.NewWrapperType(decls.Double), nil - case "google.protobuf.Int32Value", "google.protobuf.Int64Value": - return decls.NewWrapperType(decls.Int), nil - case "google.protobuf.StringValue": - return decls.NewWrapperType(decls.String), nil - case "google.protobuf.UInt32Value", "google.protobuf.UInt64Value": - return decls.NewWrapperType(decls.Uint), nil - default: - return decls.NewObjectType(t.runtimeType.TypeName()), nil - } - case TimestampKind: - return decls.Timestamp, nil - case TypeParamKind: - return decls.NewTypeParamType(t.runtimeType.TypeName()), nil - case TypeKind: - return decls.NewTypeType(decls.Dyn), nil - case UintKind: - return maybeWrapper(t, decls.Uint), nil - } - return nil, fmt.Errorf("missing type conversion to proto: %v", t) + return types.TypeToExprType(t) } // ExprTypeToType converts a protobuf CEL type representation to a CEL-native type representation. func ExprTypeToType(t *exprpb.Type) (*Type, error) { - switch t.GetTypeKind().(type) { - case *exprpb.Type_Dyn: - return DynType, nil - case *exprpb.Type_AbstractType_: - paramTypes := make([]*Type, len(t.GetAbstractType().GetParameterTypes())) - for i, p := range t.GetAbstractType().GetParameterTypes() { - pt, err := ExprTypeToType(p) - if err != nil { - return nil, err - } - paramTypes[i] = pt - } - return OpaqueType(t.GetAbstractType().GetName(), paramTypes...), nil - case *exprpb.Type_ListType_: - et, err := ExprTypeToType(t.GetListType().GetElemType()) - if err != nil { - return nil, err - } - return ListType(et), nil - case *exprpb.Type_MapType_: - kt, err := ExprTypeToType(t.GetMapType().GetKeyType()) - if err != nil { - return nil, err - } - vt, err := ExprTypeToType(t.GetMapType().GetValueType()) - if err != nil { - return nil, err - } - return MapType(kt, vt), nil - case *exprpb.Type_MessageType: - switch t.GetMessageType() { - case "google.protobuf.Any": - return AnyType, nil - case "google.protobuf.Duration": - return DurationType, nil - case "google.protobuf.Timestamp": - return TimestampType, nil - case "google.protobuf.Value": - return DynType, nil - case "google.protobuf.ListValue": - return ListType(DynType), nil - case "google.protobuf.Struct": - return MapType(StringType, DynType), nil - case "google.protobuf.BoolValue": - return NullableType(BoolType), nil - case "google.protobuf.BytesValue": - return NullableType(BytesType), nil - case "google.protobuf.DoubleValue", "google.protobuf.FloatValue": - return NullableType(DoubleType), nil - case "google.protobuf.Int32Value", "google.protobuf.Int64Value": - return NullableType(IntType), nil - case "google.protobuf.StringValue": - return NullableType(StringType), nil - case "google.protobuf.UInt32Value", "google.protobuf.UInt64Value": - return NullableType(UintType), nil - default: - return ObjectType(t.GetMessageType()), nil - } - case *exprpb.Type_Null: - return NullType, nil - case *exprpb.Type_Primitive: - switch t.GetPrimitive() { - case exprpb.Type_BOOL: - return BoolType, nil - case exprpb.Type_BYTES: - return BytesType, nil - case exprpb.Type_DOUBLE: - return DoubleType, nil - case exprpb.Type_INT64: - return IntType, nil - case exprpb.Type_STRING: - return StringType, nil - case exprpb.Type_UINT64: - return UintType, nil - default: - return nil, fmt.Errorf("unsupported primitive type: %v", t) - } - case *exprpb.Type_TypeParam: - return TypeParamType(t.GetTypeParam()), nil - case *exprpb.Type_Type: - return TypeType, nil - case *exprpb.Type_WellKnown: - switch t.GetWellKnown() { - case exprpb.Type_ANY: - return AnyType, nil - case exprpb.Type_DURATION: - return DurationType, nil - case exprpb.Type_TIMESTAMP: - return TimestampType, nil - default: - return nil, fmt.Errorf("unsupported well-known type: %v", t) - } - case *exprpb.Type_Wrapper: - t, err := ExprTypeToType(&exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: t.GetWrapper()}}) - if err != nil { - return nil, err - } - return NullableType(t), nil - default: - return nil, fmt.Errorf("unsupported type: %v", t) - } + return types.ExprTypeToType(t) } // ExprDeclToDeclaration converts a protobuf CEL declaration to a CEL-native declaration, either a Variable or Function. @@ -1131,77 +319,77 @@ func ExprDeclToDeclaration(d *exprpb.Decl) (EnvOption, error) { for i, o := range overloads { args := make([]*Type, len(o.GetParams())) for j, p := range o.GetParams() { - a, err := ExprTypeToType(p) + a, err := types.ExprTypeToType(p) if err != nil { return nil, err } args[j] = a } - res, err := ExprTypeToType(o.GetResultType()) + res, err := types.ExprTypeToType(o.GetResultType()) if err != nil { return nil, err } - opts[i] = Overload(o.GetOverloadId(), args, res) + if o.IsInstanceFunction { + opts[i] = decls.MemberOverload(o.GetOverloadId(), args, res) + } else { + opts[i] = decls.Overload(o.GetOverloadId(), args, res) + } } return Function(d.GetName(), opts...), nil case *exprpb.Decl_Ident: - t, err := ExprTypeToType(d.GetIdent().GetType()) + t, err := types.ExprTypeToType(d.GetIdent().GetType()) if err != nil { return nil, err } - return Variable(d.GetName(), t), nil - default: - return nil, fmt.Errorf("unsupported decl: %v", d) - } - -} - -func functionDeclToExprDecl(f *functionDecl) (*exprpb.Decl, error) { - overloads := make([]*exprpb.Decl_FunctionDecl_Overload, len(f.overloads)) - i := 0 - for _, o := range f.overloads { - paramNames := map[string]struct{}{} - argTypes := make([]*exprpb.Type, len(o.argTypes)) - for j, a := range o.argTypes { - collectParamNames(paramNames, a) - at, err := TypeToExprType(a) - if err != nil { - return nil, err - } - argTypes[j] = at + if d.GetIdent().GetValue() == nil { + return Variable(d.GetName(), t), nil } - collectParamNames(paramNames, o.resultType) - resultType, err := TypeToExprType(o.resultType) + val, err := ast.ConstantToVal(d.GetIdent().GetValue()) if err != nil { return nil, err } - if len(paramNames) == 0 { - if o.memberFunction { - overloads[i] = decls.NewInstanceOverload(o.id, argTypes, resultType) - } else { - overloads[i] = decls.NewOverload(o.id, argTypes, resultType) - } - } else { - params := []string{} - for pn := range paramNames { - params = append(params, pn) - } - if o.memberFunction { - overloads[i] = decls.NewParameterizedInstanceOverload(o.id, argTypes, resultType, params) - } else { - overloads[i] = decls.NewParameterizedOverload(o.id, argTypes, resultType, params) - } - } - i++ + return Constant(d.GetName(), t, val), nil + default: + return nil, fmt.Errorf("unsupported decl: %v", d) } - return decls.NewFunction(f.name, overloads...), nil } -func collectParamNames(paramNames map[string]struct{}, arg *Type) { - if arg.kind == TypeParamKind { - paramNames[arg.runtimeType.TypeName()] = struct{}{} - } - for _, param := range arg.parameters { - collectParamNames(paramNames, param) +func typeValueToKind(tv ref.Type) (Kind, error) { + switch tv { + case types.BoolType: + return BoolKind, nil + case types.DoubleType: + return DoubleKind, nil + case types.IntType: + return IntKind, nil + case types.UintType: + return UintKind, nil + case types.ListType: + return ListKind, nil + case types.MapType: + return MapKind, nil + case types.StringType: + return StringKind, nil + case types.BytesType: + return BytesKind, nil + case types.DurationType: + return DurationKind, nil + case types.TimestampType: + return TimestampKind, nil + case types.NullType: + return NullTypeKind, nil + case types.TypeType: + return TypeKind, nil + default: + switch tv.TypeName() { + case "dyn": + return DynKind, nil + case "google.protobuf.Any": + return AnyKind, nil + case "optional": + return OpaqueKind, nil + default: + return 0, fmt.Errorf("no known conversion for type of %s", tv.TypeName()) + } } } diff --git a/vendor/github.com/google/cel-go/cel/env.go b/vendor/github.com/google/cel-go/cel/env.go index 1a0b11ec7..69ba34dbd 100644 --- a/vendor/github.com/google/cel-go/cel/env.go +++ b/vendor/github.com/google/cel-go/cel/env.go @@ -16,13 +16,14 @@ package cel import ( "errors" - "fmt" "sync" "github.com/google/cel-go/checker" - "github.com/google/cel-go/checker/decls" + chkdecls "github.com/google/cel-go/checker/decls" "github.com/google/cel-go/common" + celast "github.com/google/cel-go/common/ast" "github.com/google/cel-go/common/containers" + "github.com/google/cel-go/common/decls" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/interpreter" @@ -40,8 +41,8 @@ type Ast struct { expr *exprpb.Expr info *exprpb.SourceInfo source Source - refMap map[int64]*exprpb.Reference - typeMap map[int64]*exprpb.Type + refMap map[int64]*celast.ReferenceInfo + typeMap map[int64]*types.Type } // Expr returns the proto serializable instance of the parsed/checked expression. @@ -60,21 +61,26 @@ func (ast *Ast) SourceInfo() *exprpb.SourceInfo { } // ResultType returns the output type of the expression if the Ast has been type-checked, else -// returns decls.Dyn as the parse step cannot infer the type. +// returns chkdecls.Dyn as the parse step cannot infer the type. // // Deprecated: use OutputType func (ast *Ast) ResultType() *exprpb.Type { if !ast.IsChecked() { - return decls.Dyn + return chkdecls.Dyn } - return ast.typeMap[ast.expr.GetId()] + out := ast.OutputType() + t, err := TypeToExprType(out) + if err != nil { + return chkdecls.Dyn + } + return t } // OutputType returns the output type of the expression if the Ast has been type-checked, else // returns cel.DynType as the parse step cannot infer types. func (ast *Ast) OutputType() *Type { - t, err := ExprTypeToType(ast.ResultType()) - if err != nil { + t, found := ast.typeMap[ast.expr.GetId()] + if !found { return DynType } return t @@ -87,32 +93,43 @@ func (ast *Ast) Source() Source { } // FormatType converts a type message into a string representation. +// +// Deprecated: prefer FormatCELType func FormatType(t *exprpb.Type) string { return checker.FormatCheckedType(t) } +// FormatCELType formats a cel.Type value to a string representation. +// +// The type formatting is identical to FormatType. +func FormatCELType(t *Type) string { + return checker.FormatCELType(t) +} + // Env encapsulates the context necessary to perform parsing, type checking, or generation of // evaluable programs for different expressions. type Env struct { Container *containers.Container - functions map[string]*functionDecl - declarations []*exprpb.Decl + variables []*decls.VariableDecl + functions map[string]*decls.FunctionDecl macros []parser.Macro - adapter ref.TypeAdapter - provider ref.TypeProvider + adapter types.Adapter + provider types.Provider features map[int]bool appliedFeatures map[int]bool libraries map[string]bool + validators []ASTValidator // Internal parser representation prsr *parser.Parser prsrOpts []parser.Option // Internal checker representation - chk *checker.Env - chkErr error - chkOnce sync.Once - chkOpts []checker.Option + chkMutex sync.Mutex + chk *checker.Env + chkErr error + chkOnce sync.Once + chkOpts []checker.Option // Program options tied to the environment progOpts []ProgramOption @@ -153,8 +170,8 @@ func NewCustomEnv(opts ...EnvOption) (*Env, error) { return nil, err } return (&Env{ - declarations: []*exprpb.Decl{}, - functions: map[string]*functionDecl{}, + variables: []*decls.VariableDecl{}, + functions: map[string]*decls.FunctionDecl{}, macros: []parser.Macro{}, Container: containers.DefaultContainer, adapter: registry, @@ -162,14 +179,19 @@ func NewCustomEnv(opts ...EnvOption) (*Env, error) { features: map[int]bool{}, appliedFeatures: map[int]bool{}, libraries: map[string]bool{}, + validators: []ASTValidator{}, progOpts: []ProgramOption{}, }).configure(opts) } // Check performs type-checking on the input Ast and yields a checked Ast and/or set of Issues. +// If any `ASTValidators` are configured on the environment, they will be applied after a valid +// type-check result. If any issues are detected, the validators will provide them on the +// output Issues object. // -// Checking has failed if the returned Issues value and its Issues.Err() value are non-nil. -// Issues should be inspected if they are non-nil, but may not represent a fatal error. +// Either checking or validation has failed if the returned Issues value and its Issues.Err() +// value are non-nil. Issues should be inspected if they are non-nil, but may not represent a +// fatal error. // // It is possible to have both non-nil Ast and Issues values returned from this call: however, // the mere presence of an Ast does not imply that it is valid for use. @@ -178,25 +200,42 @@ func (e *Env) Check(ast *Ast) (*Ast, *Issues) { pe, _ := AstToParsedExpr(ast) // Construct the internal checker env, erroring if there is an issue adding the declarations. - err := e.initChecker() + chk, err := e.initChecker() if err != nil { errs := common.NewErrors(ast.Source()) - errs.ReportError(common.NoLocation, e.chkErr.Error()) - return nil, NewIssues(errs) + errs.ReportError(common.NoLocation, err.Error()) + return nil, NewIssuesWithSourceInfo(errs, ast.SourceInfo()) } - res, errs := checker.Check(pe, ast.Source(), e.chk) + res, errs := checker.Check(pe, ast.Source(), chk) if len(errs.GetErrors()) > 0 { - return nil, NewIssues(errs) + return nil, NewIssuesWithSourceInfo(errs, ast.SourceInfo()) } // Manually create the Ast to ensure that the Ast source information (which may be more // detailed than the information provided by Check), is returned to the caller. - return &Ast{ + ast = &Ast{ source: ast.Source(), - expr: res.GetExpr(), - info: res.GetSourceInfo(), - refMap: res.GetReferenceMap(), - typeMap: res.GetTypeMap()}, nil + expr: res.Expr, + info: res.SourceInfo, + refMap: res.ReferenceMap, + typeMap: res.TypeMap} + + // Generate a validator configuration from the set of configured validators. + vConfig := newValidatorConfig() + for _, v := range e.validators { + if cv, ok := v.(ASTValidatorConfigurer); ok { + cv.Configure(vConfig) + } + } + // Apply additional validators on the type-checked result. + iss := NewIssuesWithSourceInfo(errs, ast.SourceInfo()) + for _, v := range e.validators { + v.Validate(e, vConfig, res, iss) + } + if iss.Err() != nil { + return nil, iss + } + return ast, nil } // Compile combines the Parse and Check phases CEL program compilation to produce an Ast and @@ -239,8 +278,9 @@ func (e *Env) CompileSource(src Source) (*Ast, *Issues) { // TypeProvider are immutable, or that their underlying implementations are based on the // ref.TypeRegistry which provides a Copy method which will be invoked by this method. func (e *Env) Extend(opts ...EnvOption) (*Env, error) { - if e.chkErr != nil { - return nil, e.chkErr + chk, chkErr := e.getCheckerOrError() + if chkErr != nil { + return nil, chkErr } prsrOptsCopy := make([]parser.Option, len(e.prsrOpts)) @@ -253,16 +293,16 @@ func (e *Env) Extend(opts ...EnvOption) (*Env, error) { copy(chkOptsCopy, e.chkOpts) // Copy the declarations if needed. - decsCopy := []*exprpb.Decl{} - if e.chk != nil { + varsCopy := []*decls.VariableDecl{} + if chk != nil { // If the type-checker has already been instantiated, then the e.declarations have been - // valdiated within the chk instance. - chkOptsCopy = append(chkOptsCopy, checker.ValidatedDeclarations(e.chk)) + // validated within the chk instance. + chkOptsCopy = append(chkOptsCopy, checker.ValidatedDeclarations(chk)) } else { // If the type-checker has not been instantiated, ensure the unvalidated declarations are // provided to the extended Env instance. - decsCopy = make([]*exprpb.Decl, len(e.declarations)) - copy(decsCopy, e.declarations) + varsCopy = make([]*decls.VariableDecl, len(e.variables)) + copy(varsCopy, e.variables) } // Copy macros and program options @@ -274,8 +314,8 @@ func (e *Env) Extend(opts ...EnvOption) (*Env, error) { // Copy the adapter / provider if they appear to be mutable. adapter := e.adapter provider := e.provider - adapterReg, isAdapterReg := e.adapter.(ref.TypeRegistry) - providerReg, isProviderReg := e.provider.(ref.TypeRegistry) + adapterReg, isAdapterReg := e.adapter.(*types.Registry) + providerReg, isProviderReg := e.provider.(*types.Registry) // In most cases the provider and adapter will be a ref.TypeRegistry; // however, in the rare cases where they are not, they are assumed to // be immutable. Since it is possible to set the TypeProvider separately @@ -306,7 +346,7 @@ func (e *Env) Extend(opts ...EnvOption) (*Env, error) { for k, v := range e.appliedFeatures { appliedFeaturesCopy[k] = v } - funcsCopy := make(map[string]*functionDecl, len(e.functions)) + funcsCopy := make(map[string]*decls.FunctionDecl, len(e.functions)) for k, v := range e.functions { funcsCopy[k] = v } @@ -314,10 +354,12 @@ func (e *Env) Extend(opts ...EnvOption) (*Env, error) { for k, v := range e.libraries { libsCopy[k] = v } + validatorsCopy := make([]ASTValidator, len(e.validators)) + copy(validatorsCopy, e.validators) ext := &Env{ Container: e.Container, - declarations: decsCopy, + variables: varsCopy, functions: funcsCopy, macros: macsCopy, progOpts: progOptsCopy, @@ -325,6 +367,7 @@ func (e *Env) Extend(opts ...EnvOption) (*Env, error) { features: featuresCopy, appliedFeatures: appliedFeaturesCopy, libraries: libsCopy, + validators: validatorsCopy, provider: provider, chkOpts: chkOptsCopy, prsrOpts: prsrOptsCopy, @@ -345,6 +388,25 @@ func (e *Env) HasLibrary(libName string) bool { return exists && configured } +// Libraries returns a list of SingletonLibrary that have been configured in the environment. +func (e *Env) Libraries() []string { + libraries := make([]string, 0, len(e.libraries)) + for libName := range e.libraries { + libraries = append(libraries, libName) + } + return libraries +} + +// HasValidator returns whether a specific ASTValidator has been configured in the environment. +func (e *Env) HasValidator(name string) bool { + for _, v := range e.validators { + if v.Name() == name { + return true + } + } + return false +} + // Parse parses the input expression value `txt` to a Ast and/or a set of Issues. // // This form of Parse creates a Source value for the input `txt` and forwards to the @@ -386,36 +448,64 @@ func (e *Env) Program(ast *Ast, opts ...ProgramOption) (Program, error) { return newProgram(e, ast, optSet) } +// CELTypeAdapter returns the `types.Adapter` configured for the environment. +func (e *Env) CELTypeAdapter() types.Adapter { + return e.adapter +} + +// CELTypeProvider returns the `types.Provider` configured for the environment. +func (e *Env) CELTypeProvider() types.Provider { + return e.provider +} + // TypeAdapter returns the `ref.TypeAdapter` configured for the environment. +// +// Deprecated: use CELTypeAdapter() func (e *Env) TypeAdapter() ref.TypeAdapter { return e.adapter } // TypeProvider returns the `ref.TypeProvider` configured for the environment. +// +// Deprecated: use CELTypeProvider() func (e *Env) TypeProvider() ref.TypeProvider { - return e.provider + if legacyProvider, ok := e.provider.(ref.TypeProvider); ok { + return legacyProvider + } + return &interopLegacyTypeProvider{Provider: e.provider} } -// UnknownVars returns an interpreter.PartialActivation which marks all variables -// declared in the Env as unknown AttributePattern values. +// UnknownVars returns an interpreter.PartialActivation which marks all variables declared in the +// Env as unknown AttributePattern values. // -// Note, the UnknownVars will behave the same as an interpreter.EmptyActivation -// unless the PartialAttributes option is provided as a ProgramOption. +// Note, the UnknownVars will behave the same as an interpreter.EmptyActivation unless the +// PartialAttributes option is provided as a ProgramOption. func (e *Env) UnknownVars() interpreter.PartialActivation { - var unknownPatterns []*interpreter.AttributePattern - for _, d := range e.declarations { - switch d.GetDeclKind().(type) { - case *exprpb.Decl_Ident: - unknownPatterns = append(unknownPatterns, - interpreter.NewAttributePattern(d.GetName())) - } - } - part, _ := PartialVars( - interpreter.EmptyActivation(), - unknownPatterns...) + act := interpreter.EmptyActivation() + part, _ := PartialVars(act, e.computeUnknownVars(act)...) return part } +// PartialVars returns an interpreter.PartialActivation where all variables not in the input variable +// set, but which have been configured in the environment, are marked as unknown. +// +// The `vars` value may either be an interpreter.Activation or any valid input to the +// interpreter.NewActivation call. +// +// Note, this is equivalent to calling cel.PartialVars and manually configuring the set of unknown +// variables. For more advanced use cases of partial state where portions of an object graph, rather +// than top-level variables, are missing the PartialVars() method may be a more suitable choice. +// +// Note, the PartialVars will behave the same as an interpreter.EmptyActivation unless the +// PartialAttributes option is provided as a ProgramOption. +func (e *Env) PartialVars(vars any) (interpreter.PartialActivation, error) { + act, err := interpreter.NewActivation(vars) + if err != nil { + return nil, err + } + return PartialVars(act, e.computeUnknownVars(act)...) +} + // ResidualAst takes an Ast and its EvalDetails to produce a new Ast which only contains the // attribute references which are unknown. // @@ -439,8 +529,8 @@ func (e *Env) UnknownVars() interpreter.PartialActivation { // TODO: Consider adding an option to generate a Program.Residual to avoid round-tripping to an // Ast format and then Program again. func (e *Env) ResidualAst(a *Ast, details *EvalDetails) (*Ast, error) { - pruned := interpreter.PruneAst(a.Expr(), details.State()) - expr, err := AstToString(ParsedExprToAst(&exprpb.ParsedExpr{Expr: pruned})) + pruned := interpreter.PruneAst(a.Expr(), a.SourceInfo().GetMacroCalls(), details.State()) + expr, err := AstToString(ParsedExprToAst(pruned)) if err != nil { return nil, err } @@ -460,12 +550,14 @@ func (e *Env) ResidualAst(a *Ast, details *EvalDetails) (*Ast, error) { // EstimateCost estimates the cost of a type checked CEL expression using the length estimates of input data and // extension functions provided by estimator. -func (e *Env) EstimateCost(ast *Ast, estimator checker.CostEstimator) (checker.CostEstimate, error) { - checked, err := AstToCheckedExpr(ast) - if err != nil { - return checker.CostEstimate{}, fmt.Errorf("EsimateCost could not inspect Ast: %v", err) +func (e *Env) EstimateCost(ast *Ast, estimator checker.CostEstimator, opts ...checker.CostOption) (checker.CostEstimate, error) { + checked := &celast.CheckedAST{ + Expr: ast.Expr(), + SourceInfo: ast.SourceInfo(), + TypeMap: ast.typeMap, + ReferenceMap: ast.refMap, } - return checker.Cost(checked, estimator), nil + return checker.Cost(checked, estimator, opts...) } // configure applies a series of EnvOptions to the current environment. @@ -486,14 +578,6 @@ func (e *Env) configure(opts []EnvOption) (*Env, error) { return nil, err } - // Initialize all of the functions configured within the environment. - for _, fn := range e.functions { - err = fn.init() - if err != nil { - return nil, err - } - } - // Configure the parser. prsrOpts := []parser.Option{} prsrOpts = append(prsrOpts, e.prsrOpts...) @@ -502,6 +586,9 @@ func (e *Env) configure(opts []EnvOption) (*Env, error) { if e.HasFeature(featureEnableMacroCallTracking) { prsrOpts = append(prsrOpts, parser.PopulateMacroCalls(true)) } + if e.HasFeature(featureVariadicLogicalASTs) { + prsrOpts = append(prsrOpts, parser.EnableVariadicOperatorASTs(true)) + } e.prsr, err = parser.NewParser(prsrOpts...) if err != nil { return nil, err @@ -509,7 +596,7 @@ func (e *Env) configure(opts []EnvOption) (*Env, error) { // Ensure that the checker init happens eagerly rather than lazily. if e.HasFeature(featureEagerlyValidateDeclarations) { - err := e.initChecker() + _, err := e.initChecker() if err != nil { return nil, err } @@ -518,44 +605,55 @@ func (e *Env) configure(opts []EnvOption) (*Env, error) { return e, nil } -func (e *Env) initChecker() error { +func (e *Env) initChecker() (*checker.Env, error) { e.chkOnce.Do(func() { chkOpts := []checker.Option{} chkOpts = append(chkOpts, e.chkOpts...) chkOpts = append(chkOpts, - checker.HomogeneousAggregateLiterals( - e.HasFeature(featureDisableDynamicAggregateLiterals)), checker.CrossTypeNumericComparisons( e.HasFeature(featureCrossTypeNumericComparisons))) ce, err := checker.NewEnv(e.Container, e.provider, chkOpts...) if err != nil { - e.chkErr = err + e.setCheckerOrError(nil, err) return } // Add the statically configured declarations. - err = ce.Add(e.declarations...) + err = ce.AddIdents(e.variables...) if err != nil { - e.chkErr = err + e.setCheckerOrError(nil, err) return } // Add the function declarations which are derived from the FunctionDecl instances. for _, fn := range e.functions { - fnDecl, err := functionDeclToExprDecl(fn) - if err != nil { - e.chkErr = err - return + if fn.IsDeclarationDisabled() { + continue } - err = ce.Add(fnDecl) + err = ce.AddFunctions(fn) if err != nil { - e.chkErr = err + e.setCheckerOrError(nil, err) return } } // Add function declarations here separately. - e.chk = ce + e.setCheckerOrError(ce, nil) }) - return e.chkErr + return e.getCheckerOrError() +} + +// setCheckerOrError sets the checker.Env or error state in a concurrency-safe manner +func (e *Env) setCheckerOrError(chk *checker.Env, chkErr error) { + e.chkMutex.Lock() + e.chk = chk + e.chkErr = chkErr + e.chkMutex.Unlock() +} + +// getCheckerOrError gets the checker.Env or error state in a concurrency-safe manner +func (e *Env) getCheckerOrError() (*checker.Env, error) { + e.chkMutex.Lock() + defer e.chkMutex.Unlock() + return e.chk, e.chkErr } // maybeApplyFeature determines whether the feature-guarded option is enabled, and if so applies @@ -579,17 +677,43 @@ func (e *Env) maybeApplyFeature(feature int, option EnvOption) (*Env, error) { return e, nil } +// computeUnknownVars determines a set of missing variables based on the input activation and the +// environment's configured declaration set. +func (e *Env) computeUnknownVars(vars interpreter.Activation) []*interpreter.AttributePattern { + var unknownPatterns []*interpreter.AttributePattern + for _, v := range e.variables { + varName := v.Name() + if _, found := vars.ResolveName(varName); found { + continue + } + unknownPatterns = append(unknownPatterns, interpreter.NewAttributePattern(varName)) + } + return unknownPatterns +} + +// Error type which references an expression id, a location within source, and a message. +type Error = common.Error + // Issues defines methods for inspecting the error details of parse and check calls. // // Note: in the future, non-fatal warnings and notices may be inspectable via the Issues struct. type Issues struct { errs *common.Errors + info *exprpb.SourceInfo } // NewIssues returns an Issues struct from a common.Errors object. func NewIssues(errs *common.Errors) *Issues { + return NewIssuesWithSourceInfo(errs, nil) +} + +// NewIssuesWithSourceInfo returns an Issues struct from a common.Errors object with SourceInfo metatata +// which can be used with the `ReportErrorAtID` method for additional error reports within the context +// information that's inferred from an expression id. +func NewIssuesWithSourceInfo(errs *common.Errors, info *exprpb.SourceInfo) *Issues { return &Issues{ errs: errs, + info: info, } } @@ -605,9 +729,9 @@ func (i *Issues) Err() error { } // Errors returns the collection of errors encountered in more granular detail. -func (i *Issues) Errors() []common.Error { +func (i *Issues) Errors() []*Error { if i == nil { - return []common.Error{} + return []*Error{} } return i.errs.GetErrors() } @@ -631,6 +755,37 @@ func (i *Issues) String() string { return i.errs.ToDisplayString() } +// ReportErrorAtID reports an error message with an optional set of formatting arguments. +// +// The source metadata for the expression at `id`, if present, is attached to the error report. +// To ensure that source metadata is attached to error reports, use NewIssuesWithSourceInfo. +func (i *Issues) ReportErrorAtID(id int64, message string, args ...any) { + i.errs.ReportErrorAtID(id, locationByID(id, i.info), message, args...) +} + +// locationByID returns a common.Location given an expression id. +// +// TODO: move this functionality into the native SourceInfo and an overhaul of the common.Source +// as this implementation relies on the abstractions present in the protobuf SourceInfo object, +// and is replicated in the checker. +func locationByID(id int64, sourceInfo *exprpb.SourceInfo) common.Location { + positions := sourceInfo.GetPositions() + var line = 1 + if offset, found := positions[id]; found { + col := int(offset) + for _, lineOffset := range sourceInfo.GetLineOffsets() { + if lineOffset < offset { + line++ + col = int(offset - lineOffset) + } else { + break + } + } + return common.NewLocation(line, col) + } + return common.NoLocation +} + // getStdEnv lazy initializes the CEL standard environment. func getStdEnv() (*Env, error) { stdEnvInit.Do(func() { @@ -639,6 +794,90 @@ func getStdEnv() (*Env, error) { return stdEnv, stdEnvErr } +// interopCELTypeProvider layers support for the types.Provider interface on top of a ref.TypeProvider. +type interopCELTypeProvider struct { + ref.TypeProvider +} + +// FindStructType returns a types.Type instance for the given fully-qualified typeName if one exists. +// +// This method proxies to the underyling ref.TypeProvider's FindType method and converts protobuf type +// into a native type representation. If the conversion fails, the type is listed as not found. +func (p *interopCELTypeProvider) FindStructType(typeName string) (*types.Type, bool) { + if et, found := p.FindType(typeName); found { + t, err := types.ExprTypeToType(et) + if err != nil { + return nil, false + } + return t, true + } + return nil, false +} + +// FindStructFieldType returns a types.FieldType instance for the given fully-qualified typeName and field +// name, if one exists. +// +// This method proxies to the underyling ref.TypeProvider's FindFieldType method and converts protobuf type +// into a native type representation. If the conversion fails, the type is listed as not found. +func (p *interopCELTypeProvider) FindStructFieldType(structType, fieldName string) (*types.FieldType, bool) { + if ft, found := p.FindFieldType(structType, fieldName); found { + t, err := types.ExprTypeToType(ft.Type) + if err != nil { + return nil, false + } + return &types.FieldType{ + Type: t, + IsSet: ft.IsSet, + GetFrom: ft.GetFrom, + }, true + } + return nil, false +} + +// interopLegacyTypeProvider layers support for the ref.TypeProvider interface on top of a types.Provider. +type interopLegacyTypeProvider struct { + types.Provider +} + +// FindType retruns the protobuf Type representation for the input type name if one exists. +// +// This method proxies to the underlying types.Provider FindStructType method and converts the types.Type +// value to a protobuf Type representation. +// +// Failure to convert the type will result in the type not being found. +func (p *interopLegacyTypeProvider) FindType(typeName string) (*exprpb.Type, bool) { + if t, found := p.FindStructType(typeName); found { + et, err := types.TypeToExprType(t) + if err != nil { + return nil, false + } + return et, true + } + return nil, false +} + +// FindFieldType returns the protobuf-based FieldType representation for the input type name and field, +// if one exists. +// +// This call proxies to the types.Provider FindStructFieldType method and converts the types.FIeldType +// value to a protobuf-based ref.FieldType representation if found. +// +// Failure to convert the FieldType will result in the field not being found. +func (p *interopLegacyTypeProvider) FindFieldType(structType, fieldName string) (*ref.FieldType, bool) { + if cft, found := p.FindStructFieldType(structType, fieldName); found { + et, err := types.TypeToExprType(cft.Type) + if err != nil { + return nil, false + } + return &ref.FieldType{ + Type: et, + IsSet: cft.IsSet, + GetFrom: cft.GetFrom, + }, true + } + return nil, false +} + var ( stdEnvInit sync.Once stdEnv *Env diff --git a/vendor/github.com/google/cel-go/cel/io.go b/vendor/github.com/google/cel-go/cel/io.go index 93ded3cf1..80f63140e 100644 --- a/vendor/github.com/google/cel-go/cel/io.go +++ b/vendor/github.com/google/cel-go/cel/io.go @@ -22,6 +22,7 @@ import ( "google.golang.org/protobuf/proto" "github.com/google/cel-go/common" + "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" @@ -33,7 +34,8 @@ import ( // CheckedExprToAst converts a checked expression proto message to an Ast. func CheckedExprToAst(checkedExpr *exprpb.CheckedExpr) *Ast { - return CheckedExprToAstWithSource(checkedExpr, nil) + checked, _ := CheckedExprToAstWithSource(checkedExpr, nil) + return checked } // CheckedExprToAstWithSource converts a checked expression proto message to an Ast, @@ -44,29 +46,18 @@ func CheckedExprToAst(checkedExpr *exprpb.CheckedExpr) *Ast { // through future calls. // // Prefer CheckedExprToAst if loading expressions from storage. -func CheckedExprToAstWithSource(checkedExpr *exprpb.CheckedExpr, src Source) *Ast { - refMap := checkedExpr.GetReferenceMap() - if refMap == nil { - refMap = map[int64]*exprpb.Reference{} - } - typeMap := checkedExpr.GetTypeMap() - if typeMap == nil { - typeMap = map[int64]*exprpb.Type{} - } - si := checkedExpr.GetSourceInfo() - if si == nil { - si = &exprpb.SourceInfo{} - } - if src == nil { - src = common.NewInfoSource(si) +func CheckedExprToAstWithSource(checkedExpr *exprpb.CheckedExpr, src Source) (*Ast, error) { + checkedAST, err := ast.CheckedExprToCheckedAST(checkedExpr) + if err != nil { + return nil, err } return &Ast{ - expr: checkedExpr.GetExpr(), - info: si, + expr: checkedAST.Expr, + info: checkedAST.SourceInfo, source: src, - refMap: refMap, - typeMap: typeMap, - } + refMap: checkedAST.ReferenceMap, + typeMap: checkedAST.TypeMap, + }, nil } // AstToCheckedExpr converts an Ast to an protobuf CheckedExpr value. @@ -76,12 +67,13 @@ func AstToCheckedExpr(a *Ast) (*exprpb.CheckedExpr, error) { if !a.IsChecked() { return nil, fmt.Errorf("cannot convert unchecked ast") } - return &exprpb.CheckedExpr{ - Expr: a.Expr(), - SourceInfo: a.SourceInfo(), + cAst := &ast.CheckedAST{ + Expr: a.expr, + SourceInfo: a.info, ReferenceMap: a.refMap, TypeMap: a.typeMap, - }, nil + } + return ast.CheckedASTToCheckedExpr(cAst) } // ParsedExprToAst converts a parsed expression proto message to an Ast. @@ -202,7 +194,7 @@ func RefValueToValue(res ref.Val) (*exprpb.Value, error) { } var ( - typeNameToTypeValue = map[string]*types.TypeValue{ + typeNameToTypeValue = map[string]ref.Val{ "bool": types.BoolType, "bytes": types.BytesType, "double": types.DoubleType, @@ -219,7 +211,7 @@ var ( ) // ValueToRefValue converts between exprpb.Value and ref.Val. -func ValueToRefValue(adapter ref.TypeAdapter, v *exprpb.Value) (ref.Val, error) { +func ValueToRefValue(adapter types.Adapter, v *exprpb.Value) (ref.Val, error) { switch v.Kind.(type) { case *exprpb.Value_NullValue: return types.NullValue, nil diff --git a/vendor/github.com/google/cel-go/cel/library.go b/vendor/github.com/google/cel-go/cel/library.go index f04fda743..4d232085c 100644 --- a/vendor/github.com/google/cel-go/cel/library.go +++ b/vendor/github.com/google/cel-go/cel/library.go @@ -15,19 +15,32 @@ package cel import ( + "math" "strconv" "strings" "time" - "github.com/google/cel-go/checker" "github.com/google/cel-go/common/operators" "github.com/google/cel-go/common/overloads" + "github.com/google/cel-go/common/stdlib" "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" - "github.com/google/cel-go/interpreter/functions" "github.com/google/cel-go/parser" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +const ( + optMapMacro = "optMap" + optFlatMapMacro = "optFlatMap" + hasValueFunc = "hasValue" + optionalNoneFunc = "optional.none" + optionalOfFunc = "optional.of" + optionalOfNonZeroValueFunc = "optional.ofNonZeroValue" + valueFunc = "value" + unusedIterVar = "#unused" ) // Library provides a collection of EnvOption and ProgramOption values used to configure a CEL @@ -93,50 +106,222 @@ func (stdLibrary) LibraryName() string { return "cel.lib.std" } -// EnvOptions returns options for the standard CEL function declarations and macros. +// CompileOptions returns options for the standard CEL function declarations and macros. func (stdLibrary) CompileOptions() []EnvOption { return []EnvOption{ - Declarations(checker.StandardDeclarations()...), + func(e *Env) (*Env, error) { + var err error + for _, fn := range stdlib.Functions() { + existing, found := e.functions[fn.Name()] + if found { + fn, err = existing.Merge(fn) + if err != nil { + return nil, err + } + } + e.functions[fn.Name()] = fn + } + return e, nil + }, + func(e *Env) (*Env, error) { + e.variables = append(e.variables, stdlib.Types()...) + return e, nil + }, Macros(StandardMacros...), } } // ProgramOptions returns function implementations for the standard CEL functions. func (stdLibrary) ProgramOptions() []ProgramOption { - return []ProgramOption{ - Functions(functions.StandardOverloads()...), + return []ProgramOption{} +} + +// OptionalTypes enable support for optional syntax and types in CEL. +// +// The optional value type makes it possible to express whether variables have +// been provided, whether a result has been computed, and in the future whether +// an object field path, map key value, or list index has a value. +// +// # Syntax Changes +// +// OptionalTypes are unlike other CEL extensions because they modify the CEL +// syntax itself, notably through the use of a `?` preceding a field name or +// index value. +// +// ## Field Selection +// +// The optional syntax in field selection is denoted as `obj.?field`. In other +// words, if a field is set, return `optional.of(obj.field)“, else +// `optional.none()`. The optional field selection is viral in the sense that +// after the first optional selection all subsequent selections or indices +// are treated as optional, i.e. the following expressions are equivalent: +// +// obj.?field.subfield +// obj.?field.?subfield +// +// ## Indexing +// +// Similar to field selection, the optional syntax can be used in index +// expressions on maps and lists: +// +// list[?0] +// map[?key] +// +// ## Optional Field Setting +// +// When creating map or message literals, if a field may be optionally set +// based on its presence, then placing a `?` before the field name or key +// will ensure the type on the right-hand side must be optional(T) where T +// is the type of the field or key-value. +// +// The following returns a map with the key expression set only if the +// subfield is present, otherwise an empty map is created: +// +// {?key: obj.?field.subfield} +// +// ## Optional Element Setting +// +// When creating list literals, an element in the list may be optionally added +// when the element expression is preceded by a `?`: +// +// [a, ?b, ?c] // return a list with either [a], [a, b], [a, b, c], or [a, c] +// +// # Optional.Of +// +// Create an optional(T) value of a given value with type T. +// +// optional.of(10) +// +// # Optional.OfNonZeroValue +// +// Create an optional(T) value of a given value with type T if it is not a +// zero-value. A zero-value the default empty value for any given CEL type, +// including empty protobuf message types. If the value is empty, the result +// of this call will be optional.none(). +// +// optional.ofNonZeroValue([1, 2, 3]) // optional(list(int)) +// optional.ofNonZeroValue([]) // optional.none() +// optional.ofNonZeroValue(0) // optional.none() +// optional.ofNonZeroValue("") // optional.none() +// +// # Optional.None +// +// Create an empty optional value. +// +// # HasValue +// +// Determine whether the optional contains a value. +// +// optional.of(b'hello').hasValue() // true +// optional.ofNonZeroValue({}).hasValue() // false +// +// # Value +// +// Get the value contained by the optional. If the optional does not have a +// value, the result will be a CEL error. +// +// optional.of(b'hello').value() // b'hello' +// optional.ofNonZeroValue({}).value() // error +// +// # Or +// +// If the value on the left-hand side is optional.none(), the optional value +// on the right hand side is returned. If the value on the left-hand set is +// valued, then it is returned. This operation is short-circuiting and will +// only evaluate as many links in the `or` chain as are needed to return a +// non-empty optional value. +// +// obj.?field.or(m[?key]) +// l[?index].or(obj.?field.subfield).or(obj.?other) +// +// # OrValue +// +// Either return the value contained within the optional on the left-hand side +// or return the alternative value on the right hand side. +// +// m[?key].orValue("none") +// +// # OptMap +// +// Apply a transformation to the optional's underlying value if it is not empty +// and return an optional typed result based on the transformation. The +// transformation expression type must return a type T which is wrapped into +// an optional. +// +// msg.?elements.optMap(e, e.size()).orValue(0) +// +// # OptFlatMap +// +// Introduced in version: 1 +// +// Apply a transformation to the optional's underlying value if it is not empty +// and return the result. The transform expression must return an optional(T) +// rather than type T. This can be useful when dealing with zero values and +// conditionally generating an empty or non-empty result in ways which cannot +// be expressed with `optMap`. +// +// msg.?elements.optFlatMap(e, e[?0]) // return the first element if present. +func OptionalTypes(opts ...OptionalTypesOption) EnvOption { + lib := &optionalLib{version: math.MaxUint32} + for _, opt := range opts { + lib = opt(lib) } + return Lib(lib) +} + +type optionalLib struct { + version uint32 } -type optionalLibrary struct{} +// OptionalTypesOption is a functional interface for configuring the strings library. +type OptionalTypesOption func(*optionalLib) *optionalLib + +// OptionalTypesVersion configures the version of the optional type library. +// +// The version limits which functions are available. Only functions introduced +// below or equal to the given version included in the library. If this option +// is not set, all functions are available. +// +// See the library documentation to determine which version a function was introduced. +// If the documentation does not state which version a function was introduced, it can +// be assumed to be introduced at version 0, when the library was first created. +func OptionalTypesVersion(version uint32) OptionalTypesOption { + return func(lib *optionalLib) *optionalLib { + lib.version = version + return lib + } +} // LibraryName implements the SingletonLibrary interface method. -func (optionalLibrary) LibraryName() string { +func (lib *optionalLib) LibraryName() string { return "cel.lib.optional" } // CompileOptions implements the Library interface method. -func (optionalLibrary) CompileOptions() []EnvOption { +func (lib *optionalLib) CompileOptions() []EnvOption { paramTypeK := TypeParamType("K") paramTypeV := TypeParamType("V") optionalTypeV := OptionalType(paramTypeV) listTypeV := ListType(paramTypeV) mapTypeKV := MapType(paramTypeK, paramTypeV) - return []EnvOption{ + opts := []EnvOption{ // Enable the optional syntax in the parser. enableOptionalSyntax(), // Introduce the optional type. Types(types.OptionalType), + // Configure the optMap and optFlatMap macros. + Macros(NewReceiverMacro(optMapMacro, 2, optMap)), + // Global and member functions for working with optional values. - Function("optional.of", + Function(optionalOfFunc, Overload("optional_of", []*Type{paramTypeV}, optionalTypeV, UnaryBinding(func(value ref.Val) ref.Val { return types.OptionalOf(value) }))), - Function("optional.ofNonZeroValue", + Function(optionalOfNonZeroValueFunc, Overload("optional_ofNonZeroValue", []*Type{paramTypeV}, optionalTypeV, UnaryBinding(func(value ref.Val) ref.Val { v, isZeroer := value.(traits.Zeroer) @@ -145,18 +330,18 @@ func (optionalLibrary) CompileOptions() []EnvOption { } return types.OptionalNone }))), - Function("optional.none", + Function(optionalNoneFunc, Overload("optional_none", []*Type{}, optionalTypeV, FunctionBinding(func(values ...ref.Val) ref.Val { return types.OptionalNone }))), - Function("value", + Function(valueFunc, MemberOverload("optional_value", []*Type{optionalTypeV}, paramTypeV, UnaryBinding(func(value ref.Val) ref.Val { opt := value.(*types.Optional) return opt.GetValue() }))), - Function("hasValue", + Function(hasValueFunc, MemberOverload("optional_hasValue", []*Type{optionalTypeV}, BoolType, UnaryBinding(func(value ref.Val) ref.Val { opt := value.(*types.Optional) @@ -183,20 +368,78 @@ func (optionalLibrary) CompileOptions() []EnvOption { Overload("map_optindex_optional_value", []*Type{mapTypeKV, paramTypeK}, optionalTypeV), Overload("optional_map_optindex_optional_value", []*Type{OptionalType(mapTypeKV), paramTypeK}, optionalTypeV)), - // Index overloads to accomodate using an optional value as the operand. + // Index overloads to accommodate using an optional value as the operand. Function(operators.Index, Overload("optional_list_index_int", []*Type{OptionalType(listTypeV), IntType}, optionalTypeV), - Overload("optional_map_index_optional_value", []*Type{OptionalType(mapTypeKV), paramTypeK}, optionalTypeV)), + Overload("optional_map_index_value", []*Type{OptionalType(mapTypeKV), paramTypeK}, optionalTypeV)), } + if lib.version >= 1 { + opts = append(opts, Macros(NewReceiverMacro(optFlatMapMacro, 2, optFlatMap))) + } + return opts } // ProgramOptions implements the Library interface method. -func (optionalLibrary) ProgramOptions() []ProgramOption { +func (lib *optionalLib) ProgramOptions() []ProgramOption { return []ProgramOption{ CustomDecorator(decorateOptionalOr), } } +func optMap(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *Error) { + varIdent := args[0] + varName := "" + switch varIdent.GetExprKind().(type) { + case *exprpb.Expr_IdentExpr: + varName = varIdent.GetIdentExpr().GetName() + default: + return nil, meh.NewError(varIdent.GetId(), "optMap() variable name must be a simple identifier") + } + mapExpr := args[1] + return meh.GlobalCall( + operators.Conditional, + meh.ReceiverCall(hasValueFunc, target), + meh.GlobalCall(optionalOfFunc, + meh.Fold( + unusedIterVar, + meh.NewList(), + varName, + meh.ReceiverCall(valueFunc, target), + meh.LiteralBool(false), + meh.Ident(varName), + mapExpr, + ), + ), + meh.GlobalCall(optionalNoneFunc), + ), nil +} + +func optFlatMap(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *Error) { + varIdent := args[0] + varName := "" + switch varIdent.GetExprKind().(type) { + case *exprpb.Expr_IdentExpr: + varName = varIdent.GetIdentExpr().GetName() + default: + return nil, meh.NewError(varIdent.GetId(), "optFlatMap() variable name must be a simple identifier") + } + mapExpr := args[1] + return meh.GlobalCall( + operators.Conditional, + meh.ReceiverCall(hasValueFunc, target), + meh.Fold( + unusedIterVar, + meh.NewList(), + varName, + meh.ReceiverCall(valueFunc, target), + meh.LiteralBool(false), + meh.Ident(varName), + mapExpr, + ), + meh.GlobalCall(optionalNoneFunc), + ), nil +} + func enableOptionalSyntax() EnvOption { return func(e *Env) (*Env, error) { e.prsrOpts = append(e.prsrOpts, parser.EnableOptionalSyntax(true)) @@ -311,28 +554,16 @@ var ( timeOverloadDeclarations = []EnvOption{ Function(overloads.TimeGetHours, MemberOverload(overloads.DurationToHours, []*Type{DurationType}, IntType, - UnaryBinding(func(dur ref.Val) ref.Val { - d := dur.(types.Duration) - return types.Int(d.Hours()) - }))), + UnaryBinding(types.DurationGetHours))), Function(overloads.TimeGetMinutes, MemberOverload(overloads.DurationToMinutes, []*Type{DurationType}, IntType, - UnaryBinding(func(dur ref.Val) ref.Val { - d := dur.(types.Duration) - return types.Int(d.Minutes()) - }))), + UnaryBinding(types.DurationGetMinutes))), Function(overloads.TimeGetSeconds, MemberOverload(overloads.DurationToSeconds, []*Type{DurationType}, IntType, - UnaryBinding(func(dur ref.Val) ref.Val { - d := dur.(types.Duration) - return types.Int(d.Seconds()) - }))), + UnaryBinding(types.DurationGetSeconds))), Function(overloads.TimeGetMilliseconds, MemberOverload(overloads.DurationToMilliseconds, []*Type{DurationType}, IntType, - UnaryBinding(func(dur ref.Val) ref.Val { - d := dur.(types.Duration) - return types.Int(d.Milliseconds()) - }))), + UnaryBinding(types.DurationGetMilliseconds))), Function(overloads.TimeGetFullYear, MemberOverload(overloads.TimestampToYear, []*Type{TimestampType}, IntType, UnaryBinding(func(ts ref.Val) ref.Val { diff --git a/vendor/github.com/google/cel-go/cel/macro.go b/vendor/github.com/google/cel-go/cel/macro.go index e48c5bf8e..1eb414c8b 100644 --- a/vendor/github.com/google/cel-go/cel/macro.go +++ b/vendor/github.com/google/cel-go/cel/macro.go @@ -15,7 +15,6 @@ package cel import ( - "github.com/google/cel-go/common" "github.com/google/cel-go/parser" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" @@ -63,21 +62,21 @@ func NewReceiverVarArgMacro(function string, expander MacroExpander) Macro { } // HasMacroExpander expands the input call arguments into a presence test, e.g. has(.field) -func HasMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { +func HasMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *Error) { return parser.MakeHas(meh, target, args) } // ExistsMacroExpander expands the input call arguments into a comprehension that returns true if any of the // elements in the range match the predicate expressions: // .exists(, ) -func ExistsMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { +func ExistsMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *Error) { return parser.MakeExists(meh, target, args) } // ExistsOneMacroExpander expands the input call arguments into a comprehension that returns true if exactly // one of the elements in the range match the predicate expressions: // .exists_one(, ) -func ExistsOneMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { +func ExistsOneMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *Error) { return parser.MakeExistsOne(meh, target, args) } @@ -91,14 +90,14 @@ func ExistsOneMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*ex // // In the second form only iterVar values which return true when provided to the predicate expression // are transformed. -func MapMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { +func MapMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *Error) { return parser.MakeMap(meh, target, args) } // FilterMacroExpander expands the input call arguments into a comprehension which produces a list which contains // only elements which match the provided predicate expression: // .filter(, ) -func FilterMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { +func FilterMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *Error) { return parser.MakeFilter(meh, target, args) } diff --git a/vendor/github.com/google/cel-go/cel/options.go b/vendor/github.com/google/cel-go/cel/options.go index 23e5223ed..d47f55d8e 100644 --- a/vendor/github.com/google/cel-go/cel/options.go +++ b/vendor/github.com/google/cel-go/cel/options.go @@ -23,12 +23,12 @@ import ( "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/types/dynamicpb" - "github.com/google/cel-go/checker/decls" "github.com/google/cel-go/common/containers" + "github.com/google/cel-go/common/functions" + "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/pb" "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/interpreter" - "github.com/google/cel-go/interpreter/functions" "github.com/google/cel-go/parser" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" @@ -41,13 +41,6 @@ import ( const ( _ = iota - // Disallow heterogeneous aggregate (list, map) literals. - // Note, it is still possible to have heterogeneous aggregates when - // provided as variables to the expression, as well as via conversion - // of well-known dynamic types, or with unchecked expressions. - // Affects checking. Provides a subset of standard behavior. - featureDisableDynamicAggregateLiterals - // Enable the tracking of function call expressions replaced by macros. featureEnableMacroCallTracking @@ -63,9 +56,10 @@ const ( // is not already in UTC. featureDefaultUTCTimeZone - // Enable the use of optional types in the syntax, type-system, type-checking, - // and runtime. - featureOptionalTypes + // Enable the serialization of logical operator ASTs as variadic calls, thus + // compressing the logic graph to a single call when multiple like-operator + // expressions occur: e.g. a && b && c && d -> call(_&&_, [a, b, c, d]) + featureVariadicLogicalASTs ) // EnvOption is a functional interface for configuring the environment. @@ -82,23 +76,26 @@ func ClearMacros() EnvOption { } } -// CustomTypeAdapter swaps the default ref.TypeAdapter implementation with a custom one. +// CustomTypeAdapter swaps the default types.Adapter implementation with a custom one. // // Note: This option must be specified before the Types and TypeDescs options when used together. -func CustomTypeAdapter(adapter ref.TypeAdapter) EnvOption { +func CustomTypeAdapter(adapter types.Adapter) EnvOption { return func(e *Env) (*Env, error) { e.adapter = adapter return e, nil } } -// CustomTypeProvider swaps the default ref.TypeProvider implementation with a custom one. +// CustomTypeProvider replaces the types.Provider implementation with a custom one. +// +// The `provider` variable type may either be types.Provider or ref.TypeProvider (deprecated) // // Note: This option must be specified before the Types and TypeDescs options when used together. -func CustomTypeProvider(provider ref.TypeProvider) EnvOption { +func CustomTypeProvider(provider any) EnvOption { return func(e *Env) (*Env, error) { - e.provider = provider - return e, nil + var err error + e.provider, err = maybeInteropProvider(provider) + return e, err } } @@ -108,8 +105,28 @@ func CustomTypeProvider(provider ref.TypeProvider) EnvOption { // for the environment. The NewEnv call builds on top of the standard CEL declarations. For a // purely custom set of declarations use NewCustomEnv. func Declarations(decls ...*exprpb.Decl) EnvOption { + declOpts := []EnvOption{} + var err error + var opt EnvOption + // Convert the declarations to `EnvOption` values ahead of time. + // Surface any errors in conversion when the options are applied. + for _, d := range decls { + opt, err = ExprDeclToDeclaration(d) + if err != nil { + break + } + declOpts = append(declOpts, opt) + } return func(e *Env) (*Env, error) { - e.declarations = append(e.declarations, decls...) + if err != nil { + return nil, err + } + for _, o := range declOpts { + e, err = o(e) + if err != nil { + return nil, err + } + } return e, nil } } @@ -126,14 +143,25 @@ func EagerlyValidateDeclarations(enabled bool) EnvOption { return features(featureEagerlyValidateDeclarations, enabled) } -// HomogeneousAggregateLiterals option ensures that list and map literal entry types must agree -// during type-checking. +// HomogeneousAggregateLiterals disables mixed type list and map literal values. // // Note, it is still possible to have heterogeneous aggregates when provided as variables to the // expression, as well as via conversion of well-known dynamic types, or with unchecked // expressions. func HomogeneousAggregateLiterals() EnvOption { - return features(featureDisableDynamicAggregateLiterals, true) + return ASTValidators(ValidateHomogeneousAggregateLiterals()) +} + +// variadicLogicalOperatorASTs flatten like-operator chained logical expressions into a single +// variadic call with N-terms. This behavior is useful when serializing to a protocol buffer as +// it will reduce the number of recursive calls needed to deserialize the AST later. +// +// For example, given the following expression the call graph will be rendered accordingly: +// +// expression: a && b && c && (d || e) +// ast: call(_&&_, [a, b, c, call(_||_, [d, e])]) +func variadicLogicalOperatorASTs() EnvOption { + return features(featureVariadicLogicalASTs, true) } // Macros option extends the macro set configured in the environment. @@ -226,7 +254,12 @@ func Abbrevs(qualifiedNames ...string) EnvOption { // Note: This option must be specified after the CustomTypeProvider option when used together. func Types(addTypes ...any) EnvOption { return func(e *Env) (*Env, error) { - reg, isReg := e.provider.(ref.TypeRegistry) + var reg ref.TypeRegistry + var isReg bool + reg, isReg = e.provider.(*types.Registry) + if !isReg { + reg, isReg = e.provider.(ref.TypeRegistry) + } if !isReg { return nil, fmt.Errorf("custom types not supported by provider: %T", e.provider) } @@ -412,6 +445,9 @@ const ( // OptTrackCost enables the runtime cost calculation while validation and return cost within evalDetails // cost calculation is available via func ActualCost() OptTrackCost EvalOption = 1 << iota + + // OptCheckStringFormat enables compile-time checking of string.format calls for syntax/cardinality. + OptCheckStringFormat EvalOption = 1 << iota ) // EvalOptions sets one or more evaluation options which may affect the evaluation or Result. @@ -454,25 +490,21 @@ func CostLimit(costLimit uint64) ProgramOption { } } -func fieldToCELType(field protoreflect.FieldDescriptor) (*exprpb.Type, error) { +func fieldToCELType(field protoreflect.FieldDescriptor) (*Type, error) { if field.Kind() == protoreflect.MessageKind || field.Kind() == protoreflect.GroupKind { msgName := (string)(field.Message().FullName()) - wellKnownType, found := pb.CheckedWellKnowns[msgName] - if found { - return wellKnownType, nil - } - return decls.NewObjectType(msgName), nil + return ObjectType(msgName), nil } - if primitiveType, found := pb.CheckedPrimitives[field.Kind()]; found { + if primitiveType, found := types.ProtoCELPrimitives[field.Kind()]; found { return primitiveType, nil } if field.Kind() == protoreflect.EnumKind { - return decls.Int, nil + return IntType, nil } return nil, fmt.Errorf("field %s type %s not implemented", field.FullName(), field.Kind().String()) } -func fieldToDecl(field protoreflect.FieldDescriptor) (*exprpb.Decl, error) { +func fieldToVariable(field protoreflect.FieldDescriptor) (EnvOption, error) { name := string(field.Name()) if field.IsMap() { mapKey := field.MapKey() @@ -485,20 +517,20 @@ func fieldToDecl(field protoreflect.FieldDescriptor) (*exprpb.Decl, error) { if err != nil { return nil, err } - return decls.NewVar(name, decls.NewMapType(keyType, valueType)), nil + return Variable(name, MapType(keyType, valueType)), nil } if field.IsList() { elemType, err := fieldToCELType(field) if err != nil { return nil, err } - return decls.NewVar(name, decls.NewListType(elemType)), nil + return Variable(name, ListType(elemType)), nil } celType, err := fieldToCELType(field) if err != nil { return nil, err } - return decls.NewVar(name, celType), nil + return Variable(name, celType), nil } // DeclareContextProto returns an option to extend CEL environment with declarations from the given context proto. @@ -506,23 +538,51 @@ func fieldToDecl(field protoreflect.FieldDescriptor) (*exprpb.Decl, error) { // https://github.com/google/cel-spec/blob/master/doc/langdef.md#evaluation-environment func DeclareContextProto(descriptor protoreflect.MessageDescriptor) EnvOption { return func(e *Env) (*Env, error) { - var decls []*exprpb.Decl fields := descriptor.Fields() for i := 0; i < fields.Len(); i++ { field := fields.Get(i) - decl, err := fieldToDecl(field) + variable, err := fieldToVariable(field) + if err != nil { + return nil, err + } + e, err = variable(e) if err != nil { return nil, err } - decls = append(decls, decl) } - var err error - e, err = Declarations(decls...)(e) + return Types(dynamicpb.NewMessage(descriptor))(e) + } +} + +// ContextProtoVars uses the fields of the input proto.Messages as top-level variables within an Activation. +// +// Consider using with `DeclareContextProto` to simplify variable type declarations and publishing when using +// protocol buffers. +func ContextProtoVars(ctx proto.Message) (interpreter.Activation, error) { + if ctx == nil || !ctx.ProtoReflect().IsValid() { + return interpreter.EmptyActivation(), nil + } + reg, err := types.NewRegistry(ctx) + if err != nil { + return nil, err + } + pbRef := ctx.ProtoReflect() + typeName := string(pbRef.Descriptor().FullName()) + fields := pbRef.Descriptor().Fields() + vars := make(map[string]any, fields.Len()) + for i := 0; i < fields.Len(); i++ { + field := fields.Get(i) + sft, found := reg.FindStructFieldType(typeName, field.TextName()) + if !found { + return nil, fmt.Errorf("no such field: %s", field.TextName()) + } + fieldVal, err := sft.GetFrom(ctx) if err != nil { return nil, err } - return Types(dynamicpb.NewMessage(descriptor))(e) + vars[field.TextName()] = fieldVal } + return interpreter.NewActivation(vars) } // EnableMacroCallTracking ensures that call expressions which are replaced by macros @@ -542,13 +602,6 @@ func DefaultUTCTimeZone(enabled bool) EnvOption { return features(featureDefaultUTCTimeZone, enabled) } -// OptionalTypes enable support for optional syntax and types in CEL. The optional value type makes -// it possible to express whether variables have been provided, whether a result has been computed, -// and in the future whether an object field path, map key value, or list index has a value. -func OptionalTypes() EnvOption { - return Lib(optionalLibrary{}) -} - // features sets the given feature flags. See list of Feature constants above. func features(flag int, enabled bool) EnvOption { return func(e *Env) (*Env, error) { @@ -565,3 +618,23 @@ func ParserRecursionLimit(limit int) EnvOption { return e, nil } } + +// ParserExpressionSizeLimit adjusts the number of code points the expression parser is allowed to parse. +// Defaults defined in the parser package. +func ParserExpressionSizeLimit(limit int) EnvOption { + return func(e *Env) (*Env, error) { + e.prsrOpts = append(e.prsrOpts, parser.ExpressionSizeCodePointLimit(limit)) + return e, nil + } +} + +func maybeInteropProvider(provider any) (types.Provider, error) { + switch p := provider.(type) { + case types.Provider: + return p, nil + case ref.TypeProvider: + return &interopCELTypeProvider{TypeProvider: p}, nil + default: + return nil, fmt.Errorf("unsupported type provider: %T", provider) + } +} diff --git a/vendor/github.com/google/cel-go/cel/program.go b/vendor/github.com/google/cel-go/cel/program.go index f4b77f77a..11c5c447e 100644 --- a/vendor/github.com/google/cel-go/cel/program.go +++ b/vendor/github.com/google/cel-go/cel/program.go @@ -17,14 +17,12 @@ package cel import ( "context" "fmt" - "math" "sync" + celast "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/interpreter" - - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) // Program is an evaluable view of an Ast. @@ -63,6 +61,9 @@ func NoVars() interpreter.Activation { // PartialVars returns a PartialActivation which contains variables and a set of AttributePattern // values that indicate variables or parts of variables whose value are not yet known. // +// This method relies on manually configured sets of missing attribute patterns. For a method which +// infers the missing variables from the input and the configured environment, use Env.PartialVars(). +// // The `vars` value may either be an interpreter.Activation or any valid input to the // interpreter.NewActivation call. func PartialVars(vars any, @@ -170,7 +171,7 @@ func newProgram(e *Env, ast *Ast, opts []ProgramOption) (Program, error) { // Add the function bindings created via Function() options. for _, fn := range e.functions { - bindings, err := fn.bindings() + bindings, err := fn.Bindings() if err != nil { return nil, err } @@ -207,13 +208,44 @@ func newProgram(e *Env, ast *Ast, opts []ProgramOption) (Program, error) { if len(p.regexOptimizations) > 0 { decorators = append(decorators, interpreter.CompileRegexConstants(p.regexOptimizations...)) } + // Enable compile-time checking of syntax/cardinality for string.format calls. + if p.evalOpts&OptCheckStringFormat == OptCheckStringFormat { + var isValidType func(id int64, validTypes ...ref.Type) (bool, error) + if ast.IsChecked() { + isValidType = func(id int64, validTypes ...ref.Type) (bool, error) { + t := ast.typeMap[id] + if t.Kind() == DynKind { + return true, nil + } + for _, vt := range validTypes { + k, err := typeValueToKind(vt) + if err != nil { + return false, err + } + if t.Kind() == k { + return true, nil + } + } + return false, nil + } + } else { + // if the AST isn't type-checked, short-circuit validation + isValidType = func(id int64, validTypes ...ref.Type) (bool, error) { + return true, nil + } + } + decorators = append(decorators, interpreter.InterpolateFormattedString(isValidType)) + } // Enable exhaustive eval, state tracking and cost tracking last since they require a factory. if p.evalOpts&(OptExhaustiveEval|OptTrackState|OptTrackCost) != 0 { factory := func(state interpreter.EvalState, costTracker *interpreter.CostTracker) (Program, error) { costTracker.Estimator = p.callCostEstimator costTracker.Limit = p.costLimit - decs := decorators + // Limit capacity to guarantee a reallocation when calling 'append(decs, ...)' below. This + // prevents the underlying memory from being shared between factory function calls causing + // undesired mutations. + decs := decorators[:len(decorators):len(decorators)] var observers []interpreter.EvalObserver if p.evalOpts&(OptExhaustiveEval|OptTrackState) != 0 { @@ -251,10 +283,11 @@ func (p *prog) initInterpretable(ast *Ast, decs []interpreter.InterpretableDecor } // When the AST has been checked it contains metadata that can be used to speed up program execution. - var checked *exprpb.CheckedExpr - checked, err := AstToCheckedExpr(ast) - if err != nil { - return nil, err + checked := &celast.CheckedAST{ + Expr: ast.Expr(), + SourceInfo: ast.SourceInfo(), + TypeMap: ast.typeMap, + ReferenceMap: ast.refMap, } interpretable, err := p.interpreter.NewInterpretable(checked, decs...) if err != nil { @@ -326,11 +359,6 @@ func (p *prog) ContextEval(ctx context.Context, input any) (ref.Val, *EvalDetail return p.Eval(vars) } -// Cost implements the Coster interface method. -func (p *prog) Cost() (min, max int64) { - return estimateCost(p.interpretable) -} - // progFactory is a helper alias for marking a program creation factory function. type progFactory func(interpreter.EvalState, *interpreter.CostTracker) (Program, error) @@ -403,29 +431,6 @@ func (gen *progGen) ContextEval(ctx context.Context, input any) (ref.Val, *EvalD return v, det, nil } -// Cost implements the Coster interface method. -func (gen *progGen) Cost() (min, max int64) { - // Use an empty state value since no evaluation is performed. - p, err := gen.factory(emptyEvalState, nil) - if err != nil { - return 0, math.MaxInt64 - } - return estimateCost(p) -} - -// EstimateCost returns the heuristic cost interval for the program. -func EstimateCost(p Program) (min, max int64) { - return estimateCost(p) -} - -func estimateCost(i any) (min, max int64) { - c, ok := i.(interpreter.Coster) - if !ok { - return 0, math.MaxInt64 - } - return c.Cost() -} - type ctxEvalActivation struct { parent interpreter.Activation interrupt <-chan struct{} @@ -493,7 +498,7 @@ type evalActivation struct { // The lazy binding will only be invoked once per evaluation. // // Values which are not represented as ref.Val types on input may be adapted to a ref.Val using -// the ref.TypeAdapter configured in the environment. +// the types.Adapter configured in the environment. func (a *evalActivation) ResolveName(name string) (any, bool) { v, found := a.vars[name] if !found { diff --git a/vendor/github.com/google/cel-go/cel/validator.go b/vendor/github.com/google/cel-go/cel/validator.go new file mode 100644 index 000000000..78b311381 --- /dev/null +++ b/vendor/github.com/google/cel-go/cel/validator.go @@ -0,0 +1,388 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cel + +import ( + "fmt" + "reflect" + "regexp" + + "github.com/google/cel-go/common/ast" + "github.com/google/cel-go/common/overloads" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +const ( + homogeneousValidatorName = "cel.lib.std.validate.types.homogeneous" + + // HomogeneousAggregateLiteralExemptFunctions is the ValidatorConfig key used to configure + // the set of function names which are exempt from homogeneous type checks. The expected type + // is a string list of function names. + // + // As an example, the `.format([args])` call expects the input arguments list to be + // comprised of a variety of types which correspond to the types expected by the format control + // clauses; however, all other uses of a mixed element type list, would be unexpected. + HomogeneousAggregateLiteralExemptFunctions = homogeneousValidatorName + ".exempt" +) + +// ASTValidators configures a set of ASTValidator instances into the target environment. +// +// Validators are applied in the order in which the are specified and are treated as singletons. +// The same ASTValidator with a given name will not be applied more than once. +func ASTValidators(validators ...ASTValidator) EnvOption { + return func(e *Env) (*Env, error) { + for _, v := range validators { + if !e.HasValidator(v.Name()) { + e.validators = append(e.validators, v) + } + } + return e, nil + } +} + +// ASTValidator defines a singleton interface for validating a type-checked Ast against an environment. +// +// Note: the Issues argument is mutable in the sense that it is intended to collect errors which will be +// reported to the caller. +type ASTValidator interface { + // Name returns the name of the validator. Names must be unique. + Name() string + + // Validate validates a given Ast within an Environment and collects a set of potential issues. + // + // The ValidatorConfig is generated from the set of ASTValidatorConfigurer instances prior to + // the invocation of the Validate call. The expectation is that the validator configuration + // is created in sequence and immutable once provided to the Validate call. + // + // See individual validators for more information on their configuration keys and configuration + // properties. + Validate(*Env, ValidatorConfig, *ast.CheckedAST, *Issues) +} + +// ValidatorConfig provides an accessor method for querying validator configuration state. +type ValidatorConfig interface { + GetOrDefault(name string, value any) any +} + +// MutableValidatorConfig provides mutation methods for querying and updating validator configuration +// settings. +type MutableValidatorConfig interface { + ValidatorConfig + Set(name string, value any) error +} + +// ASTValidatorConfigurer indicates that this object, currently expected to be an ASTValidator, +// participates in validator configuration settings. +// +// This interface may be split from the expectation of being an ASTValidator instance in the future. +type ASTValidatorConfigurer interface { + Configure(MutableValidatorConfig) error +} + +// validatorConfig implements the ValidatorConfig and MutableValidatorConfig interfaces. +type validatorConfig struct { + data map[string]any +} + +// newValidatorConfig initializes the validator config with default values for core CEL validators. +func newValidatorConfig() *validatorConfig { + return &validatorConfig{ + data: map[string]any{ + HomogeneousAggregateLiteralExemptFunctions: []string{}, + }, + } +} + +// GetOrDefault returns the configured value for the name, if present, else the input default value. +// +// Note, the type-agreement between the input default and configured value is not checked on read. +func (config *validatorConfig) GetOrDefault(name string, value any) any { + v, found := config.data[name] + if !found { + return value + } + return v +} + +// Set configures a validator option with the given name and value. +// +// If the value had previously been set, the new value must have the same reflection type as the old one, +// or the call will error. +func (config *validatorConfig) Set(name string, value any) error { + v, found := config.data[name] + if found && reflect.TypeOf(v) != reflect.TypeOf(value) { + return fmt.Errorf("incompatible configuration type for %s, got %T, wanted %T", name, value, v) + } + config.data[name] = value + return nil +} + +// ExtendedValidations collects a set of common AST validations which reduce the likelihood of runtime errors. +// +// - Validate duration and timestamp literals +// - Ensure regex strings are valid +// - Disable mixed type list and map literals +func ExtendedValidations() EnvOption { + return ASTValidators( + ValidateDurationLiterals(), + ValidateTimestampLiterals(), + ValidateRegexLiterals(), + ValidateHomogeneousAggregateLiterals(), + ) +} + +// ValidateDurationLiterals ensures that duration literal arguments are valid immediately after type-check. +func ValidateDurationLiterals() ASTValidator { + return newFormatValidator(overloads.TypeConvertDuration, 0, evalCall) +} + +// ValidateTimestampLiterals ensures that timestamp literal arguments are valid immediately after type-check. +func ValidateTimestampLiterals() ASTValidator { + return newFormatValidator(overloads.TypeConvertTimestamp, 0, evalCall) +} + +// ValidateRegexLiterals ensures that regex patterns are validated after type-check. +func ValidateRegexLiterals() ASTValidator { + return newFormatValidator(overloads.Matches, 0, compileRegex) +} + +// ValidateHomogeneousAggregateLiterals checks that all list and map literals entries have the same types, i.e. +// no mixed list element types or mixed map key or map value types. +// +// Note: the string format call relies on a mixed element type list for ease of use, so this check skips all +// literals which occur within string format calls. +func ValidateHomogeneousAggregateLiterals() ASTValidator { + return homogeneousAggregateLiteralValidator{} +} + +// ValidateComprehensionNestingLimit ensures that comprehension nesting does not exceed the specified limit. +// +// This validator can be useful for preventing arbitrarily nested comprehensions which can take high polynomial +// time to complete. +// +// Note, this limit does not apply to comprehensions with an empty iteration range, as these comprehensions have +// no actual looping cost. The cel.bind() utilizes the comprehension structure to perform local variable +// assignments and supplies an empty iteration range, so they won't count against the nesting limit either. +func ValidateComprehensionNestingLimit(limit int) ASTValidator { + return nestingLimitValidator{limit: limit} +} + +type argChecker func(env *Env, call, arg ast.NavigableExpr) error + +func newFormatValidator(funcName string, argNum int, check argChecker) formatValidator { + return formatValidator{ + funcName: funcName, + check: check, + argNum: argNum, + } +} + +type formatValidator struct { + funcName string + argNum int + check argChecker +} + +// Name returns the unique name of this function format validator. +func (v formatValidator) Name() string { + return fmt.Sprintf("cel.lib.std.validate.functions.%s", v.funcName) +} + +// Validate searches the AST for uses of a given function name with a constant argument and performs a check +// on whether the argument is a valid literal value. +func (v formatValidator) Validate(e *Env, _ ValidatorConfig, a *ast.CheckedAST, iss *Issues) { + root := ast.NavigateCheckedAST(a) + funcCalls := ast.MatchDescendants(root, ast.FunctionMatcher(v.funcName)) + for _, call := range funcCalls { + callArgs := call.AsCall().Args() + if len(callArgs) <= v.argNum { + continue + } + litArg := callArgs[v.argNum] + if litArg.Kind() != ast.LiteralKind { + continue + } + if err := v.check(e, call, litArg); err != nil { + iss.ReportErrorAtID(litArg.ID(), "invalid %s argument", v.funcName) + } + } +} + +func evalCall(env *Env, call, arg ast.NavigableExpr) error { + ast := ParsedExprToAst(&exprpb.ParsedExpr{Expr: call.ToExpr()}) + prg, err := env.Program(ast) + if err != nil { + return err + } + _, _, err = prg.Eval(NoVars()) + return err +} + +func compileRegex(_ *Env, _, arg ast.NavigableExpr) error { + pattern := arg.AsLiteral().Value().(string) + _, err := regexp.Compile(pattern) + return err +} + +type homogeneousAggregateLiteralValidator struct{} + +// Name returns the unique name of the homogeneous type validator. +func (homogeneousAggregateLiteralValidator) Name() string { + return homogeneousValidatorName +} + +// Configure implements the ASTValidatorConfigurer interface and currently sets the list of standard +// and exempt functions from homogeneous aggregate literal checks. +// +// TODO: Move this call into the string.format() ASTValidator once ported. +func (homogeneousAggregateLiteralValidator) Configure(c MutableValidatorConfig) error { + emptyList := []string{} + exemptFunctions := c.GetOrDefault(HomogeneousAggregateLiteralExemptFunctions, emptyList).([]string) + exemptFunctions = append(exemptFunctions, "format") + return c.Set(HomogeneousAggregateLiteralExemptFunctions, exemptFunctions) +} + +// Validate validates that all lists and map literals have homogeneous types, i.e. don't contain dyn types. +// +// This validator makes an exception for list and map literals which occur at any level of nesting within +// string format calls. +func (v homogeneousAggregateLiteralValidator) Validate(_ *Env, c ValidatorConfig, a *ast.CheckedAST, iss *Issues) { + var exemptedFunctions []string + exemptedFunctions = c.GetOrDefault(HomogeneousAggregateLiteralExemptFunctions, exemptedFunctions).([]string) + root := ast.NavigateCheckedAST(a) + listExprs := ast.MatchDescendants(root, ast.KindMatcher(ast.ListKind)) + for _, listExpr := range listExprs { + if inExemptFunction(listExpr, exemptedFunctions) { + continue + } + l := listExpr.AsList() + elements := l.Elements() + optIndices := l.OptionalIndices() + var elemType *Type + for i, e := range elements { + et := e.Type() + if isOptionalIndex(i, optIndices) { + et = et.Parameters()[0] + } + if elemType == nil { + elemType = et + continue + } + if !elemType.IsEquivalentType(et) { + v.typeMismatch(iss, e.ID(), elemType, et) + break + } + } + } + mapExprs := ast.MatchDescendants(root, ast.KindMatcher(ast.MapKind)) + for _, mapExpr := range mapExprs { + if inExemptFunction(mapExpr, exemptedFunctions) { + continue + } + m := mapExpr.AsMap() + entries := m.Entries() + var keyType, valType *Type + for _, e := range entries { + key, val := e.Key(), e.Value() + kt, vt := key.Type(), val.Type() + if e.IsOptional() { + vt = vt.Parameters()[0] + } + if keyType == nil && valType == nil { + keyType, valType = kt, vt + continue + } + if !keyType.IsEquivalentType(kt) { + v.typeMismatch(iss, key.ID(), keyType, kt) + } + if !valType.IsEquivalentType(vt) { + v.typeMismatch(iss, val.ID(), valType, vt) + } + } + } +} + +func inExemptFunction(e ast.NavigableExpr, exemptFunctions []string) bool { + if parent, found := e.Parent(); found { + if parent.Kind() == ast.CallKind { + fnName := parent.AsCall().FunctionName() + for _, exempt := range exemptFunctions { + if exempt == fnName { + return true + } + } + } + if parent.Kind() == ast.ListKind || parent.Kind() == ast.MapKind { + return inExemptFunction(parent, exemptFunctions) + } + } + return false +} + +func isOptionalIndex(i int, optIndices []int32) bool { + for _, optInd := range optIndices { + if i == int(optInd) { + return true + } + } + return false +} + +func (homogeneousAggregateLiteralValidator) typeMismatch(iss *Issues, id int64, expected, actual *Type) { + iss.ReportErrorAtID(id, "expected type '%s' but found '%s'", FormatCELType(expected), FormatCELType(actual)) +} + +type nestingLimitValidator struct { + limit int +} + +func (v nestingLimitValidator) Name() string { + return "cel.lib.std.validate.comprehension_nesting_limit" +} + +func (v nestingLimitValidator) Validate(e *Env, _ ValidatorConfig, a *ast.CheckedAST, iss *Issues) { + root := ast.NavigateCheckedAST(a) + comprehensions := ast.MatchDescendants(root, ast.KindMatcher(ast.ComprehensionKind)) + if len(comprehensions) <= v.limit { + return + } + for _, comp := range comprehensions { + count := 0 + e := comp + hasParent := true + for hasParent { + // When the expression is not a comprehension, continue to the next ancestor. + if e.Kind() != ast.ComprehensionKind { + e, hasParent = e.Parent() + continue + } + // When the comprehension has an empty range, continue to the next ancestor + // as this comprehension does not have any associated cost. + iterRange := e.AsComprehension().IterRange() + if iterRange.Kind() == ast.ListKind && iterRange.AsList().Size() == 0 { + e, hasParent = e.Parent() + continue + } + // Otherwise check the nesting limit. + count++ + if count > v.limit { + iss.ReportErrorAtID(comp.ID(), "comprehension exceeds nesting limit") + break + } + e, hasParent = e.Parent() + } + } +} diff --git a/vendor/github.com/google/cel-go/checker/BUILD.bazel b/vendor/github.com/google/cel-go/checker/BUILD.bazel index bec40b6e6..0459d3523 100644 --- a/vendor/github.com/google/cel-go/checker/BUILD.bazel +++ b/vendor/github.com/google/cel-go/checker/BUILD.bazel @@ -11,9 +11,11 @@ go_library( "cost.go", "env.go", "errors.go", + "format.go", "mapping.go", "options.go", "printer.go", + "scopes.go", "standard.go", "types.go", ], @@ -22,15 +24,18 @@ go_library( deps = [ "//checker/decls:go_default_library", "//common:go_default_library", + "//common/ast:go_default_library", "//common/containers:go_default_library", "//common/debug:go_default_library", + "//common/decls:go_default_library", "//common/operators:go_default_library", "//common/overloads:go_default_library", + "//common/stdlib:go_default_library", "//common/types:go_default_library", "//common/types/pb:go_default_library", "//common/types/ref:go_default_library", "//parser:go_default_library", - "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//types/known/emptypb:go_default_library", "@org_golang_google_protobuf//types/known/structpb:go_default_library", @@ -44,6 +49,7 @@ go_test( "checker_test.go", "cost_test.go", "env_test.go", + "format_test.go", ], embed = [ ":go_default_library", @@ -54,7 +60,7 @@ go_test( "//test:go_default_library", "//test/proto2pb:go_default_library", "//test/proto3pb:go_default_library", - "@com_github_antlr_antlr4_runtime_go_antlr//:go_default_library", + "@com_github_antlr_antlr4_runtime_go_antlr_v4//:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/checker/checker.go b/vendor/github.com/google/cel-go/checker/checker.go index dc4cb5c64..720e4fa96 100644 --- a/vendor/github.com/google/cel-go/checker/checker.go +++ b/vendor/github.com/google/cel-go/checker/checker.go @@ -18,15 +18,13 @@ package checker import ( "fmt" - "reflect" - "github.com/google/cel-go/checker/decls" "github.com/google/cel-go/common" + "github.com/google/cel-go/common/ast" "github.com/google/cel-go/common/containers" + "github.com/google/cel-go/common/decls" "github.com/google/cel-go/common/operators" - "github.com/google/cel-go/common/types/ref" - - "google.golang.org/protobuf/proto" + "github.com/google/cel-go/common/types" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) @@ -37,8 +35,8 @@ type checker struct { mappings *mapping freeTypeVarCounter int sourceInfo *exprpb.SourceInfo - types map[int64]*exprpb.Type - references map[int64]*exprpb.Reference + types map[int64]*types.Type + references map[int64]*ast.ReferenceInfo } // Check performs type checking, giving a typed AST. @@ -47,40 +45,38 @@ type checker struct { // descriptions of protocol buffers, and a registry for errors. // Returns a CheckedExpr proto, which might not be usable if // there are errors in the error registry. -func Check(parsedExpr *exprpb.ParsedExpr, - source common.Source, - env *Env) (*exprpb.CheckedExpr, *common.Errors) { +func Check(parsedExpr *exprpb.ParsedExpr, source common.Source, env *Env) (*ast.CheckedAST, *common.Errors) { + errs := common.NewErrors(source) c := checker{ env: env, - errors: &typeErrors{common.NewErrors(source)}, + errors: &typeErrors{errs: errs}, mappings: newMapping(), freeTypeVarCounter: 0, sourceInfo: parsedExpr.GetSourceInfo(), - types: make(map[int64]*exprpb.Type), - references: make(map[int64]*exprpb.Reference), + types: make(map[int64]*types.Type), + references: make(map[int64]*ast.ReferenceInfo), } c.check(parsedExpr.GetExpr()) // Walk over the final type map substituting any type parameters either by their bound value or // by DYN. - m := make(map[int64]*exprpb.Type) - for k, v := range c.types { - m[k] = substitute(c.mappings, v, true) + m := make(map[int64]*types.Type) + for id, t := range c.types { + m[id] = substitute(c.mappings, t, true) } - return &exprpb.CheckedExpr{ + return &ast.CheckedAST{ Expr: parsedExpr.GetExpr(), SourceInfo: parsedExpr.GetSourceInfo(), TypeMap: m, ReferenceMap: c.references, - }, c.errors.Errors + }, errs } func (c *checker) check(e *exprpb.Expr) { if e == nil { return } - switch e.GetExprKind().(type) { case *exprpb.Expr_ConstExpr: literal := e.GetConstExpr() @@ -113,53 +109,51 @@ func (c *checker) check(e *exprpb.Expr) { case *exprpb.Expr_ComprehensionExpr: c.checkComprehension(e) default: - c.errors.ReportError( - c.location(e), "Unrecognized ast type: %v", reflect.TypeOf(e)) + c.errors.unexpectedASTType(e.GetId(), c.location(e), e) } } func (c *checker) checkInt64Literal(e *exprpb.Expr) { - c.setType(e, decls.Int) + c.setType(e, types.IntType) } func (c *checker) checkUint64Literal(e *exprpb.Expr) { - c.setType(e, decls.Uint) + c.setType(e, types.UintType) } func (c *checker) checkStringLiteral(e *exprpb.Expr) { - c.setType(e, decls.String) + c.setType(e, types.StringType) } func (c *checker) checkBytesLiteral(e *exprpb.Expr) { - c.setType(e, decls.Bytes) + c.setType(e, types.BytesType) } func (c *checker) checkDoubleLiteral(e *exprpb.Expr) { - c.setType(e, decls.Double) + c.setType(e, types.DoubleType) } func (c *checker) checkBoolLiteral(e *exprpb.Expr) { - c.setType(e, decls.Bool) + c.setType(e, types.BoolType) } func (c *checker) checkNullLiteral(e *exprpb.Expr) { - c.setType(e, decls.Null) + c.setType(e, types.NullType) } func (c *checker) checkIdent(e *exprpb.Expr) { identExpr := e.GetIdentExpr() // Check to see if the identifier is declared. if ident := c.env.LookupIdent(identExpr.GetName()); ident != nil { - c.setType(e, ident.GetIdent().GetType()) - c.setReference(e, newIdentReference(ident.GetName(), ident.GetIdent().GetValue())) + c.setType(e, ident.Type()) + c.setReference(e, ast.NewIdentReference(ident.Name(), ident.Value())) // Overwrite the identifier with its fully qualified name. - identExpr.Name = ident.GetName() + identExpr.Name = ident.Name() return } - c.setType(e, decls.Error) - c.errors.undeclaredReference( - c.location(e), c.env.container.Name(), identExpr.GetName()) + c.setType(e, types.ErrorType) + c.errors.undeclaredReference(e.GetId(), c.location(e), c.env.container.Name(), identExpr.GetName()) } func (c *checker) checkSelect(e *exprpb.Expr) { @@ -174,9 +168,9 @@ func (c *checker) checkSelect(e *exprpb.Expr) { // Rewrite the node to be a variable reference to the resolved fully-qualified // variable name. - c.setType(e, ident.GetIdent().GetType()) - c.setReference(e, newIdentReference(ident.GetName(), ident.GetIdent().GetValue())) - identName := ident.GetName() + c.setType(e, ident.Type()) + c.setReference(e, ast.NewIdentReference(ident.Name(), ident.Value())) + identName := ident.Name() e.ExprKind = &exprpb.Expr_IdentExpr{ IdentExpr: &exprpb.Expr_Ident{ Name: identName, @@ -188,7 +182,7 @@ func (c *checker) checkSelect(e *exprpb.Expr) { resultType := c.checkSelectField(e, sel.GetOperand(), sel.GetField(), false) if sel.TestOnly { - resultType = decls.Bool + resultType = types.BoolType } c.setType(e, substitute(c.mappings, resultType, false)) } @@ -200,16 +194,17 @@ func (c *checker) checkOptSelect(e *exprpb.Expr) { field := call.GetArgs()[1] fieldName, isString := maybeUnwrapString(field) if !isString { - c.errors.ReportError(c.location(field), "unsupported optional field selection: %v", field) + c.errors.notAnOptionalFieldSelection(field.GetId(), c.location(field), field) return } // Perform type-checking using the field selection logic. resultType := c.checkSelectField(e, operand, fieldName, true) c.setType(e, substitute(c.mappings, resultType, false)) + c.setReference(e, ast.NewFunctionReference("select_optional_field")) } -func (c *checker) checkSelectField(e, operand *exprpb.Expr, field string, optional bool) *exprpb.Type { +func (c *checker) checkSelectField(e, operand *exprpb.Expr, field string, optional bool) *types.Type { // Interpret as field selection, first traversing down the operand. c.check(operand) operandType := substitute(c.mappings, c.getType(operand), false) @@ -218,38 +213,37 @@ func (c *checker) checkSelectField(e, operand *exprpb.Expr, field string, option targetType, isOpt := maybeUnwrapOptional(operandType) // Assume error type by default as most types do not support field selection. - resultType := decls.Error - switch kindOf(targetType) { - case kindMap: + resultType := types.ErrorType + switch targetType.Kind() { + case types.MapKind: // Maps yield their value type as the selection result type. - mapType := targetType.GetMapType() - resultType = mapType.GetValueType() - case kindObject: + resultType = targetType.Parameters()[1] + case types.StructKind: // Objects yield their field type declaration as the selection result type, but only if // the field is defined. messageType := targetType - if fieldType, found := c.lookupFieldType(c.location(e), messageType.GetMessageType(), field); found { - resultType = fieldType.Type + if fieldType, found := c.lookupFieldType(e.GetId(), messageType.TypeName(), field); found { + resultType = fieldType } - case kindTypeParam: + case types.TypeParamKind: // Set the operand type to DYN to prevent assignment to a potentially incorrect type // at a later point in type-checking. The isAssignable call will update the type // substitutions for the type param under the covers. - c.isAssignable(decls.Dyn, targetType) + c.isAssignable(types.DynType, targetType) // Also, set the result type to DYN. - resultType = decls.Dyn + resultType = types.DynType default: // Dynamic / error values are treated as DYN type. Errors are handled this way as well // in order to allow forward progress on the check. if !isDynOrError(targetType) { - c.errors.typeDoesNotSupportFieldSelection(c.location(e), targetType) + c.errors.typeDoesNotSupportFieldSelection(e.GetId(), c.location(e), targetType) } - resultType = decls.Dyn + resultType = types.DynType } // If the target type was optional coming in, then the result must be optional going out. if isOpt || optional { - return decls.NewOptionalType(resultType) + return types.NewOptionalType(resultType) } return resultType } @@ -277,15 +271,14 @@ func (c *checker) checkCall(e *exprpb.Expr) { // Check for the existence of the function. fn := c.env.LookupFunction(fnName) if fn == nil { - c.errors.undeclaredReference( - c.location(e), c.env.container.Name(), fnName) - c.setType(e, decls.Error) + c.errors.undeclaredReference(e.GetId(), c.location(e), c.env.container.Name(), fnName) + c.setType(e, types.ErrorType) return } // Overwrite the function name with its fully qualified resolved name. - call.Function = fn.GetName() + call.Function = fn.Name() // Check to see whether the overload resolves. - c.resolveOverloadOrError(c.location(e), e, fn, nil, args) + c.resolveOverloadOrError(e, fn, nil, args) return } @@ -303,8 +296,8 @@ func (c *checker) checkCall(e *exprpb.Expr) { // be an inaccurate representation of the desired evaluation behavior. // Overwrite with fully-qualified resolved function name sans receiver target. call.Target = nil - call.Function = fn.GetName() - c.resolveOverloadOrError(c.location(e), e, fn, nil, args) + call.Function = fn.Name() + c.resolveOverloadOrError(e, fn, nil, args) return } } @@ -314,22 +307,21 @@ func (c *checker) checkCall(e *exprpb.Expr) { fn := c.env.LookupFunction(fnName) // Function found, attempt overload resolution. if fn != nil { - c.resolveOverloadOrError(c.location(e), e, fn, target, args) + c.resolveOverloadOrError(e, fn, target, args) return } // Function name not declared, record error. - c.errors.undeclaredReference(c.location(e), c.env.container.Name(), fnName) + c.setType(e, types.ErrorType) + c.errors.undeclaredReference(e.GetId(), c.location(e), c.env.container.Name(), fnName) } func (c *checker) resolveOverloadOrError( - loc common.Location, - e *exprpb.Expr, - fn *exprpb.Decl, target *exprpb.Expr, args []*exprpb.Expr) { + e *exprpb.Expr, fn *decls.FunctionDecl, target *exprpb.Expr, args []*exprpb.Expr) { // Attempt to resolve the overload. - resolution := c.resolveOverload(loc, fn, target, args) + resolution := c.resolveOverload(e, fn, target, args) // No such overload, error noted in the resolveOverload call, type recorded here. if resolution == nil { - c.setType(e, decls.Error) + c.setType(e, types.ErrorType) return } // Overload found. @@ -338,10 +330,9 @@ func (c *checker) resolveOverloadOrError( } func (c *checker) resolveOverload( - loc common.Location, - fn *exprpb.Decl, target *exprpb.Expr, args []*exprpb.Expr) *overloadResolution { + call *exprpb.Expr, fn *decls.FunctionDecl, target *exprpb.Expr, args []*exprpb.Expr) *overloadResolution { - var argTypes []*exprpb.Type + var argTypes []*types.Type if target != nil { argTypes = append(argTypes, c.getType(target)) } @@ -349,55 +340,75 @@ func (c *checker) resolveOverload( argTypes = append(argTypes, c.getType(arg)) } - var resultType *exprpb.Type - var checkedRef *exprpb.Reference - for _, overload := range fn.GetFunction().GetOverloads() { + var resultType *types.Type + var checkedRef *ast.ReferenceInfo + for _, overload := range fn.OverloadDecls() { // Determine whether the overload is currently considered. - if c.env.isOverloadDisabled(overload.GetOverloadId()) { + if c.env.isOverloadDisabled(overload.ID()) { continue } // Ensure the call style for the overload matches. - if (target == nil && overload.GetIsInstanceFunction()) || - (target != nil && !overload.GetIsInstanceFunction()) { + if (target == nil && overload.IsMemberFunction()) || + (target != nil && !overload.IsMemberFunction()) { // not a compatible call style. continue } - overloadType := decls.NewFunctionType(overload.ResultType, overload.Params...) - if len(overload.GetTypeParams()) > 0 { + // Alternative type-checking behavior when the logical operators are compacted into + // variadic AST representations. + if fn.Name() == operators.LogicalAnd || fn.Name() == operators.LogicalOr { + checkedRef = ast.NewFunctionReference(overload.ID()) + for i, argType := range argTypes { + if !c.isAssignable(argType, types.BoolType) { + c.errors.typeMismatch( + args[i].GetId(), + c.locationByID(args[i].GetId()), + types.BoolType, + argType) + resultType = types.ErrorType + } + } + if isError(resultType) { + return nil + } + return newResolution(checkedRef, types.BoolType) + } + + overloadType := newFunctionType(overload.ResultType(), overload.ArgTypes()...) + typeParams := overload.TypeParams() + if len(typeParams) != 0 { // Instantiate overload's type with fresh type variables. substitutions := newMapping() - for _, typePar := range overload.GetTypeParams() { - substitutions.add(decls.NewTypeParamType(typePar), c.newTypeVar()) + for _, typePar := range typeParams { + substitutions.add(types.NewTypeParamType(typePar), c.newTypeVar()) } overloadType = substitute(substitutions, overloadType, false) } - candidateArgTypes := overloadType.GetFunction().GetArgTypes() + candidateArgTypes := overloadType.Parameters()[1:] if c.isAssignableList(argTypes, candidateArgTypes) { if checkedRef == nil { - checkedRef = newFunctionReference(overload.GetOverloadId()) + checkedRef = ast.NewFunctionReference(overload.ID()) } else { - checkedRef.OverloadId = append(checkedRef.GetOverloadId(), overload.GetOverloadId()) + checkedRef.AddOverload(overload.ID()) } // First matching overload, determines result type. - fnResultType := substitute(c.mappings, overloadType.GetFunction().GetResultType(), false) + fnResultType := substitute(c.mappings, overloadType.Parameters()[0], false) if resultType == nil { resultType = fnResultType - } else if !isDyn(resultType) && !proto.Equal(fnResultType, resultType) { - resultType = decls.Dyn + } else if !isDyn(resultType) && !fnResultType.IsExactType(resultType) { + resultType = types.DynType } } } if resultType == nil { - for i, arg := range argTypes { - argTypes[i] = substitute(c.mappings, arg, true) + for i, argType := range argTypes { + argTypes[i] = substitute(c.mappings, argType, true) } - c.errors.noMatchingOverload(loc, fn.GetName(), argTypes, target != nil) - resultType = decls.Error + c.errors.noMatchingOverload(call.GetId(), c.location(call), fn.Name(), argTypes, target != nil) return nil } @@ -406,16 +417,29 @@ func (c *checker) resolveOverload( func (c *checker) checkCreateList(e *exprpb.Expr) { create := e.GetListExpr() - var elemType *exprpb.Type - for _, e := range create.GetElements() { + var elemsType *types.Type + optionalIndices := create.GetOptionalIndices() + optionals := make(map[int32]bool, len(optionalIndices)) + for _, optInd := range optionalIndices { + optionals[optInd] = true + } + for i, e := range create.GetElements() { c.check(e) - elemType = c.joinTypes(c.location(e), elemType, c.getType(e)) + elemType := c.getType(e) + if optionals[int32(i)] { + var isOptional bool + elemType, isOptional = maybeUnwrapOptional(elemType) + if !isOptional && !isDyn(elemType) { + c.errors.typeMismatch(e.GetId(), c.location(e), types.NewOptionalType(elemType), elemType) + } + } + elemsType = c.joinTypes(e, elemsType, elemType) } - if elemType == nil { + if elemsType == nil { // If the list is empty, assign free type var to elem type. - elemType = c.newTypeVar() + elemsType = c.newTypeVar() } - c.setType(e, decls.NewListType(elemType)) + c.setType(e, types.NewListType(elemsType)) } func (c *checker) checkCreateStruct(e *exprpb.Expr) { @@ -429,12 +453,12 @@ func (c *checker) checkCreateStruct(e *exprpb.Expr) { func (c *checker) checkCreateMap(e *exprpb.Expr) { mapVal := e.GetStructExpr() - var mapKeyType *exprpb.Type - var mapValueType *exprpb.Type + var mapKeyType *types.Type + var mapValueType *types.Type for _, ent := range mapVal.GetEntries() { key := ent.GetMapKey() c.check(key) - mapKeyType = c.joinTypes(c.location(key), mapKeyType, c.getType(key)) + mapKeyType = c.joinTypes(key, mapKeyType, c.getType(key)) val := ent.GetValue() c.check(val) @@ -443,50 +467,54 @@ func (c *checker) checkCreateMap(e *exprpb.Expr) { var isOptional bool valType, isOptional = maybeUnwrapOptional(valType) if !isOptional && !isDyn(valType) { - c.errors.typeMismatch(c.location(val), decls.NewOptionalType(valType), valType) + c.errors.typeMismatch(val.GetId(), c.location(val), types.NewOptionalType(valType), valType) } } - mapValueType = c.joinTypes(c.location(val), mapValueType, valType) + mapValueType = c.joinTypes(val, mapValueType, valType) } if mapKeyType == nil { // If the map is empty, assign free type variables to typeKey and value type. mapKeyType = c.newTypeVar() mapValueType = c.newTypeVar() } - c.setType(e, decls.NewMapType(mapKeyType, mapValueType)) + c.setType(e, types.NewMapType(mapKeyType, mapValueType)) } func (c *checker) checkCreateMessage(e *exprpb.Expr) { msgVal := e.GetStructExpr() // Determine the type of the message. - messageType := decls.Error - decl := c.env.LookupIdent(msgVal.GetMessageName()) - if decl == nil { + resultType := types.ErrorType + ident := c.env.LookupIdent(msgVal.GetMessageName()) + if ident == nil { c.errors.undeclaredReference( - c.location(e), c.env.container.Name(), msgVal.GetMessageName()) + e.GetId(), c.location(e), c.env.container.Name(), msgVal.GetMessageName()) + c.setType(e, types.ErrorType) return } // Ensure the type name is fully qualified in the AST. - msgVal.MessageName = decl.GetName() - c.setReference(e, newIdentReference(decl.GetName(), nil)) - ident := decl.GetIdent() - identKind := kindOf(ident.GetType()) - if identKind != kindError { - if identKind != kindType { - c.errors.notAType(c.location(e), ident.GetType()) + typeName := ident.Name() + msgVal.MessageName = typeName + c.setReference(e, ast.NewIdentReference(ident.Name(), nil)) + identKind := ident.Type().Kind() + if identKind != types.ErrorKind { + if identKind != types.TypeKind { + c.errors.notAType(e.GetId(), c.location(e), ident.Type().DeclaredTypeName()) } else { - messageType = ident.GetType().GetType() - if kindOf(messageType) != kindObject { - c.errors.notAMessageType(c.location(e), messageType) - messageType = decls.Error + resultType = ident.Type().Parameters()[0] + // Backwards compatibility test between well-known types and message types + // In this context, the type is being instantiated by its protobuf name which + // is not ideal or recommended, but some users expect this to work. + if isWellKnownType(resultType) { + typeName = getWellKnownTypeName(resultType) + } else if resultType.Kind() == types.StructKind { + typeName = resultType.DeclaredTypeName() + } else { + c.errors.notAMessageType(e.GetId(), c.location(e), resultType.DeclaredTypeName()) + resultType = types.ErrorType } } } - if isObjectWellKnownType(messageType) { - c.setType(e, getObjectWellKnownType(messageType)) - } else { - c.setType(e, messageType) - } + c.setType(e, resultType) // Check the field initializers. for _, ent := range msgVal.GetEntries() { @@ -494,10 +522,10 @@ func (c *checker) checkCreateMessage(e *exprpb.Expr) { value := ent.GetValue() c.check(value) - fieldType := decls.Error - ft, found := c.lookupFieldType(c.locationByID(ent.GetId()), messageType.GetMessageType(), field) + fieldType := types.ErrorType + ft, found := c.lookupFieldType(ent.GetId(), typeName, field) if found { - fieldType = ft.Type + fieldType = ft } valType := c.getType(value) @@ -505,11 +533,11 @@ func (c *checker) checkCreateMessage(e *exprpb.Expr) { var isOptional bool valType, isOptional = maybeUnwrapOptional(valType) if !isOptional && !isDyn(valType) { - c.errors.typeMismatch(c.location(value), decls.NewOptionalType(valType), valType) + c.errors.typeMismatch(value.GetId(), c.location(value), types.NewOptionalType(valType), valType) } } if !c.isAssignable(fieldType, valType) { - c.errors.fieldTypeMismatch(c.locationByID(ent.Id), field, fieldType, valType) + c.errors.fieldTypeMismatch(ent.GetId(), c.locationByID(ent.GetId()), field, fieldType, valType) } } } @@ -520,36 +548,36 @@ func (c *checker) checkComprehension(e *exprpb.Expr) { c.check(comp.GetAccuInit()) accuType := c.getType(comp.GetAccuInit()) rangeType := substitute(c.mappings, c.getType(comp.GetIterRange()), false) - var varType *exprpb.Type + var varType *types.Type - switch kindOf(rangeType) { - case kindList: - varType = rangeType.GetListType().GetElemType() - case kindMap: + switch rangeType.Kind() { + case types.ListKind: + varType = rangeType.Parameters()[0] + case types.MapKind: // Ranges over the keys. - varType = rangeType.GetMapType().GetKeyType() - case kindDyn, kindError, kindTypeParam: + varType = rangeType.Parameters()[0] + case types.DynKind, types.ErrorKind, types.TypeParamKind: // Set the range type to DYN to prevent assignment to a potentially incorrect type // at a later point in type-checking. The isAssignable call will update the type // substitutions for the type param under the covers. - c.isAssignable(decls.Dyn, rangeType) + c.isAssignable(types.DynType, rangeType) // Set the range iteration variable to type DYN as well. - varType = decls.Dyn + varType = types.DynType default: - c.errors.notAComprehensionRange(c.location(comp.GetIterRange()), rangeType) - varType = decls.Error + c.errors.notAComprehensionRange(comp.GetIterRange().GetId(), c.location(comp.GetIterRange()), rangeType) + varType = types.ErrorType } // Create a scope for the comprehension since it has a local accumulation variable. // This scope will contain the accumulation variable used to compute the result. c.env = c.env.enterScope() - c.env.Add(decls.NewVar(comp.GetAccuVar(), accuType)) + c.env.AddIdents(decls.NewVariable(comp.GetAccuVar(), accuType)) // Create a block scope for the loop. c.env = c.env.enterScope() - c.env.Add(decls.NewVar(comp.GetIterVar(), varType)) + c.env.AddIdents(decls.NewVariable(comp.GetIterVar(), varType)) // Check the variable references in the condition and step. c.check(comp.GetLoopCondition()) - c.assertType(comp.GetLoopCondition(), decls.Bool) + c.assertType(comp.GetLoopCondition(), types.BoolType) c.check(comp.GetLoopStep()) c.assertType(comp.GetLoopStep(), accuType) // Exit the loop's block scope before checking the result. @@ -561,9 +589,7 @@ func (c *checker) checkComprehension(e *exprpb.Expr) { } // Checks compatibility of joined types, and returns the most general common type. -func (c *checker) joinTypes(loc common.Location, - previous *exprpb.Type, - current *exprpb.Type) *exprpb.Type { +func (c *checker) joinTypes(e *exprpb.Expr, previous, current *types.Type) *types.Type { if previous == nil { return current } @@ -571,23 +597,23 @@ func (c *checker) joinTypes(loc common.Location, return mostGeneral(previous, current) } if c.dynAggregateLiteralElementTypesEnabled() { - return decls.Dyn + return types.DynType } - c.errors.typeMismatch(loc, previous, current) - return decls.Error + c.errors.typeMismatch(e.GetId(), c.location(e), previous, current) + return types.ErrorType } func (c *checker) dynAggregateLiteralElementTypesEnabled() bool { return c.env.aggLitElemType == dynElementType } -func (c *checker) newTypeVar() *exprpb.Type { +func (c *checker) newTypeVar() *types.Type { id := c.freeTypeVarCounter c.freeTypeVarCounter++ - return decls.NewTypeParamType(fmt.Sprintf("_var%d", id)) + return types.NewTypeParamType(fmt.Sprintf("_var%d", id)) } -func (c *checker) isAssignable(t1 *exprpb.Type, t2 *exprpb.Type) bool { +func (c *checker) isAssignable(t1, t2 *types.Type) bool { subs := isAssignable(c.mappings, t1, t2) if subs != nil { c.mappings = subs @@ -597,7 +623,7 @@ func (c *checker) isAssignable(t1 *exprpb.Type, t2 *exprpb.Type) bool { return false } -func (c *checker) isAssignableList(l1 []*exprpb.Type, l2 []*exprpb.Type) bool { +func (c *checker) isAssignableList(l1, l2 []*types.Type) bool { subs := isAssignableList(c.mappings, l1, l2) if subs != nil { c.mappings = subs @@ -607,57 +633,52 @@ func (c *checker) isAssignableList(l1 []*exprpb.Type, l2 []*exprpb.Type) bool { return false } -func (c *checker) lookupFieldType(l common.Location, messageType string, fieldName string) (*ref.FieldType, bool) { - if _, found := c.env.provider.FindType(messageType); !found { - // This should not happen, anyway, report an error. - c.errors.unexpectedFailedResolution(l, messageType) - return nil, false - } - - if ft, found := c.env.provider.FindFieldType(messageType, fieldName); found { - return ft, found +func maybeUnwrapString(e *exprpb.Expr) (string, bool) { + switch e.GetExprKind().(type) { + case *exprpb.Expr_ConstExpr: + literal := e.GetConstExpr() + switch literal.GetConstantKind().(type) { + case *exprpb.Constant_StringValue: + return literal.GetStringValue(), true + } } - - c.errors.undefinedField(l, fieldName) - return nil, false + return "", false } -func (c *checker) setType(e *exprpb.Expr, t *exprpb.Type) { - if old, found := c.types[e.GetId()]; found && !proto.Equal(old, t) { - c.errors.ReportError(c.location(e), - "(Incompatible) Type already exists for expression: %v(%d) old:%v, new:%v", e, e.GetId(), old, t) +func (c *checker) setType(e *exprpb.Expr, t *types.Type) { + if old, found := c.types[e.GetId()]; found && !old.IsExactType(t) { + c.errors.incompatibleType(e.GetId(), c.location(e), e, old, t) return } c.types[e.GetId()] = t } -func (c *checker) getType(e *exprpb.Expr) *exprpb.Type { +func (c *checker) getType(e *exprpb.Expr) *types.Type { return c.types[e.GetId()] } -func (c *checker) setReference(e *exprpb.Expr, r *exprpb.Reference) { - if old, found := c.references[e.GetId()]; found && !proto.Equal(old, r) { - c.errors.ReportError(c.location(e), - "Reference already exists for expression: %v(%d) old:%v, new:%v", e, e.GetId(), old, r) +func (c *checker) setReference(e *exprpb.Expr, r *ast.ReferenceInfo) { + if old, found := c.references[e.GetId()]; found && !old.Equals(r) { + c.errors.referenceRedefinition(e.GetId(), c.location(e), e, old, r) return } c.references[e.GetId()] = r } -func (c *checker) assertType(e *exprpb.Expr, t *exprpb.Type) { +func (c *checker) assertType(e *exprpb.Expr, t *types.Type) { if !c.isAssignable(t, c.getType(e)) { - c.errors.typeMismatch(c.location(e), t, c.getType(e)) + c.errors.typeMismatch(e.GetId(), c.location(e), t, c.getType(e)) } } type overloadResolution struct { - Reference *exprpb.Reference - Type *exprpb.Type + Type *types.Type + Reference *ast.ReferenceInfo } -func newResolution(checkedRef *exprpb.Reference, t *exprpb.Type) *overloadResolution { +func newResolution(r *ast.ReferenceInfo, t *types.Type) *overloadResolution { return &overloadResolution{ - Reference: checkedRef, + Reference: r, Type: t, } } @@ -684,10 +705,56 @@ func (c *checker) locationByID(id int64) common.Location { return common.NoLocation } -func newIdentReference(name string, value *exprpb.Constant) *exprpb.Reference { - return &exprpb.Reference{Name: name, Value: value} +func (c *checker) lookupFieldType(exprID int64, structType, fieldName string) (*types.Type, bool) { + if _, found := c.env.provider.FindStructType(structType); !found { + // This should not happen, anyway, report an error. + c.errors.unexpectedFailedResolution(exprID, c.locationByID(exprID), structType) + return nil, false + } + + if ft, found := c.env.provider.FindStructFieldType(structType, fieldName); found { + return ft.Type, found + } + + c.errors.undefinedField(exprID, c.locationByID(exprID), fieldName) + return nil, false +} + +func isWellKnownType(t *types.Type) bool { + switch t.Kind() { + case types.AnyKind, types.TimestampKind, types.DurationKind, types.DynKind, types.NullTypeKind: + return true + case types.BoolKind, types.BytesKind, types.DoubleKind, types.IntKind, types.StringKind, types.UintKind: + return t.IsAssignableType(types.NullType) + case types.ListKind: + return t.Parameters()[0] == types.DynType + case types.MapKind: + return t.Parameters()[0] == types.StringType && t.Parameters()[1] == types.DynType + } + return false } -func newFunctionReference(overloads ...string) *exprpb.Reference { - return &exprpb.Reference{OverloadId: overloads} +func getWellKnownTypeName(t *types.Type) string { + if name, found := wellKnownTypes[t.Kind()]; found { + return name + } + return "" } + +var ( + wellKnownTypes = map[types.Kind]string{ + types.AnyKind: "google.protobuf.Any", + types.BoolKind: "google.protobuf.BoolValue", + types.BytesKind: "google.protobuf.BytesValue", + types.DoubleKind: "google.protobuf.DoubleValue", + types.DurationKind: "google.protobuf.Duration", + types.DynKind: "google.protobuf.Value", + types.IntKind: "google.protobuf.Int64Value", + types.ListKind: "google.protobuf.ListValue", + types.NullTypeKind: "google.protobuf.NullValue", + types.MapKind: "google.protobuf.Struct", + types.StringKind: "google.protobuf.StringValue", + types.TimestampKind: "google.protobuf.Timestamp", + types.UintKind: "google.protobuf.UInt64Value", + } +) diff --git a/vendor/github.com/google/cel-go/checker/cost.go b/vendor/github.com/google/cel-go/checker/cost.go index 7312d1fe2..d02f2628a 100644 --- a/vendor/github.com/google/cel-go/checker/cost.go +++ b/vendor/github.com/google/cel-go/checker/cost.go @@ -18,7 +18,9 @@ import ( "math" "github.com/google/cel-go/common" + "github.com/google/cel-go/common/ast" "github.com/google/cel-go/common/overloads" + "github.com/google/cel-go/common/types" "github.com/google/cel-go/parser" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" @@ -54,7 +56,7 @@ type AstNode interface { // The first path element is a variable. All subsequent path elements are one of: field name, '@items', '@keys', '@values'. Path() []string // Type returns the deduced type of the AstNode. - Type() *exprpb.Type + Type() *types.Type // Expr returns the expression of the AstNode. Expr() *exprpb.Expr // ComputedSize returns a size estimate of the AstNode derived from information available in the CEL expression. @@ -66,7 +68,7 @@ type AstNode interface { type astNode struct { path []string - t *exprpb.Type + t *types.Type expr *exprpb.Expr derivedSize *SizeEstimate } @@ -75,7 +77,7 @@ func (e astNode) Path() []string { return e.path } -func (e astNode) Type() *exprpb.Type { +func (e astNode) Type() *types.Type { return e.t } @@ -92,7 +94,10 @@ func (e astNode) ComputedSize() *SizeEstimate { case *exprpb.Expr_ConstExpr: switch ck := ek.ConstExpr.GetConstantKind().(type) { case *exprpb.Constant_StringValue: - v = uint64(len(ck.StringValue)) + // converting to runes here is an O(n) operation, but + // this is consistent with how size is computed at runtime, + // and how the language definition defines string size + v = uint64(len([]rune(ck.StringValue))) case *exprpb.Constant_BytesValue: v = uint64(len(ck.BytesValue)) case *exprpb.Constant_BoolValue, *exprpb.Constant_DoubleValue, *exprpb.Constant_DurationValue, @@ -256,8 +261,10 @@ type coster struct { iterRanges iterRangeScopes // computedSizes tracks the computed sizes of call results. computedSizes map[int64]SizeEstimate - checkedExpr *exprpb.CheckedExpr + checkedAST *ast.CheckedAST estimator CostEstimator + // presenceTestCost will either be a zero or one based on whether has() macros count against cost computations. + presenceTestCost CostEstimate } // Use a stack of iterVar -> iterRange Expr Ids to handle shadowed variable names. @@ -280,16 +287,39 @@ func (vs iterRangeScopes) peek(varName string) (int64, bool) { return 0, false } +// CostOption configures flags which affect cost computations. +type CostOption func(*coster) error + +// PresenceTestHasCost determines whether presence testing has a cost of one or zero. +// Defaults to presence test has a cost of one. +func PresenceTestHasCost(hasCost bool) CostOption { + return func(c *coster) error { + if hasCost { + c.presenceTestCost = selectAndIdentCost + return nil + } + c.presenceTestCost = CostEstimate{Min: 0, Max: 0} + return nil + } +} + // Cost estimates the cost of the parsed and type checked CEL expression. -func Cost(checker *exprpb.CheckedExpr, estimator CostEstimator) CostEstimate { - c := coster{ - checkedExpr: checker, - estimator: estimator, - exprPath: map[int64][]string{}, - iterRanges: map[string][]int64{}, - computedSizes: map[int64]SizeEstimate{}, +func Cost(checker *ast.CheckedAST, estimator CostEstimator, opts ...CostOption) (CostEstimate, error) { + c := &coster{ + checkedAST: checker, + estimator: estimator, + exprPath: map[int64][]string{}, + iterRanges: map[string][]int64{}, + computedSizes: map[int64]SizeEstimate{}, + presenceTestCost: CostEstimate{Min: 1, Max: 1}, + } + for _, opt := range opts { + err := opt(c) + if err != nil { + return CostEstimate{}, err + } } - return c.cost(checker.GetExpr()) + return c.cost(checker.Expr), nil } func (c *coster) cost(e *exprpb.Expr) CostEstimate { @@ -323,10 +353,10 @@ func (c *coster) costIdent(e *exprpb.Expr) CostEstimate { // build and track the field path if iterRange, ok := c.iterRanges.peek(identExpr.GetName()); ok { - switch c.checkedExpr.TypeMap[iterRange].GetTypeKind().(type) { - case *exprpb.Type_ListType_: + switch c.checkedAST.TypeMap[iterRange].Kind() { + case types.ListKind: c.addPath(e, append(c.exprPath[iterRange], "@items")) - case *exprpb.Type_MapType_: + case types.MapKind: c.addPath(e, append(c.exprPath[iterRange], "@keys")) } } else { @@ -340,12 +370,18 @@ func (c *coster) costSelect(e *exprpb.Expr) CostEstimate { sel := e.GetSelectExpr() var sum CostEstimate if sel.GetTestOnly() { + // recurse, but do not add any cost + // this is equivalent to how evalTestOnly increments the runtime cost counter + // but does not add any additional cost for the qualifier, except here we do + // the reverse (ident adds cost) + sum = sum.Add(c.presenceTestCost) + sum = sum.Add(c.cost(sel.GetOperand())) return sum } sum = sum.Add(c.cost(sel.GetOperand())) targetType := c.getType(sel.GetOperand()) - switch kindOf(targetType) { - case kindMap, kindObject, kindTypeParam: + switch targetType.Kind() { + case types.MapKind, types.StructKind, types.TypeParamKind: sum = sum.Add(selectAndIdentCost) } @@ -369,8 +405,8 @@ func (c *coster) costCall(e *exprpb.Expr) CostEstimate { argTypes[i] = c.newAstNode(arg) } - ref := c.checkedExpr.ReferenceMap[e.GetId()] - if ref == nil || len(ref.GetOverloadId()) == 0 { + ref := c.checkedAST.ReferenceMap[e.GetId()] + if ref == nil || len(ref.OverloadIDs) == 0 { return CostEstimate{} } var targetType AstNode @@ -383,7 +419,7 @@ func (c *coster) costCall(e *exprpb.Expr) CostEstimate { // Pick a cost estimate range that covers all the overload cost estimation ranges fnCost := CostEstimate{Min: uint64(math.MaxUint64), Max: 0} var resultSize *SizeEstimate - for _, overload := range ref.GetOverloadId() { + for _, overload := range ref.OverloadIDs { overloadCost := c.functionCost(call.GetFunction(), overload, &targetType, argTypes, argCosts) fnCost = fnCost.Union(overloadCost.CostEstimate) if overloadCost.ResultSize != nil { @@ -499,11 +535,34 @@ func (c *coster) functionCost(function, overloadID string, target *AstNode, args if est := c.estimator.EstimateCallCost(function, overloadID, target, args); est != nil { callEst := *est - return CallEstimate{CostEstimate: callEst.Add(argCostSum())} + return CallEstimate{CostEstimate: callEst.Add(argCostSum()), ResultSize: est.ResultSize} } switch overloadID { // O(n) functions - case overloads.StartsWithString, overloads.EndsWithString, overloads.StringToBytes, overloads.BytesToString: + case overloads.ExtFormatString: + if target != nil { + // ResultSize not calculated because we can't bound the max size. + return CallEstimate{CostEstimate: c.sizeEstimate(*target).MultiplyByCostFactor(common.StringTraversalCostFactor).Add(argCostSum())} + } + case overloads.StringToBytes: + if len(args) == 1 { + sz := c.sizeEstimate(args[0]) + // ResultSize max is when each char converts to 4 bytes. + return CallEstimate{CostEstimate: sz.MultiplyByCostFactor(common.StringTraversalCostFactor).Add(argCostSum()), ResultSize: &SizeEstimate{Min: sz.Min, Max: sz.Max * 4}} + } + case overloads.BytesToString: + if len(args) == 1 { + sz := c.sizeEstimate(args[0]) + // ResultSize min is when 4 bytes convert to 1 char. + return CallEstimate{CostEstimate: sz.MultiplyByCostFactor(common.StringTraversalCostFactor).Add(argCostSum()), ResultSize: &SizeEstimate{Min: sz.Min / 4, Max: sz.Max}} + } + case overloads.ExtQuoteString: + if len(args) == 1 { + sz := c.sizeEstimate(args[0]) + // ResultSize max is when each char is escaped. 2 quote chars always added. + return CallEstimate{CostEstimate: sz.MultiplyByCostFactor(common.StringTraversalCostFactor).Add(argCostSum()), ResultSize: &SizeEstimate{Min: sz.Min + 2, Max: sz.Max*2 + 2}} + } + case overloads.StartsWithString, overloads.EndsWithString: if len(args) == 1 { return CallEstimate{CostEstimate: c.sizeEstimate(args[0]).MultiplyByCostFactor(common.StringTraversalCostFactor).Add(argCostSum())} } @@ -584,8 +643,8 @@ func (c *coster) functionCost(function, overloadID string, target *AstNode, args return CallEstimate{CostEstimate: CostEstimate{Min: 1, Max: 1}.Add(argCostSum())} } -func (c *coster) getType(e *exprpb.Expr) *exprpb.Type { - return c.checkedExpr.TypeMap[e.GetId()] +func (c *coster) getType(e *exprpb.Expr) *types.Type { + return c.checkedAST.TypeMap[e.GetId()] } func (c *coster) getPath(e *exprpb.Expr) []string { @@ -606,22 +665,20 @@ func (c *coster) newAstNode(e *exprpb.Expr) *astNode { if size, ok := c.computedSizes[e.GetId()]; ok { derivedSize = &size } - return &astNode{path: path, t: c.getType(e), expr: e, derivedSize: derivedSize} + return &astNode{ + path: path, + t: c.getType(e), + expr: e, + derivedSize: derivedSize} } // isScalar returns true if the given type is known to be of a constant size at // compile time. isScalar will return false for strings (they are variable-width) // in addition to protobuf.Any and protobuf.Value (their size is not knowable at compile time). -func isScalar(t *exprpb.Type) bool { - switch kindOf(t) { - case kindPrimitive: - if t.GetPrimitive() != exprpb.Type_STRING && t.GetPrimitive() != exprpb.Type_BYTES { - return true - } - case kindWellKnown: - if t.GetWellKnown() == exprpb.Type_DURATION || t.GetWellKnown() == exprpb.Type_TIMESTAMP { - return true - } +func isScalar(t *types.Type) bool { + switch t.Kind() { + case types.BoolKind, types.DoubleKind, types.DurationKind, types.IntKind, types.TimestampKind, types.UintKind: + return true } return false } diff --git a/vendor/github.com/google/cel-go/checker/decls/BUILD.bazel b/vendor/github.com/google/cel-go/checker/decls/BUILD.bazel index 5a24f1da8..a6b0be292 100644 --- a/vendor/github.com/google/cel-go/checker/decls/BUILD.bazel +++ b/vendor/github.com/google/cel-go/checker/decls/BUILD.bazel @@ -9,11 +9,10 @@ go_library( name = "go_default_library", srcs = [ "decls.go", - "scopes.go", ], importpath = "github.com/google/cel-go/checker/decls", deps = [ - "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", "@org_golang_google_protobuf//types/known/emptypb:go_default_library", "@org_golang_google_protobuf//types/known/structpb:go_default_library", ], diff --git a/vendor/github.com/google/cel-go/checker/env.go b/vendor/github.com/google/cel-go/checker/env.go index c7eeb04ee..70682b17c 100644 --- a/vendor/github.com/google/cel-go/checker/env.go +++ b/vendor/github.com/google/cel-go/checker/env.go @@ -18,17 +18,11 @@ import ( "fmt" "strings" - "google.golang.org/protobuf/proto" - - "github.com/google/cel-go/checker/decls" "github.com/google/cel-go/common/containers" + "github.com/google/cel-go/common/decls" "github.com/google/cel-go/common/overloads" "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/pb" - "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/parser" - - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) type aggregateLiteralElementType int @@ -76,15 +70,15 @@ var ( // which can be used to assist with type-checking. type Env struct { container *containers.Container - provider ref.TypeProvider - declarations *decls.Scopes + provider types.Provider + declarations *Scopes aggLitElemType aggregateLiteralElementType filteredOverloadIDs map[string]struct{} } // NewEnv returns a new *Env with the given parameters. -func NewEnv(container *containers.Container, provider ref.TypeProvider, opts ...Option) (*Env, error) { - declarations := decls.NewScopes() +func NewEnv(container *containers.Container, provider types.Provider, opts ...Option) (*Env, error) { + declarations := newScopes() declarations.Push() envOptions := &options{} @@ -113,24 +107,31 @@ func NewEnv(container *containers.Container, provider ref.TypeProvider, opts ... }, nil } -// Add adds new Decl protos to the Env. -// Returns an error for identifier redeclarations. -func (e *Env) Add(decls ...*exprpb.Decl) error { +// AddIdents configures the checker with a list of variable declarations. +// +// If there are overlapping declarations, the method will error. +func (e *Env) AddIdents(declarations ...*decls.VariableDecl) error { errMsgs := make([]errorMsg, 0) - for _, decl := range decls { - switch decl.DeclKind.(type) { - case *exprpb.Decl_Ident: - errMsgs = append(errMsgs, e.addIdent(sanitizeIdent(decl))) - case *exprpb.Decl_Function: - errMsgs = append(errMsgs, e.setFunction(sanitizeFunction(decl))...) - } + for _, d := range declarations { + errMsgs = append(errMsgs, e.addIdent(d)) + } + return formatError(errMsgs) +} + +// AddFunctions configures the checker with a list of function declarations. +// +// If there are overlapping declarations, the method will error. +func (e *Env) AddFunctions(declarations ...*decls.FunctionDecl) error { + errMsgs := make([]errorMsg, 0) + for _, d := range declarations { + errMsgs = append(errMsgs, e.setFunction(d)...) } return formatError(errMsgs) } // LookupIdent returns a Decl proto for typeName as an identifier in the Env. // Returns nil if no such identifier is found in the Env. -func (e *Env) LookupIdent(name string) *exprpb.Decl { +func (e *Env) LookupIdent(name string) *decls.VariableDecl { for _, candidate := range e.container.ResolveCandidateNames(name) { if ident := e.declarations.FindIdent(candidate); ident != nil { return ident @@ -139,8 +140,8 @@ func (e *Env) LookupIdent(name string) *exprpb.Decl { // Next try to import the name as a reference to a message type. If found, // the declaration is added to the outest (global) scope of the // environment, so next time we can access it faster. - if t, found := e.provider.FindType(candidate); found { - decl := decls.NewVar(candidate, t) + if t, found := e.provider.FindStructType(candidate); found { + decl := decls.NewVariable(candidate, t) e.declarations.AddIdent(decl) return decl } @@ -148,11 +149,7 @@ func (e *Env) LookupIdent(name string) *exprpb.Decl { // Next try to import this as an enum value by splitting the name in a type prefix and // the enum inside. if enumValue := e.provider.EnumValue(candidate); enumValue.Type() != types.ErrType { - decl := decls.NewIdent(candidate, - decls.Int, - &exprpb.Constant{ - ConstantKind: &exprpb.Constant_Int64Value{ - Int64Value: int64(enumValue.(types.Int))}}) + decl := decls.NewConstant(candidate, types.IntType, enumValue) e.declarations.AddIdent(decl) return decl } @@ -162,7 +159,7 @@ func (e *Env) LookupIdent(name string) *exprpb.Decl { // LookupFunction returns a Decl proto for typeName as a function in env. // Returns nil if no such function is found in env. -func (e *Env) LookupFunction(name string) *exprpb.Decl { +func (e *Env) LookupFunction(name string) *decls.FunctionDecl { for _, candidate := range e.container.ResolveCandidateNames(name) { if fn := e.declarations.FindFunction(candidate); fn != nil { return fn @@ -171,88 +168,46 @@ func (e *Env) LookupFunction(name string) *exprpb.Decl { return nil } -// addOverload adds overload to function declaration f. -// Returns one or more errorMsg values if the overload overlaps with an existing overload or macro. -func (e *Env) addOverload(f *exprpb.Decl, overload *exprpb.Decl_FunctionDecl_Overload) []errorMsg { - errMsgs := make([]errorMsg, 0) - function := f.GetFunction() - emptyMappings := newMapping() - overloadFunction := decls.NewFunctionType(overload.GetResultType(), - overload.GetParams()...) - overloadErased := substitute(emptyMappings, overloadFunction, true) - for _, existing := range function.GetOverloads() { - existingFunction := decls.NewFunctionType(existing.GetResultType(), existing.GetParams()...) - existingErased := substitute(emptyMappings, existingFunction, true) - overlap := isAssignable(emptyMappings, overloadErased, existingErased) != nil || - isAssignable(emptyMappings, existingErased, overloadErased) != nil - if overlap && - overload.GetIsInstanceFunction() == existing.GetIsInstanceFunction() { - errMsgs = append(errMsgs, - overlappingOverloadError(f.Name, - overload.GetOverloadId(), overloadFunction, - existing.GetOverloadId(), existingFunction)) - } - } - - for _, macro := range parser.AllMacros { - if macro.Function() == f.Name && - macro.IsReceiverStyle() == overload.GetIsInstanceFunction() && - macro.ArgCount() == len(overload.GetParams()) { - errMsgs = append(errMsgs, overlappingMacroError(f.Name, macro.ArgCount())) - } - } - if len(errMsgs) > 0 { - return errMsgs - } - function.Overloads = append(function.GetOverloads(), overload) - return errMsgs -} - // setFunction adds the function Decl to the Env. // Adds a function decl if one doesn't already exist, then adds all overloads from the Decl. // If overload overlaps with an existing overload, adds to the errors in the Env instead. -func (e *Env) setFunction(decl *exprpb.Decl) []errorMsg { - errorMsgs := make([]errorMsg, 0) - overloads := decl.GetFunction().GetOverloads() - current := e.declarations.FindFunction(decl.Name) - if current == nil { - //Add the function declaration without overloads and check the overloads below. - current = decls.NewFunction(decl.Name) - } else { - existingOverloads := map[string]*exprpb.Decl_FunctionDecl_Overload{} - for _, overload := range current.GetFunction().GetOverloads() { - existingOverloads[overload.GetOverloadId()] = overload +func (e *Env) setFunction(fn *decls.FunctionDecl) []errorMsg { + errMsgs := make([]errorMsg, 0) + current := e.declarations.FindFunction(fn.Name()) + if current != nil { + var err error + current, err = current.Merge(fn) + if err != nil { + return append(errMsgs, errorMsg(err.Error())) } - newOverloads := []*exprpb.Decl_FunctionDecl_Overload{} - for _, overload := range overloads { - existing, found := existingOverloads[overload.GetOverloadId()] - if !found || !proto.Equal(existing, overload) { - newOverloads = append(newOverloads, overload) + } else { + current = fn + } + for _, overload := range current.OverloadDecls() { + for _, macro := range parser.AllMacros { + if macro.Function() == current.Name() && + macro.IsReceiverStyle() == overload.IsMemberFunction() && + macro.ArgCount() == len(overload.ArgTypes()) { + errMsgs = append(errMsgs, overlappingMacroError(current.Name(), macro.ArgCount())) } } - overloads = newOverloads - if len(newOverloads) == 0 { - return errorMsgs + if len(errMsgs) > 0 { + return errMsgs } - // Copy on write since we don't know where this original definition came from. - current = proto.Clone(current).(*exprpb.Decl) } e.declarations.SetFunction(current) - for _, overload := range overloads { - errorMsgs = append(errorMsgs, e.addOverload(current, overload)...) - } - return errorMsgs + return errMsgs } // addIdent adds the Decl to the declarations in the Env. // Returns a non-empty errorMsg if the identifier is already declared in the scope. -func (e *Env) addIdent(decl *exprpb.Decl) errorMsg { - current := e.declarations.FindIdentInScope(decl.Name) +func (e *Env) addIdent(decl *decls.VariableDecl) errorMsg { + current := e.declarations.FindIdentInScope(decl.Name()) if current != nil { - if proto.Equal(current, decl) { + if current.DeclarationIsEquivalent(decl) { return "" } - return overlappingIdentifierError(decl.Name) + return overlappingIdentifierError(decl.Name()) } e.declarations.AddIdent(decl) return "" @@ -264,86 +219,9 @@ func (e *Env) isOverloadDisabled(overloadID string) bool { return found } -// sanitizeFunction replaces well-known types referenced by message name with their equivalent -// CEL built-in type instances. -func sanitizeFunction(decl *exprpb.Decl) *exprpb.Decl { - fn := decl.GetFunction() - // Determine whether the declaration requires replacements from proto-based message type - // references to well-known CEL type references. - var needsSanitizing bool - for _, o := range fn.GetOverloads() { - if isObjectWellKnownType(o.GetResultType()) { - needsSanitizing = true - break - } - for _, p := range o.GetParams() { - if isObjectWellKnownType(p) { - needsSanitizing = true - break - } - } - } - - // Early return if the declaration requires no modification. - if !needsSanitizing { - return decl - } - - // Sanitize all of the overloads if any overload requires an update to its type references. - overloads := make([]*exprpb.Decl_FunctionDecl_Overload, len(fn.GetOverloads())) - for i, o := range fn.GetOverloads() { - rt := o.GetResultType() - if isObjectWellKnownType(rt) { - rt = getObjectWellKnownType(rt) - } - params := make([]*exprpb.Type, len(o.GetParams())) - copy(params, o.GetParams()) - for j, p := range params { - if isObjectWellKnownType(p) { - params[j] = getObjectWellKnownType(p) - } - } - // If sanitized, replace the overload definition. - if o.IsInstanceFunction { - overloads[i] = - decls.NewInstanceOverload(o.GetOverloadId(), params, rt) - } else { - overloads[i] = - decls.NewOverload(o.GetOverloadId(), params, rt) - } - } - return decls.NewFunction(decl.GetName(), overloads...) -} - -// sanitizeIdent replaces the identifier's well-known types referenced by message name with -// references to CEL built-in type instances. -func sanitizeIdent(decl *exprpb.Decl) *exprpb.Decl { - id := decl.GetIdent() - t := id.GetType() - if !isObjectWellKnownType(t) { - return decl - } - return decls.NewIdent(decl.GetName(), getObjectWellKnownType(t), id.GetValue()) -} - -// isObjectWellKnownType returns true if the input type is an OBJECT type with a message name -// that corresponds the message name of a built-in CEL type. -func isObjectWellKnownType(t *exprpb.Type) bool { - if kindOf(t) != kindObject { - return false - } - _, found := pb.CheckedWellKnowns[t.GetMessageType()] - return found -} - -// getObjectWellKnownType returns the built-in CEL type declaration for input type's message name. -func getObjectWellKnownType(t *exprpb.Type) *exprpb.Type { - return pb.CheckedWellKnowns[t.GetMessageType()] -} - // validatedDeclarations returns a reference to the validated variable and function declaration scope stack. // must be copied before use. -func (e *Env) validatedDeclarations() *decls.Scopes { +func (e *Env) validatedDeclarations() *Scopes { return e.declarations } @@ -377,19 +255,6 @@ func overlappingIdentifierError(name string) errorMsg { return errorMsg(fmt.Sprintf("overlapping identifier for name '%s'", name)) } -func overlappingOverloadError(name string, - overloadID1 string, f1 *exprpb.Type, - overloadID2 string, f2 *exprpb.Type) errorMsg { - return errorMsg(fmt.Sprintf( - "overlapping overload for name '%s' (type '%s' with overloadId: '%s' "+ - "cannot be distinguished from '%s' with overloadId: '%s')", - name, - FormatCheckedType(f1), - overloadID1, - FormatCheckedType(f2), - overloadID2)) -} - func overlappingMacroError(name string, argCount int) errorMsg { return errorMsg(fmt.Sprintf( "overlapping macro for name '%s' with %d args", name, argCount)) diff --git a/vendor/github.com/google/cel-go/checker/errors.go b/vendor/github.com/google/cel-go/checker/errors.go index 0014f9abe..c2b96498d 100644 --- a/vendor/github.com/google/cel-go/checker/errors.go +++ b/vendor/github.com/google/cel-go/checker/errors.go @@ -15,82 +15,78 @@ package checker import ( + "reflect" + "github.com/google/cel-go/common" + "github.com/google/cel-go/common/ast" + "github.com/google/cel-go/common/types" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) // typeErrors is a specialization of Errors. type typeErrors struct { - *common.Errors + errs *common.Errors +} + +func (e *typeErrors) fieldTypeMismatch(id int64, l common.Location, name string, field, value *types.Type) { + e.errs.ReportErrorAtID(id, l, "expected type of field '%s' is '%s' but provided type is '%s'", + name, FormatCELType(field), FormatCELType(value)) +} + +func (e *typeErrors) incompatibleType(id int64, l common.Location, ex *exprpb.Expr, prev, next *types.Type) { + e.errs.ReportErrorAtID(id, l, + "incompatible type already exists for expression: %v(%d) old:%v, new:%v", ex, ex.GetId(), prev, next) +} + +func (e *typeErrors) noMatchingOverload(id int64, l common.Location, name string, args []*types.Type, isInstance bool) { + signature := formatFunctionDeclType(nil, args, isInstance) + e.errs.ReportErrorAtID(id, l, "found no matching overload for '%s' applied to '%s'", name, signature) } -func (e *typeErrors) undeclaredReference(l common.Location, container string, name string) { - e.ReportError(l, "undeclared reference to '%s' (in container '%s')", name, container) +func (e *typeErrors) notAComprehensionRange(id int64, l common.Location, t *types.Type) { + e.errs.ReportErrorAtID(id, l, "expression of type '%s' cannot be range of a comprehension (must be list, map, or dynamic)", + FormatCELType(t)) } -func (e *typeErrors) typeDoesNotSupportFieldSelection(l common.Location, t *exprpb.Type) { - e.ReportError(l, "type '%s' does not support field selection", t) +func (e *typeErrors) notAnOptionalFieldSelection(id int64, l common.Location, field *exprpb.Expr) { + e.errs.ReportErrorAtID(id, l, "unsupported optional field selection: %v", field) } -func (e *typeErrors) undefinedField(l common.Location, field string) { - e.ReportError(l, "undefined field '%s'", field) +func (e *typeErrors) notAType(id int64, l common.Location, typeName string) { + e.errs.ReportErrorAtID(id, l, "'%s' is not a type", typeName) } -func (e *typeErrors) noMatchingOverload(l common.Location, name string, args []*exprpb.Type, isInstance bool) { - signature := formatFunction(nil, args, isInstance) - e.ReportError(l, "found no matching overload for '%s' applied to '%s'", name, signature) +func (e *typeErrors) notAMessageType(id int64, l common.Location, typeName string) { + e.errs.ReportErrorAtID(id, l, "'%s' is not a message type", typeName) } -func (e *typeErrors) notAType(l common.Location, t *exprpb.Type) { - e.ReportError(l, "'%s(%v)' is not a type", FormatCheckedType(t), t) +func (e *typeErrors) referenceRedefinition(id int64, l common.Location, ex *exprpb.Expr, prev, next *ast.ReferenceInfo) { + e.errs.ReportErrorAtID(id, l, + "reference already exists for expression: %v(%d) old:%v, new:%v", ex, ex.GetId(), prev, next) } -func (e *typeErrors) notAMessageType(l common.Location, t *exprpb.Type) { - e.ReportError(l, "'%s' is not a message type", FormatCheckedType(t)) +func (e *typeErrors) typeDoesNotSupportFieldSelection(id int64, l common.Location, t *types.Type) { + e.errs.ReportErrorAtID(id, l, "type '%s' does not support field selection", FormatCELType(t)) } -func (e *typeErrors) fieldTypeMismatch(l common.Location, name string, field *exprpb.Type, value *exprpb.Type) { - e.ReportError(l, "expected type of field '%s' is '%s' but provided type is '%s'", - name, FormatCheckedType(field), FormatCheckedType(value)) +func (e *typeErrors) typeMismatch(id int64, l common.Location, expected, actual *types.Type) { + e.errs.ReportErrorAtID(id, l, "expected type '%s' but found '%s'", + FormatCELType(expected), FormatCELType(actual)) } -func (e *typeErrors) unexpectedFailedResolution(l common.Location, typeName string) { - e.ReportError(l, "[internal] unexpected failed resolution of '%s'", typeName) +func (e *typeErrors) undefinedField(id int64, l common.Location, field string) { + e.errs.ReportErrorAtID(id, l, "undefined field '%s'", field) } -func (e *typeErrors) notAComprehensionRange(l common.Location, t *exprpb.Type) { - e.ReportError(l, "expression of type '%s' cannot be range of a comprehension (must be list, map, or dynamic)", - FormatCheckedType(t)) +func (e *typeErrors) undeclaredReference(id int64, l common.Location, container string, name string) { + e.errs.ReportErrorAtID(id, l, "undeclared reference to '%s' (in container '%s')", name, container) } -func (e *typeErrors) typeMismatch(l common.Location, expected *exprpb.Type, actual *exprpb.Type) { - e.ReportError(l, "expected type '%s' but found '%s'", - FormatCheckedType(expected), FormatCheckedType(actual)) +func (e *typeErrors) unexpectedFailedResolution(id int64, l common.Location, typeName string) { + e.errs.ReportErrorAtID(id, l, "unexpected failed resolution of '%s'", typeName) } -func formatFunction(resultType *exprpb.Type, argTypes []*exprpb.Type, isInstance bool) string { - result := "" - if isInstance { - target := argTypes[0] - argTypes = argTypes[1:] - - result += FormatCheckedType(target) - result += "." - } - - result += "(" - for i, arg := range argTypes { - if i > 0 { - result += ", " - } - result += FormatCheckedType(arg) - } - result += ")" - if resultType != nil { - result += " -> " - result += FormatCheckedType(resultType) - } - - return result +func (e *typeErrors) unexpectedASTType(id int64, l common.Location, ex *exprpb.Expr) { + e.errs.ReportErrorAtID(id, l, "unrecognized ast type: %v", reflect.TypeOf(ex)) } diff --git a/vendor/github.com/google/cel-go/checker/format.go b/vendor/github.com/google/cel-go/checker/format.go new file mode 100644 index 000000000..95842905e --- /dev/null +++ b/vendor/github.com/google/cel-go/checker/format.go @@ -0,0 +1,216 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package checker + +import ( + "fmt" + "strings" + + chkdecls "github.com/google/cel-go/checker/decls" + "github.com/google/cel-go/common/types" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +const ( + kindUnknown = iota + 1 + kindError + kindFunction + kindDyn + kindPrimitive + kindWellKnown + kindWrapper + kindNull + kindAbstract + kindType + kindList + kindMap + kindObject + kindTypeParam +) + +// FormatCheckedType converts a type message into a string representation. +func FormatCheckedType(t *exprpb.Type) string { + switch kindOf(t) { + case kindDyn: + return "dyn" + case kindFunction: + return formatFunctionExprType(t.GetFunction().GetResultType(), + t.GetFunction().GetArgTypes(), + false) + case kindList: + return fmt.Sprintf("list(%s)", FormatCheckedType(t.GetListType().GetElemType())) + case kindObject: + return t.GetMessageType() + case kindMap: + return fmt.Sprintf("map(%s, %s)", + FormatCheckedType(t.GetMapType().GetKeyType()), + FormatCheckedType(t.GetMapType().GetValueType())) + case kindNull: + return "null" + case kindPrimitive: + switch t.GetPrimitive() { + case exprpb.Type_UINT64: + return "uint" + case exprpb.Type_INT64: + return "int" + } + return strings.Trim(strings.ToLower(t.GetPrimitive().String()), " ") + case kindType: + if t.GetType() == nil || t.GetType().GetTypeKind() == nil { + return "type" + } + return fmt.Sprintf("type(%s)", FormatCheckedType(t.GetType())) + case kindWellKnown: + switch t.GetWellKnown() { + case exprpb.Type_ANY: + return "any" + case exprpb.Type_DURATION: + return "duration" + case exprpb.Type_TIMESTAMP: + return "timestamp" + } + case kindWrapper: + return fmt.Sprintf("wrapper(%s)", + FormatCheckedType(chkdecls.NewPrimitiveType(t.GetWrapper()))) + case kindError: + return "!error!" + case kindTypeParam: + return t.GetTypeParam() + case kindAbstract: + at := t.GetAbstractType() + params := at.GetParameterTypes() + paramStrs := make([]string, len(params)) + for i, p := range params { + paramStrs[i] = FormatCheckedType(p) + } + return fmt.Sprintf("%s(%s)", at.GetName(), strings.Join(paramStrs, ", ")) + } + return t.String() +} + +type formatter func(any) string + +// FormatCELType formats a types.Type value to a string representation. +// +// The type formatting is identical to FormatCheckedType. +func FormatCELType(t any) string { + dt := t.(*types.Type) + switch dt.Kind() { + case types.AnyKind: + return "any" + case types.DurationKind: + return "duration" + case types.ErrorKind: + return "!error!" + case types.NullTypeKind: + return "null" + case types.TimestampKind: + return "timestamp" + case types.TypeParamKind: + return dt.TypeName() + case types.OpaqueKind: + if dt.TypeName() == "function" { + // There is no explicit function type in the new types representation, so information like + // whether the function is a member function is absent. + return formatFunctionDeclType(dt.Parameters()[0], dt.Parameters()[1:], false) + } + case types.UnspecifiedKind: + return "" + } + if len(dt.Parameters()) == 0 { + return dt.DeclaredTypeName() + } + paramTypeNames := make([]string, 0, len(dt.Parameters())) + for _, p := range dt.Parameters() { + paramTypeNames = append(paramTypeNames, FormatCELType(p)) + } + return fmt.Sprintf("%s(%s)", dt.TypeName(), strings.Join(paramTypeNames, ", ")) +} + +func formatExprType(t any) string { + if t == nil { + return "" + } + return FormatCheckedType(t.(*exprpb.Type)) +} + +func formatFunctionExprType(resultType *exprpb.Type, argTypes []*exprpb.Type, isInstance bool) string { + return formatFunctionInternal[*exprpb.Type](resultType, argTypes, isInstance, formatExprType) +} + +func formatFunctionDeclType(resultType *types.Type, argTypes []*types.Type, isInstance bool) string { + return formatFunctionInternal[*types.Type](resultType, argTypes, isInstance, FormatCELType) +} + +func formatFunctionInternal[T any](resultType T, argTypes []T, isInstance bool, format formatter) string { + result := "" + if isInstance { + target := argTypes[0] + argTypes = argTypes[1:] + result += format(target) + result += "." + } + result += "(" + for i, arg := range argTypes { + if i > 0 { + result += ", " + } + result += format(arg) + } + result += ")" + rt := format(resultType) + if rt != "" { + result += " -> " + result += rt + } + return result +} + +// kindOf returns the kind of the type as defined in the checked.proto. +func kindOf(t *exprpb.Type) int { + if t == nil || t.TypeKind == nil { + return kindUnknown + } + switch t.GetTypeKind().(type) { + case *exprpb.Type_Error: + return kindError + case *exprpb.Type_Function: + return kindFunction + case *exprpb.Type_Dyn: + return kindDyn + case *exprpb.Type_Primitive: + return kindPrimitive + case *exprpb.Type_WellKnown: + return kindWellKnown + case *exprpb.Type_Wrapper: + return kindWrapper + case *exprpb.Type_Null: + return kindNull + case *exprpb.Type_Type: + return kindType + case *exprpb.Type_ListType_: + return kindList + case *exprpb.Type_MapType_: + return kindMap + case *exprpb.Type_MessageType: + return kindObject + case *exprpb.Type_TypeParam: + return kindTypeParam + case *exprpb.Type_AbstractType_: + return kindAbstract + } + return kindUnknown +} diff --git a/vendor/github.com/google/cel-go/checker/mapping.go b/vendor/github.com/google/cel-go/checker/mapping.go index fbc55a28d..8163a908a 100644 --- a/vendor/github.com/google/cel-go/checker/mapping.go +++ b/vendor/github.com/google/cel-go/checker/mapping.go @@ -15,25 +15,25 @@ package checker import ( - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + "github.com/google/cel-go/common/types" ) type mapping struct { - mapping map[string]*exprpb.Type + mapping map[string]*types.Type } func newMapping() *mapping { return &mapping{ - mapping: make(map[string]*exprpb.Type), + mapping: make(map[string]*types.Type), } } -func (m *mapping) add(from *exprpb.Type, to *exprpb.Type) { - m.mapping[typeKey(from)] = to +func (m *mapping) add(from, to *types.Type) { + m.mapping[FormatCELType(from)] = to } -func (m *mapping) find(from *exprpb.Type) (*exprpb.Type, bool) { - if r, found := m.mapping[typeKey(from)]; found { +func (m *mapping) find(from *types.Type) (*types.Type, bool) { + if r, found := m.mapping[FormatCELType(from)]; found { return r, found } return nil, false diff --git a/vendor/github.com/google/cel-go/checker/options.go b/vendor/github.com/google/cel-go/checker/options.go index cded00a66..0560c3813 100644 --- a/vendor/github.com/google/cel-go/checker/options.go +++ b/vendor/github.com/google/cel-go/checker/options.go @@ -14,12 +14,10 @@ package checker -import "github.com/google/cel-go/checker/decls" - type options struct { crossTypeNumericComparisons bool homogeneousAggregateLiterals bool - validatedDeclarations *decls.Scopes + validatedDeclarations *Scopes } // Option is a functional option for configuring the type-checker @@ -34,15 +32,6 @@ func CrossTypeNumericComparisons(enabled bool) Option { } } -// HomogeneousAggregateLiterals toggles support for constructing lists and maps whose elements all -// have the same type. -func HomogeneousAggregateLiterals(enabled bool) Option { - return func(opts *options) error { - opts.homogeneousAggregateLiterals = enabled - return nil - } -} - // ValidatedDeclarations provides a references to validated declarations which will be copied // into new checker instances. func ValidatedDeclarations(env *Env) Option { diff --git a/vendor/github.com/google/cel-go/checker/printer.go b/vendor/github.com/google/cel-go/checker/printer.go index 0cecc5210..15cba06ee 100644 --- a/vendor/github.com/google/cel-go/checker/printer.go +++ b/vendor/github.com/google/cel-go/checker/printer.go @@ -15,6 +15,8 @@ package checker import ( + "sort" + "github.com/google/cel-go/common/debug" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" @@ -47,6 +49,7 @@ func (a *semanticAdorner) GetMetadata(elem any) string { if len(ref.GetOverloadId()) == 0 { result += "^" + ref.Name } else { + sort.Strings(ref.GetOverloadId()) for i, overload := range ref.GetOverloadId() { if i == 0 { result += "^" diff --git a/vendor/github.com/google/cel-go/checker/decls/scopes.go b/vendor/github.com/google/cel-go/checker/scopes.go similarity index 81% rename from vendor/github.com/google/cel-go/checker/decls/scopes.go rename to vendor/github.com/google/cel-go/checker/scopes.go index 608bca3e5..8bb73ddb6 100644 --- a/vendor/github.com/google/cel-go/checker/decls/scopes.go +++ b/vendor/github.com/google/cel-go/checker/scopes.go @@ -12,9 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -package decls +package checker -import exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +import ( + "github.com/google/cel-go/common/decls" +) // Scopes represents nested Decl sets where the Scopes value contains a Groups containing all // identifiers in scope and an optional parent representing outer scopes. @@ -25,9 +27,9 @@ type Scopes struct { scopes *Group } -// NewScopes creates a new, empty Scopes. +// newScopes creates a new, empty Scopes. // Some operations can't be safely performed until a Group is added with Push. -func NewScopes() *Scopes { +func newScopes() *Scopes { return &Scopes{ scopes: newGroup(), } @@ -35,7 +37,7 @@ func NewScopes() *Scopes { // Copy creates a copy of the current Scopes values, including a copy of its parent if non-nil. func (s *Scopes) Copy() *Scopes { - cpy := NewScopes() + cpy := newScopes() if s == nil { return cpy } @@ -66,14 +68,14 @@ func (s *Scopes) Pop() *Scopes { // AddIdent adds the ident Decl in the current scope. // Note: If the name collides with an existing identifier in the scope, the Decl is overwritten. -func (s *Scopes) AddIdent(decl *exprpb.Decl) { - s.scopes.idents[decl.Name] = decl +func (s *Scopes) AddIdent(decl *decls.VariableDecl) { + s.scopes.idents[decl.Name()] = decl } // FindIdent finds the first ident Decl with a matching name in Scopes, or nil if one cannot be // found. // Note: The search is performed from innermost to outermost. -func (s *Scopes) FindIdent(name string) *exprpb.Decl { +func (s *Scopes) FindIdent(name string) *decls.VariableDecl { if ident, found := s.scopes.idents[name]; found { return ident } @@ -86,7 +88,7 @@ func (s *Scopes) FindIdent(name string) *exprpb.Decl { // FindIdentInScope finds the first ident Decl with a matching name in the current Scopes value, or // nil if one does not exist. // Note: The search is only performed on the current scope and does not search outer scopes. -func (s *Scopes) FindIdentInScope(name string) *exprpb.Decl { +func (s *Scopes) FindIdentInScope(name string) *decls.VariableDecl { if ident, found := s.scopes.idents[name]; found { return ident } @@ -95,14 +97,14 @@ func (s *Scopes) FindIdentInScope(name string) *exprpb.Decl { // SetFunction adds the function Decl to the current scope. // Note: Any previous entry for a function in the current scope with the same name is overwritten. -func (s *Scopes) SetFunction(fn *exprpb.Decl) { - s.scopes.functions[fn.Name] = fn +func (s *Scopes) SetFunction(fn *decls.FunctionDecl) { + s.scopes.functions[fn.Name()] = fn } // FindFunction finds the first function Decl with a matching name in Scopes. // The search is performed from innermost to outermost. // Returns nil if no such function in Scopes. -func (s *Scopes) FindFunction(name string) *exprpb.Decl { +func (s *Scopes) FindFunction(name string) *decls.FunctionDecl { if fn, found := s.scopes.functions[name]; found { return fn } @@ -116,16 +118,16 @@ func (s *Scopes) FindFunction(name string) *exprpb.Decl { // Contains separate namespaces for identifier and function Decls. // (Should be named "Scope" perhaps?) type Group struct { - idents map[string]*exprpb.Decl - functions map[string]*exprpb.Decl + idents map[string]*decls.VariableDecl + functions map[string]*decls.FunctionDecl } // copy creates a new Group instance with a shallow copy of the variables and functions. // If callers need to mutate the exprpb.Decl definitions for a Function, they should copy-on-write. func (g *Group) copy() *Group { cpy := &Group{ - idents: make(map[string]*exprpb.Decl, len(g.idents)), - functions: make(map[string]*exprpb.Decl, len(g.functions)), + idents: make(map[string]*decls.VariableDecl, len(g.idents)), + functions: make(map[string]*decls.FunctionDecl, len(g.functions)), } for n, id := range g.idents { cpy.idents[n] = id @@ -139,7 +141,7 @@ func (g *Group) copy() *Group { // newGroup creates a new Group with empty maps for identifiers and functions. func newGroup() *Group { return &Group{ - idents: make(map[string]*exprpb.Decl), - functions: make(map[string]*exprpb.Decl), + idents: make(map[string]*decls.VariableDecl), + functions: make(map[string]*decls.FunctionDecl), } } diff --git a/vendor/github.com/google/cel-go/checker/standard.go b/vendor/github.com/google/cel-go/checker/standard.go index e64337ba4..11b35b80e 100644 --- a/vendor/github.com/google/cel-go/checker/standard.go +++ b/vendor/github.com/google/cel-go/checker/standard.go @@ -15,480 +15,21 @@ package checker import ( - "github.com/google/cel-go/checker/decls" - "github.com/google/cel-go/common/operators" - "github.com/google/cel-go/common/overloads" + "github.com/google/cel-go/common/stdlib" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) -var ( - standardDeclarations []*exprpb.Decl -) - -func init() { - // Some shortcuts we use when building declarations. - paramA := decls.NewTypeParamType("A") - typeParamAList := []string{"A"} - listOfA := decls.NewListType(paramA) - paramB := decls.NewTypeParamType("B") - typeParamABList := []string{"A", "B"} - mapOfAB := decls.NewMapType(paramA, paramB) - - var idents []*exprpb.Decl - for _, t := range []*exprpb.Type{ - decls.Int, decls.Uint, decls.Bool, - decls.Double, decls.Bytes, decls.String} { - idents = append(idents, - decls.NewVar(FormatCheckedType(t), decls.NewTypeType(t))) - } - idents = append(idents, - decls.NewVar("list", decls.NewTypeType(listOfA)), - decls.NewVar("map", decls.NewTypeType(mapOfAB)), - decls.NewVar("null_type", decls.NewTypeType(decls.Null)), - decls.NewVar("type", decls.NewTypeType(decls.NewTypeType(nil)))) - - standardDeclarations = append(standardDeclarations, idents...) - standardDeclarations = append(standardDeclarations, []*exprpb.Decl{ - // Booleans - decls.NewFunction(operators.Conditional, - decls.NewParameterizedOverload(overloads.Conditional, - []*exprpb.Type{decls.Bool, paramA, paramA}, paramA, - typeParamAList)), - - decls.NewFunction(operators.LogicalAnd, - decls.NewOverload(overloads.LogicalAnd, - []*exprpb.Type{decls.Bool, decls.Bool}, decls.Bool)), - - decls.NewFunction(operators.LogicalOr, - decls.NewOverload(overloads.LogicalOr, - []*exprpb.Type{decls.Bool, decls.Bool}, decls.Bool)), - - decls.NewFunction(operators.LogicalNot, - decls.NewOverload(overloads.LogicalNot, - []*exprpb.Type{decls.Bool}, decls.Bool)), - - decls.NewFunction(operators.NotStrictlyFalse, - decls.NewOverload(overloads.NotStrictlyFalse, - []*exprpb.Type{decls.Bool}, decls.Bool)), - - decls.NewFunction(operators.Equals, - decls.NewParameterizedOverload(overloads.Equals, - []*exprpb.Type{paramA, paramA}, decls.Bool, - typeParamAList)), - - decls.NewFunction(operators.NotEquals, - decls.NewParameterizedOverload(overloads.NotEquals, - []*exprpb.Type{paramA, paramA}, decls.Bool, - typeParamAList)), - - // Algebra. - - decls.NewFunction(operators.Subtract, - decls.NewOverload(overloads.SubtractInt64, - []*exprpb.Type{decls.Int, decls.Int}, decls.Int), - decls.NewOverload(overloads.SubtractUint64, - []*exprpb.Type{decls.Uint, decls.Uint}, decls.Uint), - decls.NewOverload(overloads.SubtractDouble, - []*exprpb.Type{decls.Double, decls.Double}, decls.Double), - decls.NewOverload(overloads.SubtractTimestampTimestamp, - []*exprpb.Type{decls.Timestamp, decls.Timestamp}, decls.Duration), - decls.NewOverload(overloads.SubtractTimestampDuration, - []*exprpb.Type{decls.Timestamp, decls.Duration}, decls.Timestamp), - decls.NewOverload(overloads.SubtractDurationDuration, - []*exprpb.Type{decls.Duration, decls.Duration}, decls.Duration)), - - decls.NewFunction(operators.Multiply, - decls.NewOverload(overloads.MultiplyInt64, - []*exprpb.Type{decls.Int, decls.Int}, decls.Int), - decls.NewOverload(overloads.MultiplyUint64, - []*exprpb.Type{decls.Uint, decls.Uint}, decls.Uint), - decls.NewOverload(overloads.MultiplyDouble, - []*exprpb.Type{decls.Double, decls.Double}, decls.Double)), - - decls.NewFunction(operators.Divide, - decls.NewOverload(overloads.DivideInt64, - []*exprpb.Type{decls.Int, decls.Int}, decls.Int), - decls.NewOverload(overloads.DivideUint64, - []*exprpb.Type{decls.Uint, decls.Uint}, decls.Uint), - decls.NewOverload(overloads.DivideDouble, - []*exprpb.Type{decls.Double, decls.Double}, decls.Double)), - - decls.NewFunction(operators.Modulo, - decls.NewOverload(overloads.ModuloInt64, - []*exprpb.Type{decls.Int, decls.Int}, decls.Int), - decls.NewOverload(overloads.ModuloUint64, - []*exprpb.Type{decls.Uint, decls.Uint}, decls.Uint)), - - decls.NewFunction(operators.Add, - decls.NewOverload(overloads.AddInt64, - []*exprpb.Type{decls.Int, decls.Int}, decls.Int), - decls.NewOverload(overloads.AddUint64, - []*exprpb.Type{decls.Uint, decls.Uint}, decls.Uint), - decls.NewOverload(overloads.AddDouble, - []*exprpb.Type{decls.Double, decls.Double}, decls.Double), - decls.NewOverload(overloads.AddString, - []*exprpb.Type{decls.String, decls.String}, decls.String), - decls.NewOverload(overloads.AddBytes, - []*exprpb.Type{decls.Bytes, decls.Bytes}, decls.Bytes), - decls.NewParameterizedOverload(overloads.AddList, - []*exprpb.Type{listOfA, listOfA}, listOfA, - typeParamAList), - decls.NewOverload(overloads.AddTimestampDuration, - []*exprpb.Type{decls.Timestamp, decls.Duration}, decls.Timestamp), - decls.NewOverload(overloads.AddDurationTimestamp, - []*exprpb.Type{decls.Duration, decls.Timestamp}, decls.Timestamp), - decls.NewOverload(overloads.AddDurationDuration, - []*exprpb.Type{decls.Duration, decls.Duration}, decls.Duration)), - - decls.NewFunction(operators.Negate, - decls.NewOverload(overloads.NegateInt64, - []*exprpb.Type{decls.Int}, decls.Int), - decls.NewOverload(overloads.NegateDouble, - []*exprpb.Type{decls.Double}, decls.Double)), - - // Index. - - decls.NewFunction(operators.Index, - decls.NewParameterizedOverload(overloads.IndexList, - []*exprpb.Type{listOfA, decls.Int}, paramA, - typeParamAList), - decls.NewParameterizedOverload(overloads.IndexMap, - []*exprpb.Type{mapOfAB, paramA}, paramB, - typeParamABList)), - - // Collections. - - decls.NewFunction(overloads.Size, - decls.NewInstanceOverload(overloads.SizeStringInst, - []*exprpb.Type{decls.String}, decls.Int), - decls.NewInstanceOverload(overloads.SizeBytesInst, - []*exprpb.Type{decls.Bytes}, decls.Int), - decls.NewParameterizedInstanceOverload(overloads.SizeListInst, - []*exprpb.Type{listOfA}, decls.Int, typeParamAList), - decls.NewParameterizedInstanceOverload(overloads.SizeMapInst, - []*exprpb.Type{mapOfAB}, decls.Int, typeParamABList), - decls.NewOverload(overloads.SizeString, - []*exprpb.Type{decls.String}, decls.Int), - decls.NewOverload(overloads.SizeBytes, - []*exprpb.Type{decls.Bytes}, decls.Int), - decls.NewParameterizedOverload(overloads.SizeList, - []*exprpb.Type{listOfA}, decls.Int, typeParamAList), - decls.NewParameterizedOverload(overloads.SizeMap, - []*exprpb.Type{mapOfAB}, decls.Int, typeParamABList)), - - decls.NewFunction(operators.In, - decls.NewParameterizedOverload(overloads.InList, - []*exprpb.Type{paramA, listOfA}, decls.Bool, - typeParamAList), - decls.NewParameterizedOverload(overloads.InMap, - []*exprpb.Type{paramA, mapOfAB}, decls.Bool, - typeParamABList)), - - // Deprecated 'in()' function. - - decls.NewFunction(overloads.DeprecatedIn, - decls.NewParameterizedOverload(overloads.InList, - []*exprpb.Type{paramA, listOfA}, decls.Bool, - typeParamAList), - decls.NewParameterizedOverload(overloads.InMap, - []*exprpb.Type{paramA, mapOfAB}, decls.Bool, - typeParamABList)), - - // Conversions to type. - - decls.NewFunction(overloads.TypeConvertType, - decls.NewParameterizedOverload(overloads.TypeConvertType, - []*exprpb.Type{paramA}, decls.NewTypeType(paramA), typeParamAList)), - - // Conversions to int. - - decls.NewFunction(overloads.TypeConvertInt, - decls.NewOverload(overloads.IntToInt, []*exprpb.Type{decls.Int}, decls.Int), - decls.NewOverload(overloads.UintToInt, []*exprpb.Type{decls.Uint}, decls.Int), - decls.NewOverload(overloads.DoubleToInt, []*exprpb.Type{decls.Double}, decls.Int), - decls.NewOverload(overloads.StringToInt, []*exprpb.Type{decls.String}, decls.Int), - decls.NewOverload(overloads.TimestampToInt, []*exprpb.Type{decls.Timestamp}, decls.Int), - decls.NewOverload(overloads.DurationToInt, []*exprpb.Type{decls.Duration}, decls.Int)), - - // Conversions to uint. - - decls.NewFunction(overloads.TypeConvertUint, - decls.NewOverload(overloads.UintToUint, []*exprpb.Type{decls.Uint}, decls.Uint), - decls.NewOverload(overloads.IntToUint, []*exprpb.Type{decls.Int}, decls.Uint), - decls.NewOverload(overloads.DoubleToUint, []*exprpb.Type{decls.Double}, decls.Uint), - decls.NewOverload(overloads.StringToUint, []*exprpb.Type{decls.String}, decls.Uint)), - - // Conversions to double. - - decls.NewFunction(overloads.TypeConvertDouble, - decls.NewOverload(overloads.DoubleToDouble, []*exprpb.Type{decls.Double}, decls.Double), - decls.NewOverload(overloads.IntToDouble, []*exprpb.Type{decls.Int}, decls.Double), - decls.NewOverload(overloads.UintToDouble, []*exprpb.Type{decls.Uint}, decls.Double), - decls.NewOverload(overloads.StringToDouble, []*exprpb.Type{decls.String}, decls.Double)), - - // Conversions to bool. - - decls.NewFunction(overloads.TypeConvertBool, - decls.NewOverload(overloads.BoolToBool, []*exprpb.Type{decls.Bool}, decls.Bool), - decls.NewOverload(overloads.StringToBool, []*exprpb.Type{decls.String}, decls.Bool)), - - // Conversions to string. - - decls.NewFunction(overloads.TypeConvertString, - decls.NewOverload(overloads.StringToString, []*exprpb.Type{decls.String}, decls.String), - decls.NewOverload(overloads.BoolToString, []*exprpb.Type{decls.Bool}, decls.String), - decls.NewOverload(overloads.IntToString, []*exprpb.Type{decls.Int}, decls.String), - decls.NewOverload(overloads.UintToString, []*exprpb.Type{decls.Uint}, decls.String), - decls.NewOverload(overloads.DoubleToString, []*exprpb.Type{decls.Double}, decls.String), - decls.NewOverload(overloads.BytesToString, []*exprpb.Type{decls.Bytes}, decls.String), - decls.NewOverload(overloads.TimestampToString, []*exprpb.Type{decls.Timestamp}, decls.String), - decls.NewOverload(overloads.DurationToString, []*exprpb.Type{decls.Duration}, decls.String)), - - // Conversions to bytes. - - decls.NewFunction(overloads.TypeConvertBytes, - decls.NewOverload(overloads.BytesToBytes, []*exprpb.Type{decls.Bytes}, decls.Bytes), - decls.NewOverload(overloads.StringToBytes, []*exprpb.Type{decls.String}, decls.Bytes)), - - // Conversions to timestamps. - - decls.NewFunction(overloads.TypeConvertTimestamp, - decls.NewOverload(overloads.TimestampToTimestamp, - []*exprpb.Type{decls.Timestamp}, decls.Timestamp), - decls.NewOverload(overloads.StringToTimestamp, - []*exprpb.Type{decls.String}, decls.Timestamp), - decls.NewOverload(overloads.IntToTimestamp, - []*exprpb.Type{decls.Int}, decls.Timestamp)), - - // Conversions to durations. - - decls.NewFunction(overloads.TypeConvertDuration, - decls.NewOverload(overloads.DurationToDuration, - []*exprpb.Type{decls.Duration}, decls.Duration), - decls.NewOverload(overloads.StringToDuration, - []*exprpb.Type{decls.String}, decls.Duration), - decls.NewOverload(overloads.IntToDuration, - []*exprpb.Type{decls.Int}, decls.Duration)), - - // Conversions to Dyn. - - decls.NewFunction(overloads.TypeConvertDyn, - decls.NewParameterizedOverload(overloads.ToDyn, - []*exprpb.Type{paramA}, decls.Dyn, - typeParamAList)), - - // String functions. - - decls.NewFunction(overloads.Contains, - decls.NewInstanceOverload(overloads.ContainsString, - []*exprpb.Type{decls.String, decls.String}, decls.Bool)), - decls.NewFunction(overloads.EndsWith, - decls.NewInstanceOverload(overloads.EndsWithString, - []*exprpb.Type{decls.String, decls.String}, decls.Bool)), - decls.NewFunction(overloads.Matches, - decls.NewOverload(overloads.Matches, - []*exprpb.Type{decls.String, decls.String}, decls.Bool), - decls.NewInstanceOverload(overloads.MatchesString, - []*exprpb.Type{decls.String, decls.String}, decls.Bool)), - decls.NewFunction(overloads.StartsWith, - decls.NewInstanceOverload(overloads.StartsWithString, - []*exprpb.Type{decls.String, decls.String}, decls.Bool)), - - // Date/time functions. - - decls.NewFunction(overloads.TimeGetFullYear, - decls.NewInstanceOverload(overloads.TimestampToYear, - []*exprpb.Type{decls.Timestamp}, decls.Int), - decls.NewInstanceOverload(overloads.TimestampToYearWithTz, - []*exprpb.Type{decls.Timestamp, decls.String}, decls.Int)), - - decls.NewFunction(overloads.TimeGetMonth, - decls.NewInstanceOverload(overloads.TimestampToMonth, - []*exprpb.Type{decls.Timestamp}, decls.Int), - decls.NewInstanceOverload(overloads.TimestampToMonthWithTz, - []*exprpb.Type{decls.Timestamp, decls.String}, decls.Int)), - - decls.NewFunction(overloads.TimeGetDayOfYear, - decls.NewInstanceOverload(overloads.TimestampToDayOfYear, - []*exprpb.Type{decls.Timestamp}, decls.Int), - decls.NewInstanceOverload(overloads.TimestampToDayOfYearWithTz, - []*exprpb.Type{decls.Timestamp, decls.String}, decls.Int)), - - decls.NewFunction(overloads.TimeGetDayOfMonth, - decls.NewInstanceOverload(overloads.TimestampToDayOfMonthZeroBased, - []*exprpb.Type{decls.Timestamp}, decls.Int), - decls.NewInstanceOverload(overloads.TimestampToDayOfMonthZeroBasedWithTz, - []*exprpb.Type{decls.Timestamp, decls.String}, decls.Int)), - - decls.NewFunction(overloads.TimeGetDate, - decls.NewInstanceOverload(overloads.TimestampToDayOfMonthOneBased, - []*exprpb.Type{decls.Timestamp}, decls.Int), - decls.NewInstanceOverload(overloads.TimestampToDayOfMonthOneBasedWithTz, - []*exprpb.Type{decls.Timestamp, decls.String}, decls.Int)), - - decls.NewFunction(overloads.TimeGetDayOfWeek, - decls.NewInstanceOverload(overloads.TimestampToDayOfWeek, - []*exprpb.Type{decls.Timestamp}, decls.Int), - decls.NewInstanceOverload(overloads.TimestampToDayOfWeekWithTz, - []*exprpb.Type{decls.Timestamp, decls.String}, decls.Int)), - - decls.NewFunction(overloads.TimeGetHours, - decls.NewInstanceOverload(overloads.TimestampToHours, - []*exprpb.Type{decls.Timestamp}, decls.Int), - decls.NewInstanceOverload(overloads.TimestampToHoursWithTz, - []*exprpb.Type{decls.Timestamp, decls.String}, decls.Int), - decls.NewInstanceOverload(overloads.DurationToHours, - []*exprpb.Type{decls.Duration}, decls.Int)), - - decls.NewFunction(overloads.TimeGetMinutes, - decls.NewInstanceOverload(overloads.TimestampToMinutes, - []*exprpb.Type{decls.Timestamp}, decls.Int), - decls.NewInstanceOverload(overloads.TimestampToMinutesWithTz, - []*exprpb.Type{decls.Timestamp, decls.String}, decls.Int), - decls.NewInstanceOverload(overloads.DurationToMinutes, - []*exprpb.Type{decls.Duration}, decls.Int)), - - decls.NewFunction(overloads.TimeGetSeconds, - decls.NewInstanceOverload(overloads.TimestampToSeconds, - []*exprpb.Type{decls.Timestamp}, decls.Int), - decls.NewInstanceOverload(overloads.TimestampToSecondsWithTz, - []*exprpb.Type{decls.Timestamp, decls.String}, decls.Int), - decls.NewInstanceOverload(overloads.DurationToSeconds, - []*exprpb.Type{decls.Duration}, decls.Int)), - - decls.NewFunction(overloads.TimeGetMilliseconds, - decls.NewInstanceOverload(overloads.TimestampToMilliseconds, - []*exprpb.Type{decls.Timestamp}, decls.Int), - decls.NewInstanceOverload(overloads.TimestampToMillisecondsWithTz, - []*exprpb.Type{decls.Timestamp, decls.String}, decls.Int), - decls.NewInstanceOverload(overloads.DurationToMilliseconds, - []*exprpb.Type{decls.Duration}, decls.Int)), - - // Relations. - decls.NewFunction(operators.Less, - decls.NewOverload(overloads.LessBool, - []*exprpb.Type{decls.Bool, decls.Bool}, decls.Bool), - decls.NewOverload(overloads.LessInt64, - []*exprpb.Type{decls.Int, decls.Int}, decls.Bool), - decls.NewOverload(overloads.LessInt64Double, - []*exprpb.Type{decls.Int, decls.Double}, decls.Bool), - decls.NewOverload(overloads.LessInt64Uint64, - []*exprpb.Type{decls.Int, decls.Uint}, decls.Bool), - decls.NewOverload(overloads.LessUint64, - []*exprpb.Type{decls.Uint, decls.Uint}, decls.Bool), - decls.NewOverload(overloads.LessUint64Double, - []*exprpb.Type{decls.Uint, decls.Double}, decls.Bool), - decls.NewOverload(overloads.LessUint64Int64, - []*exprpb.Type{decls.Uint, decls.Int}, decls.Bool), - decls.NewOverload(overloads.LessDouble, - []*exprpb.Type{decls.Double, decls.Double}, decls.Bool), - decls.NewOverload(overloads.LessDoubleInt64, - []*exprpb.Type{decls.Double, decls.Int}, decls.Bool), - decls.NewOverload(overloads.LessDoubleUint64, - []*exprpb.Type{decls.Double, decls.Uint}, decls.Bool), - decls.NewOverload(overloads.LessString, - []*exprpb.Type{decls.String, decls.String}, decls.Bool), - decls.NewOverload(overloads.LessBytes, - []*exprpb.Type{decls.Bytes, decls.Bytes}, decls.Bool), - decls.NewOverload(overloads.LessTimestamp, - []*exprpb.Type{decls.Timestamp, decls.Timestamp}, decls.Bool), - decls.NewOverload(overloads.LessDuration, - []*exprpb.Type{decls.Duration, decls.Duration}, decls.Bool)), - - decls.NewFunction(operators.LessEquals, - decls.NewOverload(overloads.LessEqualsBool, - []*exprpb.Type{decls.Bool, decls.Bool}, decls.Bool), - decls.NewOverload(overloads.LessEqualsInt64, - []*exprpb.Type{decls.Int, decls.Int}, decls.Bool), - decls.NewOverload(overloads.LessEqualsInt64Double, - []*exprpb.Type{decls.Int, decls.Double}, decls.Bool), - decls.NewOverload(overloads.LessEqualsInt64Uint64, - []*exprpb.Type{decls.Int, decls.Uint}, decls.Bool), - decls.NewOverload(overloads.LessEqualsUint64, - []*exprpb.Type{decls.Uint, decls.Uint}, decls.Bool), - decls.NewOverload(overloads.LessEqualsUint64Double, - []*exprpb.Type{decls.Uint, decls.Double}, decls.Bool), - decls.NewOverload(overloads.LessEqualsUint64Int64, - []*exprpb.Type{decls.Uint, decls.Int}, decls.Bool), - decls.NewOverload(overloads.LessEqualsDouble, - []*exprpb.Type{decls.Double, decls.Double}, decls.Bool), - decls.NewOverload(overloads.LessEqualsDoubleInt64, - []*exprpb.Type{decls.Double, decls.Int}, decls.Bool), - decls.NewOverload(overloads.LessEqualsDoubleUint64, - []*exprpb.Type{decls.Double, decls.Uint}, decls.Bool), - decls.NewOverload(overloads.LessEqualsString, - []*exprpb.Type{decls.String, decls.String}, decls.Bool), - decls.NewOverload(overloads.LessEqualsBytes, - []*exprpb.Type{decls.Bytes, decls.Bytes}, decls.Bool), - decls.NewOverload(overloads.LessEqualsTimestamp, - []*exprpb.Type{decls.Timestamp, decls.Timestamp}, decls.Bool), - decls.NewOverload(overloads.LessEqualsDuration, - []*exprpb.Type{decls.Duration, decls.Duration}, decls.Bool)), - - decls.NewFunction(operators.Greater, - decls.NewOverload(overloads.GreaterBool, - []*exprpb.Type{decls.Bool, decls.Bool}, decls.Bool), - decls.NewOverload(overloads.GreaterInt64, - []*exprpb.Type{decls.Int, decls.Int}, decls.Bool), - decls.NewOverload(overloads.GreaterInt64Double, - []*exprpb.Type{decls.Int, decls.Double}, decls.Bool), - decls.NewOverload(overloads.GreaterInt64Uint64, - []*exprpb.Type{decls.Int, decls.Uint}, decls.Bool), - decls.NewOverload(overloads.GreaterUint64, - []*exprpb.Type{decls.Uint, decls.Uint}, decls.Bool), - decls.NewOverload(overloads.GreaterUint64Double, - []*exprpb.Type{decls.Uint, decls.Double}, decls.Bool), - decls.NewOverload(overloads.GreaterUint64Int64, - []*exprpb.Type{decls.Uint, decls.Int}, decls.Bool), - decls.NewOverload(overloads.GreaterDouble, - []*exprpb.Type{decls.Double, decls.Double}, decls.Bool), - decls.NewOverload(overloads.GreaterDoubleInt64, - []*exprpb.Type{decls.Double, decls.Int}, decls.Bool), - decls.NewOverload(overloads.GreaterDoubleUint64, - []*exprpb.Type{decls.Double, decls.Uint}, decls.Bool), - decls.NewOverload(overloads.GreaterString, - []*exprpb.Type{decls.String, decls.String}, decls.Bool), - decls.NewOverload(overloads.GreaterBytes, - []*exprpb.Type{decls.Bytes, decls.Bytes}, decls.Bool), - decls.NewOverload(overloads.GreaterTimestamp, - []*exprpb.Type{decls.Timestamp, decls.Timestamp}, decls.Bool), - decls.NewOverload(overloads.GreaterDuration, - []*exprpb.Type{decls.Duration, decls.Duration}, decls.Bool)), - - decls.NewFunction(operators.GreaterEquals, - decls.NewOverload(overloads.GreaterEqualsBool, - []*exprpb.Type{decls.Bool, decls.Bool}, decls.Bool), - decls.NewOverload(overloads.GreaterEqualsInt64, - []*exprpb.Type{decls.Int, decls.Int}, decls.Bool), - decls.NewOverload(overloads.GreaterEqualsInt64Double, - []*exprpb.Type{decls.Int, decls.Double}, decls.Bool), - decls.NewOverload(overloads.GreaterEqualsInt64Uint64, - []*exprpb.Type{decls.Int, decls.Uint}, decls.Bool), - decls.NewOverload(overloads.GreaterEqualsUint64, - []*exprpb.Type{decls.Uint, decls.Uint}, decls.Bool), - decls.NewOverload(overloads.GreaterEqualsUint64Double, - []*exprpb.Type{decls.Uint, decls.Double}, decls.Bool), - decls.NewOverload(overloads.GreaterEqualsUint64Int64, - []*exprpb.Type{decls.Uint, decls.Int}, decls.Bool), - decls.NewOverload(overloads.GreaterEqualsDouble, - []*exprpb.Type{decls.Double, decls.Double}, decls.Bool), - decls.NewOverload(overloads.GreaterEqualsDoubleInt64, - []*exprpb.Type{decls.Double, decls.Int}, decls.Bool), - decls.NewOverload(overloads.GreaterEqualsDoubleUint64, - []*exprpb.Type{decls.Double, decls.Uint}, decls.Bool), - decls.NewOverload(overloads.GreaterEqualsString, - []*exprpb.Type{decls.String, decls.String}, decls.Bool), - decls.NewOverload(overloads.GreaterEqualsBytes, - []*exprpb.Type{decls.Bytes, decls.Bytes}, decls.Bool), - decls.NewOverload(overloads.GreaterEqualsTimestamp, - []*exprpb.Type{decls.Timestamp, decls.Timestamp}, decls.Bool), - decls.NewOverload(overloads.GreaterEqualsDuration, - []*exprpb.Type{decls.Duration, decls.Duration}, decls.Bool)), - }...) +// StandardFunctions returns the Decls for all functions in the evaluator. +// +// Deprecated: prefer stdlib.FunctionExprDecls() +func StandardFunctions() []*exprpb.Decl { + return stdlib.FunctionExprDecls() } -// StandardDeclarations returns the Decls for all functions and constants in the evaluator. -func StandardDeclarations() []*exprpb.Decl { - return standardDeclarations +// StandardTypes returns the set of type identifiers for standard library types. +// +// Deprecated: prefer stdlib.TypeExprDecls() +func StandardTypes() []*exprpb.Decl { + return stdlib.TypeExprDecls() } diff --git a/vendor/github.com/google/cel-go/checker/types.go b/vendor/github.com/google/cel-go/checker/types.go index f5c382725..e2373d1b7 100644 --- a/vendor/github.com/google/cel-go/checker/types.go +++ b/vendor/github.com/google/cel-go/checker/types.go @@ -15,154 +15,54 @@ package checker import ( - "fmt" - "strings" - - "github.com/google/cel-go/checker/decls" - - "google.golang.org/protobuf/proto" - - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + "github.com/google/cel-go/common/types" ) -const ( - kindUnknown = iota + 1 - kindError - kindFunction - kindDyn - kindPrimitive - kindWellKnown - kindWrapper - kindNull - kindAbstract - kindType - kindList - kindMap - kindObject - kindTypeParam -) - -// FormatCheckedType converts a type message into a string representation. -func FormatCheckedType(t *exprpb.Type) string { - switch kindOf(t) { - case kindDyn: - return "dyn" - case kindFunction: - return formatFunction(t.GetFunction().GetResultType(), - t.GetFunction().GetArgTypes(), - false) - case kindList: - return fmt.Sprintf("list(%s)", FormatCheckedType(t.GetListType().GetElemType())) - case kindObject: - return t.GetMessageType() - case kindMap: - return fmt.Sprintf("map(%s, %s)", - FormatCheckedType(t.GetMapType().GetKeyType()), - FormatCheckedType(t.GetMapType().GetValueType())) - case kindNull: - return "null" - case kindPrimitive: - switch t.GetPrimitive() { - case exprpb.Type_UINT64: - return "uint" - case exprpb.Type_INT64: - return "int" - } - return strings.Trim(strings.ToLower(t.GetPrimitive().String()), " ") - case kindType: - if t.GetType() == nil { - return "type" - } - return fmt.Sprintf("type(%s)", FormatCheckedType(t.GetType())) - case kindWellKnown: - switch t.GetWellKnown() { - case exprpb.Type_ANY: - return "any" - case exprpb.Type_DURATION: - return "duration" - case exprpb.Type_TIMESTAMP: - return "timestamp" - } - case kindWrapper: - return fmt.Sprintf("wrapper(%s)", - FormatCheckedType(decls.NewPrimitiveType(t.GetWrapper()))) - case kindError: - return "!error!" - case kindTypeParam: - return t.GetTypeParam() - case kindAbstract: - at := t.GetAbstractType() - params := at.GetParameterTypes() - paramStrs := make([]string, len(params)) - for i, p := range params { - paramStrs[i] = FormatCheckedType(p) - } - return fmt.Sprintf("%s(%s)", at.GetName(), strings.Join(paramStrs, ", ")) - } - return t.String() -} - // isDyn returns true if the input t is either type DYN or a well-known ANY message. -func isDyn(t *exprpb.Type) bool { +func isDyn(t *types.Type) bool { // Note: object type values that are well-known and map to a DYN value in practice // are sanitized prior to being added to the environment. - switch kindOf(t) { - case kindDyn: + switch t.Kind() { + case types.DynKind, types.AnyKind: return true - case kindWellKnown: - return t.GetWellKnown() == exprpb.Type_ANY default: return false } } // isDynOrError returns true if the input is either an Error, DYN, or well-known ANY message. -func isDynOrError(t *exprpb.Type) bool { +func isDynOrError(t *types.Type) bool { return isError(t) || isDyn(t) } -func isError(t *exprpb.Type) bool { - return kindOf(t) == kindError +func isError(t *types.Type) bool { + return t.Kind() == types.ErrorKind } -func isOptional(t *exprpb.Type) bool { - if kindOf(t) == kindAbstract { - at := t.GetAbstractType() - return at.GetName() == "optional" +func isOptional(t *types.Type) bool { + if t.Kind() == types.OpaqueKind { + return t.TypeName() == "optional" } return false } -func maybeUnwrapOptional(t *exprpb.Type) (*exprpb.Type, bool) { +func maybeUnwrapOptional(t *types.Type) (*types.Type, bool) { if isOptional(t) { - at := t.GetAbstractType() - return at.GetParameterTypes()[0], true + return t.Parameters()[0], true } return t, false } -func maybeUnwrapString(e *exprpb.Expr) (string, bool) { - switch e.GetExprKind().(type) { - case *exprpb.Expr_ConstExpr: - literal := e.GetConstExpr() - switch literal.GetConstantKind().(type) { - case *exprpb.Constant_StringValue: - return literal.GetStringValue(), true - } - } - return "", false -} - // isEqualOrLessSpecific checks whether one type is equal or less specific than the other one. // A type is less specific if it matches the other type using the DYN type. -func isEqualOrLessSpecific(t1 *exprpb.Type, t2 *exprpb.Type) bool { - kind1, kind2 := kindOf(t1), kindOf(t2) +func isEqualOrLessSpecific(t1, t2 *types.Type) bool { + kind1, kind2 := t1.Kind(), t2.Kind() // The first type is less specific. - if isDyn(t1) || kind1 == kindTypeParam { + if isDyn(t1) || kind1 == types.TypeParamKind { return true } // The first type is not less specific. - if isDyn(t2) || kind2 == kindTypeParam { + if isDyn(t2) || kind2 == types.TypeParamKind { return false } // Types must be of the same kind to be equal. @@ -173,38 +73,34 @@ func isEqualOrLessSpecific(t1 *exprpb.Type, t2 *exprpb.Type) bool { // With limited exceptions for ANY and JSON values, the types must agree and be equivalent in // order to return true. switch kind1 { - case kindAbstract: - a1 := t1.GetAbstractType() - a2 := t2.GetAbstractType() - if a1.GetName() != a2.GetName() || - len(a1.GetParameterTypes()) != len(a2.GetParameterTypes()) { + case types.OpaqueKind: + if t1.TypeName() != t2.TypeName() || + len(t1.Parameters()) != len(t2.Parameters()) { return false } - for i, p1 := range a1.GetParameterTypes() { - if !isEqualOrLessSpecific(p1, a2.GetParameterTypes()[i]) { + for i, p1 := range t1.Parameters() { + if !isEqualOrLessSpecific(p1, t2.Parameters()[i]) { return false } } return true - case kindList: - return isEqualOrLessSpecific(t1.GetListType().GetElemType(), t2.GetListType().GetElemType()) - case kindMap: - m1 := t1.GetMapType() - m2 := t2.GetMapType() - return isEqualOrLessSpecific(m1.GetKeyType(), m2.GetKeyType()) && - isEqualOrLessSpecific(m1.GetValueType(), m2.GetValueType()) - case kindType: + case types.ListKind: + return isEqualOrLessSpecific(t1.Parameters()[0], t2.Parameters()[0]) + case types.MapKind: + return isEqualOrLessSpecific(t1.Parameters()[0], t2.Parameters()[0]) && + isEqualOrLessSpecific(t1.Parameters()[1], t2.Parameters()[1]) + case types.TypeKind: return true default: - return proto.Equal(t1, t2) + return t1.IsExactType(t2) } } // / internalIsAssignable returns true if t1 is assignable to t2. -func internalIsAssignable(m *mapping, t1 *exprpb.Type, t2 *exprpb.Type) bool { +func internalIsAssignable(m *mapping, t1, t2 *types.Type) bool { // Process type parameters. - kind1, kind2 := kindOf(t1), kindOf(t2) - if kind2 == kindTypeParam { + kind1, kind2 := t1.Kind(), t2.Kind() + if kind2 == types.TypeParamKind { // If t2 is a valid type substitution for t1, return true. valid, t2HasSub := isValidTypeSubstitution(m, t1, t2) if valid { @@ -217,7 +113,7 @@ func internalIsAssignable(m *mapping, t1 *exprpb.Type, t2 *exprpb.Type) bool { } // Otherwise, fall through to check whether t1 is a possible substitution for t2. } - if kind1 == kindTypeParam { + if kind1 == types.TypeParamKind { // Return whether t1 is a valid substitution for t2. If not, do no additional checks as the // possible type substitutions have been searched in both directions. valid, _ := isValidTypeSubstitution(m, t2, t1) @@ -228,40 +124,25 @@ func internalIsAssignable(m *mapping, t1 *exprpb.Type, t2 *exprpb.Type) bool { if isDynOrError(t1) || isDynOrError(t2) { return true } - - // Test for when the types do not need to agree, but are more specific than dyn. - switch kind1 { - case kindNull: + // Preserve the nullness checks of the legacy type-checker. + if kind1 == types.NullTypeKind { return internalIsAssignableNull(t2) - case kindPrimitive: - return internalIsAssignablePrimitive(t1.GetPrimitive(), t2) - case kindWrapper: - return internalIsAssignable(m, decls.NewPrimitiveType(t1.GetWrapper()), t2) - default: - if kind1 != kind2 { - return false - } + } + if kind2 == types.NullTypeKind { + return internalIsAssignableNull(t1) } - // Test for when the types must agree. + // Test for when the types do not need to agree, but are more specific than dyn. switch kind1 { - // ERROR, TYPE_PARAM, and DYN handled above. - case kindAbstract: - return internalIsAssignableAbstractType(m, t1.GetAbstractType(), t2.GetAbstractType()) - case kindFunction: - return internalIsAssignableFunction(m, t1.GetFunction(), t2.GetFunction()) - case kindList: - return internalIsAssignable(m, t1.GetListType().GetElemType(), t2.GetListType().GetElemType()) - case kindMap: - return internalIsAssignableMap(m, t1.GetMapType(), t2.GetMapType()) - case kindObject: - return t1.GetMessageType() == t2.GetMessageType() - case kindType: - // A type is a type is a type, any additional parameterization of the - // type cannot affect method resolution or assignability. - return true - case kindWellKnown: - return t1.GetWellKnown() == t2.GetWellKnown() + case types.BoolKind, types.BytesKind, types.DoubleKind, types.IntKind, types.StringKind, types.UintKind, + types.AnyKind, types.DurationKind, types.TimestampKind, + types.StructKind: + return t1.IsAssignableType(t2) + case types.TypeKind: + return kind2 == types.TypeKind + case types.OpaqueKind, types.ListKind, types.MapKind: + return t1.Kind() == t2.Kind() && t1.TypeName() == t2.TypeName() && + internalIsAssignableList(m, t1.Parameters(), t2.Parameters()) default: return false } @@ -271,19 +152,19 @@ func internalIsAssignable(m *mapping, t1 *exprpb.Type, t2 *exprpb.Type) bool { // substitution for t1, and whether t2 has a type substitution in mapping m. // // The type t2 is a valid substitution for t1 if any of the following statements is true -// - t2 has a type substitition (t2sub) equal to t1 +// - t2 has a type substitution (t2sub) equal to t1 // - t2 has a type substitution (t2sub) assignable to t1 // - t2 does not occur within t1. -func isValidTypeSubstitution(m *mapping, t1, t2 *exprpb.Type) (valid, hasSub bool) { +func isValidTypeSubstitution(m *mapping, t1, t2 *types.Type) (valid, hasSub bool) { // Early return if the t1 and t2 are the same instance. - kind1, kind2 := kindOf(t1), kindOf(t2) - if kind1 == kind2 && (t1 == t2 || proto.Equal(t1, t2)) { + kind1, kind2 := t1.Kind(), t2.Kind() + if kind1 == kind2 && t1.IsExactType(t2) { return true, true } if t2Sub, found := m.find(t2); found { // Early return if t1 and t2Sub are the same instance as otherwise the mapping // might mark a type as being a subtitution for itself. - if kind1 == kindOf(t2Sub) && (t1 == t2Sub || proto.Equal(t1, t2Sub)) { + if kind1 == t2Sub.Kind() && t1.IsExactType(t2Sub) { return true, true } // If the types are compatible, pick the more general type and return true @@ -305,28 +186,10 @@ func isValidTypeSubstitution(m *mapping, t1, t2 *exprpb.Type) (valid, hasSub boo return false, false } -// internalIsAssignableAbstractType returns true if the abstract type names agree and all type -// parameters are assignable. -func internalIsAssignableAbstractType(m *mapping, a1 *exprpb.Type_AbstractType, a2 *exprpb.Type_AbstractType) bool { - return a1.GetName() == a2.GetName() && - internalIsAssignableList(m, a1.GetParameterTypes(), a2.GetParameterTypes()) -} - -// internalIsAssignableFunction returns true if the function return type and arg types are -// assignable. -func internalIsAssignableFunction(m *mapping, f1 *exprpb.Type_FunctionType, f2 *exprpb.Type_FunctionType) bool { - f1ArgTypes := flattenFunctionTypes(f1) - f2ArgTypes := flattenFunctionTypes(f2) - if internalIsAssignableList(m, f1ArgTypes, f2ArgTypes) { - return true - } - return false -} - // internalIsAssignableList returns true if the element types at each index in the list are // assignable from l1[i] to l2[i]. The list lengths must also agree for the lists to be // assignable. -func internalIsAssignableList(m *mapping, l1 []*exprpb.Type, l2 []*exprpb.Type) bool { +func internalIsAssignableList(m *mapping, l1, l2 []*types.Type) bool { if len(l1) != len(l2) { return false } @@ -338,41 +201,22 @@ func internalIsAssignableList(m *mapping, l1 []*exprpb.Type, l2 []*exprpb.Type) return true } -// internalIsAssignableMap returns true if map m1 may be assigned to map m2. -func internalIsAssignableMap(m *mapping, m1 *exprpb.Type_MapType, m2 *exprpb.Type_MapType) bool { - if internalIsAssignableList(m, - []*exprpb.Type{m1.GetKeyType(), m1.GetValueType()}, - []*exprpb.Type{m2.GetKeyType(), m2.GetValueType()}) { - return true - } - return false -} - // internalIsAssignableNull returns true if the type is nullable. -func internalIsAssignableNull(t *exprpb.Type) bool { - switch kindOf(t) { - case kindAbstract, kindObject, kindNull, kindWellKnown, kindWrapper: - return true - default: - return false - } +func internalIsAssignableNull(t *types.Type) bool { + return isLegacyNullable(t) || t.IsAssignableType(types.NullType) } -// internalIsAssignablePrimitive returns true if the target type is the same or if it is a wrapper -// for the primitive type. -func internalIsAssignablePrimitive(p exprpb.Type_PrimitiveType, target *exprpb.Type) bool { - switch kindOf(target) { - case kindPrimitive: - return p == target.GetPrimitive() - case kindWrapper: - return p == target.GetWrapper() - default: - return false +// isLegacyNullable preserves the null-ness compatibility of the original type-checker implementation. +func isLegacyNullable(t *types.Type) bool { + switch t.Kind() { + case types.OpaqueKind, types.StructKind, types.AnyKind, types.DurationKind, types.TimestampKind: + return true } + return false } // isAssignable returns an updated type substitution mapping if t1 is assignable to t2. -func isAssignable(m *mapping, t1 *exprpb.Type, t2 *exprpb.Type) *mapping { +func isAssignable(m *mapping, t1, t2 *types.Type) *mapping { mCopy := m.copy() if internalIsAssignable(mCopy, t1, t2) { return mCopy @@ -381,7 +225,7 @@ func isAssignable(m *mapping, t1 *exprpb.Type, t2 *exprpb.Type) *mapping { } // isAssignableList returns an updated type substitution mapping if l1 is assignable to l2. -func isAssignableList(m *mapping, l1 []*exprpb.Type, l2 []*exprpb.Type) *mapping { +func isAssignableList(m *mapping, l1, l2 []*types.Type) *mapping { mCopy := m.copy() if internalIsAssignableList(mCopy, l1, l2) { return mCopy @@ -389,44 +233,8 @@ func isAssignableList(m *mapping, l1 []*exprpb.Type, l2 []*exprpb.Type) *mapping return nil } -// kindOf returns the kind of the type as defined in the checked.proto. -func kindOf(t *exprpb.Type) int { - if t == nil || t.TypeKind == nil { - return kindUnknown - } - switch t.GetTypeKind().(type) { - case *exprpb.Type_Error: - return kindError - case *exprpb.Type_Function: - return kindFunction - case *exprpb.Type_Dyn: - return kindDyn - case *exprpb.Type_Primitive: - return kindPrimitive - case *exprpb.Type_WellKnown: - return kindWellKnown - case *exprpb.Type_Wrapper: - return kindWrapper - case *exprpb.Type_Null: - return kindNull - case *exprpb.Type_Type: - return kindType - case *exprpb.Type_ListType_: - return kindList - case *exprpb.Type_MapType_: - return kindMap - case *exprpb.Type_MessageType: - return kindObject - case *exprpb.Type_TypeParam: - return kindTypeParam - case *exprpb.Type_AbstractType_: - return kindAbstract - } - return kindUnknown -} - // mostGeneral returns the more general of two types which are known to unify. -func mostGeneral(t1 *exprpb.Type, t2 *exprpb.Type) *exprpb.Type { +func mostGeneral(t1, t2 *types.Type) *types.Type { if isEqualOrLessSpecific(t1, t2) { return t1 } @@ -436,32 +244,25 @@ func mostGeneral(t1 *exprpb.Type, t2 *exprpb.Type) *exprpb.Type { // notReferencedIn checks whether the type doesn't appear directly or transitively within the other // type. This is a standard requirement for type unification, commonly referred to as the "occurs // check". -func notReferencedIn(m *mapping, t *exprpb.Type, withinType *exprpb.Type) bool { - if proto.Equal(t, withinType) { +func notReferencedIn(m *mapping, t, withinType *types.Type) bool { + if t.IsExactType(withinType) { return false } - withinKind := kindOf(withinType) + withinKind := withinType.Kind() switch withinKind { - case kindTypeParam: + case types.TypeParamKind: wtSub, found := m.find(withinType) if !found { return true } return notReferencedIn(m, t, wtSub) - case kindAbstract: - for _, pt := range withinType.GetAbstractType().GetParameterTypes() { + case types.OpaqueKind, types.ListKind, types.MapKind: + for _, pt := range withinType.Parameters() { if !notReferencedIn(m, t, pt) { return false } } return true - case kindList: - return notReferencedIn(m, t, withinType.GetListType().GetElemType()) - case kindMap: - mt := withinType.GetMapType() - return notReferencedIn(m, t, mt.GetKeyType()) && notReferencedIn(m, t, mt.GetValueType()) - case kindWrapper: - return notReferencedIn(m, t, decls.NewPrimitiveType(withinType.GetWrapper())) default: return true } @@ -469,39 +270,25 @@ func notReferencedIn(m *mapping, t *exprpb.Type, withinType *exprpb.Type) bool { // substitute replaces all direct and indirect occurrences of bound type parameters. Unbound type // parameters are replaced by DYN if typeParamToDyn is true. -func substitute(m *mapping, t *exprpb.Type, typeParamToDyn bool) *exprpb.Type { +func substitute(m *mapping, t *types.Type, typeParamToDyn bool) *types.Type { if tSub, found := m.find(t); found { return substitute(m, tSub, typeParamToDyn) } - kind := kindOf(t) - if typeParamToDyn && kind == kindTypeParam { - return decls.Dyn + kind := t.Kind() + if typeParamToDyn && kind == types.TypeParamKind { + return types.DynType } switch kind { - case kindAbstract: - at := t.GetAbstractType() - params := make([]*exprpb.Type, len(at.GetParameterTypes())) - for i, p := range at.GetParameterTypes() { - params[i] = substitute(m, p, typeParamToDyn) - } - return decls.NewAbstractType(at.GetName(), params...) - case kindFunction: - fn := t.GetFunction() - rt := substitute(m, fn.ResultType, typeParamToDyn) - args := make([]*exprpb.Type, len(fn.GetArgTypes())) - for i, a := range fn.ArgTypes { - args[i] = substitute(m, a, typeParamToDyn) - } - return decls.NewFunctionType(rt, args...) - case kindList: - return decls.NewListType(substitute(m, t.GetListType().GetElemType(), typeParamToDyn)) - case kindMap: - mt := t.GetMapType() - return decls.NewMapType(substitute(m, mt.GetKeyType(), typeParamToDyn), - substitute(m, mt.GetValueType(), typeParamToDyn)) - case kindType: - if t.GetType() != nil { - return decls.NewTypeType(substitute(m, t.GetType(), typeParamToDyn)) + case types.OpaqueKind: + return types.NewOpaqueType(t.TypeName(), substituteParams(m, t.Parameters(), typeParamToDyn)...) + case types.ListKind: + return types.NewListType(substitute(m, t.Parameters()[0], typeParamToDyn)) + case types.MapKind: + return types.NewMapType(substitute(m, t.Parameters()[0], typeParamToDyn), + substitute(m, t.Parameters()[1], typeParamToDyn)) + case types.TypeKind: + if len(t.Parameters()) > 0 { + return types.NewTypeTypeWithParam(substitute(m, t.Parameters()[0], typeParamToDyn)) } return t default: @@ -509,21 +296,14 @@ func substitute(m *mapping, t *exprpb.Type, typeParamToDyn bool) *exprpb.Type { } } -func typeKey(t *exprpb.Type) string { - return FormatCheckedType(t) +func substituteParams(m *mapping, typeParams []*types.Type, typeParamToDyn bool) []*types.Type { + subParams := make([]*types.Type, len(typeParams)) + for i, tp := range typeParams { + subParams[i] = substitute(m, tp, typeParamToDyn) + } + return subParams } -// flattenFunctionTypes takes a function with arg types T1, T2, ..., TN and result type TR -// and returns a slice containing {T1, T2, ..., TN, TR}. -func flattenFunctionTypes(f *exprpb.Type_FunctionType) []*exprpb.Type { - argTypes := f.GetArgTypes() - if len(argTypes) == 0 { - return []*exprpb.Type{f.GetResultType()} - } - flattend := make([]*exprpb.Type, len(argTypes)+1, len(argTypes)+1) - for i, at := range argTypes { - flattend[i] = at - } - flattend[len(argTypes)] = f.GetResultType() - return flattend +func newFunctionType(resultType *types.Type, argTypes ...*types.Type) *types.Type { + return types.NewOpaqueType("function", append([]*types.Type{resultType}, argTypes...)...) } diff --git a/vendor/github.com/google/cel-go/common/BUILD.bazel b/vendor/github.com/google/cel-go/common/BUILD.bazel index a0058aebe..d6165b13a 100644 --- a/vendor/github.com/google/cel-go/common/BUILD.bazel +++ b/vendor/github.com/google/cel-go/common/BUILD.bazel @@ -17,7 +17,7 @@ go_library( importpath = "github.com/google/cel-go/common", deps = [ "//common/runes:go_default_library", - "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", "@org_golang_x_text//width:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/common/ast/BUILD.bazel b/vendor/github.com/google/cel-go/common/ast/BUILD.bazel new file mode 100644 index 000000000..7269cdff5 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/ast/BUILD.bazel @@ -0,0 +1,52 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +package( + default_visibility = [ + "//cel:__subpackages__", + "//checker:__subpackages__", + "//common:__subpackages__", + "//interpreter:__subpackages__", + ], + licenses = ["notice"], # Apache 2.0 +) + +go_library( + name = "go_default_library", + srcs = [ + "ast.go", + "expr.go", + ], + importpath = "github.com/google/cel-go/common/ast", + deps = [ + "//common/types:go_default_library", + "//common/types/ref:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", + "@org_golang_google_protobuf//types/known/structpb:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = [ + "ast_test.go", + "expr_test.go", + ], + embed = [ + ":go_default_library", + ], + deps = [ + "//checker:go_default_library", + "//checker/decls:go_default_library", + "//common:go_default_library", + "//common/containers:go_default_library", + "//common/decls:go_default_library", + "//common/overloads:go_default_library", + "//common/stdlib:go_default_library", + "//common/types:go_default_library", + "//common/types/ref:go_default_library", + "//parser:go_default_library", + "//test/proto3pb:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", + "@org_golang_google_protobuf//proto:go_default_library", + ], +) \ No newline at end of file diff --git a/vendor/github.com/google/cel-go/common/ast/ast.go b/vendor/github.com/google/cel-go/common/ast/ast.go new file mode 100644 index 000000000..b3c150793 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/ast/ast.go @@ -0,0 +1,226 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package ast declares data structures useful for parsed and checked abstract syntax trees +package ast + +import ( + "fmt" + + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + + structpb "google.golang.org/protobuf/types/known/structpb" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// CheckedAST contains a protobuf expression and source info along with CEL-native type and reference information. +type CheckedAST struct { + Expr *exprpb.Expr + SourceInfo *exprpb.SourceInfo + TypeMap map[int64]*types.Type + ReferenceMap map[int64]*ReferenceInfo +} + +// CheckedASTToCheckedExpr converts a CheckedAST to a CheckedExpr protobouf. +func CheckedASTToCheckedExpr(ast *CheckedAST) (*exprpb.CheckedExpr, error) { + refMap := make(map[int64]*exprpb.Reference, len(ast.ReferenceMap)) + for id, ref := range ast.ReferenceMap { + r, err := ReferenceInfoToReferenceExpr(ref) + if err != nil { + return nil, err + } + refMap[id] = r + } + typeMap := make(map[int64]*exprpb.Type, len(ast.TypeMap)) + for id, typ := range ast.TypeMap { + t, err := types.TypeToExprType(typ) + if err != nil { + return nil, err + } + typeMap[id] = t + } + return &exprpb.CheckedExpr{ + Expr: ast.Expr, + SourceInfo: ast.SourceInfo, + ReferenceMap: refMap, + TypeMap: typeMap, + }, nil +} + +// CheckedExprToCheckedAST converts a CheckedExpr protobuf to a CheckedAST instance. +func CheckedExprToCheckedAST(checked *exprpb.CheckedExpr) (*CheckedAST, error) { + refMap := make(map[int64]*ReferenceInfo, len(checked.GetReferenceMap())) + for id, ref := range checked.GetReferenceMap() { + r, err := ReferenceExprToReferenceInfo(ref) + if err != nil { + return nil, err + } + refMap[id] = r + } + typeMap := make(map[int64]*types.Type, len(checked.GetTypeMap())) + for id, typ := range checked.GetTypeMap() { + t, err := types.ExprTypeToType(typ) + if err != nil { + return nil, err + } + typeMap[id] = t + } + return &CheckedAST{ + Expr: checked.GetExpr(), + SourceInfo: checked.GetSourceInfo(), + ReferenceMap: refMap, + TypeMap: typeMap, + }, nil +} + +// ReferenceInfo contains a CEL native representation of an identifier reference which may refer to +// either a qualified identifier name, a set of overload ids, or a constant value from an enum. +type ReferenceInfo struct { + Name string + OverloadIDs []string + Value ref.Val +} + +// NewIdentReference creates a ReferenceInfo instance for an identifier with an optional constant value. +func NewIdentReference(name string, value ref.Val) *ReferenceInfo { + return &ReferenceInfo{Name: name, Value: value} +} + +// NewFunctionReference creates a ReferenceInfo instance for a set of function overloads. +func NewFunctionReference(overloads ...string) *ReferenceInfo { + info := &ReferenceInfo{} + for _, id := range overloads { + info.AddOverload(id) + } + return info +} + +// AddOverload appends a function overload ID to the ReferenceInfo. +func (r *ReferenceInfo) AddOverload(overloadID string) { + for _, id := range r.OverloadIDs { + if id == overloadID { + return + } + } + r.OverloadIDs = append(r.OverloadIDs, overloadID) +} + +// Equals returns whether two references are identical to each other. +func (r *ReferenceInfo) Equals(other *ReferenceInfo) bool { + if r.Name != other.Name { + return false + } + if len(r.OverloadIDs) != len(other.OverloadIDs) { + return false + } + if len(r.OverloadIDs) != 0 { + overloadMap := make(map[string]struct{}, len(r.OverloadIDs)) + for _, id := range r.OverloadIDs { + overloadMap[id] = struct{}{} + } + for _, id := range other.OverloadIDs { + _, found := overloadMap[id] + if !found { + return false + } + } + } + if r.Value == nil && other.Value == nil { + return true + } + if r.Value == nil && other.Value != nil || + r.Value != nil && other.Value == nil || + r.Value.Equal(other.Value) != types.True { + return false + } + return true +} + +// ReferenceInfoToReferenceExpr converts a ReferenceInfo instance to a protobuf Reference suitable for serialization. +func ReferenceInfoToReferenceExpr(info *ReferenceInfo) (*exprpb.Reference, error) { + c, err := ValToConstant(info.Value) + if err != nil { + return nil, err + } + return &exprpb.Reference{ + Name: info.Name, + OverloadId: info.OverloadIDs, + Value: c, + }, nil +} + +// ReferenceExprToReferenceInfo converts a protobuf Reference into a CEL-native ReferenceInfo instance. +func ReferenceExprToReferenceInfo(ref *exprpb.Reference) (*ReferenceInfo, error) { + v, err := ConstantToVal(ref.GetValue()) + if err != nil { + return nil, err + } + return &ReferenceInfo{ + Name: ref.GetName(), + OverloadIDs: ref.GetOverloadId(), + Value: v, + }, nil +} + +// ValToConstant converts a CEL-native ref.Val to a protobuf Constant. +// +// Only simple scalar types are supported by this method. +func ValToConstant(v ref.Val) (*exprpb.Constant, error) { + if v == nil { + return nil, nil + } + switch v.Type() { + case types.BoolType: + return &exprpb.Constant{ConstantKind: &exprpb.Constant_BoolValue{BoolValue: v.Value().(bool)}}, nil + case types.BytesType: + return &exprpb.Constant{ConstantKind: &exprpb.Constant_BytesValue{BytesValue: v.Value().([]byte)}}, nil + case types.DoubleType: + return &exprpb.Constant{ConstantKind: &exprpb.Constant_DoubleValue{DoubleValue: v.Value().(float64)}}, nil + case types.IntType: + return &exprpb.Constant{ConstantKind: &exprpb.Constant_Int64Value{Int64Value: v.Value().(int64)}}, nil + case types.NullType: + return &exprpb.Constant{ConstantKind: &exprpb.Constant_NullValue{NullValue: structpb.NullValue_NULL_VALUE}}, nil + case types.StringType: + return &exprpb.Constant{ConstantKind: &exprpb.Constant_StringValue{StringValue: v.Value().(string)}}, nil + case types.UintType: + return &exprpb.Constant{ConstantKind: &exprpb.Constant_Uint64Value{Uint64Value: v.Value().(uint64)}}, nil + } + return nil, fmt.Errorf("unsupported constant kind: %v", v.Type()) +} + +// ConstantToVal converts a protobuf Constant to a CEL-native ref.Val. +func ConstantToVal(c *exprpb.Constant) (ref.Val, error) { + if c == nil { + return nil, nil + } + switch c.GetConstantKind().(type) { + case *exprpb.Constant_BoolValue: + return types.Bool(c.GetBoolValue()), nil + case *exprpb.Constant_BytesValue: + return types.Bytes(c.GetBytesValue()), nil + case *exprpb.Constant_DoubleValue: + return types.Double(c.GetDoubleValue()), nil + case *exprpb.Constant_Int64Value: + return types.Int(c.GetInt64Value()), nil + case *exprpb.Constant_NullValue: + return types.NullValue, nil + case *exprpb.Constant_StringValue: + return types.String(c.GetStringValue()), nil + case *exprpb.Constant_Uint64Value: + return types.Uint(c.GetUint64Value()), nil + } + return nil, fmt.Errorf("unsupported constant kind: %v", c.GetConstantKind()) +} diff --git a/vendor/github.com/google/cel-go/common/ast/expr.go b/vendor/github.com/google/cel-go/common/ast/expr.go new file mode 100644 index 000000000..b63884a60 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/ast/expr.go @@ -0,0 +1,709 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ast + +import ( + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// ExprKind represents the expression node kind. +type ExprKind int + +const ( + // UnspecifiedKind represents an unset expression with no specified properties. + UnspecifiedKind ExprKind = iota + + // LiteralKind represents a primitive scalar literal. + LiteralKind + + // IdentKind represents a simple variable, constant, or type identifier. + IdentKind + + // SelectKind represents a field selection expression. + SelectKind + + // CallKind represents a function call. + CallKind + + // ListKind represents a list literal expression. + ListKind + + // MapKind represents a map literal expression. + MapKind + + // StructKind represents a struct literal expression. + StructKind + + // ComprehensionKind represents a comprehension expression generated by a macro. + ComprehensionKind +) + +// NavigateCheckedAST converts a CheckedAST to a NavigableExpr +func NavigateCheckedAST(ast *CheckedAST) NavigableExpr { + return newNavigableExpr(nil, ast.Expr, ast.TypeMap) +} + +// ExprMatcher takes a NavigableExpr in and indicates whether the value is a match. +// +// This function type should be use with the `Match` and `MatchList` calls. +type ExprMatcher func(NavigableExpr) bool + +// ConstantValueMatcher returns an ExprMatcher which will return true if the input NavigableExpr +// is comprised of all constant values, such as a simple literal or even list and map literal. +func ConstantValueMatcher() ExprMatcher { + return matchIsConstantValue +} + +// KindMatcher returns an ExprMatcher which will return true if the input NavigableExpr.Kind() matches +// the specified `kind`. +func KindMatcher(kind ExprKind) ExprMatcher { + return func(e NavigableExpr) bool { + return e.Kind() == kind + } +} + +// FunctionMatcher returns an ExprMatcher which will match NavigableExpr nodes of CallKind type whose +// function name is equal to `funcName`. +func FunctionMatcher(funcName string) ExprMatcher { + return func(e NavigableExpr) bool { + if e.Kind() != CallKind { + return false + } + return e.AsCall().FunctionName() == funcName + } +} + +// AllMatcher returns true for all descendants of a NavigableExpr, effectively flattening them into a list. +// +// Such a result would work well with subsequent MatchList calls. +func AllMatcher() ExprMatcher { + return func(NavigableExpr) bool { + return true + } +} + +// MatchDescendants takes a NavigableExpr and ExprMatcher and produces a list of NavigableExpr values of the +// descendants which match. +func MatchDescendants(expr NavigableExpr, matcher ExprMatcher) []NavigableExpr { + return matchListInternal([]NavigableExpr{expr}, matcher, true) +} + +// MatchSubset applies an ExprMatcher to a list of NavigableExpr values and their descendants, producing a +// subset of NavigableExpr values which match. +func MatchSubset(exprs []NavigableExpr, matcher ExprMatcher) []NavigableExpr { + visit := make([]NavigableExpr, len(exprs)) + copy(visit, exprs) + return matchListInternal(visit, matcher, false) +} + +func matchListInternal(visit []NavigableExpr, matcher ExprMatcher, visitDescendants bool) []NavigableExpr { + var matched []NavigableExpr + for len(visit) != 0 { + e := visit[0] + if matcher(e) { + matched = append(matched, e) + } + if visitDescendants { + visit = append(visit[1:], e.Children()...) + } else { + visit = visit[1:] + } + } + return matched +} + +func matchIsConstantValue(e NavigableExpr) bool { + if e.Kind() == LiteralKind { + return true + } + if e.Kind() == StructKind || e.Kind() == MapKind || e.Kind() == ListKind { + for _, child := range e.Children() { + if !matchIsConstantValue(child) { + return false + } + } + return true + } + return false +} + +// NavigableExpr represents the base navigable expression value. +// +// Depending on the `Kind()` value, the NavigableExpr may be converted to a concrete expression types +// as indicated by the `As` methods. +// +// NavigableExpr values and their concrete expression types should be nil-safe. Conversion of an expr +// to the wrong kind should produce a nil value. +type NavigableExpr interface { + // ID of the expression as it appears in the AST + ID() int64 + + // Kind of the expression node. See ExprKind for the valid enum values. + Kind() ExprKind + + // Type of the expression node. + Type() *types.Type + + // Parent returns the parent expression node, if one exists. + Parent() (NavigableExpr, bool) + + // Children returns a list of child expression nodes. + Children() []NavigableExpr + + // ToExpr adapts this NavigableExpr to a protobuf representation. + ToExpr() *exprpb.Expr + + // AsCall adapts the expr into a NavigableCallExpr + // + // The Kind() must be equal to a CallKind for the conversion to be well-defined. + AsCall() NavigableCallExpr + + // AsComprehension adapts the expr into a NavigableComprehensionExpr. + // + // The Kind() must be equal to a ComprehensionKind for the conversion to be well-defined. + AsComprehension() NavigableComprehensionExpr + + // AsIdent adapts the expr into an identifier string. + // + // The Kind() must be equal to an IdentKind for the conversion to be well-defined. + AsIdent() string + + // AsLiteral adapts the expr into a constant ref.Val. + // + // The Kind() must be equal to a LiteralKind for the conversion to be well-defined. + AsLiteral() ref.Val + + // AsList adapts the expr into a NavigableListExpr. + // + // The Kind() must be equal to a ListKind for the conversion to be well-defined. + AsList() NavigableListExpr + + // AsMap adapts the expr into a NavigableMapExpr. + // + // The Kind() must be equal to a MapKind for the conversion to be well-defined. + AsMap() NavigableMapExpr + + // AsSelect adapts the expr into a NavigableSelectExpr. + // + // The Kind() must be equal to a SelectKind for the conversion to be well-defined. + AsSelect() NavigableSelectExpr + + // AsStruct adapts the expr into a NavigableStructExpr. + // + // The Kind() must be equal to a StructKind for the conversion to be well-defined. + AsStruct() NavigableStructExpr + + // marker interface method + isNavigable() +} + +// NavigableCallExpr defines an interface for inspecting a function call and its arugments. +type NavigableCallExpr interface { + // FunctionName returns the name of the function. + FunctionName() string + + // Target returns the target of the expression if one is present. + Target() NavigableExpr + + // Args returns the list of call arguments, excluding the target. + Args() []NavigableExpr + + // ReturnType returns the result type of the call. + ReturnType() *types.Type + + // marker interface method + isNavigable() +} + +// NavigableListExpr defines an interface for inspecting a list literal expression. +type NavigableListExpr interface { + // Elements returns the list elements as navigable expressions. + Elements() []NavigableExpr + + // OptionalIndicies returns the list of optional indices in the list literal. + OptionalIndices() []int32 + + // Size returns the number of elements in the list. + Size() int + + // marker interface method + isNavigable() +} + +// NavigableSelectExpr defines an interface for inspecting a select expression. +type NavigableSelectExpr interface { + // Operand returns the selection operand expression. + Operand() NavigableExpr + + // FieldName returns the field name being selected from the operand. + FieldName() string + + // IsTestOnly indicates whether the select expression is a presence test generated by a macro. + IsTestOnly() bool + + // marker interface method + isNavigable() +} + +// NavigableMapExpr defines an interface for inspecting a map expression. +type NavigableMapExpr interface { + // Entries returns the map key value pairs as NavigableEntry values. + Entries() []NavigableEntry + + // Size returns the number of entries in the map. + Size() int + + // marker interface method + isNavigable() +} + +// NavigableEntry defines an interface for inspecting a map entry. +type NavigableEntry interface { + // Key returns the map entry key expression. + Key() NavigableExpr + + // Value returns the map entry value expression. + Value() NavigableExpr + + // IsOptional returns whether the entry is optional. + IsOptional() bool + + // marker interface method + isNavigable() +} + +// NavigableStructExpr defines an interfaces for inspecting a struct and its field initializers. +type NavigableStructExpr interface { + // TypeName returns the struct type name. + TypeName() string + + // Fields returns the set of field initializers in the struct expression as NavigableField values. + Fields() []NavigableField + + // marker interface method + isNavigable() +} + +// NavigableField defines an interface for inspecting a struct field initialization. +type NavigableField interface { + // FieldName returns the name of the field. + FieldName() string + + // Value returns the field initialization expression. + Value() NavigableExpr + + // IsOptional returns whether the field is optional. + IsOptional() bool + + // marker interface method + isNavigable() +} + +// NavigableComprehensionExpr defines an interface for inspecting a comprehension expression. +type NavigableComprehensionExpr interface { + // IterRange returns the iteration range expression. + IterRange() NavigableExpr + + // IterVar returns the iteration variable name. + IterVar() string + + // AccuVar returns the accumulation variable name. + AccuVar() string + + // AccuInit returns the accumulation variable initialization expression. + AccuInit() NavigableExpr + + // LoopCondition returns the loop condition expression. + LoopCondition() NavigableExpr + + // LoopStep returns the loop step expression. + LoopStep() NavigableExpr + + // Result returns the comprehension result expression. + Result() NavigableExpr + + // marker interface method + isNavigable() +} + +func newNavigableExpr(parent NavigableExpr, expr *exprpb.Expr, typeMap map[int64]*types.Type) NavigableExpr { + kind, factory := kindOf(expr) + nav := &navigableExprImpl{ + parent: parent, + kind: kind, + expr: expr, + typeMap: typeMap, + createChildren: factory, + } + return nav +} + +type navigableExprImpl struct { + parent NavigableExpr + kind ExprKind + expr *exprpb.Expr + typeMap map[int64]*types.Type + createChildren childFactory +} + +func (nav *navigableExprImpl) ID() int64 { + return nav.ToExpr().GetId() +} + +func (nav *navigableExprImpl) Kind() ExprKind { + return nav.kind +} + +func (nav *navigableExprImpl) Type() *types.Type { + if t, found := nav.typeMap[nav.ID()]; found { + return t + } + return types.DynType +} + +func (nav *navigableExprImpl) Parent() (NavigableExpr, bool) { + if nav.parent != nil { + return nav.parent, true + } + return nil, false +} + +func (nav *navigableExprImpl) Children() []NavigableExpr { + return nav.createChildren(nav) +} + +func (nav *navigableExprImpl) ToExpr() *exprpb.Expr { + return nav.expr +} + +func (nav *navigableExprImpl) AsCall() NavigableCallExpr { + return navigableCallImpl{navigableExprImpl: nav} +} + +func (nav *navigableExprImpl) AsComprehension() NavigableComprehensionExpr { + return navigableComprehensionImpl{navigableExprImpl: nav} +} + +func (nav *navigableExprImpl) AsIdent() string { + return nav.ToExpr().GetIdentExpr().GetName() +} + +func (nav *navigableExprImpl) AsLiteral() ref.Val { + if nav.Kind() != LiteralKind { + return nil + } + val, err := ConstantToVal(nav.ToExpr().GetConstExpr()) + if err != nil { + panic(err) + } + return val +} + +func (nav *navigableExprImpl) AsList() NavigableListExpr { + return navigableListImpl{navigableExprImpl: nav} +} + +func (nav *navigableExprImpl) AsMap() NavigableMapExpr { + return navigableMapImpl{navigableExprImpl: nav} +} + +func (nav *navigableExprImpl) AsSelect() NavigableSelectExpr { + return navigableSelectImpl{navigableExprImpl: nav} +} + +func (nav *navigableExprImpl) AsStruct() NavigableStructExpr { + return navigableStructImpl{navigableExprImpl: nav} +} + +func (nav *navigableExprImpl) createChild(e *exprpb.Expr) NavigableExpr { + return newNavigableExpr(nav, e, nav.typeMap) +} + +func (nav *navigableExprImpl) isNavigable() {} + +type navigableCallImpl struct { + *navigableExprImpl +} + +func (call navigableCallImpl) FunctionName() string { + return call.ToExpr().GetCallExpr().GetFunction() +} + +func (call navigableCallImpl) Target() NavigableExpr { + t := call.ToExpr().GetCallExpr().GetTarget() + if t != nil { + return call.createChild(t) + } + return nil +} + +func (call navigableCallImpl) Args() []NavigableExpr { + args := call.ToExpr().GetCallExpr().GetArgs() + navArgs := make([]NavigableExpr, len(args)) + for i, a := range args { + navArgs[i] = call.createChild(a) + } + return navArgs +} + +func (call navigableCallImpl) ReturnType() *types.Type { + return call.Type() +} + +type navigableComprehensionImpl struct { + *navigableExprImpl +} + +func (comp navigableComprehensionImpl) IterRange() NavigableExpr { + return comp.createChild(comp.ToExpr().GetComprehensionExpr().GetIterRange()) +} + +func (comp navigableComprehensionImpl) IterVar() string { + return comp.ToExpr().GetComprehensionExpr().GetIterVar() +} + +func (comp navigableComprehensionImpl) AccuVar() string { + return comp.ToExpr().GetComprehensionExpr().GetAccuVar() +} + +func (comp navigableComprehensionImpl) AccuInit() NavigableExpr { + return comp.createChild(comp.ToExpr().GetComprehensionExpr().GetAccuInit()) +} + +func (comp navigableComprehensionImpl) LoopCondition() NavigableExpr { + return comp.createChild(comp.ToExpr().GetComprehensionExpr().GetLoopCondition()) +} + +func (comp navigableComprehensionImpl) LoopStep() NavigableExpr { + return comp.createChild(comp.ToExpr().GetComprehensionExpr().GetLoopStep()) +} + +func (comp navigableComprehensionImpl) Result() NavigableExpr { + return comp.createChild(comp.ToExpr().GetComprehensionExpr().GetResult()) +} + +type navigableListImpl struct { + *navigableExprImpl +} + +func (l navigableListImpl) Elements() []NavigableExpr { + return l.Children() +} + +func (l navigableListImpl) OptionalIndices() []int32 { + return l.ToExpr().GetListExpr().GetOptionalIndices() +} + +func (l navigableListImpl) Size() int { + return len(l.ToExpr().GetListExpr().GetElements()) +} + +type navigableMapImpl struct { + *navigableExprImpl +} + +func (m navigableMapImpl) Entries() []NavigableEntry { + mapExpr := m.ToExpr().GetStructExpr() + entries := make([]NavigableEntry, len(mapExpr.GetEntries())) + for i, e := range mapExpr.GetEntries() { + entries[i] = navigableEntryImpl{ + key: m.createChild(e.GetMapKey()), + val: m.createChild(e.GetValue()), + isOpt: e.GetOptionalEntry(), + } + } + return entries +} + +func (m navigableMapImpl) Size() int { + return len(m.ToExpr().GetStructExpr().GetEntries()) +} + +type navigableEntryImpl struct { + key NavigableExpr + val NavigableExpr + isOpt bool +} + +func (e navigableEntryImpl) Key() NavigableExpr { + return e.key +} + +func (e navigableEntryImpl) Value() NavigableExpr { + return e.val +} + +func (e navigableEntryImpl) IsOptional() bool { + return e.isOpt +} + +func (e navigableEntryImpl) isNavigable() {} + +type navigableSelectImpl struct { + *navigableExprImpl +} + +func (sel navigableSelectImpl) FieldName() string { + return sel.ToExpr().GetSelectExpr().GetField() +} + +func (sel navigableSelectImpl) IsTestOnly() bool { + return sel.ToExpr().GetSelectExpr().GetTestOnly() +} + +func (sel navigableSelectImpl) Operand() NavigableExpr { + return sel.createChild(sel.ToExpr().GetSelectExpr().GetOperand()) +} + +type navigableStructImpl struct { + *navigableExprImpl +} + +func (s navigableStructImpl) TypeName() string { + return s.ToExpr().GetStructExpr().GetMessageName() +} + +func (s navigableStructImpl) Fields() []NavigableField { + fieldInits := s.ToExpr().GetStructExpr().GetEntries() + fields := make([]NavigableField, len(fieldInits)) + for i, f := range fieldInits { + fields[i] = navigableFieldImpl{ + name: f.GetFieldKey(), + val: s.createChild(f.GetValue()), + isOpt: f.GetOptionalEntry(), + } + } + return fields +} + +type navigableFieldImpl struct { + name string + val NavigableExpr + isOpt bool +} + +func (f navigableFieldImpl) FieldName() string { + return f.name +} + +func (f navigableFieldImpl) Value() NavigableExpr { + return f.val +} + +func (f navigableFieldImpl) IsOptional() bool { + return f.isOpt +} + +func (f navigableFieldImpl) isNavigable() {} + +func kindOf(expr *exprpb.Expr) (ExprKind, childFactory) { + switch expr.GetExprKind().(type) { + case *exprpb.Expr_ConstExpr: + return LiteralKind, noopFactory + case *exprpb.Expr_IdentExpr: + return IdentKind, noopFactory + case *exprpb.Expr_SelectExpr: + return SelectKind, selectFactory + case *exprpb.Expr_CallExpr: + return CallKind, callArgFactory + case *exprpb.Expr_ListExpr: + return ListKind, listElemFactory + case *exprpb.Expr_StructExpr: + if expr.GetStructExpr().GetMessageName() != "" { + return StructKind, structEntryFactory + } + return MapKind, mapEntryFactory + case *exprpb.Expr_ComprehensionExpr: + return ComprehensionKind, comprehensionFactory + default: + return UnspecifiedKind, noopFactory + } +} + +type childFactory func(*navigableExprImpl) []NavigableExpr + +func noopFactory(*navigableExprImpl) []NavigableExpr { + return nil +} + +func selectFactory(nav *navigableExprImpl) []NavigableExpr { + return []NavigableExpr{ + nav.createChild(nav.ToExpr().GetSelectExpr().GetOperand()), + } +} + +func callArgFactory(nav *navigableExprImpl) []NavigableExpr { + call := nav.ToExpr().GetCallExpr() + argCount := len(call.GetArgs()) + if call.GetTarget() != nil { + argCount++ + } + navExprs := make([]NavigableExpr, argCount) + i := 0 + if call.GetTarget() != nil { + navExprs[i] = nav.createChild(call.GetTarget()) + i++ + } + for _, arg := range call.GetArgs() { + navExprs[i] = nav.createChild(arg) + i++ + } + return navExprs +} + +func listElemFactory(nav *navigableExprImpl) []NavigableExpr { + l := nav.ToExpr().GetListExpr() + navExprs := make([]NavigableExpr, len(l.GetElements())) + for i, e := range l.GetElements() { + navExprs[i] = nav.createChild(e) + } + return navExprs +} + +func structEntryFactory(nav *navigableExprImpl) []NavigableExpr { + s := nav.ToExpr().GetStructExpr() + entries := make([]NavigableExpr, len(s.GetEntries())) + for i, e := range s.GetEntries() { + + entries[i] = nav.createChild(e.GetValue()) + } + return entries +} + +func mapEntryFactory(nav *navigableExprImpl) []NavigableExpr { + s := nav.ToExpr().GetStructExpr() + entries := make([]NavigableExpr, len(s.GetEntries())*2) + j := 0 + for _, e := range s.GetEntries() { + entries[j] = nav.createChild(e.GetMapKey()) + entries[j+1] = nav.createChild(e.GetValue()) + j += 2 + } + return entries +} + +func comprehensionFactory(nav *navigableExprImpl) []NavigableExpr { + compre := nav.ToExpr().GetComprehensionExpr() + return []NavigableExpr{ + nav.createChild(compre.GetIterRange()), + nav.createChild(compre.GetAccuInit()), + nav.createChild(compre.GetLoopCondition()), + nav.createChild(compre.GetLoopStep()), + nav.createChild(compre.GetResult()), + } +} diff --git a/vendor/github.com/google/cel-go/common/containers/BUILD.bazel b/vendor/github.com/google/cel-go/common/containers/BUILD.bazel index 18142d94e..3f3f07887 100644 --- a/vendor/github.com/google/cel-go/common/containers/BUILD.bazel +++ b/vendor/github.com/google/cel-go/common/containers/BUILD.bazel @@ -12,7 +12,7 @@ go_library( ], importpath = "github.com/google/cel-go/common/containers", deps = [ - "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", ], ) @@ -26,6 +26,6 @@ go_test( ":go_default_library", ], deps = [ - "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/common/debug/BUILD.bazel b/vendor/github.com/google/cel-go/common/debug/BUILD.bazel index cf5c5d246..1f029839c 100644 --- a/vendor/github.com/google/cel-go/common/debug/BUILD.bazel +++ b/vendor/github.com/google/cel-go/common/debug/BUILD.bazel @@ -13,6 +13,6 @@ go_library( importpath = "github.com/google/cel-go/common/debug", deps = [ "//common:go_default_library", - "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/common/decls/BUILD.bazel b/vendor/github.com/google/cel-go/common/decls/BUILD.bazel new file mode 100644 index 000000000..17791dce6 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/decls/BUILD.bazel @@ -0,0 +1,39 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +package( + default_visibility = ["//visibility:public"], + licenses = ["notice"], # Apache 2.0 +) + +go_library( + name = "go_default_library", + srcs = [ + "decls.go", + ], + importpath = "github.com/google/cel-go/common/decls", + deps = [ + "//checker/decls:go_default_library", + "//common/functions:go_default_library", + "//common/types:go_default_library", + "//common/types/ref:go_default_library", + "//common/types/traits:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = [ + "decls_test.go", + ], + embed = [":go_default_library"], + deps = [ + "//checker/decls:go_default_library", + "//common/overloads:go_default_library", + "//common/types:go_default_library", + "//common/types/ref:go_default_library", + "//common/types/traits:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", + "@org_golang_google_protobuf//proto:go_default_library", + ], +) diff --git a/vendor/github.com/google/cel-go/common/decls/decls.go b/vendor/github.com/google/cel-go/common/decls/decls.go new file mode 100644 index 000000000..734ebe57e --- /dev/null +++ b/vendor/github.com/google/cel-go/common/decls/decls.go @@ -0,0 +1,844 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package decls contains function and variable declaration structs and helper methods. +package decls + +import ( + "fmt" + "strings" + + chkdecls "github.com/google/cel-go/checker/decls" + "github.com/google/cel-go/common/functions" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// NewFunction creates a new function declaration with a set of function options to configure overloads +// and function definitions (implementations). +// +// Functions are checked for name collisions and singleton redefinition. +func NewFunction(name string, opts ...FunctionOpt) (*FunctionDecl, error) { + fn := &FunctionDecl{ + name: name, + overloads: map[string]*OverloadDecl{}, + overloadOrdinals: []string{}, + } + var err error + for _, opt := range opts { + fn, err = opt(fn) + if err != nil { + return nil, err + } + } + if len(fn.overloads) == 0 { + return nil, fmt.Errorf("function %s must have at least one overload", name) + } + return fn, nil +} + +// FunctionDecl defines a function name, overload set, and optionally a singleton definition for all +// overload instances. +type FunctionDecl struct { + name string + + // overloads associated with the function name. + overloads map[string]*OverloadDecl + + // singleton implementation of the function for all overloads. + // + // If this option is set, an error will occur if any overloads specify a per-overload implementation + // or if another function with the same name attempts to redefine the singleton. + singleton *functions.Overload + + // disableTypeGuards is a performance optimization to disable detailed runtime type checks which could + // add overhead on common operations. Setting this option true leaves error checks and argument checks + // intact. + disableTypeGuards bool + + // state indicates that the binding should be provided as a declaration, as a runtime binding, or both. + state declarationState + + // overloadOrdinals indicates the order in which the overload was declared. + overloadOrdinals []string +} + +type declarationState int + +const ( + declarationStateUnset declarationState = iota + declarationDisabled + declarationEnabled +) + +// Name returns the function name in human-readable terms, e.g. 'contains' of 'math.least' +func (f *FunctionDecl) Name() string { + if f == nil { + return "" + } + return f.name +} + +// IsDeclarationDisabled indicates that the function implementation should be added to the dispatcher, but the +// declaration should not be exposed for use in expressions. +func (f *FunctionDecl) IsDeclarationDisabled() bool { + return f.state == declarationDisabled +} + +// Merge combines an existing function declaration with another. +// +// If a function is extended, by say adding new overloads to an existing function, then it is merged with the +// prior definition of the function at which point its overloads must not collide with pre-existing overloads +// and its bindings (singleton, or per-overload) must not conflict with previous definitions either. +func (f *FunctionDecl) Merge(other *FunctionDecl) (*FunctionDecl, error) { + if f == other { + return f, nil + } + if f.Name() != other.Name() { + return nil, fmt.Errorf("cannot merge unrelated functions. %s and %s", f.Name(), other.Name()) + } + merged := &FunctionDecl{ + name: f.Name(), + overloads: make(map[string]*OverloadDecl, len(f.overloads)), + singleton: f.singleton, + overloadOrdinals: make([]string, len(f.overloads)), + // if one function is expecting type-guards and the other is not, then they + // must not be disabled. + disableTypeGuards: f.disableTypeGuards && other.disableTypeGuards, + // default to the current functions declaration state. + state: f.state, + } + // If the other state indicates that the declaration should be explicitly enabled or + // disabled, then update the merged state with the most recent value. + if other.state != declarationStateUnset { + merged.state = other.state + } + // baseline copy of the overloads and their ordinals + copy(merged.overloadOrdinals, f.overloadOrdinals) + for oID, o := range f.overloads { + merged.overloads[oID] = o + } + // overloads and their ordinals are added from the left + for _, oID := range other.overloadOrdinals { + o := other.overloads[oID] + err := merged.AddOverload(o) + if err != nil { + return nil, fmt.Errorf("function declaration merge failed: %v", err) + } + } + if other.singleton != nil { + if merged.singleton != nil && merged.singleton != other.singleton { + return nil, fmt.Errorf("function already has a singleton binding: %s", f.Name()) + } + merged.singleton = other.singleton + } + return merged, nil +} + +// AddOverload ensures that the new overload does not collide with an existing overload signature; +// however, if the function signatures are identical, the implementation may be rewritten as its +// difficult to compare functions by object identity. +func (f *FunctionDecl) AddOverload(overload *OverloadDecl) error { + if f == nil { + return fmt.Errorf("nil function cannot add overload: %s", overload.ID()) + } + for oID, o := range f.overloads { + if oID != overload.ID() && o.SignatureOverlaps(overload) { + return fmt.Errorf("overload signature collision in function %s: %s collides with %s", f.Name(), oID, overload.ID()) + } + if oID == overload.ID() { + if o.SignatureEquals(overload) && o.IsNonStrict() == overload.IsNonStrict() { + // Allow redefinition of an overload implementation so long as the signatures match. + f.overloads[oID] = overload + return nil + } + return fmt.Errorf("overload redefinition in function. %s: %s has multiple definitions", f.Name(), oID) + } + } + f.overloadOrdinals = append(f.overloadOrdinals, overload.ID()) + f.overloads[overload.ID()] = overload + return nil +} + +// OverloadDecls returns the overload declarations in the order in which they were declared. +func (f *FunctionDecl) OverloadDecls() []*OverloadDecl { + if f == nil { + return []*OverloadDecl{} + } + overloads := make([]*OverloadDecl, 0, len(f.overloads)) + for _, oID := range f.overloadOrdinals { + overloads = append(overloads, f.overloads[oID]) + } + return overloads +} + +// Bindings produces a set of function bindings, if any are defined. +func (f *FunctionDecl) Bindings() ([]*functions.Overload, error) { + if f == nil { + return []*functions.Overload{}, nil + } + overloads := []*functions.Overload{} + nonStrict := false + for _, oID := range f.overloadOrdinals { + o := f.overloads[oID] + if o.hasBinding() { + overload := &functions.Overload{ + Operator: o.ID(), + Unary: o.guardedUnaryOp(f.Name(), f.disableTypeGuards), + Binary: o.guardedBinaryOp(f.Name(), f.disableTypeGuards), + Function: o.guardedFunctionOp(f.Name(), f.disableTypeGuards), + OperandTrait: o.OperandTrait(), + NonStrict: o.IsNonStrict(), + } + overloads = append(overloads, overload) + nonStrict = nonStrict || o.IsNonStrict() + } + } + if f.singleton != nil { + if len(overloads) != 0 { + return nil, fmt.Errorf("singleton function incompatible with specialized overloads: %s", f.Name()) + } + overloads = []*functions.Overload{ + { + Operator: f.Name(), + Unary: f.singleton.Unary, + Binary: f.singleton.Binary, + Function: f.singleton.Function, + OperandTrait: f.singleton.OperandTrait, + }, + } + // fall-through to return single overload case. + } + if len(overloads) == 0 { + return overloads, nil + } + // Single overload. Replicate an entry for it using the function name as well. + if len(overloads) == 1 { + if overloads[0].Operator == f.Name() { + return overloads, nil + } + return append(overloads, &functions.Overload{ + Operator: f.Name(), + Unary: overloads[0].Unary, + Binary: overloads[0].Binary, + Function: overloads[0].Function, + NonStrict: overloads[0].NonStrict, + OperandTrait: overloads[0].OperandTrait, + }), nil + } + // All of the defined overloads are wrapped into a top-level function which + // performs dynamic dispatch to the proper overload based on the argument types. + bindings := append([]*functions.Overload{}, overloads...) + funcDispatch := func(args ...ref.Val) ref.Val { + for _, oID := range f.overloadOrdinals { + o := f.overloads[oID] + // During dynamic dispatch over multiple functions, signature agreement checks + // are preserved in order to assist with the function resolution step. + switch len(args) { + case 1: + if o.unaryOp != nil && o.matchesRuntimeSignature( /* disableTypeGuards=*/ false, args...) { + return o.unaryOp(args[0]) + } + case 2: + if o.binaryOp != nil && o.matchesRuntimeSignature( /* disableTypeGuards=*/ false, args...) { + return o.binaryOp(args[0], args[1]) + } + } + if o.functionOp != nil && o.matchesRuntimeSignature( /* disableTypeGuards=*/ false, args...) { + return o.functionOp(args...) + } + // eventually this will fall through to the noSuchOverload below. + } + return MaybeNoSuchOverload(f.Name(), args...) + } + function := &functions.Overload{ + Operator: f.Name(), + Function: funcDispatch, + NonStrict: nonStrict, + } + return append(bindings, function), nil +} + +// MaybeNoSuchOverload determines whether to propagate an error if one is provided as an argument, or +// to return an unknown set, or to produce a new error for a missing function signature. +func MaybeNoSuchOverload(funcName string, args ...ref.Val) ref.Val { + argTypes := make([]string, len(args)) + var unk *types.Unknown = nil + for i, arg := range args { + if types.IsError(arg) { + return arg + } + if types.IsUnknown(arg) { + unk = types.MergeUnknowns(arg.(*types.Unknown), unk) + } + argTypes[i] = arg.Type().TypeName() + } + if unk != nil { + return unk + } + signature := strings.Join(argTypes, ", ") + return types.NewErr("no such overload: %s(%s)", funcName, signature) +} + +// FunctionOpt defines a functional option for mutating a function declaration. +type FunctionOpt func(*FunctionDecl) (*FunctionDecl, error) + +// DisableTypeGuards disables automatically generated function invocation guards on direct overload calls. +// Type guards remain on during dynamic dispatch for parsed-only expressions. +func DisableTypeGuards(value bool) FunctionOpt { + return func(fn *FunctionDecl) (*FunctionDecl, error) { + fn.disableTypeGuards = value + return fn, nil + } +} + +// DisableDeclaration indicates that the function declaration should be disabled, but the runtime function +// binding should be provided. Marking a function as runtime-only is a safe way to manage deprecations +// of function declarations while still preserving the runtime behavior for previously compiled expressions. +func DisableDeclaration(value bool) FunctionOpt { + return func(fn *FunctionDecl) (*FunctionDecl, error) { + if value { + fn.state = declarationDisabled + } else { + fn.state = declarationEnabled + } + return fn, nil + } +} + +// SingletonUnaryBinding creates a singleton function definition to be used for all function overloads. +// +// Note, this approach works well if operand is expected to have a specific trait which it implements, +// e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings. +func SingletonUnaryBinding(fn functions.UnaryOp, traits ...int) FunctionOpt { + trait := 0 + for _, t := range traits { + trait = trait | t + } + return func(f *FunctionDecl) (*FunctionDecl, error) { + if f.singleton != nil { + return nil, fmt.Errorf("function already has a singleton binding: %s", f.Name()) + } + f.singleton = &functions.Overload{ + Operator: f.Name(), + Unary: fn, + OperandTrait: trait, + } + return f, nil + } +} + +// SingletonBinaryBinding creates a singleton function definition to be used with all function overloads. +// +// Note, this approach works well if operand is expected to have a specific trait which it implements, +// e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings. +func SingletonBinaryBinding(fn functions.BinaryOp, traits ...int) FunctionOpt { + trait := 0 + for _, t := range traits { + trait = trait | t + } + return func(f *FunctionDecl) (*FunctionDecl, error) { + if f.singleton != nil { + return nil, fmt.Errorf("function already has a singleton binding: %s", f.Name()) + } + f.singleton = &functions.Overload{ + Operator: f.Name(), + Binary: fn, + OperandTrait: trait, + } + return f, nil + } +} + +// SingletonFunctionBinding creates a singleton function definition to be used with all function overloads. +// +// Note, this approach works well if operand is expected to have a specific trait which it implements, +// e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings. +func SingletonFunctionBinding(fn functions.FunctionOp, traits ...int) FunctionOpt { + trait := 0 + for _, t := range traits { + trait = trait | t + } + return func(f *FunctionDecl) (*FunctionDecl, error) { + if f.singleton != nil { + return nil, fmt.Errorf("function already has a singleton binding: %s", f.Name()) + } + f.singleton = &functions.Overload{ + Operator: f.Name(), + Function: fn, + OperandTrait: trait, + } + return f, nil + } +} + +// Overload defines a new global overload with an overload id, argument types, and result type. Through the +// use of OverloadOpt options, the overload may also be configured with a binding, an operand trait, and to +// be non-strict. +// +// Note: function bindings should be commonly configured with Overload instances whereas operand traits and +// strict-ness should be rare occurrences. +func Overload(overloadID string, + args []*types.Type, resultType *types.Type, + opts ...OverloadOpt) FunctionOpt { + return newOverload(overloadID, false, args, resultType, opts...) +} + +// MemberOverload defines a new receiver-style overload (or member function) with an overload id, argument types, +// and result type. Through the use of OverloadOpt options, the overload may also be configured with a binding, +// an operand trait, and to be non-strict. +// +// Note: function bindings should be commonly configured with Overload instances whereas operand traits and +// strict-ness should be rare occurrences. +func MemberOverload(overloadID string, + args []*types.Type, resultType *types.Type, + opts ...OverloadOpt) FunctionOpt { + return newOverload(overloadID, true, args, resultType, opts...) +} + +func newOverload(overloadID string, + memberFunction bool, args []*types.Type, resultType *types.Type, + opts ...OverloadOpt) FunctionOpt { + return func(f *FunctionDecl) (*FunctionDecl, error) { + overload, err := newOverloadInternal(overloadID, memberFunction, args, resultType, opts...) + if err != nil { + return nil, err + } + err = f.AddOverload(overload) + if err != nil { + return nil, err + } + return f, nil + } +} + +func newOverloadInternal(overloadID string, + memberFunction bool, args []*types.Type, resultType *types.Type, + opts ...OverloadOpt) (*OverloadDecl, error) { + overload := &OverloadDecl{ + id: overloadID, + argTypes: args, + resultType: resultType, + isMemberFunction: memberFunction, + } + var err error + for _, opt := range opts { + overload, err = opt(overload) + if err != nil { + return nil, err + } + } + return overload, nil +} + +// OverloadDecl contains the definition of a single overload id with a specific signature, and an optional +// implementation. +type OverloadDecl struct { + id string + argTypes []*types.Type + resultType *types.Type + isMemberFunction bool + // nonStrict indicates that the function will accept error and unknown arguments as inputs. + nonStrict bool + // operandTrait indicates whether the member argument should have a specific type-trait. + // + // This is useful for creating overloads which operate on a type-interface rather than a concrete type. + operandTrait int + + // Function implementation options. Optional, but encouraged. + // unaryOp is a function binding that takes a single argument. + unaryOp functions.UnaryOp + // binaryOp is a function binding that takes two arguments. + binaryOp functions.BinaryOp + // functionOp is a catch-all for zero-arity and three-plus arity functions. + functionOp functions.FunctionOp +} + +// ID mirrors the overload signature and provides a unique id which may be referenced within the type-checker +// and interpreter to optimize performance. +// +// The ID format is usually one of two styles: +// global: __ +// member: ___ +func (o *OverloadDecl) ID() string { + if o == nil { + return "" + } + return o.id +} + +// ArgTypes contains the set of argument types expected by the overload. +// +// For member functions ArgTypes[0] represents the member operand type. +func (o *OverloadDecl) ArgTypes() []*types.Type { + if o == nil { + return emptyArgs + } + return o.argTypes +} + +// IsMemberFunction indicates whether the overload is a member function +func (o *OverloadDecl) IsMemberFunction() bool { + if o == nil { + return false + } + return o.isMemberFunction +} + +// IsNonStrict returns whether the overload accepts errors and unknown values as arguments. +func (o *OverloadDecl) IsNonStrict() bool { + if o == nil { + return false + } + return o.nonStrict +} + +// OperandTrait returns the trait mask of the first operand to the overload call, e.g. +// `traits.Indexer` +func (o *OverloadDecl) OperandTrait() int { + if o == nil { + return 0 + } + return o.operandTrait +} + +// ResultType indicates the output type from calling the function. +func (o *OverloadDecl) ResultType() *types.Type { + if o == nil { + // *types.Type is nil-safe + return nil + } + return o.resultType +} + +// TypeParams returns the type parameter names associated with the overload. +func (o *OverloadDecl) TypeParams() []string { + typeParams := map[string]struct{}{} + collectParamNames(typeParams, o.ResultType()) + for _, arg := range o.ArgTypes() { + collectParamNames(typeParams, arg) + } + params := make([]string, 0, len(typeParams)) + for param := range typeParams { + params = append(params, param) + } + return params +} + +// SignatureEquals determines whether the incoming overload declaration signature is equal to the current signature. +// +// Result type, operand trait, and strict-ness are not considered as part of signature equality. +func (o *OverloadDecl) SignatureEquals(other *OverloadDecl) bool { + if o == other { + return true + } + if o.ID() != other.ID() || o.IsMemberFunction() != other.IsMemberFunction() || len(o.ArgTypes()) != len(other.ArgTypes()) { + return false + } + for i, at := range o.ArgTypes() { + oat := other.ArgTypes()[i] + if !at.IsEquivalentType(oat) { + return false + } + } + return o.ResultType().IsEquivalentType(other.ResultType()) +} + +// SignatureOverlaps indicates whether two functions have non-equal, but overloapping function signatures. +// +// For example, list(dyn) collides with list(string) since the 'dyn' type can contain a 'string' type. +func (o *OverloadDecl) SignatureOverlaps(other *OverloadDecl) bool { + if o.IsMemberFunction() != other.IsMemberFunction() || len(o.ArgTypes()) != len(other.ArgTypes()) { + return false + } + argsOverlap := true + for i, argType := range o.ArgTypes() { + otherArgType := other.ArgTypes()[i] + argsOverlap = argsOverlap && + (argType.IsAssignableType(otherArgType) || + otherArgType.IsAssignableType(argType)) + } + return argsOverlap +} + +// hasBinding indicates whether the overload already has a definition. +func (o *OverloadDecl) hasBinding() bool { + return o != nil && (o.unaryOp != nil || o.binaryOp != nil || o.functionOp != nil) +} + +// guardedUnaryOp creates an invocation guard around the provided unary operator, if one is defined. +func (o *OverloadDecl) guardedUnaryOp(funcName string, disableTypeGuards bool) functions.UnaryOp { + if o.unaryOp == nil { + return nil + } + return func(arg ref.Val) ref.Val { + if !o.matchesRuntimeUnarySignature(disableTypeGuards, arg) { + return MaybeNoSuchOverload(funcName, arg) + } + return o.unaryOp(arg) + } +} + +// guardedBinaryOp creates an invocation guard around the provided binary operator, if one is defined. +func (o *OverloadDecl) guardedBinaryOp(funcName string, disableTypeGuards bool) functions.BinaryOp { + if o.binaryOp == nil { + return nil + } + return func(arg1, arg2 ref.Val) ref.Val { + if !o.matchesRuntimeBinarySignature(disableTypeGuards, arg1, arg2) { + return MaybeNoSuchOverload(funcName, arg1, arg2) + } + return o.binaryOp(arg1, arg2) + } +} + +// guardedFunctionOp creates an invocation guard around the provided variadic function binding, if one is provided. +func (o *OverloadDecl) guardedFunctionOp(funcName string, disableTypeGuards bool) functions.FunctionOp { + if o.functionOp == nil { + return nil + } + return func(args ...ref.Val) ref.Val { + if !o.matchesRuntimeSignature(disableTypeGuards, args...) { + return MaybeNoSuchOverload(funcName, args...) + } + return o.functionOp(args...) + } +} + +// matchesRuntimeUnarySignature indicates whether the argument type is runtime assiganble to the overload's expected argument. +func (o *OverloadDecl) matchesRuntimeUnarySignature(disableTypeGuards bool, arg ref.Val) bool { + return matchRuntimeArgType(o.IsNonStrict(), disableTypeGuards, o.ArgTypes()[0], arg) && + matchOperandTrait(o.OperandTrait(), arg) +} + +// matchesRuntimeBinarySignature indicates whether the argument types are runtime assiganble to the overload's expected arguments. +func (o *OverloadDecl) matchesRuntimeBinarySignature(disableTypeGuards bool, arg1, arg2 ref.Val) bool { + return matchRuntimeArgType(o.IsNonStrict(), disableTypeGuards, o.ArgTypes()[0], arg1) && + matchRuntimeArgType(o.IsNonStrict(), disableTypeGuards, o.ArgTypes()[1], arg2) && + matchOperandTrait(o.OperandTrait(), arg1) +} + +// matchesRuntimeSignature indicates whether the argument types are runtime assiganble to the overload's expected arguments. +func (o *OverloadDecl) matchesRuntimeSignature(disableTypeGuards bool, args ...ref.Val) bool { + if len(args) != len(o.ArgTypes()) { + return false + } + if len(args) == 0 { + return true + } + for i, arg := range args { + if !matchRuntimeArgType(o.IsNonStrict(), disableTypeGuards, o.ArgTypes()[i], arg) { + return false + } + } + return matchOperandTrait(o.OperandTrait(), args[0]) +} + +func matchRuntimeArgType(nonStrict, disableTypeGuards bool, argType *types.Type, arg ref.Val) bool { + if nonStrict && (disableTypeGuards || types.IsUnknownOrError(arg)) { + return true + } + if types.IsUnknownOrError(arg) { + return false + } + return disableTypeGuards || argType.IsAssignableRuntimeType(arg) +} + +func matchOperandTrait(trait int, arg ref.Val) bool { + return trait == 0 || arg.Type().HasTrait(trait) || types.IsUnknownOrError(arg) +} + +// OverloadOpt is a functional option for configuring a function overload. +type OverloadOpt func(*OverloadDecl) (*OverloadDecl, error) + +// UnaryBinding provides the implementation of a unary overload. The provided function is protected by a runtime +// type-guard which ensures runtime type agreement between the overload signature and runtime argument types. +func UnaryBinding(binding functions.UnaryOp) OverloadOpt { + return func(o *OverloadDecl) (*OverloadDecl, error) { + if o.hasBinding() { + return nil, fmt.Errorf("overload already has a binding: %s", o.ID()) + } + if len(o.ArgTypes()) != 1 { + return nil, fmt.Errorf("unary function bound to non-unary overload: %s", o.ID()) + } + o.unaryOp = binding + return o, nil + } +} + +// BinaryBinding provides the implementation of a binary overload. The provided function is protected by a runtime +// type-guard which ensures runtime type agreement between the overload signature and runtime argument types. +func BinaryBinding(binding functions.BinaryOp) OverloadOpt { + return func(o *OverloadDecl) (*OverloadDecl, error) { + if o.hasBinding() { + return nil, fmt.Errorf("overload already has a binding: %s", o.ID()) + } + if len(o.ArgTypes()) != 2 { + return nil, fmt.Errorf("binary function bound to non-binary overload: %s", o.ID()) + } + o.binaryOp = binding + return o, nil + } +} + +// FunctionBinding provides the implementation of a variadic overload. The provided function is protected by a runtime +// type-guard which ensures runtime type agreement between the overload signature and runtime argument types. +func FunctionBinding(binding functions.FunctionOp) OverloadOpt { + return func(o *OverloadDecl) (*OverloadDecl, error) { + if o.hasBinding() { + return nil, fmt.Errorf("overload already has a binding: %s", o.ID()) + } + o.functionOp = binding + return o, nil + } +} + +// OverloadIsNonStrict enables the function to be called with error and unknown argument values. +// +// Note: do not use this option unless absoluately necessary as it should be an uncommon feature. +func OverloadIsNonStrict() OverloadOpt { + return func(o *OverloadDecl) (*OverloadDecl, error) { + o.nonStrict = true + return o, nil + } +} + +// OverloadOperandTrait configures a set of traits which the first argument to the overload must implement in order to be +// successfully invoked. +func OverloadOperandTrait(trait int) OverloadOpt { + return func(o *OverloadDecl) (*OverloadDecl, error) { + o.operandTrait = trait + return o, nil + } +} + +// NewConstant creates a new constant declaration. +func NewConstant(name string, t *types.Type, v ref.Val) *VariableDecl { + return &VariableDecl{name: name, varType: t, value: v} +} + +// NewVariable creates a new variable declaration. +func NewVariable(name string, t *types.Type) *VariableDecl { + return &VariableDecl{name: name, varType: t} +} + +// VariableDecl defines a variable declaration which may optionally have a constant value. +type VariableDecl struct { + name string + varType *types.Type + value ref.Val +} + +// Name returns the fully-qualified variable name +func (v *VariableDecl) Name() string { + if v == nil { + return "" + } + return v.name +} + +// Type returns the types.Type value associated with the variable. +func (v *VariableDecl) Type() *types.Type { + if v == nil { + // types.Type is nil-safe + return nil + } + return v.varType +} + +// Value returns the constant value associated with the declaration. +func (v *VariableDecl) Value() ref.Val { + if v == nil { + return nil + } + return v.value +} + +// DeclarationIsEquivalent returns true if one variable declaration has the same name and same type as the input. +func (v *VariableDecl) DeclarationIsEquivalent(other *VariableDecl) bool { + if v == other { + return true + } + return v.Name() == other.Name() && v.Type().IsEquivalentType(other.Type()) +} + +// VariableDeclToExprDecl converts a go-native variable declaration into a protobuf-type variable declaration. +func VariableDeclToExprDecl(v *VariableDecl) (*exprpb.Decl, error) { + varType, err := types.TypeToExprType(v.Type()) + if err != nil { + return nil, err + } + return chkdecls.NewVar(v.Name(), varType), nil +} + +// TypeVariable creates a new type identifier for use within a types.Provider +func TypeVariable(t *types.Type) *VariableDecl { + return NewVariable(t.TypeName(), types.NewTypeTypeWithParam(t)) +} + +// FunctionDeclToExprDecl converts a go-native function declaration into a protobuf-typed function declaration. +func FunctionDeclToExprDecl(f *FunctionDecl) (*exprpb.Decl, error) { + overloads := make([]*exprpb.Decl_FunctionDecl_Overload, len(f.overloads)) + for i, oID := range f.overloadOrdinals { + o := f.overloads[oID] + paramNames := map[string]struct{}{} + argTypes := make([]*exprpb.Type, len(o.ArgTypes())) + for j, a := range o.ArgTypes() { + collectParamNames(paramNames, a) + at, err := types.TypeToExprType(a) + if err != nil { + return nil, err + } + argTypes[j] = at + } + collectParamNames(paramNames, o.ResultType()) + resultType, err := types.TypeToExprType(o.ResultType()) + if err != nil { + return nil, err + } + if len(paramNames) == 0 { + if o.IsMemberFunction() { + overloads[i] = chkdecls.NewInstanceOverload(oID, argTypes, resultType) + } else { + overloads[i] = chkdecls.NewOverload(oID, argTypes, resultType) + } + } else { + params := []string{} + for pn := range paramNames { + params = append(params, pn) + } + if o.IsMemberFunction() { + overloads[i] = chkdecls.NewParameterizedInstanceOverload(oID, argTypes, resultType, params) + } else { + overloads[i] = chkdecls.NewParameterizedOverload(oID, argTypes, resultType, params) + } + } + } + return chkdecls.NewFunction(f.Name(), overloads...), nil +} + +func collectParamNames(paramNames map[string]struct{}, arg *types.Type) { + if arg.Kind() == types.TypeParamKind { + paramNames[arg.TypeName()] = struct{}{} + } + for _, param := range arg.Parameters() { + collectParamNames(paramNames, param) + } +} + +var ( + emptyArgs = []*types.Type{} +) diff --git a/vendor/github.com/google/cel-go/common/error.go b/vendor/github.com/google/cel-go/common/error.go index f91f7f8d1..774dcb5b4 100644 --- a/vendor/github.com/google/cel-go/common/error.go +++ b/vendor/github.com/google/cel-go/common/error.go @@ -22,10 +22,16 @@ import ( "golang.org/x/text/width" ) -// Error type which references a location within source and a message. +// NewError creates an error associated with an expression id with the given message at the given location. +func NewError(id int64, message string, location Location) *Error { + return &Error{Message: message, Location: location, ExprID: id} +} + +// Error type which references an expression id, a location within source, and a message. type Error struct { Location Location Message string + ExprID int64 } const ( diff --git a/vendor/github.com/google/cel-go/common/errors.go b/vendor/github.com/google/cel-go/common/errors.go index 1565085ab..63919714e 100644 --- a/vendor/github.com/google/cel-go/common/errors.go +++ b/vendor/github.com/google/cel-go/common/errors.go @@ -22,7 +22,7 @@ import ( // Errors type which contains a list of errors observed during parsing. type Errors struct { - errors []Error + errors []*Error source Source numErrors int maxErrorsToReport int @@ -31,7 +31,7 @@ type Errors struct { // NewErrors creates a new instance of the Errors type. func NewErrors(source Source) *Errors { return &Errors{ - errors: []Error{}, + errors: []*Error{}, source: source, maxErrorsToReport: 100, } @@ -39,11 +39,17 @@ func NewErrors(source Source) *Errors { // ReportError records an error at a source location. func (e *Errors) ReportError(l Location, format string, args ...any) { + e.ReportErrorAtID(0, l, format, args...) +} + +// ReportErrorAtID records an error at a source location and expression id. +func (e *Errors) ReportErrorAtID(id int64, l Location, format string, args ...any) { e.numErrors++ if e.numErrors > e.maxErrorsToReport { return } - err := Error{ + err := &Error{ + ExprID: id, Location: l, Message: fmt.Sprintf(format, args...), } @@ -51,12 +57,12 @@ func (e *Errors) ReportError(l Location, format string, args ...any) { } // GetErrors returns the list of observed errors. -func (e *Errors) GetErrors() []Error { +func (e *Errors) GetErrors() []*Error { return e.errors[:] } // Append creates a new Errors object with the current and input errors. -func (e *Errors) Append(errs []Error) *Errors { +func (e *Errors) Append(errs []*Error) *Errors { return &Errors{ errors: append(e.errors, errs...), source: e.source, diff --git a/vendor/github.com/google/cel-go/common/functions/BUILD.bazel b/vendor/github.com/google/cel-go/common/functions/BUILD.bazel new file mode 100644 index 000000000..3cc27d60c --- /dev/null +++ b/vendor/github.com/google/cel-go/common/functions/BUILD.bazel @@ -0,0 +1,17 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +package( + default_visibility = ["//visibility:public"], + licenses = ["notice"], # Apache 2.0 +) + +go_library( + name = "go_default_library", + srcs = [ + "functions.go", + ], + importpath = "github.com/google/cel-go/common/functions", + deps = [ + "//common/types/ref:go_default_library", + ], +) diff --git a/vendor/github.com/google/cel-go/interpreter/functions/functions.go b/vendor/github.com/google/cel-go/common/functions/functions.go similarity index 95% rename from vendor/github.com/google/cel-go/interpreter/functions/functions.go rename to vendor/github.com/google/cel-go/common/functions/functions.go index 981601752..67f4a5944 100644 --- a/vendor/github.com/google/cel-go/interpreter/functions/functions.go +++ b/vendor/github.com/google/cel-go/common/functions/functions.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,8 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package functions defines the standard builtin functions supported by the -// interpreter and as declared within the checker#StandardDeclarations. +// Package functions defines the standard builtin functions supported by the interpreter package functions import "github.com/google/cel-go/common/types/ref" diff --git a/vendor/github.com/google/cel-go/common/overloads/overloads.go b/vendor/github.com/google/cel-go/common/overloads/overloads.go index 9ebaf6fab..9d50f4367 100644 --- a/vendor/github.com/google/cel-go/common/overloads/overloads.go +++ b/vendor/github.com/google/cel-go/common/overloads/overloads.go @@ -148,6 +148,11 @@ const ( StartsWith = "startsWith" ) +// Extension function overloads with complex behaviors that need to be referenced in runtime and static analysis cost computations. +const ( + ExtQuoteString = "strings_quote" +) + // String function overload names. const ( ContainsString = "contains_string" @@ -156,6 +161,11 @@ const ( StartsWithString = "starts_with_string" ) +// Extension function overloads with complex behaviors that need to be referenced in runtime and static analysis cost computations. +const ( + ExtFormatString = "string_format" +) + // Time-based functions. const ( TimeGetFullYear = "getFullYear" diff --git a/vendor/github.com/google/cel-go/common/source.go b/vendor/github.com/google/cel-go/common/source.go index 52377d930..acf22bdf1 100644 --- a/vendor/github.com/google/cel-go/common/source.go +++ b/vendor/github.com/google/cel-go/common/source.go @@ -64,7 +64,6 @@ type sourceImpl struct { runes.Buffer description string lineOffsets []int32 - idOffsets map[int64]int32 } var _ runes.Buffer = &sourceImpl{} @@ -92,7 +91,6 @@ func NewStringSource(contents string, description string) Source { Buffer: runes.NewBuffer(contents), description: description, lineOffsets: offsets, - idOffsets: map[int64]int32{}, } } @@ -102,7 +100,6 @@ func NewInfoSource(info *exprpb.SourceInfo) Source { Buffer: runes.NewBuffer(""), description: info.GetLocation(), lineOffsets: info.GetLineOffsets(), - idOffsets: info.GetPositions(), } } diff --git a/vendor/github.com/google/cel-go/interpreter/functions/BUILD.bazel b/vendor/github.com/google/cel-go/common/stdlib/BUILD.bazel similarity index 56% rename from vendor/github.com/google/cel-go/interpreter/functions/BUILD.bazel rename to vendor/github.com/google/cel-go/common/stdlib/BUILD.bazel index 846d11bf4..c130a93f6 100644 --- a/vendor/github.com/google/cel-go/interpreter/functions/BUILD.bazel +++ b/vendor/github.com/google/cel-go/common/stdlib/BUILD.bazel @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") package( default_visibility = ["//visibility:public"], @@ -8,15 +8,18 @@ package( go_library( name = "go_default_library", srcs = [ - "functions.go", "standard.go", ], - importpath = "github.com/google/cel-go/interpreter/functions", + importpath = "github.com/google/cel-go/common/stdlib", deps = [ + "//checker/decls:go_default_library", + "//common/decls:go_default_library", + "//common/functions:go_default_library", "//common/operators:go_default_library", "//common/overloads:go_default_library", "//common/types:go_default_library", "//common/types/ref:go_default_library", "//common/types/traits:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", ], -) +) \ No newline at end of file diff --git a/vendor/github.com/google/cel-go/common/stdlib/standard.go b/vendor/github.com/google/cel-go/common/stdlib/standard.go new file mode 100644 index 000000000..d02cb64bf --- /dev/null +++ b/vendor/github.com/google/cel-go/common/stdlib/standard.go @@ -0,0 +1,661 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package stdlib contains all of the standard library function declarations and definitions for CEL. +package stdlib + +import ( + "github.com/google/cel-go/common/decls" + "github.com/google/cel-go/common/functions" + "github.com/google/cel-go/common/operators" + "github.com/google/cel-go/common/overloads" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +var ( + stdFunctions []*decls.FunctionDecl + stdFnDecls []*exprpb.Decl + stdTypes []*decls.VariableDecl + stdTypeDecls []*exprpb.Decl +) + +func init() { + paramA := types.NewTypeParamType("A") + paramB := types.NewTypeParamType("B") + listOfA := types.NewListType(paramA) + mapOfAB := types.NewMapType(paramA, paramB) + + stdTypes = []*decls.VariableDecl{ + decls.TypeVariable(types.BoolType), + decls.TypeVariable(types.BytesType), + decls.TypeVariable(types.DoubleType), + decls.TypeVariable(types.DurationType), + decls.TypeVariable(types.IntType), + decls.TypeVariable(listOfA), + decls.TypeVariable(mapOfAB), + decls.TypeVariable(types.NullType), + decls.TypeVariable(types.StringType), + decls.TypeVariable(types.TimestampType), + decls.TypeVariable(types.TypeType), + decls.TypeVariable(types.UintType), + } + + stdTypeDecls = make([]*exprpb.Decl, 0, len(stdTypes)) + for _, stdType := range stdTypes { + typeVar, err := decls.VariableDeclToExprDecl(stdType) + if err != nil { + panic(err) + } + stdTypeDecls = append(stdTypeDecls, typeVar) + } + + stdFunctions = []*decls.FunctionDecl{ + // Logical operators. Special-cased within the interpreter. + // Note, the singleton binding prevents extensions from overriding the operator behavior. + function(operators.Conditional, + decls.Overload(overloads.Conditional, argTypes(types.BoolType, paramA, paramA), paramA, + decls.OverloadIsNonStrict()), + decls.SingletonFunctionBinding(noFunctionOverrides)), + function(operators.LogicalAnd, + decls.Overload(overloads.LogicalAnd, argTypes(types.BoolType, types.BoolType), types.BoolType, + decls.OverloadIsNonStrict()), + decls.SingletonBinaryBinding(noBinaryOverrides)), + function(operators.LogicalOr, + decls.Overload(overloads.LogicalOr, argTypes(types.BoolType, types.BoolType), types.BoolType, + decls.OverloadIsNonStrict()), + decls.SingletonBinaryBinding(noBinaryOverrides)), + function(operators.LogicalNot, + decls.Overload(overloads.LogicalNot, argTypes(types.BoolType), types.BoolType), + decls.SingletonUnaryBinding(func(val ref.Val) ref.Val { + b, ok := val.(types.Bool) + if !ok { + return types.MaybeNoSuchOverloadErr(val) + } + return b.Negate() + })), + + // Comprehension short-circuiting related function + function(operators.NotStrictlyFalse, + decls.Overload(overloads.NotStrictlyFalse, argTypes(types.BoolType), types.BoolType, + decls.OverloadIsNonStrict(), + decls.UnaryBinding(notStrictlyFalse))), + // Deprecated: __not_strictly_false__ + function(operators.OldNotStrictlyFalse, + decls.DisableDeclaration(true), // safe deprecation + decls.Overload(operators.OldNotStrictlyFalse, argTypes(types.BoolType), types.BoolType, + decls.OverloadIsNonStrict(), + decls.UnaryBinding(notStrictlyFalse))), + + // Equality / inequality. Special-cased in the interpreter + function(operators.Equals, + decls.Overload(overloads.Equals, argTypes(paramA, paramA), types.BoolType), + decls.SingletonBinaryBinding(noBinaryOverrides)), + function(operators.NotEquals, + decls.Overload(overloads.NotEquals, argTypes(paramA, paramA), types.BoolType), + decls.SingletonBinaryBinding(noBinaryOverrides)), + + // Mathematical operators + function(operators.Add, + decls.Overload(overloads.AddBytes, + argTypes(types.BytesType, types.BytesType), types.BytesType), + decls.Overload(overloads.AddDouble, + argTypes(types.DoubleType, types.DoubleType), types.DoubleType), + decls.Overload(overloads.AddDurationDuration, + argTypes(types.DurationType, types.DurationType), types.DurationType), + decls.Overload(overloads.AddDurationTimestamp, + argTypes(types.DurationType, types.TimestampType), types.TimestampType), + decls.Overload(overloads.AddTimestampDuration, + argTypes(types.TimestampType, types.DurationType), types.TimestampType), + decls.Overload(overloads.AddInt64, + argTypes(types.IntType, types.IntType), types.IntType), + decls.Overload(overloads.AddList, + argTypes(listOfA, listOfA), listOfA), + decls.Overload(overloads.AddString, + argTypes(types.StringType, types.StringType), types.StringType), + decls.Overload(overloads.AddUint64, + argTypes(types.UintType, types.UintType), types.UintType), + decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val { + return lhs.(traits.Adder).Add(rhs) + }, traits.AdderType)), + function(operators.Divide, + decls.Overload(overloads.DivideDouble, + argTypes(types.DoubleType, types.DoubleType), types.DoubleType), + decls.Overload(overloads.DivideInt64, + argTypes(types.IntType, types.IntType), types.IntType), + decls.Overload(overloads.DivideUint64, + argTypes(types.UintType, types.UintType), types.UintType), + decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val { + return lhs.(traits.Divider).Divide(rhs) + }, traits.DividerType)), + function(operators.Modulo, + decls.Overload(overloads.ModuloInt64, + argTypes(types.IntType, types.IntType), types.IntType), + decls.Overload(overloads.ModuloUint64, + argTypes(types.UintType, types.UintType), types.UintType), + decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val { + return lhs.(traits.Modder).Modulo(rhs) + }, traits.ModderType)), + function(operators.Multiply, + decls.Overload(overloads.MultiplyDouble, + argTypes(types.DoubleType, types.DoubleType), types.DoubleType), + decls.Overload(overloads.MultiplyInt64, + argTypes(types.IntType, types.IntType), types.IntType), + decls.Overload(overloads.MultiplyUint64, + argTypes(types.UintType, types.UintType), types.UintType), + decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val { + return lhs.(traits.Multiplier).Multiply(rhs) + }, traits.MultiplierType)), + function(operators.Negate, + decls.Overload(overloads.NegateDouble, argTypes(types.DoubleType), types.DoubleType), + decls.Overload(overloads.NegateInt64, argTypes(types.IntType), types.IntType), + decls.SingletonUnaryBinding(func(val ref.Val) ref.Val { + if types.IsBool(val) { + return types.MaybeNoSuchOverloadErr(val) + } + return val.(traits.Negater).Negate() + }, traits.NegatorType)), + function(operators.Subtract, + decls.Overload(overloads.SubtractDouble, + argTypes(types.DoubleType, types.DoubleType), types.DoubleType), + decls.Overload(overloads.SubtractDurationDuration, + argTypes(types.DurationType, types.DurationType), types.DurationType), + decls.Overload(overloads.SubtractInt64, + argTypes(types.IntType, types.IntType), types.IntType), + decls.Overload(overloads.SubtractTimestampDuration, + argTypes(types.TimestampType, types.DurationType), types.TimestampType), + decls.Overload(overloads.SubtractTimestampTimestamp, + argTypes(types.TimestampType, types.TimestampType), types.DurationType), + decls.Overload(overloads.SubtractUint64, + argTypes(types.UintType, types.UintType), types.UintType), + decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val { + return lhs.(traits.Subtractor).Subtract(rhs) + }, traits.SubtractorType)), + + // Relations operators + + function(operators.Less, + decls.Overload(overloads.LessBool, + argTypes(types.BoolType, types.BoolType), types.BoolType), + decls.Overload(overloads.LessInt64, + argTypes(types.IntType, types.IntType), types.BoolType), + decls.Overload(overloads.LessInt64Double, + argTypes(types.IntType, types.DoubleType), types.BoolType), + decls.Overload(overloads.LessInt64Uint64, + argTypes(types.IntType, types.UintType), types.BoolType), + decls.Overload(overloads.LessUint64, + argTypes(types.UintType, types.UintType), types.BoolType), + decls.Overload(overloads.LessUint64Double, + argTypes(types.UintType, types.DoubleType), types.BoolType), + decls.Overload(overloads.LessUint64Int64, + argTypes(types.UintType, types.IntType), types.BoolType), + decls.Overload(overloads.LessDouble, + argTypes(types.DoubleType, types.DoubleType), types.BoolType), + decls.Overload(overloads.LessDoubleInt64, + argTypes(types.DoubleType, types.IntType), types.BoolType), + decls.Overload(overloads.LessDoubleUint64, + argTypes(types.DoubleType, types.UintType), types.BoolType), + decls.Overload(overloads.LessString, + argTypes(types.StringType, types.StringType), types.BoolType), + decls.Overload(overloads.LessBytes, + argTypes(types.BytesType, types.BytesType), types.BoolType), + decls.Overload(overloads.LessTimestamp, + argTypes(types.TimestampType, types.TimestampType), types.BoolType), + decls.Overload(overloads.LessDuration, + argTypes(types.DurationType, types.DurationType), types.BoolType), + decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val { + cmp := lhs.(traits.Comparer).Compare(rhs) + if cmp == types.IntNegOne { + return types.True + } + if cmp == types.IntOne || cmp == types.IntZero { + return types.False + } + return cmp + }, traits.ComparerType)), + + function(operators.LessEquals, + decls.Overload(overloads.LessEqualsBool, + argTypes(types.BoolType, types.BoolType), types.BoolType), + decls.Overload(overloads.LessEqualsInt64, + argTypes(types.IntType, types.IntType), types.BoolType), + decls.Overload(overloads.LessEqualsInt64Double, + argTypes(types.IntType, types.DoubleType), types.BoolType), + decls.Overload(overloads.LessEqualsInt64Uint64, + argTypes(types.IntType, types.UintType), types.BoolType), + decls.Overload(overloads.LessEqualsUint64, + argTypes(types.UintType, types.UintType), types.BoolType), + decls.Overload(overloads.LessEqualsUint64Double, + argTypes(types.UintType, types.DoubleType), types.BoolType), + decls.Overload(overloads.LessEqualsUint64Int64, + argTypes(types.UintType, types.IntType), types.BoolType), + decls.Overload(overloads.LessEqualsDouble, + argTypes(types.DoubleType, types.DoubleType), types.BoolType), + decls.Overload(overloads.LessEqualsDoubleInt64, + argTypes(types.DoubleType, types.IntType), types.BoolType), + decls.Overload(overloads.LessEqualsDoubleUint64, + argTypes(types.DoubleType, types.UintType), types.BoolType), + decls.Overload(overloads.LessEqualsString, + argTypes(types.StringType, types.StringType), types.BoolType), + decls.Overload(overloads.LessEqualsBytes, + argTypes(types.BytesType, types.BytesType), types.BoolType), + decls.Overload(overloads.LessEqualsTimestamp, + argTypes(types.TimestampType, types.TimestampType), types.BoolType), + decls.Overload(overloads.LessEqualsDuration, + argTypes(types.DurationType, types.DurationType), types.BoolType), + decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val { + cmp := lhs.(traits.Comparer).Compare(rhs) + if cmp == types.IntNegOne || cmp == types.IntZero { + return types.True + } + if cmp == types.IntOne { + return types.False + } + return cmp + }, traits.ComparerType)), + + function(operators.Greater, + decls.Overload(overloads.GreaterBool, + argTypes(types.BoolType, types.BoolType), types.BoolType), + decls.Overload(overloads.GreaterInt64, + argTypes(types.IntType, types.IntType), types.BoolType), + decls.Overload(overloads.GreaterInt64Double, + argTypes(types.IntType, types.DoubleType), types.BoolType), + decls.Overload(overloads.GreaterInt64Uint64, + argTypes(types.IntType, types.UintType), types.BoolType), + decls.Overload(overloads.GreaterUint64, + argTypes(types.UintType, types.UintType), types.BoolType), + decls.Overload(overloads.GreaterUint64Double, + argTypes(types.UintType, types.DoubleType), types.BoolType), + decls.Overload(overloads.GreaterUint64Int64, + argTypes(types.UintType, types.IntType), types.BoolType), + decls.Overload(overloads.GreaterDouble, + argTypes(types.DoubleType, types.DoubleType), types.BoolType), + decls.Overload(overloads.GreaterDoubleInt64, + argTypes(types.DoubleType, types.IntType), types.BoolType), + decls.Overload(overloads.GreaterDoubleUint64, + argTypes(types.DoubleType, types.UintType), types.BoolType), + decls.Overload(overloads.GreaterString, + argTypes(types.StringType, types.StringType), types.BoolType), + decls.Overload(overloads.GreaterBytes, + argTypes(types.BytesType, types.BytesType), types.BoolType), + decls.Overload(overloads.GreaterTimestamp, + argTypes(types.TimestampType, types.TimestampType), types.BoolType), + decls.Overload(overloads.GreaterDuration, + argTypes(types.DurationType, types.DurationType), types.BoolType), + decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val { + cmp := lhs.(traits.Comparer).Compare(rhs) + if cmp == types.IntOne { + return types.True + } + if cmp == types.IntNegOne || cmp == types.IntZero { + return types.False + } + return cmp + }, traits.ComparerType)), + + function(operators.GreaterEquals, + decls.Overload(overloads.GreaterEqualsBool, + argTypes(types.BoolType, types.BoolType), types.BoolType), + decls.Overload(overloads.GreaterEqualsInt64, + argTypes(types.IntType, types.IntType), types.BoolType), + decls.Overload(overloads.GreaterEqualsInt64Double, + argTypes(types.IntType, types.DoubleType), types.BoolType), + decls.Overload(overloads.GreaterEqualsInt64Uint64, + argTypes(types.IntType, types.UintType), types.BoolType), + decls.Overload(overloads.GreaterEqualsUint64, + argTypes(types.UintType, types.UintType), types.BoolType), + decls.Overload(overloads.GreaterEqualsUint64Double, + argTypes(types.UintType, types.DoubleType), types.BoolType), + decls.Overload(overloads.GreaterEqualsUint64Int64, + argTypes(types.UintType, types.IntType), types.BoolType), + decls.Overload(overloads.GreaterEqualsDouble, + argTypes(types.DoubleType, types.DoubleType), types.BoolType), + decls.Overload(overloads.GreaterEqualsDoubleInt64, + argTypes(types.DoubleType, types.IntType), types.BoolType), + decls.Overload(overloads.GreaterEqualsDoubleUint64, + argTypes(types.DoubleType, types.UintType), types.BoolType), + decls.Overload(overloads.GreaterEqualsString, + argTypes(types.StringType, types.StringType), types.BoolType), + decls.Overload(overloads.GreaterEqualsBytes, + argTypes(types.BytesType, types.BytesType), types.BoolType), + decls.Overload(overloads.GreaterEqualsTimestamp, + argTypes(types.TimestampType, types.TimestampType), types.BoolType), + decls.Overload(overloads.GreaterEqualsDuration, + argTypes(types.DurationType, types.DurationType), types.BoolType), + decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val { + cmp := lhs.(traits.Comparer).Compare(rhs) + if cmp == types.IntOne || cmp == types.IntZero { + return types.True + } + if cmp == types.IntNegOne { + return types.False + } + return cmp + }, traits.ComparerType)), + + // Indexing + function(operators.Index, + decls.Overload(overloads.IndexList, argTypes(listOfA, types.IntType), paramA), + decls.Overload(overloads.IndexMap, argTypes(mapOfAB, paramA), paramB), + decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val { + return lhs.(traits.Indexer).Get(rhs) + }, traits.IndexerType)), + + // Collections operators + function(operators.In, + decls.Overload(overloads.InList, argTypes(paramA, listOfA), types.BoolType), + decls.Overload(overloads.InMap, argTypes(paramA, mapOfAB), types.BoolType), + decls.SingletonBinaryBinding(inAggregate)), + function(operators.OldIn, + decls.DisableDeclaration(true), // safe deprecation + decls.Overload(overloads.InList, argTypes(paramA, listOfA), types.BoolType), + decls.Overload(overloads.InMap, argTypes(paramA, mapOfAB), types.BoolType), + decls.SingletonBinaryBinding(inAggregate)), + function(overloads.DeprecatedIn, + decls.DisableDeclaration(true), // safe deprecation + decls.Overload(overloads.InList, argTypes(paramA, listOfA), types.BoolType), + decls.Overload(overloads.InMap, argTypes(paramA, mapOfAB), types.BoolType), + decls.SingletonBinaryBinding(inAggregate)), + function(overloads.Size, + decls.Overload(overloads.SizeBytes, argTypes(types.BytesType), types.IntType), + decls.MemberOverload(overloads.SizeBytesInst, argTypes(types.BytesType), types.IntType), + decls.Overload(overloads.SizeList, argTypes(listOfA), types.IntType), + decls.MemberOverload(overloads.SizeListInst, argTypes(listOfA), types.IntType), + decls.Overload(overloads.SizeMap, argTypes(mapOfAB), types.IntType), + decls.MemberOverload(overloads.SizeMapInst, argTypes(mapOfAB), types.IntType), + decls.Overload(overloads.SizeString, argTypes(types.StringType), types.IntType), + decls.MemberOverload(overloads.SizeStringInst, argTypes(types.StringType), types.IntType), + decls.SingletonUnaryBinding(func(val ref.Val) ref.Val { + return val.(traits.Sizer).Size() + }, traits.SizerType)), + + // Type conversions + function(overloads.TypeConvertType, + decls.Overload(overloads.TypeConvertType, argTypes(paramA), types.NewTypeTypeWithParam(paramA)), + decls.SingletonUnaryBinding(convertToType(types.TypeType))), + + // Bool conversions + function(overloads.TypeConvertBool, + decls.Overload(overloads.BoolToBool, argTypes(types.BoolType), types.BoolType, + decls.UnaryBinding(identity)), + decls.Overload(overloads.StringToBool, argTypes(types.StringType), types.BoolType, + decls.UnaryBinding(convertToType(types.BoolType)))), + + // Bytes conversions + function(overloads.TypeConvertBytes, + decls.Overload(overloads.BytesToBytes, argTypes(types.BytesType), types.BytesType, + decls.UnaryBinding(identity)), + decls.Overload(overloads.StringToBytes, argTypes(types.StringType), types.BytesType, + decls.UnaryBinding(convertToType(types.BytesType)))), + + // Double conversions + function(overloads.TypeConvertDouble, + decls.Overload(overloads.DoubleToDouble, argTypes(types.DoubleType), types.DoubleType, + decls.UnaryBinding(identity)), + decls.Overload(overloads.IntToDouble, argTypes(types.IntType), types.DoubleType, + decls.UnaryBinding(convertToType(types.DoubleType))), + decls.Overload(overloads.StringToDouble, argTypes(types.StringType), types.DoubleType, + decls.UnaryBinding(convertToType(types.DoubleType))), + decls.Overload(overloads.UintToDouble, argTypes(types.UintType), types.DoubleType, + decls.UnaryBinding(convertToType(types.DoubleType)))), + + // Duration conversions + function(overloads.TypeConvertDuration, + decls.Overload(overloads.DurationToDuration, argTypes(types.DurationType), types.DurationType, + decls.UnaryBinding(identity)), + decls.Overload(overloads.IntToDuration, argTypes(types.IntType), types.DurationType, + decls.UnaryBinding(convertToType(types.DurationType))), + decls.Overload(overloads.StringToDuration, argTypes(types.StringType), types.DurationType, + decls.UnaryBinding(convertToType(types.DurationType)))), + + // Dyn conversions + function(overloads.TypeConvertDyn, + decls.Overload(overloads.ToDyn, argTypes(paramA), types.DynType), + decls.SingletonUnaryBinding(identity)), + + // Int conversions + function(overloads.TypeConvertInt, + decls.Overload(overloads.IntToInt, argTypes(types.IntType), types.IntType, + decls.UnaryBinding(identity)), + decls.Overload(overloads.DoubleToInt, argTypes(types.DoubleType), types.IntType, + decls.UnaryBinding(convertToType(types.IntType))), + decls.Overload(overloads.DurationToInt, argTypes(types.DurationType), types.IntType, + decls.UnaryBinding(convertToType(types.IntType))), + decls.Overload(overloads.StringToInt, argTypes(types.StringType), types.IntType, + decls.UnaryBinding(convertToType(types.IntType))), + decls.Overload(overloads.TimestampToInt, argTypes(types.TimestampType), types.IntType, + decls.UnaryBinding(convertToType(types.IntType))), + decls.Overload(overloads.UintToInt, argTypes(types.UintType), types.IntType, + decls.UnaryBinding(convertToType(types.IntType))), + ), + + // String conversions + function(overloads.TypeConvertString, + decls.Overload(overloads.StringToString, argTypes(types.StringType), types.StringType, + decls.UnaryBinding(identity)), + decls.Overload(overloads.BoolToString, argTypes(types.BoolType), types.StringType, + decls.UnaryBinding(convertToType(types.StringType))), + decls.Overload(overloads.BytesToString, argTypes(types.BytesType), types.StringType, + decls.UnaryBinding(convertToType(types.StringType))), + decls.Overload(overloads.DoubleToString, argTypes(types.DoubleType), types.StringType, + decls.UnaryBinding(convertToType(types.StringType))), + decls.Overload(overloads.DurationToString, argTypes(types.DurationType), types.StringType, + decls.UnaryBinding(convertToType(types.StringType))), + decls.Overload(overloads.IntToString, argTypes(types.IntType), types.StringType, + decls.UnaryBinding(convertToType(types.StringType))), + decls.Overload(overloads.TimestampToString, argTypes(types.TimestampType), types.StringType, + decls.UnaryBinding(convertToType(types.StringType))), + decls.Overload(overloads.UintToString, argTypes(types.UintType), types.StringType, + decls.UnaryBinding(convertToType(types.StringType)))), + + // Timestamp conversions + function(overloads.TypeConvertTimestamp, + decls.Overload(overloads.TimestampToTimestamp, argTypes(types.TimestampType), types.TimestampType, + decls.UnaryBinding(identity)), + decls.Overload(overloads.IntToTimestamp, argTypes(types.IntType), types.TimestampType, + decls.UnaryBinding(convertToType(types.TimestampType))), + decls.Overload(overloads.StringToTimestamp, argTypes(types.StringType), types.TimestampType, + decls.UnaryBinding(convertToType(types.TimestampType)))), + + // Uint conversions + function(overloads.TypeConvertUint, + decls.Overload(overloads.UintToUint, argTypes(types.UintType), types.UintType, + decls.UnaryBinding(identity)), + decls.Overload(overloads.DoubleToUint, argTypes(types.DoubleType), types.UintType, + decls.UnaryBinding(convertToType(types.UintType))), + decls.Overload(overloads.IntToUint, argTypes(types.IntType), types.UintType, + decls.UnaryBinding(convertToType(types.UintType))), + decls.Overload(overloads.StringToUint, argTypes(types.StringType), types.UintType, + decls.UnaryBinding(convertToType(types.UintType)))), + + // String functions + function(overloads.Contains, + decls.MemberOverload(overloads.ContainsString, + argTypes(types.StringType, types.StringType), types.BoolType, + decls.BinaryBinding(types.StringContains)), + decls.DisableTypeGuards(true)), + function(overloads.EndsWith, + decls.MemberOverload(overloads.EndsWithString, + argTypes(types.StringType, types.StringType), types.BoolType, + decls.BinaryBinding(types.StringEndsWith)), + decls.DisableTypeGuards(true)), + function(overloads.StartsWith, + decls.MemberOverload(overloads.StartsWithString, + argTypes(types.StringType, types.StringType), types.BoolType, + decls.BinaryBinding(types.StringStartsWith)), + decls.DisableTypeGuards(true)), + function(overloads.Matches, + decls.Overload(overloads.Matches, argTypes(types.StringType, types.StringType), types.BoolType), + decls.MemberOverload(overloads.MatchesString, + argTypes(types.StringType, types.StringType), types.BoolType), + decls.SingletonBinaryBinding(func(str, pat ref.Val) ref.Val { + return str.(traits.Matcher).Match(pat) + }, traits.MatcherType)), + + // Timestamp / duration functions + function(overloads.TimeGetFullYear, + decls.MemberOverload(overloads.TimestampToYear, + argTypes(types.TimestampType), types.IntType), + decls.MemberOverload(overloads.TimestampToYearWithTz, + argTypes(types.TimestampType, types.StringType), types.IntType)), + + function(overloads.TimeGetMonth, + decls.MemberOverload(overloads.TimestampToMonth, + argTypes(types.TimestampType), types.IntType), + decls.MemberOverload(overloads.TimestampToMonthWithTz, + argTypes(types.TimestampType, types.StringType), types.IntType)), + + function(overloads.TimeGetDayOfYear, + decls.MemberOverload(overloads.TimestampToDayOfYear, + argTypes(types.TimestampType), types.IntType), + decls.MemberOverload(overloads.TimestampToDayOfYearWithTz, + argTypes(types.TimestampType, types.StringType), types.IntType)), + + function(overloads.TimeGetDayOfMonth, + decls.MemberOverload(overloads.TimestampToDayOfMonthZeroBased, + argTypes(types.TimestampType), types.IntType), + decls.MemberOverload(overloads.TimestampToDayOfMonthZeroBasedWithTz, + argTypes(types.TimestampType, types.StringType), types.IntType)), + + function(overloads.TimeGetDate, + decls.MemberOverload(overloads.TimestampToDayOfMonthOneBased, + argTypes(types.TimestampType), types.IntType), + decls.MemberOverload(overloads.TimestampToDayOfMonthOneBasedWithTz, + argTypes(types.TimestampType, types.StringType), types.IntType)), + + function(overloads.TimeGetDayOfWeek, + decls.MemberOverload(overloads.TimestampToDayOfWeek, + argTypes(types.TimestampType), types.IntType), + decls.MemberOverload(overloads.TimestampToDayOfWeekWithTz, + argTypes(types.TimestampType, types.StringType), types.IntType)), + + function(overloads.TimeGetHours, + decls.MemberOverload(overloads.TimestampToHours, + argTypes(types.TimestampType), types.IntType), + decls.MemberOverload(overloads.TimestampToHoursWithTz, + argTypes(types.TimestampType, types.StringType), types.IntType), + decls.MemberOverload(overloads.DurationToHours, + argTypes(types.DurationType), types.IntType)), + + function(overloads.TimeGetMinutes, + decls.MemberOverload(overloads.TimestampToMinutes, + argTypes(types.TimestampType), types.IntType), + decls.MemberOverload(overloads.TimestampToMinutesWithTz, + argTypes(types.TimestampType, types.StringType), types.IntType), + decls.MemberOverload(overloads.DurationToMinutes, + argTypes(types.DurationType), types.IntType)), + + function(overloads.TimeGetSeconds, + decls.MemberOverload(overloads.TimestampToSeconds, + argTypes(types.TimestampType), types.IntType), + decls.MemberOverload(overloads.TimestampToSecondsWithTz, + argTypes(types.TimestampType, types.StringType), types.IntType), + decls.MemberOverload(overloads.DurationToSeconds, + argTypes(types.DurationType), types.IntType)), + + function(overloads.TimeGetMilliseconds, + decls.MemberOverload(overloads.TimestampToMilliseconds, + argTypes(types.TimestampType), types.IntType), + decls.MemberOverload(overloads.TimestampToMillisecondsWithTz, + argTypes(types.TimestampType, types.StringType), types.IntType), + decls.MemberOverload(overloads.DurationToMilliseconds, + argTypes(types.DurationType), types.IntType)), + } + + stdFnDecls = make([]*exprpb.Decl, 0, len(stdFunctions)) + for _, fn := range stdFunctions { + if fn.IsDeclarationDisabled() { + continue + } + ed, err := decls.FunctionDeclToExprDecl(fn) + if err != nil { + panic(err) + } + stdFnDecls = append(stdFnDecls, ed) + } +} + +// Functions returns the set of standard library function declarations and definitions for CEL. +func Functions() []*decls.FunctionDecl { + return stdFunctions +} + +// FunctionExprDecls returns the legacy style protobuf-typed declarations for all functions and overloads +// in the CEL standard environment. +// +// Deprecated: use Functions +func FunctionExprDecls() []*exprpb.Decl { + return stdFnDecls +} + +// Types returns the set of standard library types for CEL. +func Types() []*decls.VariableDecl { + return stdTypes +} + +// TypeExprDecls returns the legacy style protobuf-typed declarations for all types in the CEL +// standard environment. +// +// Deprecated: use Types +func TypeExprDecls() []*exprpb.Decl { + return stdTypeDecls +} + +func notStrictlyFalse(value ref.Val) ref.Val { + if types.IsBool(value) { + return value + } + return types.True +} + +func inAggregate(lhs ref.Val, rhs ref.Val) ref.Val { + if rhs.Type().HasTrait(traits.ContainerType) { + return rhs.(traits.Container).Contains(lhs) + } + return types.ValOrErr(rhs, "no such overload") +} + +func function(name string, opts ...decls.FunctionOpt) *decls.FunctionDecl { + fn, err := decls.NewFunction(name, opts...) + if err != nil { + panic(err) + } + return fn +} + +func argTypes(args ...*types.Type) []*types.Type { + return args +} + +func noBinaryOverrides(rhs, lhs ref.Val) ref.Val { + return types.NoSuchOverloadErr() +} + +func noFunctionOverrides(args ...ref.Val) ref.Val { + return types.NoSuchOverloadErr() +} + +func identity(val ref.Val) ref.Val { + return val +} + +func convertToType(t ref.Type) functions.UnaryOp { + return func(val ref.Val) ref.Val { + return val.ConvertToType(t) + } +} diff --git a/vendor/github.com/google/cel-go/common/types/BUILD.bazel b/vendor/github.com/google/cel-go/common/types/BUILD.bazel index f56700de5..b5e44ffbf 100644 --- a/vendor/github.com/google/cel-go/common/types/BUILD.bazel +++ b/vendor/github.com/google/cel-go/common/types/BUILD.bazel @@ -27,20 +27,20 @@ go_library( "provider.go", "string.go", "timestamp.go", - "type.go", + "types.go", "uint.go", "unknown.go", "util.go", ], importpath = "github.com/google/cel-go/common/types", deps = [ + "//checker/decls:go_default_library", "//common/overloads:go_default_library", "//common/types/pb:go_default_library", "//common/types/ref:go_default_library", "//common/types/traits:go_default_library", "@com_github_stoewer_go_strcase//:go_default_library", - "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", - "@org_golang_google_genproto//googleapis/rpc/status:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", "@org_golang_google_protobuf//encoding/protojson:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", @@ -71,8 +71,9 @@ go_test( "provider_test.go", "string_test.go", "timestamp_test.go", - "type_test.go", + "types_test.go", "uint_test.go", + "unknown_test.go", "util_test.go", ], embed = [":go_default_library"], @@ -80,7 +81,7 @@ go_test( "//common/types/ref:go_default_library", "//test:go_default_library", "//test/proto3pb:test_all_types_go_proto", - "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", "@org_golang_google_protobuf//encoding/protojson:go_default_library", "@org_golang_google_protobuf//types/known/anypb:go_default_library", "@org_golang_google_protobuf//types/known/durationpb:go_default_library", diff --git a/vendor/github.com/google/cel-go/common/types/bool.go b/vendor/github.com/google/cel-go/common/types/bool.go index a634ecc28..565734f3f 100644 --- a/vendor/github.com/google/cel-go/common/types/bool.go +++ b/vendor/github.com/google/cel-go/common/types/bool.go @@ -20,7 +20,6 @@ import ( "strconv" "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" @@ -31,11 +30,6 @@ import ( type Bool bool var ( - // BoolType singleton. - BoolType = NewTypeValue("bool", - traits.ComparerType, - traits.NegatorType) - // boolWrapperType golang reflected type for protobuf bool wrapper type. boolWrapperType = reflect.TypeOf(&wrapperspb.BoolValue{}) ) diff --git a/vendor/github.com/google/cel-go/common/types/bytes.go b/vendor/github.com/google/cel-go/common/types/bytes.go index bef190759..5838755f8 100644 --- a/vendor/github.com/google/cel-go/common/types/bytes.go +++ b/vendor/github.com/google/cel-go/common/types/bytes.go @@ -22,7 +22,6 @@ import ( "unicode/utf8" "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" @@ -34,12 +33,6 @@ import ( type Bytes []byte var ( - // BytesType singleton. - BytesType = NewTypeValue("bytes", - traits.AdderType, - traits.ComparerType, - traits.SizerType) - // byteWrapperType golang reflected type for protobuf bytes wrapper type. byteWrapperType = reflect.TypeOf(&wrapperspb.BytesValue{}) ) diff --git a/vendor/github.com/google/cel-go/common/types/double.go b/vendor/github.com/google/cel-go/common/types/double.go index 4647cf04f..027e78978 100644 --- a/vendor/github.com/google/cel-go/common/types/double.go +++ b/vendor/github.com/google/cel-go/common/types/double.go @@ -20,7 +20,6 @@ import ( "reflect" "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" @@ -32,15 +31,6 @@ import ( type Double float64 var ( - // DoubleType singleton. - DoubleType = NewTypeValue("double", - traits.AdderType, - traits.ComparerType, - traits.DividerType, - traits.MultiplierType, - traits.NegatorType, - traits.SubtractorType) - // doubleWrapperType reflected type for protobuf double wrapper type. doubleWrapperType = reflect.TypeOf(&wrapperspb.DoubleValue{}) @@ -134,13 +124,13 @@ func (d Double) ConvertToType(typeVal ref.Type) ref.Val { case IntType: i, err := doubleToInt64Checked(float64(d)) if err != nil { - return wrapErr(err) + return WrapErr(err) } return Int(i) case UintType: i, err := doubleToUint64Checked(float64(d)) if err != nil { - return wrapErr(err) + return WrapErr(err) } return Uint(i) case DoubleType: diff --git a/vendor/github.com/google/cel-go/common/types/duration.go b/vendor/github.com/google/cel-go/common/types/duration.go index f6a4f5a01..596e56d6b 100644 --- a/vendor/github.com/google/cel-go/common/types/duration.go +++ b/vendor/github.com/google/cel-go/common/types/duration.go @@ -22,7 +22,6 @@ import ( "github.com/google/cel-go/common/overloads" "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" anypb "google.golang.org/protobuf/types/known/anypb" dpb "google.golang.org/protobuf/types/known/durationpb" @@ -41,13 +40,14 @@ func durationOf(d time.Duration) Duration { } var ( - // DurationType singleton. - DurationType = NewTypeValue("google.protobuf.Duration", - traits.AdderType, - traits.ComparerType, - traits.NegatorType, - traits.ReceiverType, - traits.SubtractorType) + durationValueType = reflect.TypeOf(&dpb.Duration{}) + + durationZeroArgOverloads = map[string]func(ref.Val) ref.Val{ + overloads.TimeGetHours: DurationGetHours, + overloads.TimeGetMinutes: DurationGetMinutes, + overloads.TimeGetSeconds: DurationGetSeconds, + overloads.TimeGetMilliseconds: DurationGetMilliseconds, + } ) // Add implements traits.Adder.Add. @@ -57,14 +57,14 @@ func (d Duration) Add(other ref.Val) ref.Val { dur2 := other.(Duration) val, err := addDurationChecked(d.Duration, dur2.Duration) if err != nil { - return wrapErr(err) + return WrapErr(err) } return durationOf(val) case TimestampType: ts := other.(Timestamp).Time val, err := addTimeDurationChecked(ts, d.Duration) if err != nil { - return wrapErr(err) + return WrapErr(err) } return timestampOf(val) } @@ -147,7 +147,7 @@ func (d Duration) IsZeroValue() bool { func (d Duration) Negate() ref.Val { val, err := negateDurationChecked(d.Duration) if err != nil { - return wrapErr(err) + return WrapErr(err) } return durationOf(val) } @@ -156,7 +156,7 @@ func (d Duration) Negate() ref.Val { func (d Duration) Receive(function string, overload string, args []ref.Val) ref.Val { if len(args) == 0 { if f, found := durationZeroArgOverloads[function]; found { - return f(d.Duration) + return f(d) } } return NoSuchOverloadErr() @@ -170,7 +170,7 @@ func (d Duration) Subtract(subtrahend ref.Val) ref.Val { } val, err := subtractDurationChecked(d.Duration, subtraDur.Duration) if err != nil { - return wrapErr(err) + return WrapErr(err) } return durationOf(val) } @@ -185,20 +185,38 @@ func (d Duration) Value() any { return d.Duration } -var ( - durationValueType = reflect.TypeOf(&dpb.Duration{}) +// DurationGetHours returns the duration in hours. +func DurationGetHours(val ref.Val) ref.Val { + dur, ok := val.(Duration) + if !ok { + return MaybeNoSuchOverloadErr(val) + } + return Int(dur.Hours()) +} - durationZeroArgOverloads = map[string]func(time.Duration) ref.Val{ - overloads.TimeGetHours: func(dur time.Duration) ref.Val { - return Int(dur.Hours()) - }, - overloads.TimeGetMinutes: func(dur time.Duration) ref.Val { - return Int(dur.Minutes()) - }, - overloads.TimeGetSeconds: func(dur time.Duration) ref.Val { - return Int(dur.Seconds()) - }, - overloads.TimeGetMilliseconds: func(dur time.Duration) ref.Val { - return Int(dur.Milliseconds()) - }} -) +// DurationGetMinutes returns duration in minutes. +func DurationGetMinutes(val ref.Val) ref.Val { + dur, ok := val.(Duration) + if !ok { + return MaybeNoSuchOverloadErr(val) + } + return Int(dur.Minutes()) +} + +// DurationGetSeconds returns duration in seconds. +func DurationGetSeconds(val ref.Val) ref.Val { + dur, ok := val.(Duration) + if !ok { + return MaybeNoSuchOverloadErr(val) + } + return Int(dur.Seconds()) +} + +// DurationGetMilliseconds returns duration in milliseconds. +func DurationGetMilliseconds(val ref.Val) ref.Val { + dur, ok := val.(Duration) + if !ok { + return MaybeNoSuchOverloadErr(val) + } + return Int(dur.Milliseconds()) +} diff --git a/vendor/github.com/google/cel-go/common/types/err.go b/vendor/github.com/google/cel-go/common/types/err.go index d9f9b6013..aa8f94b4f 100644 --- a/vendor/github.com/google/cel-go/common/types/err.go +++ b/vendor/github.com/google/cel-go/common/types/err.go @@ -22,6 +22,12 @@ import ( "github.com/google/cel-go/common/types/ref" ) +// Error interface which allows types types.Err values to be treated as error values. +type Error interface { + error + ref.Val +} + // Err type which extends the built-in go error and implements ref.Val. type Err struct { error @@ -29,7 +35,7 @@ type Err struct { var ( // ErrType singleton. - ErrType = NewTypeValue("error") + ErrType = NewOpaqueType("error") // errDivideByZero is an error indicating a division by zero of an integer value. errDivideByZero = errors.New("division by zero") @@ -81,8 +87,8 @@ func ValOrErr(val ref.Val, format string, args ...any) ref.Val { return val } -// wrapErr wraps an existing Go error value into a CEL Err value. -func wrapErr(err error) ref.Val { +// WrapErr wraps an existing Go error value into a CEL Err value. +func WrapErr(err error) ref.Val { return &Err{error: err} } @@ -123,6 +129,11 @@ func (e *Err) Is(target error) bool { return e.error.Error() == target.Error() } +// Unwrap implements errors.Unwrap. +func (e *Err) Unwrap() error { + return e.error +} + // IsError returns whether the input element ref.Type or ref.Val is equal to // the ErrType singleton. func IsError(val ref.Val) bool { diff --git a/vendor/github.com/google/cel-go/common/types/int.go b/vendor/github.com/google/cel-go/common/types/int.go index 5f13956e7..940772aed 100644 --- a/vendor/github.com/google/cel-go/common/types/int.go +++ b/vendor/github.com/google/cel-go/common/types/int.go @@ -22,7 +22,6 @@ import ( "time" "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" @@ -41,16 +40,6 @@ const ( ) var ( - // IntType singleton. - IntType = NewTypeValue("int", - traits.AdderType, - traits.ComparerType, - traits.DividerType, - traits.ModderType, - traits.MultiplierType, - traits.NegatorType, - traits.SubtractorType) - // int32WrapperType reflected type for protobuf int32 wrapper type. int32WrapperType = reflect.TypeOf(&wrapperspb.Int32Value{}) @@ -66,7 +55,7 @@ func (i Int) Add(other ref.Val) ref.Val { } val, err := addInt64Checked(int64(i), int64(otherInt)) if err != nil { - return wrapErr(err) + return WrapErr(err) } return Int(val) } @@ -176,7 +165,7 @@ func (i Int) ConvertToType(typeVal ref.Type) ref.Val { case UintType: u, err := int64ToUint64Checked(int64(i)) if err != nil { - return wrapErr(err) + return WrapErr(err) } return Uint(u) case DoubleType: @@ -204,7 +193,7 @@ func (i Int) Divide(other ref.Val) ref.Val { } val, err := divideInt64Checked(int64(i), int64(otherInt)) if err != nil { - return wrapErr(err) + return WrapErr(err) } return Int(val) } @@ -239,7 +228,7 @@ func (i Int) Modulo(other ref.Val) ref.Val { } val, err := moduloInt64Checked(int64(i), int64(otherInt)) if err != nil { - return wrapErr(err) + return WrapErr(err) } return Int(val) } @@ -252,7 +241,7 @@ func (i Int) Multiply(other ref.Val) ref.Val { } val, err := multiplyInt64Checked(int64(i), int64(otherInt)) if err != nil { - return wrapErr(err) + return WrapErr(err) } return Int(val) } @@ -261,7 +250,7 @@ func (i Int) Multiply(other ref.Val) ref.Val { func (i Int) Negate() ref.Val { val, err := negateInt64Checked(int64(i)) if err != nil { - return wrapErr(err) + return WrapErr(err) } return Int(val) } @@ -274,7 +263,7 @@ func (i Int) Subtract(subtrahend ref.Val) ref.Val { } val, err := subtractInt64Checked(int64(i), int64(subtraInt)) if err != nil { - return wrapErr(err) + return WrapErr(err) } return Int(val) } diff --git a/vendor/github.com/google/cel-go/common/types/iterator.go b/vendor/github.com/google/cel-go/common/types/iterator.go index 9f224ad4f..98e9147b6 100644 --- a/vendor/github.com/google/cel-go/common/types/iterator.go +++ b/vendor/github.com/google/cel-go/common/types/iterator.go @@ -24,7 +24,7 @@ import ( var ( // IteratorType singleton. - IteratorType = NewTypeValue("iterator", traits.IteratorType) + IteratorType = NewObjectType("iterator", traits.IteratorType) ) // baseIterator is the basis for list, map, and object iterators. diff --git a/vendor/github.com/google/cel-go/common/types/list.go b/vendor/github.com/google/cel-go/common/types/list.go index de5f2099b..d4932b4a9 100644 --- a/vendor/github.com/google/cel-go/common/types/list.go +++ b/vendor/github.com/google/cel-go/common/types/list.go @@ -29,25 +29,15 @@ import ( structpb "google.golang.org/protobuf/types/known/structpb" ) -var ( - // ListType singleton. - ListType = NewTypeValue("list", - traits.AdderType, - traits.ContainerType, - traits.IndexerType, - traits.IterableType, - traits.SizerType) -) - // NewDynamicList returns a traits.Lister with heterogenous elements. // value should be an array of "native" types, i.e. any type that // NativeToValue() can convert to a ref.Val. -func NewDynamicList(adapter ref.TypeAdapter, value any) traits.Lister { +func NewDynamicList(adapter Adapter, value any) traits.Lister { refValue := reflect.ValueOf(value) return &baseList{ - TypeAdapter: adapter, - value: value, - size: refValue.Len(), + Adapter: adapter, + value: value, + size: refValue.Len(), get: func(i int) any { return refValue.Index(i).Interface() }, @@ -55,56 +45,56 @@ func NewDynamicList(adapter ref.TypeAdapter, value any) traits.Lister { } // NewStringList returns a traits.Lister containing only strings. -func NewStringList(adapter ref.TypeAdapter, elems []string) traits.Lister { +func NewStringList(adapter Adapter, elems []string) traits.Lister { return &baseList{ - TypeAdapter: adapter, - value: elems, - size: len(elems), - get: func(i int) any { return elems[i] }, + Adapter: adapter, + value: elems, + size: len(elems), + get: func(i int) any { return elems[i] }, } } // NewRefValList returns a traits.Lister with ref.Val elements. // // This type specialization is used with list literals within CEL expressions. -func NewRefValList(adapter ref.TypeAdapter, elems []ref.Val) traits.Lister { +func NewRefValList(adapter Adapter, elems []ref.Val) traits.Lister { return &baseList{ - TypeAdapter: adapter, - value: elems, - size: len(elems), - get: func(i int) any { return elems[i] }, + Adapter: adapter, + value: elems, + size: len(elems), + get: func(i int) any { return elems[i] }, } } // NewProtoList returns a traits.Lister based on a pb.List instance. -func NewProtoList(adapter ref.TypeAdapter, list protoreflect.List) traits.Lister { +func NewProtoList(adapter Adapter, list protoreflect.List) traits.Lister { return &baseList{ - TypeAdapter: adapter, - value: list, - size: list.Len(), - get: func(i int) any { return list.Get(i).Interface() }, + Adapter: adapter, + value: list, + size: list.Len(), + get: func(i int) any { return list.Get(i).Interface() }, } } // NewJSONList returns a traits.Lister based on structpb.ListValue instance. -func NewJSONList(adapter ref.TypeAdapter, l *structpb.ListValue) traits.Lister { +func NewJSONList(adapter Adapter, l *structpb.ListValue) traits.Lister { vals := l.GetValues() return &baseList{ - TypeAdapter: adapter, - value: l, - size: len(vals), - get: func(i int) any { return vals[i] }, + Adapter: adapter, + value: l, + size: len(vals), + get: func(i int) any { return vals[i] }, } } // NewMutableList creates a new mutable list whose internal state can be modified. -func NewMutableList(adapter ref.TypeAdapter) traits.MutableLister { +func NewMutableList(adapter Adapter) traits.MutableLister { var mutableValues []ref.Val l := &mutableList{ baseList: &baseList{ - TypeAdapter: adapter, - value: mutableValues, - size: 0, + Adapter: adapter, + value: mutableValues, + size: 0, }, mutableValues: mutableValues, } @@ -116,9 +106,9 @@ func NewMutableList(adapter ref.TypeAdapter) traits.MutableLister { // baseList points to a list containing elements of any type. // The `value` is an array of native values, and refValue is its reflection object. -// The `ref.TypeAdapter` enables native type to CEL type conversions. +// The `Adapter` enables native type to CEL type conversions. type baseList struct { - ref.TypeAdapter + Adapter value any // size indicates the number of elements within the list. @@ -143,9 +133,9 @@ func (l *baseList) Add(other ref.Val) ref.Val { return l } return &concatList{ - TypeAdapter: l.TypeAdapter, - prevList: l, - nextList: otherList} + Adapter: l.Adapter, + prevList: l, + nextList: otherList} } // Contains implements the traits.Container interface method. @@ -322,13 +312,13 @@ func (l *mutableList) Add(other ref.Val) ref.Val { func (l *mutableList) ToImmutableList() traits.Lister { // The reference to internal state is guaranteed to be safe as this call is only performed // when mutations have been completed. - return NewRefValList(l.TypeAdapter, l.mutableValues) + return NewRefValList(l.Adapter, l.mutableValues) } // concatList combines two list implementations together into a view. -// The `ref.TypeAdapter` enables native type to CEL type conversions. +// The `Adapter` enables native type to CEL type conversions. type concatList struct { - ref.TypeAdapter + Adapter value any prevList traits.Lister nextList traits.Lister @@ -347,9 +337,9 @@ func (l *concatList) Add(other ref.Val) ref.Val { return l } return &concatList{ - TypeAdapter: l.TypeAdapter, - prevList: l, - nextList: otherList} + Adapter: l.Adapter, + prevList: l, + nextList: otherList} } // Contains implements the traits.Container interface method. @@ -376,7 +366,7 @@ func (l *concatList) Contains(elem ref.Val) ref.Val { // ConvertToNative implements the ref.Val interface method. func (l *concatList) ConvertToNative(typeDesc reflect.Type) (any, error) { - combined := NewDynamicList(l.TypeAdapter, l.Value().([]any)) + combined := NewDynamicList(l.Adapter, l.Value().([]any)) return combined.ConvertToNative(typeDesc) } diff --git a/vendor/github.com/google/cel-go/common/types/map.go b/vendor/github.com/google/cel-go/common/types/map.go index 213be4ac9..739b7aab0 100644 --- a/vendor/github.com/google/cel-go/common/types/map.go +++ b/vendor/github.com/google/cel-go/common/types/map.go @@ -32,10 +32,10 @@ import ( ) // NewDynamicMap returns a traits.Mapper value with dynamic key, value pairs. -func NewDynamicMap(adapter ref.TypeAdapter, value any) traits.Mapper { +func NewDynamicMap(adapter Adapter, value any) traits.Mapper { refValue := reflect.ValueOf(value) return &baseMap{ - TypeAdapter: adapter, + Adapter: adapter, mapAccessor: newReflectMapAccessor(adapter, refValue), value: value, size: refValue.Len(), @@ -46,10 +46,10 @@ func NewDynamicMap(adapter ref.TypeAdapter, value any) traits.Mapper { // encoded in protocol buffer form. // // The `adapter` argument provides type adaptation capabilities from proto to CEL. -func NewJSONStruct(adapter ref.TypeAdapter, value *structpb.Struct) traits.Mapper { +func NewJSONStruct(adapter Adapter, value *structpb.Struct) traits.Mapper { fields := value.GetFields() return &baseMap{ - TypeAdapter: adapter, + Adapter: adapter, mapAccessor: newJSONStructAccessor(adapter, fields), value: value, size: len(fields), @@ -57,9 +57,9 @@ func NewJSONStruct(adapter ref.TypeAdapter, value *structpb.Struct) traits.Mappe } // NewRefValMap returns a specialized traits.Mapper with CEL valued keys and values. -func NewRefValMap(adapter ref.TypeAdapter, value map[ref.Val]ref.Val) traits.Mapper { +func NewRefValMap(adapter Adapter, value map[ref.Val]ref.Val) traits.Mapper { return &baseMap{ - TypeAdapter: adapter, + Adapter: adapter, mapAccessor: newRefValMapAccessor(value), value: value, size: len(value), @@ -67,9 +67,9 @@ func NewRefValMap(adapter ref.TypeAdapter, value map[ref.Val]ref.Val) traits.Map } // NewStringInterfaceMap returns a specialized traits.Mapper with string keys and interface values. -func NewStringInterfaceMap(adapter ref.TypeAdapter, value map[string]any) traits.Mapper { +func NewStringInterfaceMap(adapter Adapter, value map[string]any) traits.Mapper { return &baseMap{ - TypeAdapter: adapter, + Adapter: adapter, mapAccessor: newStringIfaceMapAccessor(adapter, value), value: value, size: len(value), @@ -77,9 +77,9 @@ func NewStringInterfaceMap(adapter ref.TypeAdapter, value map[string]any) traits } // NewStringStringMap returns a specialized traits.Mapper with string keys and values. -func NewStringStringMap(adapter ref.TypeAdapter, value map[string]string) traits.Mapper { +func NewStringStringMap(adapter Adapter, value map[string]string) traits.Mapper { return &baseMap{ - TypeAdapter: adapter, + Adapter: adapter, mapAccessor: newStringMapAccessor(value), value: value, size: len(value), @@ -87,22 +87,13 @@ func NewStringStringMap(adapter ref.TypeAdapter, value map[string]string) traits } // NewProtoMap returns a specialized traits.Mapper for handling protobuf map values. -func NewProtoMap(adapter ref.TypeAdapter, value *pb.Map) traits.Mapper { +func NewProtoMap(adapter Adapter, value *pb.Map) traits.Mapper { return &protoMap{ - TypeAdapter: adapter, - value: value, + Adapter: adapter, + value: value, } } -var ( - // MapType singleton. - MapType = NewTypeValue("map", - traits.ContainerType, - traits.IndexerType, - traits.IterableType, - traits.SizerType) -) - // mapAccessor is a private interface for finding values within a map and iterating over the keys. // This interface implements portions of the API surface area required by the traits.Mapper // interface. @@ -121,7 +112,7 @@ type mapAccessor interface { // Since CEL is side-effect free, the base map represents an immutable object. type baseMap struct { // TypeAdapter used to convert keys and values accessed within the map. - ref.TypeAdapter + Adapter // mapAccessor interface implementation used to find and iterate over map keys. mapAccessor @@ -316,15 +307,15 @@ func (m *baseMap) Value() any { return m.value } -func newJSONStructAccessor(adapter ref.TypeAdapter, st map[string]*structpb.Value) mapAccessor { +func newJSONStructAccessor(adapter Adapter, st map[string]*structpb.Value) mapAccessor { return &jsonStructAccessor{ - TypeAdapter: adapter, - st: st, + Adapter: adapter, + st: st, } } type jsonStructAccessor struct { - ref.TypeAdapter + Adapter st map[string]*structpb.Value } @@ -359,17 +350,17 @@ func (a *jsonStructAccessor) Iterator() traits.Iterator { } } -func newReflectMapAccessor(adapter ref.TypeAdapter, value reflect.Value) mapAccessor { +func newReflectMapAccessor(adapter Adapter, value reflect.Value) mapAccessor { keyType := value.Type().Key() return &reflectMapAccessor{ - TypeAdapter: adapter, - refValue: value, - keyType: keyType, + Adapter: adapter, + refValue: value, + keyType: keyType, } } type reflectMapAccessor struct { - ref.TypeAdapter + Adapter refValue reflect.Value keyType reflect.Type } @@ -427,9 +418,9 @@ func (m *reflectMapAccessor) findInternal(key ref.Val) (ref.Val, bool) { // Iterator creates a Golang reflection based traits.Iterator. func (m *reflectMapAccessor) Iterator() traits.Iterator { return &mapIterator{ - TypeAdapter: m.TypeAdapter, - mapKeys: m.refValue.MapRange(), - len: m.refValue.Len(), + Adapter: m.Adapter, + mapKeys: m.refValue.MapRange(), + len: m.refValue.Len(), } } @@ -480,9 +471,9 @@ func (a *refValMapAccessor) Find(key ref.Val) (ref.Val, bool) { // Iterator produces a new traits.Iterator which iterates over the map keys via Golang reflection. func (a *refValMapAccessor) Iterator() traits.Iterator { return &mapIterator{ - TypeAdapter: DefaultTypeAdapter, - mapKeys: reflect.ValueOf(a.mapVal).MapRange(), - len: len(a.mapVal), + Adapter: DefaultTypeAdapter, + mapKeys: reflect.ValueOf(a.mapVal).MapRange(), + len: len(a.mapVal), } } @@ -524,15 +515,15 @@ func (a *stringMapAccessor) Iterator() traits.Iterator { } } -func newStringIfaceMapAccessor(adapter ref.TypeAdapter, mapVal map[string]any) mapAccessor { +func newStringIfaceMapAccessor(adapter Adapter, mapVal map[string]any) mapAccessor { return &stringIfaceMapAccessor{ - TypeAdapter: adapter, - mapVal: mapVal, + Adapter: adapter, + mapVal: mapVal, } } type stringIfaceMapAccessor struct { - ref.TypeAdapter + Adapter mapVal map[string]any } @@ -569,7 +560,7 @@ func (a *stringIfaceMapAccessor) Iterator() traits.Iterator { // protoMap is a specialized, separate implementation of the traits.Mapper interfaces tailored to // accessing protoreflect.Map values. type protoMap struct { - ref.TypeAdapter + Adapter value *pb.Map } @@ -772,9 +763,9 @@ func (m *protoMap) Iterator() traits.Iterator { return true }) return &protoMapIterator{ - TypeAdapter: m.TypeAdapter, - mapKeys: mapKeys, - len: m.value.Len(), + Adapter: m.Adapter, + mapKeys: mapKeys, + len: m.value.Len(), } } @@ -795,7 +786,7 @@ func (m *protoMap) Value() any { type mapIterator struct { *baseIterator - ref.TypeAdapter + Adapter mapKeys *reflect.MapIter cursor int len int @@ -818,7 +809,7 @@ func (it *mapIterator) Next() ref.Val { type protoMapIterator struct { *baseIterator - ref.TypeAdapter + Adapter mapKeys []protoreflect.MapKey cursor int len int diff --git a/vendor/github.com/google/cel-go/common/types/null.go b/vendor/github.com/google/cel-go/common/types/null.go index 38927a112..926ca3dc9 100644 --- a/vendor/github.com/google/cel-go/common/types/null.go +++ b/vendor/github.com/google/cel-go/common/types/null.go @@ -30,8 +30,6 @@ import ( type Null structpb.NullValue var ( - // NullType singleton. - NullType = NewTypeValue("null_type") // NullValue singleton. NullValue = Null(structpb.NullValue_NULL_VALUE) diff --git a/vendor/github.com/google/cel-go/common/types/object.go b/vendor/github.com/google/cel-go/common/types/object.go index 9955e2dce..8ba0af9fb 100644 --- a/vendor/github.com/google/cel-go/common/types/object.go +++ b/vendor/github.com/google/cel-go/common/types/object.go @@ -29,10 +29,10 @@ import ( ) type protoObj struct { - ref.TypeAdapter + Adapter value proto.Message typeDesc *pb.TypeDescription - typeValue *TypeValue + typeValue ref.Val } // NewObject returns an object based on a proto.Message value which handles @@ -42,15 +42,15 @@ type protoObj struct { // Note: the type value is pulled from the list of registered types within the // type provider. If the proto type is not registered within the type provider, // then this will result in an error within the type adapter / provider. -func NewObject(adapter ref.TypeAdapter, +func NewObject(adapter Adapter, typeDesc *pb.TypeDescription, - typeValue *TypeValue, + typeValue ref.Val, value proto.Message) ref.Val { return &protoObj{ - TypeAdapter: adapter, - value: value, - typeDesc: typeDesc, - typeValue: typeValue} + Adapter: adapter, + value: value, + typeDesc: typeDesc, + typeValue: typeValue} } func (o *protoObj) ConvertToNative(typeDesc reflect.Type) (any, error) { @@ -157,7 +157,7 @@ func (o *protoObj) Get(index ref.Val) ref.Val { } func (o *protoObj) Type() ref.Type { - return o.typeValue + return o.typeValue.(ref.Type) } func (o *protoObj) Value() any { diff --git a/vendor/github.com/google/cel-go/common/types/optional.go b/vendor/github.com/google/cel-go/common/types/optional.go index 54cb35b1a..a9f30aed0 100644 --- a/vendor/github.com/google/cel-go/common/types/optional.go +++ b/vendor/github.com/google/cel-go/common/types/optional.go @@ -24,7 +24,7 @@ import ( var ( // OptionalType indicates the runtime type of an optional value. - OptionalType = NewTypeValue("optional") + OptionalType = NewOpaqueType("optional") // OptionalNone is a sentinel value which is used to indicate an empty optional value. OptionalNone = &Optional{} diff --git a/vendor/github.com/google/cel-go/common/types/pb/BUILD.bazel b/vendor/github.com/google/cel-go/common/types/pb/BUILD.bazel index f23ac9c0e..e2b9d37b5 100644 --- a/vendor/github.com/google/cel-go/common/types/pb/BUILD.bazel +++ b/vendor/github.com/google/cel-go/common/types/pb/BUILD.bazel @@ -17,7 +17,7 @@ go_library( ], importpath = "github.com/google/cel-go/common/types/pb", deps = [ - "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", "@org_golang_google_protobuf//encoding/protowire:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", diff --git a/vendor/github.com/google/cel-go/common/types/pb/type.go b/vendor/github.com/google/cel-go/common/types/pb/type.go index df9532156..6cc95c276 100644 --- a/vendor/github.com/google/cel-go/common/types/pb/type.go +++ b/vendor/github.com/google/cel-go/common/types/pb/type.go @@ -285,7 +285,7 @@ func (fd *FieldDescription) GetFrom(target any) (any, error) { // IsEnum returns true if the field type refers to an enum value. func (fd *FieldDescription) IsEnum() bool { - return fd.desc.Kind() == protoreflect.EnumKind + return fd.ProtoKind() == protoreflect.EnumKind } // IsMap returns true if the field is of map type. @@ -295,7 +295,7 @@ func (fd *FieldDescription) IsMap() bool { // IsMessage returns true if the field is of message type. func (fd *FieldDescription) IsMessage() bool { - kind := fd.desc.Kind() + kind := fd.ProtoKind() return kind == protoreflect.MessageKind || kind == protoreflect.GroupKind } @@ -326,6 +326,11 @@ func (fd *FieldDescription) Name() string { return string(fd.desc.Name()) } +// ProtoKind returns the protobuf reflected kind of the field. +func (fd *FieldDescription) ProtoKind() protoreflect.Kind { + return fd.desc.Kind() +} + // ReflectType returns the Golang reflect.Type for this field. func (fd *FieldDescription) ReflectType() reflect.Type { return fd.reflectType @@ -345,17 +350,17 @@ func (fd *FieldDescription) Zero() proto.Message { } func (fd *FieldDescription) typeDefToType() *exprpb.Type { - if fd.desc.Kind() == protoreflect.MessageKind || fd.desc.Kind() == protoreflect.GroupKind { + if fd.IsMessage() { msgType := string(fd.desc.Message().FullName()) if wk, found := CheckedWellKnowns[msgType]; found { return wk } return checkedMessageType(msgType) } - if fd.desc.Kind() == protoreflect.EnumKind { + if fd.IsEnum() { return checkedInt } - return CheckedPrimitives[fd.desc.Kind()] + return CheckedPrimitives[fd.ProtoKind()] } // Map wraps the protoreflect.Map object with a key and value FieldDescription for use in @@ -463,13 +468,13 @@ func unwrapDynamic(desc description, refMsg protoreflect.Message) (any, bool, er unwrappedAny := &anypb.Any{} err := Merge(unwrappedAny, msg) if err != nil { - return nil, false, err + return nil, false, fmt.Errorf("unwrap dynamic field failed: %v", err) } dynMsg, err := unwrappedAny.UnmarshalNew() if err != nil { // Allow the error to move further up the stack as it should result in an type // conversion error if the caller does not recover it somehow. - return nil, false, err + return nil, false, fmt.Errorf("unmarshal dynamic any failed: %v", err) } // Attempt to unwrap the dynamic type, otherwise return the dynamic message. unwrapped, nested, err := unwrapDynamic(desc, dynMsg.ProtoReflect()) @@ -560,8 +565,10 @@ func zeroValueOf(msg proto.Message) proto.Message { } var ( + jsonValueTypeURL = "types.googleapis.com/google.protobuf.Value" + zeroValueMap = map[string]proto.Message{ - "google.protobuf.Any": &anypb.Any{}, + "google.protobuf.Any": &anypb.Any{TypeUrl: jsonValueTypeURL}, "google.protobuf.Duration": &dpb.Duration{}, "google.protobuf.ListValue": &structpb.ListValue{}, "google.protobuf.Struct": &structpb.Struct{}, diff --git a/vendor/github.com/google/cel-go/common/types/provider.go b/vendor/github.com/google/cel-go/common/types/provider.go index e66951f5b..e80b4622e 100644 --- a/vendor/github.com/google/cel-go/common/types/provider.go +++ b/vendor/github.com/google/cel-go/common/types/provider.go @@ -33,17 +33,64 @@ import ( tpb "google.golang.org/protobuf/types/known/timestamppb" ) -type protoTypeRegistry struct { - revTypeMap map[string]ref.Type +// Adapter converts native Go values of varying type and complexity to equivalent CEL values. +type Adapter = ref.TypeAdapter + +// Provider specifies functions for creating new object instances and for resolving +// enum values by name. +type Provider interface { + // EnumValue returns the numeric value of the given enum value name. + EnumValue(enumName string) ref.Val + + // FindIdent takes a qualified identifier name and returns a ref.Val if one exists. + FindIdent(identName string) (ref.Val, bool) + + // FindStructType returns the Type give a qualified type name. + // + // For historical reasons, only struct types are expected to be returned through this + // method, and the type values are expected to be wrapped in a TypeType instance using + // TypeTypeWithParam(). + // + // Returns false if not found. + FindStructType(structType string) (*Type, bool) + + // FieldStructFieldType returns the field type for a checked type value. Returns + // false if the field could not be found. + FindStructFieldType(structType, fieldName string) (*FieldType, bool) + + // NewValue creates a new type value from a qualified name and map of field + // name to value. + // + // Note, for each value, the Val.ConvertToNative function will be invoked + // to convert the Val to the field's native type. If an error occurs during + // conversion, the NewValue will be a types.Err. + NewValue(structType string, fields map[string]ref.Val) ref.Val +} + +// FieldType represents a field's type value and whether that field supports presence detection. +type FieldType struct { + // Type of the field as a CEL native type value. + Type *Type + + // IsSet indicates whether the field is set on an input object. + IsSet ref.FieldTester + + // GetFrom retrieves the field value on the input object, if set. + GetFrom ref.FieldGetter +} + +// Registry provides type information for a set of registered types. +type Registry struct { + revTypeMap map[string]*Type pbdb *pb.Db } // NewRegistry accepts a list of proto message instances and returns a type // provider which can create new instances of the provided message or any // message that proto depends upon in its FileDescriptor. -func NewRegistry(types ...proto.Message) (ref.TypeRegistry, error) { - p := &protoTypeRegistry{ - revTypeMap: make(map[string]ref.Type), +func NewRegistry(types ...proto.Message) (*Registry, error) { + p := &Registry{ + revTypeMap: make(map[string]*Type), pbdb: pb.NewDb(), } err := p.RegisterType( @@ -79,18 +126,17 @@ func NewRegistry(types ...proto.Message) (ref.TypeRegistry, error) { } // NewEmptyRegistry returns a registry which is completely unconfigured. -func NewEmptyRegistry() ref.TypeRegistry { - return &protoTypeRegistry{ - revTypeMap: make(map[string]ref.Type), +func NewEmptyRegistry() *Registry { + return &Registry{ + revTypeMap: make(map[string]*Type), pbdb: pb.NewDb(), } } -// Copy implements the ref.TypeRegistry interface method which copies the current state of the -// registry into its own memory space. -func (p *protoTypeRegistry) Copy() ref.TypeRegistry { - copy := &protoTypeRegistry{ - revTypeMap: make(map[string]ref.Type), +// Copy copies the current state of the registry into its own memory space. +func (p *Registry) Copy() *Registry { + copy := &Registry{ + revTypeMap: make(map[string]*Type), pbdb: p.pbdb.Copy(), } for k, v := range p.revTypeMap { @@ -99,7 +145,8 @@ func (p *protoTypeRegistry) Copy() ref.TypeRegistry { return copy } -func (p *protoTypeRegistry) EnumValue(enumName string) ref.Val { +// EnumValue returns the numeric value of the given enum value name. +func (p *Registry) EnumValue(enumName string) ref.Val { enumVal, found := p.pbdb.DescribeEnum(enumName) if !found { return NewErr("unknown enum name '%s'", enumName) @@ -107,9 +154,12 @@ func (p *protoTypeRegistry) EnumValue(enumName string) ref.Val { return Int(enumVal.Value()) } -func (p *protoTypeRegistry) FindFieldType(messageType string, - fieldName string) (*ref.FieldType, bool) { - msgType, found := p.pbdb.DescribeType(messageType) +// FieldFieldType returns the field type for a checked type value. Returns false if +// the field could not be found. +// +// Deprecated: use FindStructFieldType +func (p *Registry) FindFieldType(structType, fieldName string) (*ref.FieldType, bool) { + msgType, found := p.pbdb.DescribeType(structType) if !found { return nil, false } @@ -118,15 +168,32 @@ func (p *protoTypeRegistry) FindFieldType(messageType string, return nil, false } return &ref.FieldType{ - Type: field.CheckedType(), - IsSet: field.IsSet, - GetFrom: field.GetFrom}, - true + Type: field.CheckedType(), + IsSet: field.IsSet, + GetFrom: field.GetFrom}, true +} + +// FieldStructFieldType returns the field type for a checked type value. Returns +// false if the field could not be found. +func (p *Registry) FindStructFieldType(structType, fieldName string) (*FieldType, bool) { + msgType, found := p.pbdb.DescribeType(structType) + if !found { + return nil, false + } + field, found := msgType.FieldByName(fieldName) + if !found { + return nil, false + } + return &FieldType{ + Type: fieldDescToCELType(field), + IsSet: field.IsSet, + GetFrom: field.GetFrom}, true } -func (p *protoTypeRegistry) FindIdent(identName string) (ref.Val, bool) { +// FindIdent takes a qualified identifier name and returns a ref.Val if one exists. +func (p *Registry) FindIdent(identName string) (ref.Val, bool) { if t, found := p.revTypeMap[identName]; found { - return t.(ref.Val), true + return t, true } if enumVal, found := p.pbdb.DescribeEnum(identName); found { return Int(enumVal.Value()), true @@ -134,24 +201,50 @@ func (p *protoTypeRegistry) FindIdent(identName string) (ref.Val, bool) { return nil, false } -func (p *protoTypeRegistry) FindType(typeName string) (*exprpb.Type, bool) { - if _, found := p.pbdb.DescribeType(typeName); !found { +// FindType looks up the Type given a qualified typeName. Returns false if not found. +// +// Deprecated: use FindStructType +func (p *Registry) FindType(structType string) (*exprpb.Type, bool) { + if _, found := p.pbdb.DescribeType(structType); !found { return nil, false } - if typeName != "" && typeName[0] == '.' { - typeName = typeName[1:] + if structType != "" && structType[0] == '.' { + structType = structType[1:] } return &exprpb.Type{ TypeKind: &exprpb.Type_Type{ Type: &exprpb.Type{ TypeKind: &exprpb.Type_MessageType{ - MessageType: typeName}}}}, true + MessageType: structType}}}}, true +} + +// FindStructType returns the Type give a qualified type name. +// +// For historical reasons, only struct types are expected to be returned through this +// method, and the type values are expected to be wrapped in a TypeType instance using +// TypeTypeWithParam(). +// +// Returns false if not found. +func (p *Registry) FindStructType(structType string) (*Type, bool) { + if _, found := p.pbdb.DescribeType(structType); !found { + return nil, false + } + if structType != "" && structType[0] == '.' { + structType = structType[1:] + } + return NewTypeTypeWithParam(NewObjectType(structType)), true } -func (p *protoTypeRegistry) NewValue(typeName string, fields map[string]ref.Val) ref.Val { - td, found := p.pbdb.DescribeType(typeName) +// NewValue creates a new type value from a qualified name and map of field +// name to value. +// +// Note, for each value, the Val.ConvertToNative function will be invoked +// to convert the Val to the field's native type. If an error occurs during +// conversion, the NewValue will be a types.Err. +func (p *Registry) NewValue(structType string, fields map[string]ref.Val) ref.Val { + td, found := p.pbdb.DescribeType(structType) if !found { - return NewErr("unknown type '%s'", typeName) + return NewErr("unknown type '%s'", structType) } msg := td.New() fieldMap := td.FieldMap() @@ -168,7 +261,8 @@ func (p *protoTypeRegistry) NewValue(typeName string, fields map[string]ref.Val) return p.NativeToValue(msg.Interface()) } -func (p *protoTypeRegistry) RegisterDescriptor(fileDesc protoreflect.FileDescriptor) error { +// RegisterDescriptor registers the contents of a protocol buffer `FileDescriptor`. +func (p *Registry) RegisterDescriptor(fileDesc protoreflect.FileDescriptor) error { fd, err := p.pbdb.RegisterDescriptor(fileDesc) if err != nil { return err @@ -176,7 +270,8 @@ func (p *protoTypeRegistry) RegisterDescriptor(fileDesc protoreflect.FileDescrip return p.registerAllTypes(fd) } -func (p *protoTypeRegistry) RegisterMessage(message proto.Message) error { +// RegisterMessage registers a protocol buffer message and its dependencies. +func (p *Registry) RegisterMessage(message proto.Message) error { fd, err := p.pbdb.RegisterMessage(message) if err != nil { return err @@ -184,11 +279,32 @@ func (p *protoTypeRegistry) RegisterMessage(message proto.Message) error { return p.registerAllTypes(fd) } -func (p *protoTypeRegistry) RegisterType(types ...ref.Type) error { +// RegisterType registers a type value with the provider which ensures the provider is aware of how to +// map the type to an identifier. +// +// If the `ref.Type` value is a `*types.Type` it will be registered directly by its runtime type name. +// If the `ref.Type` value is not a `*types.Type` instance, a `*types.Type` instance which reflects the +// traits present on the input and the runtime type name. By default this foreign type will be treated +// as a types.StructKind. To avoid potential issues where the `ref.Type` values does not match the +// generated `*types.Type` instance, consider always using the `*types.Type` to represent type extensions +// to CEL, even when they're not based on protobuf types. +func (p *Registry) RegisterType(types ...ref.Type) error { for _, t := range types { - p.revTypeMap[t.TypeName()] = t + celType := maybeForeignType(t) + existing, found := p.revTypeMap[t.TypeName()] + if !found { + p.revTypeMap[t.TypeName()] = celType + continue + } + if !existing.IsEquivalentType(celType) { + return fmt.Errorf("type registration conflict. found: %v, input: %v", existing, celType) + } + if existing.traitMask != celType.traitMask { + return fmt.Errorf( + "type registered with conflicting traits: %v with traits %v, input: %v", + existing.TypeName(), existing.traitMask, celType.traitMask) + } } - // TODO: generate an error when the type name is registered more than once. return nil } @@ -196,7 +312,7 @@ func (p *protoTypeRegistry) RegisterType(types ...ref.Type) error { // providing support for custom proto-based types. // // This method should be the inverse of ref.Val.ConvertToNative. -func (p *protoTypeRegistry) NativeToValue(value any) ref.Val { +func (p *Registry) NativeToValue(value any) ref.Val { if val, found := nativeToValue(p, value); found { return val } @@ -218,7 +334,7 @@ func (p *protoTypeRegistry) NativeToValue(value any) ref.Val { if !found { return NewErr("unknown type: '%s'", typeName) } - return NewObject(p, td, typeVal.(*TypeValue), v) + return NewObject(p, td, typeVal, v) case *pb.Map: return NewProtoMap(p, v) case protoreflect.List: @@ -231,8 +347,13 @@ func (p *protoTypeRegistry) NativeToValue(value any) ref.Val { return UnsupportedRefValConversionErr(value) } -func (p *protoTypeRegistry) registerAllTypes(fd *pb.FileDescription) error { +func (p *Registry) registerAllTypes(fd *pb.FileDescription) error { for _, typeName := range fd.GetTypeNames() { + // skip well-known type names since they're automatically sanitized + // during NewObjectType() calls. + if _, found := checkedWellKnowns[typeName]; found { + continue + } err := p.RegisterType(NewObjectTypeValue(typeName)) if err != nil { return err @@ -241,6 +362,28 @@ func (p *protoTypeRegistry) registerAllTypes(fd *pb.FileDescription) error { return nil } +func fieldDescToCELType(field *pb.FieldDescription) *Type { + if field.IsMap() { + return NewMapType( + singularFieldDescToCELType(field.KeyType), + singularFieldDescToCELType(field.ValueType)) + } + if field.IsList() { + return NewListType(singularFieldDescToCELType(field)) + } + return singularFieldDescToCELType(field) +} + +func singularFieldDescToCELType(field *pb.FieldDescription) *Type { + if field.IsMessage() { + return NewObjectType(string(field.Descriptor().Message().FullName())) + } + if field.IsEnum() { + return IntType + } + return ProtoCELPrimitives[field.ProtoKind()] +} + // defaultTypeAdapter converts go native types to CEL values. type defaultTypeAdapter struct{} @@ -259,7 +402,7 @@ func (a *defaultTypeAdapter) NativeToValue(value any) ref.Val { // nativeToValue returns the converted (ref.Val, true) of a conversion is found, // otherwise (nil, false) -func nativeToValue(a ref.TypeAdapter, value any) (ref.Val, bool) { +func nativeToValue(a Adapter, value any) (ref.Val, bool) { switch v := value.(type) { case nil: return NullValue, true @@ -547,3 +690,24 @@ func fieldTypeConversionError(field *pb.FieldDescription, err error) error { msgName := field.Descriptor().ContainingMessage().FullName() return fmt.Errorf("field type conversion error for %v.%v value type: %v", msgName, field.Name(), err) } + +var ( + // ProtoCELPrimitives provides a map from the protoreflect Kind to the equivalent CEL type. + ProtoCELPrimitives = map[protoreflect.Kind]*Type{ + protoreflect.BoolKind: BoolType, + protoreflect.BytesKind: BytesType, + protoreflect.DoubleKind: DoubleType, + protoreflect.FloatKind: DoubleType, + protoreflect.Int32Kind: IntType, + protoreflect.Int64Kind: IntType, + protoreflect.Sint32Kind: IntType, + protoreflect.Sint64Kind: IntType, + protoreflect.Uint32Kind: UintType, + protoreflect.Uint64Kind: UintType, + protoreflect.Fixed32Kind: UintType, + protoreflect.Fixed64Kind: UintType, + protoreflect.Sfixed32Kind: IntType, + protoreflect.Sfixed64Kind: IntType, + protoreflect.StringKind: StringType, + } +) diff --git a/vendor/github.com/google/cel-go/common/types/ref/BUILD.bazel b/vendor/github.com/google/cel-go/common/types/ref/BUILD.bazel index 1d0f46899..79330c332 100644 --- a/vendor/github.com/google/cel-go/common/types/ref/BUILD.bazel +++ b/vendor/github.com/google/cel-go/common/types/ref/BUILD.bazel @@ -13,7 +13,7 @@ go_library( ], importpath = "github.com/google/cel-go/common/types/ref", deps = [ - "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", ], diff --git a/vendor/github.com/google/cel-go/common/types/ref/provider.go b/vendor/github.com/google/cel-go/common/types/ref/provider.go index 7eabbb9ca..b9820023d 100644 --- a/vendor/github.com/google/cel-go/common/types/ref/provider.go +++ b/vendor/github.com/google/cel-go/common/types/ref/provider.go @@ -23,34 +23,34 @@ import ( // TypeProvider specifies functions for creating new object instances and for // resolving enum values by name. +// +// Deprecated: use types.Provider type TypeProvider interface { // EnumValue returns the numeric value of the given enum value name. EnumValue(enumName string) Val - // FindIdent takes a qualified identifier name and returns a Value if one - // exists. + // FindIdent takes a qualified identifier name and returns a Value if one exists. FindIdent(identName string) (Val, bool) - // FindType looks up the Type given a qualified typeName. Returns false - // if not found. - // - // Used during type-checking only. + // FindType looks up the Type given a qualified typeName. Returns false if not found. FindType(typeName string) (*exprpb.Type, bool) - // FieldFieldType returns the field type for a checked type value. Returns - // false if the field could not be found. - FindFieldType(messageType string, fieldName string) (*FieldType, bool) + // FieldFieldType returns the field type for a checked type value. Returns false if + // the field could not be found. + FindFieldType(messageType, fieldName string) (*FieldType, bool) - // NewValue creates a new type value from a qualified name and map of field - // name to value. + // NewValue creates a new type value from a qualified name and map of field name + // to value. // - // Note, for each value, the Val.ConvertToNative function will be invoked - // to convert the Val to the field's native type. If an error occurs during - // conversion, the NewValue will be a types.Err. + // Note, for each value, the Val.ConvertToNative function will be invoked to convert + // the Val to the field's native type. If an error occurs during conversion, the + // NewValue will be a types.Err. NewValue(typeName string, fields map[string]Val) Val } // TypeAdapter converts native Go values of varying type and complexity to equivalent CEL values. +// +// Deprecated: use types.Adapter type TypeAdapter interface { // NativeToValue converts the input `value` to a CEL `ref.Val`. NativeToValue(value any) Val @@ -60,6 +60,8 @@ type TypeAdapter interface { // implementations support type-customization, so these features are optional. However, a // `TypeRegistry` should be a `TypeProvider` and a `TypeAdapter` to ensure that types // which are registered can be converted to CEL representations. +// +// Deprecated: use types.Registry type TypeRegistry interface { TypeAdapter TypeProvider @@ -76,15 +78,14 @@ type TypeRegistry interface { // If a type is provided more than once with an alternative definition, the // call will result in an error. RegisterType(types ...Type) error - - // Copy the TypeRegistry and return a new registry whose mutable state is isolated. - Copy() TypeRegistry } // FieldType represents a field's type value and whether that field supports // presence detection. +// +// Deprecated: use types.FieldType type FieldType struct { - // Type of the field. + // Type of the field as a protobuf type value. Type *exprpb.Type // IsSet indicates whether the field is set on an input object. diff --git a/vendor/github.com/google/cel-go/common/types/ref/reference.go b/vendor/github.com/google/cel-go/common/types/ref/reference.go index 5921ffd81..e0d58145c 100644 --- a/vendor/github.com/google/cel-go/common/types/ref/reference.go +++ b/vendor/github.com/google/cel-go/common/types/ref/reference.go @@ -37,9 +37,18 @@ type Type interface { type Val interface { // ConvertToNative converts the Value to a native Go struct according to the // reflected type description, or error if the conversion is not feasible. + // + // The ConvertToNative method is intended to be used to support conversion between CEL types + // and native types during object creation expressions or by clients who need to adapt the, + // returned CEL value into an equivalent Go value instance. + // + // When implementing or using ConvertToNative, the following guidelines apply: + // - Use ConvertToNative when marshalling CEL evaluation results to native types. + // - Do not use ConvertToNative within CEL extension functions. + // - Document whether your implementation supports non-CEL field types, such as Go or Protobuf. ConvertToNative(typeDesc reflect.Type) (any, error) - // ConvertToType supports type conversions between value types supported by the expression language. + // ConvertToType supports type conversions between CEL value types supported by the expression language. ConvertToType(typeValue Type) Val // Equal returns true if the `other` value has the same type and content as the implementing struct. diff --git a/vendor/github.com/google/cel-go/common/types/string.go b/vendor/github.com/google/cel-go/common/types/string.go index a65cc14e4..028e6824d 100644 --- a/vendor/github.com/google/cel-go/common/types/string.go +++ b/vendor/github.com/google/cel-go/common/types/string.go @@ -24,7 +24,6 @@ import ( "github.com/google/cel-go/common/overloads" "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" @@ -36,18 +35,10 @@ import ( type String string var ( - // StringType singleton. - StringType = NewTypeValue("string", - traits.AdderType, - traits.ComparerType, - traits.MatcherType, - traits.ReceiverType, - traits.SizerType) - - stringOneArgOverloads = map[string]func(String, ref.Val) ref.Val{ - overloads.Contains: stringContains, - overloads.EndsWith: stringEndsWith, - overloads.StartsWith: stringStartsWith, + stringOneArgOverloads = map[string]func(ref.Val, ref.Val) ref.Val{ + overloads.Contains: StringContains, + overloads.EndsWith: StringEndsWith, + overloads.StartsWith: StringStartsWith, } stringWrapperType = reflect.TypeOf(&wrapperspb.StringValue{}) @@ -198,26 +189,41 @@ func (s String) Value() any { return string(s) } -func stringContains(s String, sub ref.Val) ref.Val { +// StringContains returns whether the string contains a substring. +func StringContains(s, sub ref.Val) ref.Val { + str, ok := s.(String) + if !ok { + return MaybeNoSuchOverloadErr(s) + } subStr, ok := sub.(String) if !ok { return MaybeNoSuchOverloadErr(sub) } - return Bool(strings.Contains(string(s), string(subStr))) + return Bool(strings.Contains(string(str), string(subStr))) } -func stringEndsWith(s String, suf ref.Val) ref.Val { +// StringEndsWith returns whether the target string contains the input suffix. +func StringEndsWith(s, suf ref.Val) ref.Val { + str, ok := s.(String) + if !ok { + return MaybeNoSuchOverloadErr(s) + } sufStr, ok := suf.(String) if !ok { return MaybeNoSuchOverloadErr(suf) } - return Bool(strings.HasSuffix(string(s), string(sufStr))) + return Bool(strings.HasSuffix(string(str), string(sufStr))) } -func stringStartsWith(s String, pre ref.Val) ref.Val { +// StringStartsWith returns whether the target string contains the input prefix. +func StringStartsWith(s, pre ref.Val) ref.Val { + str, ok := s.(String) + if !ok { + return MaybeNoSuchOverloadErr(s) + } preStr, ok := pre.(String) if !ok { return MaybeNoSuchOverloadErr(pre) } - return Bool(strings.HasPrefix(string(s), string(preStr))) + return Bool(strings.HasPrefix(string(str), string(preStr))) } diff --git a/vendor/github.com/google/cel-go/common/types/timestamp.go b/vendor/github.com/google/cel-go/common/types/timestamp.go index 2947cecf5..33acdea8e 100644 --- a/vendor/github.com/google/cel-go/common/types/timestamp.go +++ b/vendor/github.com/google/cel-go/common/types/timestamp.go @@ -23,7 +23,6 @@ import ( "github.com/google/cel-go/common/overloads" "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" @@ -53,15 +52,6 @@ const ( maxUnixTime int64 = 253402300799 ) -var ( - // TimestampType singleton. - TimestampType = NewTypeValue("google.protobuf.Timestamp", - traits.AdderType, - traits.ComparerType, - traits.ReceiverType, - traits.SubtractorType) -) - // Add implements traits.Adder.Add. func (t Timestamp) Add(other ref.Val) ref.Val { switch other.Type() { @@ -165,14 +155,14 @@ func (t Timestamp) Subtract(subtrahend ref.Val) ref.Val { dur := subtrahend.(Duration) val, err := subtractTimeDurationChecked(t.Time, dur.Duration) if err != nil { - return wrapErr(err) + return WrapErr(err) } return timestampOf(val) case TimestampType: t2 := subtrahend.(Timestamp).Time val, err := subtractTimeChecked(t.Time, t2) if err != nil { - return wrapErr(err) + return WrapErr(err) } return durationOf(val) } @@ -293,7 +283,7 @@ func timeZone(tz ref.Val, visitor timestampVisitor) timestampVisitor { if ind == -1 { loc, err := time.LoadLocation(val) if err != nil { - return wrapErr(err) + return WrapErr(err) } return visitor(t.In(loc)) } @@ -302,11 +292,11 @@ func timeZone(tz ref.Val, visitor timestampVisitor) timestampVisitor { // in the format ^(+|-)(0[0-9]|1[0-4]):[0-5][0-9]$. The numerical input is parsed in terms of hours and minutes. hr, err := strconv.Atoi(string(val[0:ind])) if err != nil { - return wrapErr(err) + return WrapErr(err) } min, err := strconv.Atoi(string(val[ind+1:])) if err != nil { - return wrapErr(err) + return WrapErr(err) } var offset int if string(val[0]) == "-" { diff --git a/vendor/github.com/google/cel-go/common/types/type.go b/vendor/github.com/google/cel-go/common/types/type.go deleted file mode 100644 index 164a46050..000000000 --- a/vendor/github.com/google/cel-go/common/types/type.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2018 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package types - -import ( - "fmt" - "reflect" - - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" -) - -var ( - // TypeType is the type of a TypeValue. - TypeType = NewTypeValue("type") -) - -// TypeValue is an instance of a Value that describes a value's type. -type TypeValue struct { - name string - traitMask int -} - -// NewTypeValue returns *TypeValue which is both a ref.Type and ref.Val. -func NewTypeValue(name string, traits ...int) *TypeValue { - traitMask := 0 - for _, trait := range traits { - traitMask |= trait - } - return &TypeValue{ - name: name, - traitMask: traitMask} -} - -// NewObjectTypeValue returns a *TypeValue based on the input name, which is -// annotated with the traits relevant to all objects. -func NewObjectTypeValue(name string) *TypeValue { - return NewTypeValue(name, - traits.FieldTesterType, - traits.IndexerType) -} - -// ConvertToNative implements ref.Val.ConvertToNative. -func (t *TypeValue) ConvertToNative(typeDesc reflect.Type) (any, error) { - // TODO: replace the internal type representation with a proto-value. - return nil, fmt.Errorf("type conversion not supported for 'type'") -} - -// ConvertToType implements ref.Val.ConvertToType. -func (t *TypeValue) ConvertToType(typeVal ref.Type) ref.Val { - switch typeVal { - case TypeType: - return TypeType - case StringType: - return String(t.TypeName()) - } - return NewErr("type conversion error from '%s' to '%s'", TypeType, typeVal) -} - -// Equal implements ref.Val.Equal. -func (t *TypeValue) Equal(other ref.Val) ref.Val { - otherType, ok := other.(ref.Type) - return Bool(ok && t.TypeName() == otherType.TypeName()) -} - -// HasTrait indicates whether the type supports the given trait. -// Trait codes are defined in the traits package, e.g. see traits.AdderType. -func (t *TypeValue) HasTrait(trait int) bool { - return trait&t.traitMask == trait -} - -// String implements fmt.Stringer. -func (t *TypeValue) String() string { - return t.name -} - -// Type implements ref.Val.Type. -func (t *TypeValue) Type() ref.Type { - return TypeType -} - -// TypeName gives the type's name as a string. -func (t *TypeValue) TypeName() string { - return t.name -} - -// Value implements ref.Val.Value. -func (t *TypeValue) Value() any { - return t.name -} diff --git a/vendor/github.com/google/cel-go/common/types/types.go b/vendor/github.com/google/cel-go/common/types/types.go new file mode 100644 index 000000000..76624eefd --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/types.go @@ -0,0 +1,806 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "fmt" + "reflect" + "strings" + + chkdecls "github.com/google/cel-go/checker/decls" + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// Kind indicates a CEL type's kind which is used to differentiate quickly between simple +// and complex types. +type Kind uint + +const ( + // UnspecifiedKind is returned when the type is nil or its kind is not specified. + UnspecifiedKind Kind = iota + + // DynKind represents a dynamic type. This kind only exists at type-check time. + DynKind + + // AnyKind represents a google.protobuf.Any type. This kind only exists at type-check time. + // Prefer DynKind to AnyKind as AnyKind has a specific meaning which is based on protobuf + // well-known types. + AnyKind + + // BoolKind represents a boolean type. + BoolKind + + // BytesKind represents a bytes type. + BytesKind + + // DoubleKind represents a double type. + DoubleKind + + // DurationKind represents a CEL duration type. + DurationKind + + // ErrorKind represents a CEL error type. + ErrorKind + + // IntKind represents an integer type. + IntKind + + // ListKind represents a list type. + ListKind + + // MapKind represents a map type. + MapKind + + // NullTypeKind represents a null type. + NullTypeKind + + // OpaqueKind represents an abstract type which has no accessible fields. + OpaqueKind + + // StringKind represents a string type. + StringKind + + // StructKind represents a structured object with typed fields. + StructKind + + // TimestampKind represents a a CEL time type. + TimestampKind + + // TypeKind represents the CEL type. + TypeKind + + // TypeParamKind represents a parameterized type whose type name will be resolved at type-check time, if possible. + TypeParamKind + + // UintKind represents a uint type. + UintKind + + // UnknownKind represents an unknown value type. + UnknownKind +) + +var ( + // AnyType represents the google.protobuf.Any type. + AnyType = &Type{ + kind: AnyKind, + runtimeTypeName: "google.protobuf.Any", + traitMask: traits.FieldTesterType | + traits.IndexerType, + } + // BoolType represents the bool type. + BoolType = &Type{ + kind: BoolKind, + runtimeTypeName: "bool", + traitMask: traits.ComparerType | + traits.NegatorType, + } + // BytesType represents the bytes type. + BytesType = &Type{ + kind: BytesKind, + runtimeTypeName: "bytes", + traitMask: traits.AdderType | + traits.ComparerType | + traits.SizerType, + } + // DoubleType represents the double type. + DoubleType = &Type{ + kind: DoubleKind, + runtimeTypeName: "double", + traitMask: traits.AdderType | + traits.ComparerType | + traits.DividerType | + traits.MultiplierType | + traits.NegatorType | + traits.SubtractorType, + } + // DurationType represents the CEL duration type. + DurationType = &Type{ + kind: DurationKind, + runtimeTypeName: "google.protobuf.Duration", + traitMask: traits.AdderType | + traits.ComparerType | + traits.NegatorType | + traits.ReceiverType | + traits.SubtractorType, + } + // DynType represents a dynamic CEL type whose type will be determined at runtime from context. + DynType = &Type{ + kind: DynKind, + runtimeTypeName: "dyn", + } + // ErrorType represents a CEL error value. + ErrorType = &Type{ + kind: ErrorKind, + runtimeTypeName: "error", + } + // IntType represents the int type. + IntType = &Type{ + kind: IntKind, + runtimeTypeName: "int", + traitMask: traits.AdderType | + traits.ComparerType | + traits.DividerType | + traits.ModderType | + traits.MultiplierType | + traits.NegatorType | + traits.SubtractorType, + } + // ListType represents the runtime list type. + ListType = NewListType(nil) + // MapType represents the runtime map type. + MapType = NewMapType(nil, nil) + // NullType represents the type of a null value. + NullType = &Type{ + kind: NullTypeKind, + runtimeTypeName: "null_type", + } + // StringType represents the string type. + StringType = &Type{ + kind: StringKind, + runtimeTypeName: "string", + traitMask: traits.AdderType | + traits.ComparerType | + traits.MatcherType | + traits.ReceiverType | + traits.SizerType, + } + // TimestampType represents the time type. + TimestampType = &Type{ + kind: TimestampKind, + runtimeTypeName: "google.protobuf.Timestamp", + traitMask: traits.AdderType | + traits.ComparerType | + traits.ReceiverType | + traits.SubtractorType, + } + // TypeType represents a CEL type + TypeType = &Type{ + kind: TypeKind, + runtimeTypeName: "type", + } + // UintType represents a uint type. + UintType = &Type{ + kind: UintKind, + runtimeTypeName: "uint", + traitMask: traits.AdderType | + traits.ComparerType | + traits.DividerType | + traits.ModderType | + traits.MultiplierType | + traits.SubtractorType, + } + // UnknownType represents an unknown value type. + UnknownType = &Type{ + kind: UnknownKind, + runtimeTypeName: "unknown", + } +) + +var _ ref.Type = &Type{} +var _ ref.Val = &Type{} + +// Type holds a reference to a runtime type with an optional type-checked set of type parameters. +type Type struct { + // kind indicates general category of the type. + kind Kind + + // parameters holds the optional type-checked set of type Parameters that are used during static analysis. + parameters []*Type + + // runtimeTypeName indicates the runtime type name of the type. + runtimeTypeName string + + // isAssignableType function determines whether one type is assignable to this type. + // A nil value for the isAssignableType function falls back to equality of kind, runtimeType, and parameters. + isAssignableType func(other *Type) bool + + // isAssignableRuntimeType function determines whether the runtime type (with erasure) is assignable to this type. + // A nil value for the isAssignableRuntimeType function falls back to the equality of the type or type name. + isAssignableRuntimeType func(other ref.Val) bool + + // traitMask is a mask of flags which indicate the capabilities of the type. + traitMask int +} + +// ConvertToNative implements ref.Val.ConvertToNative. +func (t *Type) ConvertToNative(typeDesc reflect.Type) (any, error) { + return nil, fmt.Errorf("type conversion not supported for 'type'") +} + +// ConvertToType implements ref.Val.ConvertToType. +func (t *Type) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case TypeType: + return TypeType + case StringType: + return String(t.TypeName()) + } + return NewErr("type conversion error from '%s' to '%s'", TypeType, typeVal) +} + +// Equal indicates whether two types have the same runtime type name. +// +// The name Equal is a bit of a misnomer, but for historical reasons, this is the +// runtime behavior. For a more accurate definition see IsType(). +func (t *Type) Equal(other ref.Val) ref.Val { + otherType, ok := other.(ref.Type) + return Bool(ok && t.TypeName() == otherType.TypeName()) +} + +// HasTrait implements the ref.Type interface method. +func (t *Type) HasTrait(trait int) bool { + return trait&t.traitMask == trait +} + +// IsExactType indicates whether the two types are exactly the same. This check also verifies type parameter type names. +func (t *Type) IsExactType(other *Type) bool { + return t.isTypeInternal(other, true) +} + +// IsEquivalentType indicates whether two types are equivalent. This check ignores type parameter type names. +func (t *Type) IsEquivalentType(other *Type) bool { + return t.isTypeInternal(other, false) +} + +// Kind indicates general category of the type. +func (t *Type) Kind() Kind { + if t == nil { + return UnspecifiedKind + } + return t.kind +} + +// isTypeInternal checks whether the two types are equivalent or exactly the same based on the checkTypeParamName flag. +func (t *Type) isTypeInternal(other *Type, checkTypeParamName bool) bool { + if t == nil { + return false + } + if t == other { + return true + } + if t.Kind() != other.Kind() || len(t.Parameters()) != len(other.Parameters()) { + return false + } + if (checkTypeParamName || t.Kind() != TypeParamKind) && t.TypeName() != other.TypeName() { + return false + } + for i, p := range t.Parameters() { + if !p.isTypeInternal(other.Parameters()[i], checkTypeParamName) { + return false + } + } + return true +} + +// IsAssignableType determines whether the current type is type-check assignable from the input fromType. +func (t *Type) IsAssignableType(fromType *Type) bool { + if t == nil { + return false + } + if t.isAssignableType != nil { + return t.isAssignableType(fromType) + } + return t.defaultIsAssignableType(fromType) +} + +// IsAssignableRuntimeType determines whether the current type is runtime assignable from the input runtimeType. +// +// At runtime, parameterized types are erased and so a function which type-checks to support a map(string, string) +// will have a runtime assignable type of a map. +func (t *Type) IsAssignableRuntimeType(val ref.Val) bool { + if t == nil { + return false + } + if t.isAssignableRuntimeType != nil { + return t.isAssignableRuntimeType(val) + } + return t.defaultIsAssignableRuntimeType(val) +} + +// Parameters returns the list of type parameters if set. +// +// For ListKind, Parameters()[0] represents the list element type +// For MapKind, Parameters()[0] represents the map key type, and Parameters()[1] represents the map +// value type. +func (t *Type) Parameters() []*Type { + if t == nil { + return emptyParams + } + return t.parameters +} + +// DeclaredTypeName indicates the fully qualified and parameterized type-check type name. +func (t *Type) DeclaredTypeName() string { + // if the type itself is neither null, nor dyn, but is assignable to null, then it's a wrapper type. + if t.Kind() != NullTypeKind && !t.isDyn() && t.IsAssignableType(NullType) { + return fmt.Sprintf("wrapper(%s)", t.TypeName()) + } + return t.TypeName() +} + +// Type implements the ref.Val interface method. +func (t *Type) Type() ref.Type { + return TypeType +} + +// Value implements the ref.Val interface method. +func (t *Type) Value() any { + return t.TypeName() +} + +// TypeName returns the type-erased fully qualified runtime type name. +// +// TypeName implements the ref.Type interface method. +func (t *Type) TypeName() string { + if t == nil { + return "" + } + return t.runtimeTypeName +} + +// String returns a human-readable definition of the type name. +func (t *Type) String() string { + if len(t.Parameters()) == 0 { + return t.DeclaredTypeName() + } + params := make([]string, len(t.Parameters())) + for i, p := range t.Parameters() { + params[i] = p.String() + } + return fmt.Sprintf("%s(%s)", t.DeclaredTypeName(), strings.Join(params, ", ")) +} + +// isDyn indicates whether the type is dynamic in any way. +func (t *Type) isDyn() bool { + k := t.Kind() + return k == DynKind || k == AnyKind || k == TypeParamKind +} + +// defaultIsAssignableType provides the standard definition of what it means for one type to be assignable to another +// where any of the following may return a true result: +// - The from types are the same instance +// - The target type is dynamic +// - The fromType has the same kind and type name as the target type, and all parameters of the target type +// +// are IsAssignableType() from the parameters of the fromType. +func (t *Type) defaultIsAssignableType(fromType *Type) bool { + if t == fromType || t.isDyn() { + return true + } + if t.Kind() != fromType.Kind() || + t.TypeName() != fromType.TypeName() || + len(t.Parameters()) != len(fromType.Parameters()) { + return false + } + for i, tp := range t.Parameters() { + fp := fromType.Parameters()[i] + if !tp.IsAssignableType(fp) { + return false + } + } + return true +} + +// defaultIsAssignableRuntimeType inspects the type and in the case of list and map elements, the key and element types +// to determine whether a ref.Val is assignable to the declared type for a function signature. +func (t *Type) defaultIsAssignableRuntimeType(val ref.Val) bool { + valType := val.Type() + // If the current type and value type don't agree, then return + if !(t.isDyn() || t.TypeName() == valType.TypeName()) { + return false + } + switch t.Kind() { + case ListKind: + elemType := t.Parameters()[0] + l := val.(traits.Lister) + if l.Size() == IntZero { + return true + } + it := l.Iterator() + elemVal := it.Next() + return elemType.IsAssignableRuntimeType(elemVal) + case MapKind: + keyType := t.Parameters()[0] + elemType := t.Parameters()[1] + m := val.(traits.Mapper) + if m.Size() == IntZero { + return true + } + it := m.Iterator() + keyVal := it.Next() + elemVal := m.Get(keyVal) + return keyType.IsAssignableRuntimeType(keyVal) && elemType.IsAssignableRuntimeType(elemVal) + } + return true +} + +// NewListType creates an instances of a list type value with the provided element type. +func NewListType(elemType *Type) *Type { + return &Type{ + kind: ListKind, + parameters: []*Type{elemType}, + runtimeTypeName: "list", + traitMask: traits.AdderType | + traits.ContainerType | + traits.IndexerType | + traits.IterableType | + traits.SizerType, + } +} + +// NewMapType creates an instance of a map type value with the provided key and value types. +func NewMapType(keyType, valueType *Type) *Type { + return &Type{ + kind: MapKind, + parameters: []*Type{keyType, valueType}, + runtimeTypeName: "map", + traitMask: traits.ContainerType | + traits.IndexerType | + traits.IterableType | + traits.SizerType, + } +} + +// NewNullableType creates an instance of a nullable type with the provided wrapped type. +// +// Note: only primitive types are supported as wrapped types. +func NewNullableType(wrapped *Type) *Type { + return &Type{ + kind: wrapped.Kind(), + parameters: wrapped.Parameters(), + runtimeTypeName: wrapped.TypeName(), + traitMask: wrapped.traitMask, + isAssignableType: func(other *Type) bool { + return NullType.IsAssignableType(other) || wrapped.IsAssignableType(other) + }, + isAssignableRuntimeType: func(other ref.Val) bool { + return NullType.IsAssignableRuntimeType(other) || wrapped.IsAssignableRuntimeType(other) + }, + } +} + +// NewOptionalType creates an abstract parameterized type instance corresponding to CEL's notion of optional. +func NewOptionalType(param *Type) *Type { + return NewOpaqueType("optional", param) +} + +// NewOpaqueType creates an abstract parameterized type with a given name. +func NewOpaqueType(name string, params ...*Type) *Type { + return &Type{ + kind: OpaqueKind, + parameters: params, + runtimeTypeName: name, + } +} + +// NewObjectType creates a type reference to an externally defined type, e.g. a protobuf message type. +// +// An object type is assumed to support field presence testing and field indexing. Additionally, the +// type may also indicate additional traits through the use of the optional traits vararg argument. +func NewObjectType(typeName string, traits ...int) *Type { + // Function sanitizes object types on the fly + if wkt, found := checkedWellKnowns[typeName]; found { + return wkt + } + traitMask := 0 + for _, trait := range traits { + traitMask |= trait + } + return &Type{ + kind: StructKind, + parameters: emptyParams, + runtimeTypeName: typeName, + traitMask: structTypeTraitMask | traitMask, + } +} + +// NewObjectTypeValue creates a type reference to an externally defined type. +// +// Deprecated: use cel.ObjectType(typeName) +func NewObjectTypeValue(typeName string) *Type { + return NewObjectType(typeName) +} + +// NewTypeValue creates an opaque type which has a set of optional type traits as defined in +// the common/types/traits package. +// +// Deprecated: use cel.ObjectType(typeName, traits) +func NewTypeValue(typeName string, traits ...int) *Type { + traitMask := 0 + for _, trait := range traits { + traitMask |= trait + } + return &Type{ + kind: StructKind, + parameters: emptyParams, + runtimeTypeName: typeName, + traitMask: traitMask, + } +} + +// NewTypeParamType creates a parameterized type instance. +func NewTypeParamType(paramName string) *Type { + return &Type{ + kind: TypeParamKind, + runtimeTypeName: paramName, + } +} + +// NewTypeTypeWithParam creates a type with a type parameter. +// Used for type-checking purposes, but equivalent to TypeType otherwise. +func NewTypeTypeWithParam(param *Type) *Type { + return &Type{ + kind: TypeKind, + runtimeTypeName: "type", + parameters: []*Type{param}, + } +} + +// TypeToExprType converts a CEL-native type representation to a protobuf CEL Type representation. +func TypeToExprType(t *Type) (*exprpb.Type, error) { + switch t.Kind() { + case AnyKind: + return chkdecls.Any, nil + case BoolKind: + return maybeWrapper(t, chkdecls.Bool), nil + case BytesKind: + return maybeWrapper(t, chkdecls.Bytes), nil + case DoubleKind: + return maybeWrapper(t, chkdecls.Double), nil + case DurationKind: + return chkdecls.Duration, nil + case DynKind: + return chkdecls.Dyn, nil + case ErrorKind: + return chkdecls.Error, nil + case IntKind: + return maybeWrapper(t, chkdecls.Int), nil + case ListKind: + if len(t.Parameters()) != 1 { + return nil, fmt.Errorf("invalid list, got %d parameters, wanted one", len(t.Parameters())) + } + et, err := TypeToExprType(t.Parameters()[0]) + if err != nil { + return nil, err + } + return chkdecls.NewListType(et), nil + case MapKind: + if len(t.Parameters()) != 2 { + return nil, fmt.Errorf("invalid map, got %d parameters, wanted two", len(t.Parameters())) + } + kt, err := TypeToExprType(t.Parameters()[0]) + if err != nil { + return nil, err + } + vt, err := TypeToExprType(t.Parameters()[1]) + if err != nil { + return nil, err + } + return chkdecls.NewMapType(kt, vt), nil + case NullTypeKind: + return chkdecls.Null, nil + case OpaqueKind: + params := make([]*exprpb.Type, len(t.Parameters())) + for i, p := range t.Parameters() { + pt, err := TypeToExprType(p) + if err != nil { + return nil, err + } + params[i] = pt + } + return chkdecls.NewAbstractType(t.TypeName(), params...), nil + case StringKind: + return maybeWrapper(t, chkdecls.String), nil + case StructKind: + return chkdecls.NewObjectType(t.TypeName()), nil + case TimestampKind: + return chkdecls.Timestamp, nil + case TypeParamKind: + return chkdecls.NewTypeParamType(t.TypeName()), nil + case TypeKind: + if len(t.Parameters()) == 1 { + p, err := TypeToExprType(t.Parameters()[0]) + if err != nil { + return nil, err + } + return chkdecls.NewTypeType(p), nil + } + return chkdecls.NewTypeType(nil), nil + case UintKind: + return maybeWrapper(t, chkdecls.Uint), nil + } + return nil, fmt.Errorf("missing type conversion to proto: %v", t) +} + +// ExprTypeToType converts a protobuf CEL type representation to a CEL-native type representation. +func ExprTypeToType(t *exprpb.Type) (*Type, error) { + switch t.GetTypeKind().(type) { + case *exprpb.Type_Dyn: + return DynType, nil + case *exprpb.Type_AbstractType_: + paramTypes := make([]*Type, len(t.GetAbstractType().GetParameterTypes())) + for i, p := range t.GetAbstractType().GetParameterTypes() { + pt, err := ExprTypeToType(p) + if err != nil { + return nil, err + } + paramTypes[i] = pt + } + return NewOpaqueType(t.GetAbstractType().GetName(), paramTypes...), nil + case *exprpb.Type_ListType_: + et, err := ExprTypeToType(t.GetListType().GetElemType()) + if err != nil { + return nil, err + } + return NewListType(et), nil + case *exprpb.Type_MapType_: + kt, err := ExprTypeToType(t.GetMapType().GetKeyType()) + if err != nil { + return nil, err + } + vt, err := ExprTypeToType(t.GetMapType().GetValueType()) + if err != nil { + return nil, err + } + return NewMapType(kt, vt), nil + case *exprpb.Type_MessageType: + return NewObjectType(t.GetMessageType()), nil + case *exprpb.Type_Null: + return NullType, nil + case *exprpb.Type_Primitive: + switch t.GetPrimitive() { + case exprpb.Type_BOOL: + return BoolType, nil + case exprpb.Type_BYTES: + return BytesType, nil + case exprpb.Type_DOUBLE: + return DoubleType, nil + case exprpb.Type_INT64: + return IntType, nil + case exprpb.Type_STRING: + return StringType, nil + case exprpb.Type_UINT64: + return UintType, nil + default: + return nil, fmt.Errorf("unsupported primitive type: %v", t) + } + case *exprpb.Type_TypeParam: + return NewTypeParamType(t.GetTypeParam()), nil + case *exprpb.Type_Type: + if t.GetType().GetTypeKind() != nil { + p, err := ExprTypeToType(t.GetType()) + if err != nil { + return nil, err + } + return NewTypeTypeWithParam(p), nil + } + return TypeType, nil + case *exprpb.Type_WellKnown: + switch t.GetWellKnown() { + case exprpb.Type_ANY: + return AnyType, nil + case exprpb.Type_DURATION: + return DurationType, nil + case exprpb.Type_TIMESTAMP: + return TimestampType, nil + default: + return nil, fmt.Errorf("unsupported well-known type: %v", t) + } + case *exprpb.Type_Wrapper: + t, err := ExprTypeToType(&exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: t.GetWrapper()}}) + if err != nil { + return nil, err + } + return NewNullableType(t), nil + case *exprpb.Type_Error: + return ErrorType, nil + default: + return nil, fmt.Errorf("unsupported type: %v", t) + } +} + +func maybeWrapper(t *Type, pbType *exprpb.Type) *exprpb.Type { + if t.IsAssignableType(NullType) { + return chkdecls.NewWrapperType(pbType) + } + return pbType +} + +func maybeForeignType(t ref.Type) *Type { + if celType, ok := t.(*Type); ok { + return celType + } + // Inspect the incoming type to determine its traits. The assumption will be that the incoming + // type does not have any field values; however, if the trait mask indicates that field testing + // and indexing are supported, the foreign type is marked as a struct. + traitMask := 0 + for _, trait := range allTraits { + if t.HasTrait(trait) { + traitMask |= trait + } + } + // Treat the value like a struct. If it has no fields, this is harmless to denote the type + // as such since it basically becomes an opaque type by convention. + return NewObjectType(t.TypeName(), traitMask) +} + +var ( + checkedWellKnowns = map[string]*Type{ + // Wrapper types. + "google.protobuf.BoolValue": NewNullableType(BoolType), + "google.protobuf.BytesValue": NewNullableType(BytesType), + "google.protobuf.DoubleValue": NewNullableType(DoubleType), + "google.protobuf.FloatValue": NewNullableType(DoubleType), + "google.protobuf.Int64Value": NewNullableType(IntType), + "google.protobuf.Int32Value": NewNullableType(IntType), + "google.protobuf.UInt64Value": NewNullableType(UintType), + "google.protobuf.UInt32Value": NewNullableType(UintType), + "google.protobuf.StringValue": NewNullableType(StringType), + // Well-known types. + "google.protobuf.Any": AnyType, + "google.protobuf.Duration": DurationType, + "google.protobuf.Timestamp": TimestampType, + // Json types. + "google.protobuf.ListValue": NewListType(DynType), + "google.protobuf.NullValue": NullType, + "google.protobuf.Struct": NewMapType(StringType, DynType), + "google.protobuf.Value": DynType, + } + + emptyParams = []*Type{} + + allTraits = []int{ + traits.AdderType, + traits.ComparerType, + traits.ContainerType, + traits.DividerType, + traits.FieldTesterType, + traits.IndexerType, + traits.IterableType, + traits.IteratorType, + traits.MatcherType, + traits.ModderType, + traits.MultiplierType, + traits.NegatorType, + traits.ReceiverType, + traits.SizerType, + traits.SubtractorType, + } + + structTypeTraitMask = traits.FieldTesterType | traits.IndexerType +) diff --git a/vendor/github.com/google/cel-go/common/types/uint.go b/vendor/github.com/google/cel-go/common/types/uint.go index 988e6f1ac..3257f9ade 100644 --- a/vendor/github.com/google/cel-go/common/types/uint.go +++ b/vendor/github.com/google/cel-go/common/types/uint.go @@ -21,7 +21,6 @@ import ( "strconv" "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" @@ -32,15 +31,6 @@ import ( type Uint uint64 var ( - // UintType singleton. - UintType = NewTypeValue("uint", - traits.AdderType, - traits.ComparerType, - traits.DividerType, - traits.ModderType, - traits.MultiplierType, - traits.SubtractorType) - uint32WrapperType = reflect.TypeOf(&wrapperspb.UInt32Value{}) uint64WrapperType = reflect.TypeOf(&wrapperspb.UInt64Value{}) @@ -59,7 +49,7 @@ func (i Uint) Add(other ref.Val) ref.Val { } val, err := addUint64Checked(uint64(i), uint64(otherUint)) if err != nil { - return wrapErr(err) + return WrapErr(err) } return Uint(val) } @@ -149,7 +139,7 @@ func (i Uint) ConvertToType(typeVal ref.Type) ref.Val { case IntType: v, err := uint64ToInt64Checked(uint64(i)) if err != nil { - return wrapErr(err) + return WrapErr(err) } return Int(v) case UintType: @@ -172,7 +162,7 @@ func (i Uint) Divide(other ref.Val) ref.Val { } div, err := divideUint64Checked(uint64(i), uint64(otherUint)) if err != nil { - return wrapErr(err) + return WrapErr(err) } return Uint(div) } @@ -207,7 +197,7 @@ func (i Uint) Modulo(other ref.Val) ref.Val { } mod, err := moduloUint64Checked(uint64(i), uint64(otherUint)) if err != nil { - return wrapErr(err) + return WrapErr(err) } return Uint(mod) } @@ -220,7 +210,7 @@ func (i Uint) Multiply(other ref.Val) ref.Val { } val, err := multiplyUint64Checked(uint64(i), uint64(otherUint)) if err != nil { - return wrapErr(err) + return WrapErr(err) } return Uint(val) } @@ -233,7 +223,7 @@ func (i Uint) Subtract(subtrahend ref.Val) ref.Val { } val, err := subtractUint64Checked(uint64(i), uint64(subtraUint)) if err != nil { - return wrapErr(err) + return WrapErr(err) } return Uint(val) } diff --git a/vendor/github.com/google/cel-go/common/types/unknown.go b/vendor/github.com/google/cel-go/common/types/unknown.go index bc411c15b..9dd2b2579 100644 --- a/vendor/github.com/google/cel-go/common/types/unknown.go +++ b/vendor/github.com/google/cel-go/common/types/unknown.go @@ -15,52 +15,312 @@ package types import ( + "fmt" + "math" "reflect" + "sort" + "strings" + "unicode" "github.com/google/cel-go/common/types/ref" ) -// Unknown type implementation which collects expression ids which caused the -// current value to become unknown. -type Unknown []int64 - var ( - // UnknownType singleton. - UnknownType = NewTypeValue("unknown") + unspecifiedAttribute = &AttributeTrail{qualifierPath: []any{}} ) +// NewAttributeTrail creates a new simple attribute from a variable name. +func NewAttributeTrail(variable string) *AttributeTrail { + if variable == "" { + return unspecifiedAttribute + } + return &AttributeTrail{variable: variable} +} + +// AttributeTrail specifies a variable with an optional qualifier path. An attribute value is expected to +// correspond to an AbsoluteAttribute, meaning a field selection which starts with a top-level variable. +// +// The qualifer path elements adhere to the AttributeQualifier type constraint. +type AttributeTrail struct { + variable string + qualifierPath []any +} + +// Equal returns whether two attribute values have the same variable name and qualifier paths. +func (a *AttributeTrail) Equal(other *AttributeTrail) bool { + if a.Variable() != other.Variable() || len(a.QualifierPath()) != len(other.QualifierPath()) { + return false + } + for i, q := range a.QualifierPath() { + qual := other.QualifierPath()[i] + if !qualifiersEqual(q, qual) { + return false + } + } + return true +} + +func qualifiersEqual(a, b any) bool { + if a == b { + return true + } + switch numA := a.(type) { + case int64: + numB, ok := b.(uint64) + if !ok { + return false + } + return intUintEqual(numA, numB) + case uint64: + numB, ok := b.(int64) + if !ok { + return false + } + return intUintEqual(numB, numA) + default: + return false + } +} + +func intUintEqual(i int64, u uint64) bool { + if i < 0 || u > math.MaxInt64 { + return false + } + return i == int64(u) +} + +// Variable returns the variable name associated with the attribute. +func (a *AttributeTrail) Variable() string { + return a.variable +} + +// QualifierPath returns the optional set of qualifying fields or indices applied to the variable. +func (a *AttributeTrail) QualifierPath() []any { + return a.qualifierPath +} + +// String returns the string representation of the Attribute. +func (a *AttributeTrail) String() string { + if a.variable == "" { + return "" + } + var str strings.Builder + str.WriteString(a.variable) + for _, q := range a.qualifierPath { + switch q := q.(type) { + case bool, int64: + str.WriteString(fmt.Sprintf("[%v]", q)) + case uint64: + str.WriteString(fmt.Sprintf("[%vu]", q)) + case string: + if isIdentifierCharacter(q) { + str.WriteString(fmt.Sprintf(".%v", q)) + } else { + str.WriteString(fmt.Sprintf("[%q]", q)) + } + } + } + return str.String() +} + +func isIdentifierCharacter(str string) bool { + for _, c := range str { + if unicode.IsLetter(c) || unicode.IsDigit(c) || string(c) == "_" { + continue + } + return false + } + return true +} + +// AttributeQualifier constrains the possible types which may be used to qualify an attribute. +type AttributeQualifier interface { + bool | int64 | uint64 | string +} + +// QualifyAttribute qualifies an attribute using a valid AttributeQualifier type. +func QualifyAttribute[T AttributeQualifier](attr *AttributeTrail, qualifier T) *AttributeTrail { + attr.qualifierPath = append(attr.qualifierPath, qualifier) + return attr +} + +// Unknown type which collects expression ids which caused the current value to become unknown. +type Unknown struct { + attributeTrails map[int64][]*AttributeTrail +} + +// NewUnknown creates a new unknown at a given expression id for an attribute. +// +// If the attribute is nil, the attribute value will be the `unspecifiedAttribute`. +func NewUnknown(id int64, attr *AttributeTrail) *Unknown { + if attr == nil { + attr = unspecifiedAttribute + } + return &Unknown{ + attributeTrails: map[int64][]*AttributeTrail{id: {attr}}, + } +} + +// IDs returns the set of unknown expression ids contained by this value. +// +// Numeric identifiers are guaranteed to be in sorted order. +func (u *Unknown) IDs() []int64 { + ids := make(int64Slice, len(u.attributeTrails)) + i := 0 + for id := range u.attributeTrails { + ids[i] = id + i++ + } + ids.Sort() + return ids +} + +// GetAttributeTrails returns the attribute trails, if present, missing for a given expression id. +func (u *Unknown) GetAttributeTrails(id int64) ([]*AttributeTrail, bool) { + trails, found := u.attributeTrails[id] + return trails, found +} + +// Contains returns true if the input unknown is a subset of the current unknown. +func (u *Unknown) Contains(other *Unknown) bool { + for id, otherTrails := range other.attributeTrails { + trails, found := u.attributeTrails[id] + if !found || len(otherTrails) != len(trails) { + return false + } + for _, ot := range otherTrails { + found := false + for _, t := range trails { + if t.Equal(ot) { + found = true + break + } + } + if !found { + return false + } + } + } + return true +} + // ConvertToNative implements ref.Val.ConvertToNative. -func (u Unknown) ConvertToNative(typeDesc reflect.Type) (any, error) { +func (u *Unknown) ConvertToNative(typeDesc reflect.Type) (any, error) { return u.Value(), nil } // ConvertToType is an identity function since unknown values cannot be modified. -func (u Unknown) ConvertToType(typeVal ref.Type) ref.Val { +func (u *Unknown) ConvertToType(typeVal ref.Type) ref.Val { return u } // Equal is an identity function since unknown values cannot be modified. -func (u Unknown) Equal(other ref.Val) ref.Val { +func (u *Unknown) Equal(other ref.Val) ref.Val { return u } +// String implements the Stringer interface +func (u *Unknown) String() string { + var str strings.Builder + for id, attrs := range u.attributeTrails { + if str.Len() != 0 { + str.WriteString(", ") + } + if len(attrs) == 1 { + str.WriteString(fmt.Sprintf("%v (%d)", attrs[0], id)) + } else { + str.WriteString(fmt.Sprintf("%v (%d)", attrs, id)) + } + } + return str.String() +} + // Type implements ref.Val.Type. -func (u Unknown) Type() ref.Type { +func (u *Unknown) Type() ref.Type { return UnknownType } // Value implements ref.Val.Value. -func (u Unknown) Value() any { - return []int64(u) +func (u *Unknown) Value() any { + return u } -// IsUnknown returns whether the element ref.Type or ref.Val is equal to the -// UnknownType singleton. +// IsUnknown returns whether the element ref.Val is in instance of *types.Unknown func IsUnknown(val ref.Val) bool { switch val.(type) { - case Unknown: + case *Unknown: return true default: return false } } + +// MaybeMergeUnknowns determines whether an input value and another, possibly nil, unknown will produce +// an unknown result. +// +// If the input `val` is another Unknown, then the result will be the merge of the `val` and the input +// `unk`. If the `val` is not unknown, then the result will depend on whether the input `unk` is nil. +// If both values are non-nil and unknown, then the return value will be a merge of both unknowns. +func MaybeMergeUnknowns(val ref.Val, unk *Unknown) (*Unknown, bool) { + src, isUnk := val.(*Unknown) + if !isUnk { + if unk != nil { + return unk, true + } + return unk, false + } + return MergeUnknowns(src, unk), true +} + +// MergeUnknowns combines two unknown values into a new unknown value. +func MergeUnknowns(unk1, unk2 *Unknown) *Unknown { + if unk1 == nil { + return unk2 + } + if unk2 == nil { + return unk1 + } + out := &Unknown{ + attributeTrails: make(map[int64][]*AttributeTrail, len(unk1.attributeTrails)+len(unk2.attributeTrails)), + } + for id, ats := range unk1.attributeTrails { + out.attributeTrails[id] = ats + } + for id, ats := range unk2.attributeTrails { + existing, found := out.attributeTrails[id] + if !found { + out.attributeTrails[id] = ats + continue + } + + for _, at := range ats { + found := false + for _, et := range existing { + if at.Equal(et) { + found = true + break + } + } + if !found { + existing = append(existing, at) + } + } + out.attributeTrails[id] = existing + } + return out +} + +// int64Slice is an implementation of the sort.Interface +type int64Slice []int64 + +// Len returns the number of elements in the slice. +func (x int64Slice) Len() int { return len(x) } + +// Less indicates whether the value at index i is less than the value at index j. +func (x int64Slice) Less(i, j int) bool { return x[i] < x[j] } + +// Swap swaps the values at indices i and j in place. +func (x int64Slice) Swap(i, j int) { x[i], x[j] = x[j], x[i] } + +// Sort is a convenience method: x.Sort() calls Sort(x). +func (x int64Slice) Sort() { sort.Sort(x) } diff --git a/vendor/github.com/google/cel-go/common/types/util.go b/vendor/github.com/google/cel-go/common/types/util.go index a8e9afa9e..71662eee3 100644 --- a/vendor/github.com/google/cel-go/common/types/util.go +++ b/vendor/github.com/google/cel-go/common/types/util.go @@ -21,7 +21,7 @@ import ( // IsUnknownOrError returns whether the input element ref.Val is an ErrType or UnknownType. func IsUnknownOrError(val ref.Val) bool { switch val.(type) { - case Unknown, *Err: + case *Unknown, *Err: return true } return false diff --git a/vendor/github.com/google/cel-go/interpreter/BUILD.bazel b/vendor/github.com/google/cel-go/interpreter/BUILD.bazel index 04a3ec744..3a5219eb5 100644 --- a/vendor/github.com/google/cel-go/interpreter/BUILD.bazel +++ b/vendor/github.com/google/cel-go/interpreter/BUILD.bazel @@ -11,10 +11,10 @@ go_library( "activation.go", "attribute_patterns.go", "attributes.go", - "coster.go", "decorators.go", "dispatcher.go", "evalstate.go", + "formatting.go", "interpretable.go", "interpreter.go", "optimizations.go", @@ -25,14 +25,15 @@ go_library( importpath = "github.com/google/cel-go/interpreter", deps = [ "//common:go_default_library", + "//common/ast:go_default_library", "//common/containers:go_default_library", + "//common/functions:go_default_library", "//common/operators:go_default_library", "//common/overloads:go_default_library", "//common/types:go_default_library", "//common/types/ref:go_default_library", "//common/types/traits:go_default_library", - "//interpreter/functions:go_default_library", - "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//types/known/durationpb:go_default_library", "@org_golang_google_protobuf//types/known/structpb:go_default_library", @@ -49,23 +50,25 @@ go_test( "attributes_test.go", "interpreter_test.go", "prune_test.go", + "runtimecost_test.go", ], embed = [ ":go_default_library", ], deps = [ "//checker:go_default_library", - "//checker/decls:go_default_library", "//common/containers:go_default_library", "//common/debug:go_default_library", + "//common/decls:go_default_library", + "//common/functions:go_default_library", "//common/operators:go_default_library", + "//common/stdlib:go_default_library", "//common/types:go_default_library", - "//interpreter/functions:go_default_library", "//parser:go_default_library", "//test:go_default_library", "//test/proto2pb:go_default_library", "//test/proto3pb:go_default_library", - "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//types/known/anypb:go_default_library", ], diff --git a/vendor/github.com/google/cel-go/interpreter/activation.go b/vendor/github.com/google/cel-go/interpreter/activation.go index f82e4e903..a80264451 100644 --- a/vendor/github.com/google/cel-go/interpreter/activation.go +++ b/vendor/github.com/google/cel-go/interpreter/activation.go @@ -58,7 +58,7 @@ func (emptyActivation) Parent() Activation { return nil } // The output of the lazy binding will overwrite the variable reference in the internal map. // // Values which are not represented as ref.Val types on input may be adapted to a ref.Val using -// the ref.TypeAdapter configured in the environment. +// the types.Adapter configured in the environment. func NewActivation(bindings any) (Activation, error) { if bindings == nil { return nil, errors.New("bindings must be non-nil") diff --git a/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go b/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go index afb7c8d5b..1fbaaf17e 100644 --- a/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go +++ b/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go @@ -15,6 +15,8 @@ package interpreter import ( + "fmt" + "github.com/google/cel-go/common/containers" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" @@ -177,8 +179,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 ref.TypeAdapter, - provider ref.TypeProvider) AttributeFactory { + adapter types.Adapter, + provider types.Provider) AttributeFactory { fac := NewAttributeFactory(container, adapter, provider) return &partialAttributeFactory{ AttributeFactory: fac, @@ -191,8 +193,8 @@ func NewPartialAttributeFactory(container *containers.Container, type partialAttributeFactory struct { AttributeFactory container *containers.Container - adapter ref.TypeAdapter - provider ref.TypeProvider + adapter types.Adapter + provider types.Provider } // AbsoluteAttribute implementation of the AttributeFactory interface which wraps the @@ -241,12 +243,15 @@ func (fac *partialAttributeFactory) matchesUnknownPatterns( vars PartialActivation, attrID int64, variableNames []string, - qualifiers []Qualifier) (types.Unknown, error) { + qualifiers []Qualifier) (*types.Unknown, error) { patterns := vars.UnknownAttributePatterns() candidateIndices := map[int]struct{}{} for _, variable := range variableNames { for i, pat := range patterns { if pat.VariableMatches(variable) { + if len(qualifiers) == 0 { + return types.NewUnknown(attrID, types.NewAttributeTrail(variable)), nil + } candidateIndices[i] = struct{}{} } } @@ -255,10 +260,6 @@ func (fac *partialAttributeFactory) matchesUnknownPatterns( if len(candidateIndices) == 0 { return nil, nil } - // Determine whether to return early if there are no qualifiers. - if len(qualifiers) == 0 { - return types.Unknown{attrID}, nil - } // Resolve the attribute qualifiers into a static set. This prevents more dynamic // Attribute resolutions than necessary when there are multiple unknown patterns // that traverse the same Attribute-based qualifier field. @@ -300,7 +301,28 @@ func (fac *partialAttributeFactory) matchesUnknownPatterns( } } if isUnk { - return types.Unknown{matchExprID}, nil + attr := types.NewAttributeTrail(pat.variable) + for i := 0; i < len(qualPats) && i < len(newQuals); i++ { + if qual, ok := newQuals[i].(ConstantQualifier); ok { + switch v := qual.Value().Value().(type) { + case bool: + types.QualifyAttribute[bool](attr, v) + case float64: + types.QualifyAttribute[int64](attr, int64(v)) + case int64: + types.QualifyAttribute[int64](attr, v) + case string: + types.QualifyAttribute[string](attr, v) + case uint64: + types.QualifyAttribute[uint64](attr, v) + default: + types.QualifyAttribute[string](attr, fmt.Sprintf("%v", v)) + } + } else { + types.QualifyAttribute[string](attr, "*") + } + } + return types.NewUnknown(matchExprID, attr), nil } } return nil, nil diff --git a/vendor/github.com/google/cel-go/interpreter/attributes.go b/vendor/github.com/google/cel-go/interpreter/attributes.go index fa1c2f985..ca97bdfcf 100644 --- a/vendor/github.com/google/cel-go/interpreter/attributes.go +++ b/vendor/github.com/google/cel-go/interpreter/attributes.go @@ -16,14 +16,12 @@ package interpreter import ( "fmt" - "math" + "strings" "github.com/google/cel-go/common/containers" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/common/types/traits" - - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) // AttributeFactory provides methods creating Attribute and Qualifier values. @@ -61,7 +59,7 @@ type AttributeFactory interface { // The qualifier may consider the object type being qualified, if present. If absent, the // qualification should be considered dynamic and the qualification should still work, though // it may be sub-optimal. - NewQualifier(objType *exprpb.Type, qualID int64, val any, opt bool) (Qualifier, error) + NewQualifier(objType *types.Type, qualID int64, val any, opt bool) (Qualifier, error) } // Qualifier marker interface for designating different qualifier values and where they appear @@ -131,7 +129,7 @@ type NamespacedAttribute interface { // 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 ref.TypeAdapter, p ref.TypeProvider) AttributeFactory { +func NewAttributeFactory(cont *containers.Container, a types.Adapter, p types.Provider) AttributeFactory { return &attrFactory{ container: cont, adapter: a, @@ -141,8 +139,8 @@ func NewAttributeFactory(cont *containers.Container, a ref.TypeAdapter, p ref.Ty type attrFactory struct { container *containers.Container - adapter ref.TypeAdapter - provider ref.TypeProvider + adapter types.Adapter + provider types.Provider } // AbsoluteAttribute refers to a variable value and an optional qualifier path. @@ -199,13 +197,13 @@ func (r *attrFactory) RelativeAttribute(id int64, operand Interpretable) Attribu } // NewQualifier is an implementation of the AttributeFactory interface. -func (r *attrFactory) NewQualifier(objType *exprpb.Type, qualID int64, val any, opt bool) (Qualifier, error) { +func (r *attrFactory) NewQualifier(objType *types.Type, qualID int64, val any, opt bool) (Qualifier, error) { // Before creating a new qualifier check to see if this is a protobuf message field access. // If so, use the precomputed GetFrom qualification method rather than the standard // stringQualifier. str, isStr := val.(string) - if isStr && objType != nil && objType.GetMessageType() != "" { - ft, found := r.provider.FindFieldType(objType.GetMessageType(), str) + if isStr && objType != nil && objType.Kind() == types.StructKind { + ft, found := r.provider.FindStructFieldType(objType.TypeName(), str) if found && ft.IsSet != nil && ft.GetFrom != nil { return &fieldQualifier{ id: qualID, @@ -225,14 +223,18 @@ type absoluteAttribute struct { // (package) of the expression. namespaceNames []string qualifiers []Qualifier - adapter ref.TypeAdapter - provider ref.TypeProvider + adapter types.Adapter + provider types.Provider fac AttributeFactory } // ID implements the Attribute interface method. func (a *absoluteAttribute) ID() int64 { - return a.id + qualCount := len(a.qualifiers) + if qualCount == 0 { + return a.id + } + return a.qualifiers[qualCount-1].ID() } // IsOptional returns trivially false for an attribute as the attribute represents a fully @@ -242,18 +244,6 @@ func (a *absoluteAttribute) IsOptional() bool { return false } -// Cost implements the Coster interface method. -func (a *absoluteAttribute) Cost() (min, max int64) { - for _, q := range a.qualifiers { - minQ, maxQ := estimateCost(q) - min += minQ - max += maxQ - } - min++ // For object retrieval. - max++ - return -} - // AddQualifier implements the Attribute interface method. func (a *absoluteAttribute) AddQualifier(qual Qualifier) (Attribute, error) { a.qualifiers = append(a.qualifiers, qual) @@ -302,7 +292,11 @@ func (a *absoluteAttribute) Resolve(vars Activation) (any, error) { return nil, err } if isOpt { - return types.OptionalOf(a.adapter.NativeToValue(obj)), nil + val := a.adapter.NativeToValue(obj) + if types.IsUnknown(val) { + return val, nil + } + return types.OptionalOf(val), nil } return obj, nil } @@ -314,7 +308,14 @@ func (a *absoluteAttribute) Resolve(vars Activation) (any, error) { } } } - return nil, missingAttribute(a.String()) + var attrNames strings.Builder + for i, nm := range a.namespaceNames { + if i != 0 { + attrNames.WriteString(", ") + } + attrNames.WriteString(nm) + } + return nil, missingAttribute(attrNames.String()) } type conditionalAttribute struct { @@ -322,12 +323,17 @@ type conditionalAttribute struct { expr Interpretable truthy Attribute falsy Attribute - adapter ref.TypeAdapter + adapter types.Adapter fac AttributeFactory } // ID is an implementation of the Attribute interface method. func (a *conditionalAttribute) ID() int64 { + // There's a field access after the conditional. + if a.truthy.ID() == a.falsy.ID() { + return a.truthy.ID() + } + // Otherwise return the conditional id as the consistent id being tracked. return a.id } @@ -338,16 +344,6 @@ func (a *conditionalAttribute) IsOptional() bool { return false } -// Cost provides the heuristic cost of a ternary operation ? : . -// The cost is computed as cost(expr) plus the min/max costs of evaluating either -// `t` or `f`. -func (a *conditionalAttribute) Cost() (min, max int64) { - tMin, tMax := estimateCost(a.truthy) - fMin, fMax := estimateCost(a.falsy) - eMin, eMax := estimateCost(a.expr) - return eMin + findMin(tMin, fMin), eMax + findMax(tMax, fMax) -} - // AddQualifier appends the same qualifier to both sides of the conditional, in effect managing // the qualification of alternate attributes. func (a *conditionalAttribute) AddQualifier(qual Qualifier) (Attribute, error) { @@ -395,14 +391,14 @@ func (a *conditionalAttribute) String() string { type maybeAttribute struct { id int64 attrs []NamespacedAttribute - adapter ref.TypeAdapter - provider ref.TypeProvider + adapter types.Adapter + provider types.Provider fac AttributeFactory } // ID is an implementation of the Attribute interface method. func (a *maybeAttribute) ID() int64 { - return a.id + return a.attrs[0].ID() } // IsOptional returns trivially false for an attribute as the attribute represents a fully @@ -412,18 +408,6 @@ func (a *maybeAttribute) IsOptional() bool { return false } -// Cost implements the Coster interface method. The min cost is computed as the minimal cost among -// all the possible attributes, the max cost ditto. -func (a *maybeAttribute) Cost() (min, max int64) { - min, max = math.MaxInt64, 0 - for _, a := range a.attrs { - minA, maxA := estimateCost(a) - min = findMin(min, minA) - max = findMax(max, maxA) - } - return -} - // AddQualifier adds a qualifier to each possible attribute variant, and also creates // a new namespaced variable from the qualified value. // @@ -471,7 +455,9 @@ func (a *maybeAttribute) AddQualifier(qual Qualifier) (Attribute, error) { } } // Next, ensure the most specific variable / type reference is searched first. - a.attrs = append([]NamespacedAttribute{a.fac.AbsoluteAttribute(qual.ID(), augmentedNames...)}, a.attrs...) + if len(augmentedNames) != 0 { + a.attrs = append([]NamespacedAttribute{a.fac.AbsoluteAttribute(qual.ID(), augmentedNames...)}, a.attrs...) + } return a, nil } @@ -523,13 +509,17 @@ type relativeAttribute struct { id int64 operand Interpretable qualifiers []Qualifier - adapter ref.TypeAdapter + adapter types.Adapter fac AttributeFactory } // ID is an implementation of the Attribute interface method. func (a *relativeAttribute) ID() int64 { - return a.id + qualCount := len(a.qualifiers) + if qualCount == 0 { + return a.id + } + return a.qualifiers[qualCount-1].ID() } // IsOptional returns trivially false for an attribute as the attribute represents a fully @@ -539,17 +529,6 @@ func (a *relativeAttribute) IsOptional() bool { return false } -// Cost implements the Coster interface method. -func (a *relativeAttribute) Cost() (min, max int64) { - min, max = estimateCost(a.operand) - for _, qual := range a.qualifiers { - minQ, maxQ := estimateCost(qual) - min += minQ - max += maxQ - } - return -} - // AddQualifier implements the Attribute interface method. func (a *relativeAttribute) AddQualifier(qual Qualifier) (Attribute, error) { a.qualifiers = append(a.qualifiers, qual) @@ -581,7 +560,11 @@ func (a *relativeAttribute) Resolve(vars Activation) (any, error) { return nil, err } if isOpt { - return types.OptionalOf(a.adapter.NativeToValue(obj)), nil + val := a.adapter.NativeToValue(obj) + if types.IsUnknown(val) { + return val, nil + } + return types.OptionalOf(val), nil } return obj, nil } @@ -591,7 +574,7 @@ func (a *relativeAttribute) String() string { return fmt.Sprintf("id: %v, operand: %v", a.id, a.operand) } -func newQualifier(adapter ref.TypeAdapter, id int64, v any, opt bool) (Qualifier, error) { +func newQualifier(adapter types.Adapter, id int64, v any, opt bool) (Qualifier, error) { var qual Qualifier switch val := v.(type) { case Attribute: @@ -672,7 +655,7 @@ func newQualifier(adapter ref.TypeAdapter, id int64, v any, opt bool) (Qualifier qual = &doubleQualifier{ id: id, value: float64(val), celValue: val, adapter: adapter, optional: opt, } - case types.Unknown: + case *types.Unknown: qual = &unknownQualifier{id: id, value: val} default: if q, ok := v.(Qualifier); ok { @@ -700,16 +683,11 @@ func (q *attrQualifier) IsOptional() bool { return q.optional } -// Cost returns zero for constant field qualifiers -func (q *attrQualifier) Cost() (min, max int64) { - return estimateCost(q.Attribute) -} - type stringQualifier struct { id int64 value string celValue ref.Val - adapter ref.TypeAdapter + adapter types.Adapter optional bool } @@ -806,16 +784,11 @@ func (q *stringQualifier) Value() ref.Val { return q.celValue } -// Cost returns zero for constant field qualifiers -func (q *stringQualifier) Cost() (min, max int64) { - return 0, 0 -} - type intQualifier struct { id int64 value int64 celValue ref.Val - adapter ref.TypeAdapter + adapter types.Adapter optional bool } @@ -938,16 +911,11 @@ func (q *intQualifier) Value() ref.Val { return q.celValue } -// Cost returns zero for constant field qualifiers -func (q *intQualifier) Cost() (min, max int64) { - return 0, 0 -} - type uintQualifier struct { id int64 value uint64 celValue ref.Val - adapter ref.TypeAdapter + adapter types.Adapter optional bool } @@ -1008,16 +976,11 @@ func (q *uintQualifier) Value() ref.Val { return q.celValue } -// Cost returns zero for constant field qualifiers -func (q *uintQualifier) Cost() (min, max int64) { - return 0, 0 -} - type boolQualifier struct { id int64 value bool celValue ref.Val - adapter ref.TypeAdapter + adapter types.Adapter optional bool } @@ -1064,19 +1027,14 @@ func (q *boolQualifier) Value() ref.Val { return q.celValue } -// Cost returns zero for constant field qualifiers -func (q *boolQualifier) Cost() (min, max int64) { - return 0, 0 -} - // fieldQualifier indicates that the qualification is a well-defined field with a known // field type. When the field type is known this can be used to improve the speed and // efficiency of field resolution. type fieldQualifier struct { id int64 Name string - FieldType *ref.FieldType - adapter ref.TypeAdapter + FieldType *types.FieldType + adapter types.Adapter optional bool } @@ -1125,11 +1083,6 @@ func (q *fieldQualifier) Value() ref.Val { return types.String(q.Name) } -// Cost returns zero for constant field qualifiers -func (q *fieldQualifier) Cost() (min, max int64) { - return 0, 0 -} - // doubleQualifier qualifies a CEL object, map, or list using a double value. // // This qualifier is used for working with dynamic data like JSON or protobuf.Any where the value @@ -1139,7 +1092,7 @@ type doubleQualifier struct { id int64 value float64 celValue ref.Val - adapter ref.TypeAdapter + adapter types.Adapter optional bool } @@ -1176,7 +1129,7 @@ func (q *doubleQualifier) Value() ref.Val { // for any value subject to qualification. This is consistent with CEL's unknown handling elsewhere. type unknownQualifier struct { id int64 - value types.Unknown + value *types.Unknown } // ID is an implementation of the Qualifier interface method. @@ -1224,6 +1177,9 @@ func applyQualifiers(vars Activation, obj any, qualifiers []Qualifier) (any, boo return nil, false, err } if !present { + // We return optional none here with a presence of 'false' as the layers + // above will attempt to call types.OptionalOf() on a present value if any + // of the qualifiers is optional. return types.OptionalNone, false, nil } } else { @@ -1267,15 +1223,17 @@ 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 ref.TypeAdapter, obj any, idx ref.Val, presenceTest, presenceOnly bool) (ref.Val, bool, error) { +func refQualify(adapter types.Adapter, obj any, idx ref.Val, presenceTest, presenceOnly bool) (ref.Val, bool, error) { celVal := adapter.NativeToValue(obj) switch v := celVal.(type) { - case types.Unknown: + case *types.Unknown: return v, true, nil case *types.Err: return nil, false, v case traits.Mapper: val, found := v.Find(idx) + // If the index is of the wrong type for the map, then it is possible + // for the Find call to produce an error. if types.IsError(val) { return nil, false, val.(*types.Err) } @@ -1287,6 +1245,8 @@ func refQualify(adapter ref.TypeAdapter, obj any, idx ref.Val, presenceTest, pre } return nil, false, missingKey(idx) case traits.Lister: + // If the index argument is not a valid numeric type, then it is possible + // for the index operation to produce an error. i, err := types.IndexOrError(idx) if err != nil { return nil, false, err @@ -1307,6 +1267,8 @@ func refQualify(adapter ref.TypeAdapter, obj any, idx ref.Val, presenceTest, pre if types.IsError(presence) { return nil, false, presence.(*types.Err) } + // If not found or presence only test, then return. + // Otherwise, if found, obtain the value later on. if presenceOnly || presence == types.False { return nil, presence == types.True, nil } @@ -1364,7 +1326,7 @@ func (e *resolutionError) Error() string { return fmt.Sprintf("index out of bounds: %v", e.missingIndex) } if e.missingAttribute != "" { - return fmt.Sprintf("no such attribute: %s", e.missingAttribute) + return fmt.Sprintf("no such attribute(s): %s", e.missingAttribute) } return "invalid attribute" } @@ -1373,17 +1335,3 @@ func (e *resolutionError) Error() string { func (e *resolutionError) Is(err error) bool { return err.Error() == e.Error() } - -func findMin(x, y int64) int64 { - if x < y { - return x - } - return y -} - -func findMax(x, y int64) int64 { - if x > y { - return x - } - return y -} diff --git a/vendor/github.com/google/cel-go/interpreter/coster.go b/vendor/github.com/google/cel-go/interpreter/coster.go deleted file mode 100644 index c79862c49..000000000 --- a/vendor/github.com/google/cel-go/interpreter/coster.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package interpreter - -import "math" - -// TODO: remove Coster. - -// Coster calculates the heuristic cost incurred during evaluation. -// Deprecated: Please migrate cel.EstimateCost, it supports length estimates for input data and cost estimates for -// extension functions. -type Coster interface { - Cost() (min, max int64) -} - -// estimateCost returns the heuristic cost interval for the program. -func estimateCost(i any) (min, max int64) { - c, ok := i.(Coster) - if !ok { - return 0, math.MaxInt64 - } - return c.Cost() -} diff --git a/vendor/github.com/google/cel-go/interpreter/decorators.go b/vendor/github.com/google/cel-go/interpreter/decorators.go index bdbbad43e..502db35fc 100644 --- a/vendor/github.com/google/cel-go/interpreter/decorators.go +++ b/vendor/github.com/google/cel-go/interpreter/decorators.go @@ -29,7 +29,7 @@ type InterpretableDecorator func(Interpretable) (Interpretable, error) func decObserveEval(observer EvalObserver) InterpretableDecorator { return func(i Interpretable) (Interpretable, error) { switch inst := i.(type) { - case *evalWatch, *evalWatchAttr, *evalWatchConst: + case *evalWatch, *evalWatchAttr, *evalWatchConst, *evalWatchConstructor: // these instruction are already watching, return straight-away. return i, nil case InterpretableAttribute: @@ -42,6 +42,11 @@ func decObserveEval(observer EvalObserver) InterpretableDecorator { InterpretableConst: inst, observer: observer, }, nil + case InterpretableConstructor: + return &evalWatchConstructor{ + constructor: inst, + observer: observer, + }, nil default: return &evalWatch{ Interpretable: i, @@ -70,15 +75,13 @@ func decDisableShortcircuits() InterpretableDecorator { switch expr := i.(type) { case *evalOr: return &evalExhaustiveOr{ - id: expr.id, - lhs: expr.lhs, - rhs: expr.rhs, + id: expr.id, + terms: expr.terms, }, nil case *evalAnd: return &evalExhaustiveAnd{ - id: expr.id, - lhs: expr.lhs, - rhs: expr.rhs, + id: expr.id, + terms: expr.terms, }, nil case *evalFold: expr.exhaustive = true @@ -224,8 +227,8 @@ func maybeOptimizeSetMembership(i Interpretable, inlist InterpretableCall) (Inte valueSet := make(map[ref.Val]ref.Val) for it.HasNext() == types.True { elem := it.Next() - if !types.IsPrimitiveType(elem) { - // Note, non-primitive type are not yet supported. + if !types.IsPrimitiveType(elem) || elem.Type() == types.BytesType { + // Note, non-primitive type are not yet supported, and []byte isn't hashable. return i, nil } valueSet[elem] = types.True diff --git a/vendor/github.com/google/cel-go/interpreter/dispatcher.go b/vendor/github.com/google/cel-go/interpreter/dispatcher.go index febf9d8a8..8f0bdb7b8 100644 --- a/vendor/github.com/google/cel-go/interpreter/dispatcher.go +++ b/vendor/github.com/google/cel-go/interpreter/dispatcher.go @@ -17,7 +17,7 @@ package interpreter import ( "fmt" - "github.com/google/cel-go/interpreter/functions" + "github.com/google/cel-go/common/functions" ) // Dispatcher resolves function calls to their appropriate overload. diff --git a/vendor/github.com/google/cel-go/interpreter/evalstate.go b/vendor/github.com/google/cel-go/interpreter/evalstate.go index cc0d3e6f9..4bdd1fdc7 100644 --- a/vendor/github.com/google/cel-go/interpreter/evalstate.go +++ b/vendor/github.com/google/cel-go/interpreter/evalstate.go @@ -66,7 +66,11 @@ func (s *evalState) Value(exprID int64) (ref.Val, bool) { // SetValue is an implementation of the EvalState interface method. func (s *evalState) SetValue(exprID int64, val ref.Val) { - s.values[exprID] = val + if val == nil { + delete(s.values, exprID) + } else { + s.values[exprID] = val + } } // Reset implements the EvalState interface method. diff --git a/vendor/github.com/google/cel-go/interpreter/formatting.go b/vendor/github.com/google/cel-go/interpreter/formatting.go new file mode 100644 index 000000000..e3f753374 --- /dev/null +++ b/vendor/github.com/google/cel-go/interpreter/formatting.go @@ -0,0 +1,383 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package interpreter + +import ( + "errors" + "fmt" + "strconv" + "strings" + "unicode" + + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" +) + +type typeVerifier func(int64, ...ref.Type) (bool, error) + +// InterpolateFormattedString checks the syntax and cardinality of any string.format calls present in the expression and reports +// any errors at compile time. +func InterpolateFormattedString(verifier typeVerifier) InterpretableDecorator { + return func(inter Interpretable) (Interpretable, error) { + call, ok := inter.(InterpretableCall) + if !ok { + return inter, nil + } + if call.OverloadID() != "string_format" { + return inter, nil + } + args := call.Args() + if len(args) != 2 { + return nil, fmt.Errorf("wrong number of arguments to string.format (expected 2, got %d)", len(args)) + } + fmtStrInter, ok := args[0].(InterpretableConst) + if !ok { + return inter, nil + } + var fmtArgsInter InterpretableConstructor + fmtArgsInter, ok = args[1].(InterpretableConstructor) + if !ok { + return inter, nil + } + if fmtArgsInter.Type() != types.ListType { + // don't necessarily return an error since the list may be DynType + return inter, nil + } + formatStr := fmtStrInter.Value().Value().(string) + initVals := fmtArgsInter.InitVals() + + formatCheck := &formatCheck{ + args: initVals, + verifier: verifier, + } + // use a placeholder locale, since locale doesn't affect syntax + _, err := ParseFormatString(formatStr, formatCheck, formatCheck, "en_US") + if err != nil { + return nil, err + } + seenArgs := formatCheck.argsRequested + if len(initVals) > seenArgs { + return nil, fmt.Errorf("too many arguments supplied to string.format (expected %d, got %d)", seenArgs, len(initVals)) + } + return inter, nil + } +} + +type formatCheck struct { + args []Interpretable + argsRequested int + curArgIndex int64 + enableCheckArgTypes bool + verifier typeVerifier +} + +func (c *formatCheck) String(arg ref.Val, locale string) (string, error) { + valid, err := verifyString(c.args[c.curArgIndex], c.verifier) + if err != nil { + return "", err + } + if !valid { + return "", errors.New("string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps") + } + return "", nil +} + +func (c *formatCheck) Decimal(arg ref.Val, locale string) (string, error) { + id := c.args[c.curArgIndex].ID() + valid, err := c.verifier(id, types.IntType, types.UintType) + if err != nil { + return "", err + } + if !valid { + return "", errors.New("integer clause can only be used on integers") + } + return "", nil +} + +func (c *formatCheck) Fixed(precision *int) func(ref.Val, string) (string, error) { + return func(arg ref.Val, locale string) (string, error) { + id := c.args[c.curArgIndex].ID() + // we allow StringType since "NaN", "Infinity", and "-Infinity" are also valid values + valid, err := c.verifier(id, types.DoubleType, types.StringType) + if err != nil { + return "", err + } + if !valid { + return "", errors.New("fixed-point clause can only be used on doubles") + } + return "", nil + } +} + +func (c *formatCheck) Scientific(precision *int) func(ref.Val, string) (string, error) { + return func(arg ref.Val, locale string) (string, error) { + id := c.args[c.curArgIndex].ID() + valid, err := c.verifier(id, types.DoubleType, types.StringType) + if err != nil { + return "", err + } + if !valid { + return "", errors.New("scientific clause can only be used on doubles") + } + return "", nil + } +} + +func (c *formatCheck) Binary(arg ref.Val, locale string) (string, error) { + id := c.args[c.curArgIndex].ID() + valid, err := c.verifier(id, types.IntType, types.UintType, types.BoolType) + if err != nil { + return "", err + } + if !valid { + return "", errors.New("only integers and bools can be formatted as binary") + } + return "", nil +} + +func (c *formatCheck) Hex(useUpper bool) func(ref.Val, string) (string, error) { + return func(arg ref.Val, locale string) (string, error) { + id := c.args[c.curArgIndex].ID() + valid, err := c.verifier(id, types.IntType, types.UintType, types.StringType, types.BytesType) + if err != nil { + return "", err + } + if !valid { + return "", errors.New("only integers, byte buffers, and strings can be formatted as hex") + } + return "", nil + } +} + +func (c *formatCheck) Octal(arg ref.Val, locale string) (string, error) { + id := c.args[c.curArgIndex].ID() + valid, err := c.verifier(id, types.IntType, types.UintType) + if err != nil { + return "", err + } + if !valid { + return "", errors.New("octal clause can only be used on integers") + } + return "", nil +} + +func (c *formatCheck) Arg(index int64) (ref.Val, error) { + c.argsRequested++ + c.curArgIndex = index + // return a dummy value - this is immediately passed to back to us + // through one of the FormatCallback functions, so anything will do + return types.Int(0), nil +} + +func (c *formatCheck) ArgSize() int64 { + return int64(len(c.args)) +} + +func verifyString(sub Interpretable, verifier typeVerifier) (bool, error) { + subVerified, err := verifier(sub.ID(), + types.ListType, types.MapType, types.IntType, types.UintType, types.DoubleType, + types.BoolType, types.StringType, types.TimestampType, types.BytesType, types.DurationType, types.TypeType, types.NullType) + if err != nil { + return false, err + } + if !subVerified { + return false, nil + } + con, ok := sub.(InterpretableConstructor) + if ok { + members := con.InitVals() + for _, m := range members { + // recursively verify if we're dealing with a list/map + verified, err := verifyString(m, verifier) + if err != nil { + return false, err + } + if !verified { + return false, nil + } + } + } + return true, nil + +} + +// FormatStringInterpolator is an interface that allows user-defined behavior +// for formatting clause implementations, as well as argument retrieval. +// Each function is expected to support the appropriate types as laid out in +// the string.format documentation, and to return an error if given an inappropriate type. +type FormatStringInterpolator interface { + // String takes a ref.Val and a string representing the current locale identifier + // and returns the Val formatted as a string, or an error if one occurred. + String(ref.Val, string) (string, error) + + // Decimal takes a ref.Val and a string representing the current locale identifier + // and returns the Val formatted as a decimal integer, or an error if one occurred. + Decimal(ref.Val, string) (string, error) + + // Fixed takes an int pointer representing precision (or nil if none was given) and + // returns a function operating in a similar manner to String and Decimal, taking a + // ref.Val and locale and returning the appropriate string. A closure is returned + // so precision can be set without needing an additional function call/configuration. + Fixed(*int) func(ref.Val, string) (string, error) + + // Scientific functions identically to Fixed, except the string returned from the closure + // is expected to be in scientific notation. + Scientific(*int) func(ref.Val, string) (string, error) + + // Binary takes a ref.Val and a string representing the current locale identifier + // and returns the Val formatted as a binary integer, or an error if one occurred. + Binary(ref.Val, string) (string, error) + + // Hex takes a boolean that, if true, indicates the hex string output by the returned + // closure should use uppercase letters for A-F. + Hex(bool) func(ref.Val, string) (string, error) + + // Octal takes a ref.Val and a string representing the current locale identifier and + // returns the Val formatted in octal, or an error if one occurred. + Octal(ref.Val, string) (string, error) +} + +// FormatList is an interface that allows user-defined list-like datatypes to be used +// for formatting clause implementations. +type FormatList interface { + // Arg returns the ref.Val at the given index, or an error if one occurred. + Arg(int64) (ref.Val, error) + // ArgSize returns the length of the argument list. + ArgSize() int64 +} + +type clauseImpl func(ref.Val, string) (string, error) + +// ParseFormatString formats a string according to the string.format syntax, taking the clause implementations +// from the provided FormatCallback and the args from the given FormatList. +func ParseFormatString(formatStr string, callback FormatStringInterpolator, list FormatList, locale string) (string, error) { + i := 0 + argIndex := 0 + var builtStr strings.Builder + for i < len(formatStr) { + if formatStr[i] == '%' { + if i+1 < len(formatStr) && formatStr[i+1] == '%' { + err := builtStr.WriteByte('%') + if err != nil { + return "", fmt.Errorf("error writing format string: %w", err) + } + i += 2 + continue + } else { + argAny, err := list.Arg(int64(argIndex)) + if err != nil { + return "", err + } + if i+1 >= len(formatStr) { + return "", errors.New("unexpected end of string") + } + if int64(argIndex) >= list.ArgSize() { + return "", fmt.Errorf("index %d out of range", argIndex) + } + numRead, val, refErr := parseAndFormatClause(formatStr[i:], argAny, callback, list, locale) + if refErr != nil { + return "", refErr + } + _, err = builtStr.WriteString(val) + if err != nil { + return "", fmt.Errorf("error writing format string: %w", err) + } + i += numRead + argIndex++ + } + } else { + err := builtStr.WriteByte(formatStr[i]) + if err != nil { + return "", fmt.Errorf("error writing format string: %w", err) + } + i++ + } + } + return builtStr.String(), nil +} + +// parseAndFormatClause parses the format clause at the start of the given string with val, and returns +// how many characters were consumed and the substituted string form of val, or an error if one occurred. +func parseAndFormatClause(formatStr string, val ref.Val, callback FormatStringInterpolator, list FormatList, locale string) (int, string, error) { + i := 1 + read, formatter, err := parseFormattingClause(formatStr[i:], callback) + i += read + if err != nil { + return -1, "", fmt.Errorf("could not parse formatting clause: %s", err) + } + + valStr, err := formatter(val, locale) + if err != nil { + return -1, "", fmt.Errorf("error during formatting: %s", err) + } + return i, valStr, nil +} + +func parseFormattingClause(formatStr string, callback FormatStringInterpolator) (int, clauseImpl, error) { + i := 0 + read, precision, err := parsePrecision(formatStr[i:]) + i += read + if err != nil { + return -1, nil, fmt.Errorf("error while parsing precision: %w", err) + } + r := rune(formatStr[i]) + i++ + switch r { + case 's': + return i, callback.String, nil + case 'd': + return i, callback.Decimal, nil + case 'f': + return i, callback.Fixed(precision), nil + case 'e': + return i, callback.Scientific(precision), nil + case 'b': + return i, callback.Binary, nil + case 'x', 'X': + return i, callback.Hex(unicode.IsUpper(r)), nil + case 'o': + return i, callback.Octal, nil + default: + return -1, nil, fmt.Errorf("unrecognized formatting clause \"%c\"", r) + } +} + +func parsePrecision(formatStr string) (int, *int, error) { + i := 0 + if formatStr[i] != '.' { + return i, nil, nil + } + i++ + var buffer strings.Builder + for { + if i >= len(formatStr) { + return -1, nil, errors.New("could not find end of precision specifier") + } + if !isASCIIDigit(rune(formatStr[i])) { + break + } + buffer.WriteByte(formatStr[i]) + i++ + } + precision, err := strconv.Atoi(buffer.String()) + if err != nil { + return -1, nil, fmt.Errorf("error while converting precision to integer: %w", err) + } + return i, &precision, nil +} + +func isASCIIDigit(r rune) bool { + return r <= unicode.MaxASCII && unicode.IsDigit(r) +} diff --git a/vendor/github.com/google/cel-go/interpreter/functions/standard.go b/vendor/github.com/google/cel-go/interpreter/functions/standard.go deleted file mode 100644 index 73e936114..000000000 --- a/vendor/github.com/google/cel-go/interpreter/functions/standard.go +++ /dev/null @@ -1,270 +0,0 @@ -// Copyright 2018 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package functions - -import ( - "github.com/google/cel-go/common/operators" - "github.com/google/cel-go/common/overloads" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" -) - -// StandardOverloads returns the definitions of the built-in overloads. -func StandardOverloads() []*Overload { - return []*Overload{ - // Logical not (!a) - { - Operator: operators.LogicalNot, - OperandTrait: traits.NegatorType, - Unary: func(value ref.Val) ref.Val { - if !types.IsBool(value) { - return types.ValOrErr(value, "no such overload") - } - return value.(traits.Negater).Negate() - }}, - // Not strictly false: IsBool(a) ? a : true - { - Operator: operators.NotStrictlyFalse, - Unary: notStrictlyFalse}, - // Deprecated: not strictly false, may be overridden in the environment. - { - Operator: operators.OldNotStrictlyFalse, - Unary: notStrictlyFalse}, - - // Less than operator - {Operator: operators.Less, - OperandTrait: traits.ComparerType, - Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { - cmp := lhs.(traits.Comparer).Compare(rhs) - if cmp == types.IntNegOne { - return types.True - } - if cmp == types.IntOne || cmp == types.IntZero { - return types.False - } - return cmp - }}, - - // Less than or equal operator - {Operator: operators.LessEquals, - OperandTrait: traits.ComparerType, - Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { - cmp := lhs.(traits.Comparer).Compare(rhs) - if cmp == types.IntNegOne || cmp == types.IntZero { - return types.True - } - if cmp == types.IntOne { - return types.False - } - return cmp - }}, - - // Greater than operator - {Operator: operators.Greater, - OperandTrait: traits.ComparerType, - Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { - cmp := lhs.(traits.Comparer).Compare(rhs) - if cmp == types.IntOne { - return types.True - } - if cmp == types.IntNegOne || cmp == types.IntZero { - return types.False - } - return cmp - }}, - - // Greater than equal operators - {Operator: operators.GreaterEquals, - OperandTrait: traits.ComparerType, - Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { - cmp := lhs.(traits.Comparer).Compare(rhs) - if cmp == types.IntOne || cmp == types.IntZero { - return types.True - } - if cmp == types.IntNegOne { - return types.False - } - return cmp - }}, - - // Add operator - {Operator: operators.Add, - OperandTrait: traits.AdderType, - Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { - return lhs.(traits.Adder).Add(rhs) - }}, - - // Subtract operators - {Operator: operators.Subtract, - OperandTrait: traits.SubtractorType, - Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { - return lhs.(traits.Subtractor).Subtract(rhs) - }}, - - // Multiply operator - {Operator: operators.Multiply, - OperandTrait: traits.MultiplierType, - Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { - return lhs.(traits.Multiplier).Multiply(rhs) - }}, - - // Divide operator - {Operator: operators.Divide, - OperandTrait: traits.DividerType, - Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { - return lhs.(traits.Divider).Divide(rhs) - }}, - - // Modulo operator - {Operator: operators.Modulo, - OperandTrait: traits.ModderType, - Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { - return lhs.(traits.Modder).Modulo(rhs) - }}, - - // Negate operator - {Operator: operators.Negate, - OperandTrait: traits.NegatorType, - Unary: func(value ref.Val) ref.Val { - if types.IsBool(value) { - return types.ValOrErr(value, "no such overload") - } - return value.(traits.Negater).Negate() - }}, - - // Index operator - {Operator: operators.Index, - OperandTrait: traits.IndexerType, - Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { - return lhs.(traits.Indexer).Get(rhs) - }}, - - // Size function - {Operator: overloads.Size, - OperandTrait: traits.SizerType, - Unary: func(value ref.Val) ref.Val { - return value.(traits.Sizer).Size() - }}, - - // In operator - {Operator: operators.In, Binary: inAggregate}, - // Deprecated: in operator, may be overridden in the environment. - {Operator: operators.OldIn, Binary: inAggregate}, - - // Matches function - {Operator: overloads.Matches, - OperandTrait: traits.MatcherType, - Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { - return lhs.(traits.Matcher).Match(rhs) - }}, - - // Type conversion functions - // TODO: verify type conversion safety of numeric values. - - // Int conversions. - {Operator: overloads.TypeConvertInt, - Unary: func(value ref.Val) ref.Val { - return value.ConvertToType(types.IntType) - }}, - - // Uint conversions. - {Operator: overloads.TypeConvertUint, - Unary: func(value ref.Val) ref.Val { - return value.ConvertToType(types.UintType) - }}, - - // Double conversions. - {Operator: overloads.TypeConvertDouble, - Unary: func(value ref.Val) ref.Val { - return value.ConvertToType(types.DoubleType) - }}, - - // Bool conversions. - {Operator: overloads.TypeConvertBool, - Unary: func(value ref.Val) ref.Val { - return value.ConvertToType(types.BoolType) - }}, - - // Bytes conversions. - {Operator: overloads.TypeConvertBytes, - Unary: func(value ref.Val) ref.Val { - return value.ConvertToType(types.BytesType) - }}, - - // String conversions. - {Operator: overloads.TypeConvertString, - Unary: func(value ref.Val) ref.Val { - return value.ConvertToType(types.StringType) - }}, - - // Timestamp conversions. - {Operator: overloads.TypeConvertTimestamp, - Unary: func(value ref.Val) ref.Val { - return value.ConvertToType(types.TimestampType) - }}, - - // Duration conversions. - {Operator: overloads.TypeConvertDuration, - Unary: func(value ref.Val) ref.Val { - return value.ConvertToType(types.DurationType) - }}, - - // Type operations. - {Operator: overloads.TypeConvertType, - Unary: func(value ref.Val) ref.Val { - return value.ConvertToType(types.TypeType) - }}, - - // Dyn conversion (identity function). - {Operator: overloads.TypeConvertDyn, - Unary: func(value ref.Val) ref.Val { - return value - }}, - - {Operator: overloads.Iterator, - OperandTrait: traits.IterableType, - Unary: func(value ref.Val) ref.Val { - return value.(traits.Iterable).Iterator() - }}, - - {Operator: overloads.HasNext, - OperandTrait: traits.IteratorType, - Unary: func(value ref.Val) ref.Val { - return value.(traits.Iterator).HasNext() - }}, - - {Operator: overloads.Next, - OperandTrait: traits.IteratorType, - Unary: func(value ref.Val) ref.Val { - return value.(traits.Iterator).Next() - }}, - } - -} - -func notStrictlyFalse(value ref.Val) ref.Val { - if types.IsBool(value) { - return value - } - return types.True -} - -func inAggregate(lhs ref.Val, rhs ref.Val) ref.Val { - if rhs.Type().HasTrait(traits.ContainerType) { - return rhs.(traits.Container).Contains(lhs) - } - return types.ValOrErr(rhs, "no such overload") -} diff --git a/vendor/github.com/google/cel-go/interpreter/interpretable.go b/vendor/github.com/google/cel-go/interpreter/interpretable.go index 2011080d5..c4598dfa7 100644 --- a/vendor/github.com/google/cel-go/interpreter/interpretable.go +++ b/vendor/github.com/google/cel-go/interpreter/interpretable.go @@ -15,14 +15,14 @@ package interpreter import ( - "math" + "fmt" + "github.com/google/cel-go/common/functions" "github.com/google/cel-go/common/operators" "github.com/google/cel-go/common/overloads" "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/functions" ) // Interpretable can accept a given Activation and produce a value along with @@ -52,7 +52,7 @@ type InterpretableAttribute interface { Attr() Attribute // Adapter returns the type adapter to be used for adapting resolved Attribute values. - Adapter() ref.TypeAdapter + Adapter() types.Adapter // AddQualifier proxies the Attribute.AddQualifier method. // @@ -71,6 +71,7 @@ type InterpretableAttribute interface { // to whether the qualifier is present. QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) + // IsOptional indicates whether the resulting value is an optional type. IsOptional() bool // Resolve returns the value of the Attribute given the current Activation. @@ -110,10 +111,8 @@ type InterpretableConstructor interface { // Core Interpretable implementations used during the program planning phase. type evalTestOnly struct { - id int64 - attr InterpretableAttribute - qual Qualifier - field types.String + id int64 + InterpretableAttribute } // ID implements the Interpretable interface method. @@ -123,37 +122,55 @@ func (test *evalTestOnly) ID() int64 { // Eval implements the Interpretable interface method. func (test *evalTestOnly) Eval(ctx Activation) ref.Val { - val, err := test.attr.Resolve(ctx) + val, err := test.Resolve(ctx) + // Return an error if the resolve step fails if err != nil { - return types.NewErr(err.Error()) + return types.WrapErr(err) } - optVal, isOpt := val.(*types.Optional) - if isOpt { - if !optVal.HasValue() { - return types.False - } - val = optVal.GetValue() + if optVal, isOpt := val.(*types.Optional); isOpt { + return types.Bool(optVal.HasValue()) + } + return test.Adapter().NativeToValue(val) +} + +// AddQualifier appends a qualifier that will always and only perform a presence test. +func (test *evalTestOnly) AddQualifier(q Qualifier) (Attribute, error) { + cq, ok := q.(ConstantQualifier) + if !ok { + return nil, fmt.Errorf("test only expressions must have constant qualifiers: %v", q) } - out, found, err := test.qual.QualifyIfPresent(ctx, val, true) + return test.InterpretableAttribute.AddQualifier(&testOnlyQualifier{ConstantQualifier: cq}) +} + +type testOnlyQualifier struct { + ConstantQualifier +} + +// Qualify determines whether the test-only qualifier is present on the input object. +func (q *testOnlyQualifier) Qualify(vars Activation, obj any) (any, error) { + out, present, err := q.ConstantQualifier.QualifyIfPresent(vars, obj, true) if err != nil { - return types.NewErr(err.Error()) + return nil, err } if unk, isUnk := out.(types.Unknown); isUnk { - return unk + return unk, nil } - if found { - return types.True + if opt, isOpt := out.(types.Optional); isOpt { + return opt.HasValue(), nil } - return types.False + return present, nil +} + +// QualifyIfPresent returns whether the target field in the test-only expression is present. +func (q *testOnlyQualifier) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) { + // Only ever test for presence. + return q.ConstantQualifier.QualifyIfPresent(vars, obj, true) } -// Cost provides the heuristic cost of a `has(field)` macro. The cost has at least 1 for determining -// if the field exists, apart from the cost of accessing the field. -func (test *evalTestOnly) Cost() (min, max int64) { - min, max = estimateCost(test.attr) - min++ - max++ - return +// QualifierValueEquals determines whether the test-only constant qualifier equals the input value. +func (q *testOnlyQualifier) QualifierValueEquals(value any) bool { + // The input qualifier will always be of type string + return q.ConstantQualifier.Value().Value() == value } // NewConstValue creates a new constant valued Interpretable. @@ -179,20 +196,14 @@ func (cons *evalConst) Eval(ctx Activation) ref.Val { return cons.val } -// Cost returns zero for a constant valued Interpretable. -func (cons *evalConst) Cost() (min, max int64) { - return 0, 0 -} - // Value implements the InterpretableConst interface method. func (cons *evalConst) Value() ref.Val { return cons.val } type evalOr struct { - id int64 - lhs Interpretable - rhs Interpretable + id int64 + terms []Interpretable } // ID implements the Interpretable interface method. @@ -202,47 +213,39 @@ func (or *evalOr) ID() int64 { // Eval implements the Interpretable interface method. func (or *evalOr) Eval(ctx Activation) ref.Val { - // short-circuit lhs. - lVal := or.lhs.Eval(ctx) - lBool, lok := lVal.(types.Bool) - if lok && lBool == types.True { - return types.True - } - // short-circuit on rhs. - rVal := or.rhs.Eval(ctx) - rBool, rok := rVal.(types.Bool) - if rok && rBool == types.True { - return types.True - } - // return if both sides are bool false. - if lok && rok { - return types.False - } - // TODO: return both values as a set if both are unknown or error. - // prefer left unknown to right unknown. - if types.IsUnknown(lVal) { - return lVal + var err ref.Val = nil + var unk *types.Unknown + for _, term := range or.terms { + val := term.Eval(ctx) + boolVal, ok := val.(types.Bool) + // short-circuit on true. + if ok && boolVal == types.True { + return types.True + } + if !ok { + isUnk := false + unk, isUnk = types.MaybeMergeUnknowns(val, unk) + if !isUnk && err == nil { + if types.IsError(val) { + err = val + } else { + err = types.MaybeNoSuchOverloadErr(val) + } + } + } } - if types.IsUnknown(rVal) { - return rVal + if unk != nil { + return unk } - // If the left-hand side is non-boolean return it as the error. - if types.IsError(lVal) { - return lVal + if err != nil { + return err } - return types.ValOrErr(rVal, "no such overload") -} - -// Cost implements the Coster interface method. The minimum possible cost incurs when the left-hand -// side expr is sufficient in determining the evaluation result. -func (or *evalOr) Cost() (min, max int64) { - return calShortCircuitBinaryOpsCost(or.lhs, or.rhs) + return types.False } type evalAnd struct { - id int64 - lhs Interpretable - rhs Interpretable + id int64 + terms []Interpretable } // ID implements the Interpretable interface method. @@ -252,47 +255,34 @@ func (and *evalAnd) ID() int64 { // Eval implements the Interpretable interface method. func (and *evalAnd) Eval(ctx Activation) ref.Val { - // short-circuit lhs. - lVal := and.lhs.Eval(ctx) - lBool, lok := lVal.(types.Bool) - if lok && lBool == types.False { - return types.False - } - // short-circuit on rhs. - rVal := and.rhs.Eval(ctx) - rBool, rok := rVal.(types.Bool) - if rok && rBool == types.False { - return types.False - } - // return if both sides are bool true. - if lok && rok { - return types.True - } - // TODO: return both values as a set if both are unknown or error. - // prefer left unknown to right unknown. - if types.IsUnknown(lVal) { - return lVal + var err ref.Val = nil + var unk *types.Unknown + for _, term := range and.terms { + val := term.Eval(ctx) + boolVal, ok := val.(types.Bool) + // short-circuit on false. + if ok && boolVal == types.False { + return types.False + } + if !ok { + isUnk := false + unk, isUnk = types.MaybeMergeUnknowns(val, unk) + if !isUnk && err == nil { + if types.IsError(val) { + err = val + } else { + err = types.MaybeNoSuchOverloadErr(val) + } + } + } } - if types.IsUnknown(rVal) { - return rVal + if unk != nil { + return unk } - // If the left-hand side is non-boolean return it as the error. - if types.IsError(lVal) { - return lVal + if err != nil { + return err } - return types.ValOrErr(rVal, "no such overload") -} - -// Cost implements the Coster interface method. The minimum possible cost incurs when the left-hand -// side expr is sufficient in determining the evaluation result. -func (and *evalAnd) Cost() (min, max int64) { - return calShortCircuitBinaryOpsCost(and.lhs, and.rhs) -} - -func calShortCircuitBinaryOpsCost(lhs, rhs Interpretable) (min, max int64) { - lMin, lMax := estimateCost(lhs) - _, rMax := estimateCost(rhs) - return lMin, lMax + rMax + 1 + return types.True } type evalEq struct { @@ -319,11 +309,6 @@ func (eq *evalEq) Eval(ctx Activation) ref.Val { return types.Equal(lVal, rVal) } -// Cost implements the Coster interface method. -func (eq *evalEq) Cost() (min, max int64) { - return calExhaustiveBinaryOpsCost(eq.lhs, eq.rhs) -} - // Function implements the InterpretableCall interface method. func (*evalEq) Function() string { return operators.Equals @@ -363,11 +348,6 @@ func (ne *evalNe) Eval(ctx Activation) ref.Val { return types.Bool(types.Equal(lVal, rVal) != types.True) } -// Cost implements the Coster interface method. -func (ne *evalNe) Cost() (min, max int64) { - return calExhaustiveBinaryOpsCost(ne.lhs, ne.rhs) -} - // Function implements the InterpretableCall interface method. func (*evalNe) Function() string { return operators.NotEquals @@ -400,11 +380,6 @@ func (zero *evalZeroArity) Eval(ctx Activation) ref.Val { return zero.impl() } -// Cost returns 1 representing the heuristic cost of the function. -func (zero *evalZeroArity) Cost() (min, max int64) { - return 1, 1 -} - // Function implements the InterpretableCall interface method. func (zero *evalZeroArity) Function() string { return zero.function @@ -456,14 +431,6 @@ func (un *evalUnary) Eval(ctx Activation) ref.Val { return types.NewErr("no such overload: %s", un.function) } -// Cost implements the Coster interface method. -func (un *evalUnary) Cost() (min, max int64) { - min, max = estimateCost(un.arg) - min++ // add cost for function - max++ - return -} - // Function implements the InterpretableCall interface method. func (un *evalUnary) Function() string { return un.function @@ -522,11 +489,6 @@ func (bin *evalBinary) Eval(ctx Activation) ref.Val { return types.NewErr("no such overload: %s", bin.function) } -// Cost implements the Coster interface method. -func (bin *evalBinary) Cost() (min, max int64) { - return calExhaustiveBinaryOpsCost(bin.lhs, bin.rhs) -} - // Function implements the InterpretableCall interface method. func (bin *evalBinary) Function() string { return bin.function @@ -593,14 +555,6 @@ func (fn *evalVarArgs) Eval(ctx Activation) ref.Val { return types.NewErr("no such overload: %s", fn.function) } -// Cost implements the Coster interface method. -func (fn *evalVarArgs) Cost() (min, max int64) { - min, max = sumOfCost(fn.args) - min++ // add cost for function - max++ - return -} - // Function implements the InterpretableCall interface method. func (fn *evalVarArgs) Function() string { return fn.function @@ -617,9 +571,11 @@ func (fn *evalVarArgs) Args() []Interpretable { } type evalList struct { - id int64 - elems []Interpretable - adapter ref.TypeAdapter + id int64 + elems []Interpretable + optionals []bool + hasOptionals bool + adapter types.Adapter } // ID implements the Interpretable interface method. @@ -629,14 +585,24 @@ func (l *evalList) ID() int64 { // Eval implements the Interpretable interface method. func (l *evalList) Eval(ctx Activation) ref.Val { - elemVals := make([]ref.Val, len(l.elems)) + elemVals := make([]ref.Val, 0, len(l.elems)) // If any argument is unknown or error early terminate. for i, elem := range l.elems { elemVal := elem.Eval(ctx) if types.IsUnknownOrError(elemVal) { return elemVal } - elemVals[i] = elemVal + if l.hasOptionals && l.optionals[i] { + optVal, ok := elemVal.(*types.Optional) + if !ok { + return invalidOptionalElementInit(elemVal) + } + if !optVal.HasValue() { + continue + } + elemVal = optVal.GetValue() + } + elemVals = append(elemVals, elemVal) } return l.adapter.NativeToValue(elemVals) } @@ -649,17 +615,13 @@ func (l *evalList) Type() ref.Type { return types.ListType } -// Cost implements the Coster interface method. -func (l *evalList) Cost() (min, max int64) { - return sumOfCost(l.elems) -} - type evalMap struct { - id int64 - keys []Interpretable - vals []Interpretable - optionals []bool - adapter ref.TypeAdapter + id int64 + keys []Interpretable + vals []Interpretable + optionals []bool + hasOptionals bool + adapter types.Adapter } // ID implements the Interpretable interface method. @@ -680,8 +642,7 @@ func (m *evalMap) Eval(ctx Activation) ref.Val { if types.IsUnknownOrError(valVal) { return valVal } - isOpt := m.optionals[i] - if isOpt { + if m.hasOptionals && m.optionals[i] { optVal, ok := valVal.(*types.Optional) if !ok { return invalidOptionalEntryInit(keyVal, valVal) @@ -717,20 +678,14 @@ func (m *evalMap) Type() ref.Type { return types.MapType } -// Cost implements the Coster interface method. -func (m *evalMap) Cost() (min, max int64) { - kMin, kMax := sumOfCost(m.keys) - vMin, vMax := sumOfCost(m.vals) - return kMin + vMin, kMax + vMax -} - type evalObj struct { - id int64 - typeName string - fields []string - vals []Interpretable - optionals []bool - provider ref.TypeProvider + id int64 + typeName string + fields []string + vals []Interpretable + optionals []bool + hasOptionals bool + provider types.Provider } // ID implements the Interpretable interface method. @@ -747,8 +702,7 @@ func (o *evalObj) Eval(ctx Activation) ref.Val { if types.IsUnknownOrError(val) { return val } - isOpt := o.optionals[i] - if isOpt { + if o.hasOptionals && o.optionals[i] { optVal, ok := val.(*types.Optional) if !ok { return invalidOptionalEntryInit(field, val) @@ -772,21 +726,6 @@ func (o *evalObj) Type() ref.Type { return types.NewObjectTypeValue(o.typeName) } -// Cost implements the Coster interface method. -func (o *evalObj) Cost() (min, max int64) { - return sumOfCost(o.vals) -} - -func sumOfCost(interps []Interpretable) (min, max int64) { - min, max = 0, 0 - for _, in := range interps { - minT, maxT := estimateCost(in) - min += minT - max += maxT - } - return -} - type evalFold struct { id int64 accuVar string @@ -796,7 +735,7 @@ type evalFold struct { cond Interpretable step Interpretable result Interpretable - adapter ref.TypeAdapter + adapter types.Adapter exhaustive bool interruptable bool } @@ -868,38 +807,6 @@ func (fold *evalFold) Eval(ctx Activation) ref.Val { return res } -// Cost implements the Coster interface method. -func (fold *evalFold) Cost() (min, max int64) { - // Compute the cost for evaluating iterRange. - iMin, iMax := estimateCost(fold.iterRange) - - // Compute the size of iterRange. If the size depends on the input, return the maximum possible - // cost range. - foldRange := fold.iterRange.Eval(EmptyActivation()) - if !foldRange.Type().HasTrait(traits.IterableType) { - return 0, math.MaxInt64 - } - var rangeCnt int64 - it := foldRange.(traits.Iterable).Iterator() - for it.HasNext() == types.True { - it.Next() - rangeCnt++ - } - aMin, aMax := estimateCost(fold.accu) - cMin, cMax := estimateCost(fold.cond) - sMin, sMax := estimateCost(fold.step) - rMin, rMax := estimateCost(fold.result) - if fold.exhaustive { - cMin = cMin * rangeCnt - sMin = sMin * rangeCnt - } - - // The cond and step costs are multiplied by size(iterRange). The minimum possible cost incurs - // when the evaluation result can be determined by the first iteration. - return iMin + aMin + cMin + sMin + rMin, - iMax + aMax + cMax*rangeCnt + sMax*rangeCnt + rMax -} - // Optional Interpretable implementations that specialize, subsume, or extend the core evaluation // plan via decorators. @@ -919,17 +826,15 @@ func (e *evalSetMembership) ID() int64 { // Eval implements the Interpretable interface method. func (e *evalSetMembership) Eval(ctx Activation) ref.Val { val := e.arg.Eval(ctx) + if types.IsUnknownOrError(val) { + return val + } if ret, found := e.valueSet[val]; found { return ret } return types.False } -// Cost implements the Coster interface method. -func (e *evalSetMembership) Cost() (min, max int64) { - return estimateCost(e.arg) -} - // evalWatch is an Interpretable implementation that wraps the execution of a given // expression so that it may observe the computed value and send it to an observer. type evalWatch struct { @@ -944,11 +849,6 @@ func (e *evalWatch) Eval(ctx Activation) ref.Val { return val } -// Cost implements the Coster interface method. -func (e *evalWatch) Cost() (min, max int64) { - return estimateCost(e.Interpretable) -} - // evalWatchAttr describes a watcher of an InterpretableAttribute Interpretable. // // Since the watcher may be selected against at a later stage in program planning, the watcher @@ -961,29 +861,46 @@ type evalWatchAttr struct { // AddQualifier creates a wrapper over the incoming qualifier which observes the qualification // result. func (e *evalWatchAttr) AddQualifier(q Qualifier) (Attribute, error) { - cq, isConst := q.(ConstantQualifier) - if isConst { + switch qual := q.(type) { + // By default, the qualifier is either a constant or an attribute + // There may be some custom cases where the attribute is neither. + case ConstantQualifier: + // Expose a method to test whether the qualifier matches the input pattern. q = &evalWatchConstQual{ - ConstantQualifier: cq, + ConstantQualifier: qual, observer: e.observer, - adapter: e.InterpretableAttribute.Adapter(), + adapter: e.Adapter(), } - } else { + case *evalWatchAttr: + // Unwrap the evalWatchAttr since the observation will be applied during Qualify or + // QualifyIfPresent rather than Eval. + q = &evalWatchAttrQual{ + Attribute: qual.InterpretableAttribute, + observer: e.observer, + adapter: e.Adapter(), + } + case Attribute: + // Expose methods which intercept the qualification prior to being applied as a qualifier. + // Using this interface ensures that the qualifier is converted to a constant value one + // time during attribute pattern matching as the method embeds the Attribute interface + // needed to trip the conversion to a constant. + q = &evalWatchAttrQual{ + Attribute: qual, + observer: e.observer, + adapter: e.Adapter(), + } + default: + // This is likely a custom qualifier type. q = &evalWatchQual{ - Qualifier: q, + Qualifier: qual, observer: e.observer, - adapter: e.InterpretableAttribute.Adapter(), + adapter: e.Adapter(), } } _, err := e.InterpretableAttribute.AddQualifier(q) return e, err } -// Cost implements the Coster interface method. -func (e *evalWatchAttr) Cost() (min, max int64) { - return estimateCost(e.InterpretableAttribute) -} - // Eval implements the Interpretable interface method. func (e *evalWatchAttr) Eval(vars Activation) ref.Val { val := e.InterpretableAttribute.Eval(vars) @@ -996,12 +913,7 @@ func (e *evalWatchAttr) Eval(vars Activation) ref.Val { type evalWatchConstQual struct { ConstantQualifier observer EvalObserver - adapter ref.TypeAdapter -} - -// Cost implements the Coster interface method. -func (e *evalWatchConstQual) Cost() (min, max int64) { - return estimateCost(e.ConstantQualifier) + adapter types.Adapter } // Qualify observes the qualification of a object via a constant boolean, int, string, or uint. @@ -1009,7 +921,7 @@ func (e *evalWatchConstQual) Qualify(vars Activation, obj any) (any, error) { out, err := e.ConstantQualifier.Qualify(vars, obj) var val ref.Val if err != nil { - val = types.NewErr(err.Error()) + val = types.WrapErr(err) } else { val = e.adapter.NativeToValue(out) } @@ -1017,22 +929,71 @@ func (e *evalWatchConstQual) Qualify(vars Activation, obj any) (any, error) { return out, err } +// QualifyIfPresent conditionally qualifies the variable and only records a value if one is present. +func (e *evalWatchConstQual) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) { + out, present, err := e.ConstantQualifier.QualifyIfPresent(vars, obj, presenceOnly) + var val ref.Val + if err != nil { + val = types.WrapErr(err) + } else if out != nil { + val = e.adapter.NativeToValue(out) + } else if presenceOnly { + val = types.Bool(present) + } + if present || presenceOnly { + e.observer(e.ID(), e.ConstantQualifier, val) + } + return out, present, err +} + // QualifierValueEquals tests whether the incoming value is equal to the qualifying constant. func (e *evalWatchConstQual) QualifierValueEquals(value any) bool { qve, ok := e.ConstantQualifier.(qualifierValueEquator) return ok && qve.QualifierValueEquals(value) } -// evalWatchQual observes the qualification of an object by a value computed at runtime. -type evalWatchQual struct { - Qualifier +// evalWatchAttrQual observes the qualification of an object by a value computed at runtime. +type evalWatchAttrQual struct { + Attribute observer EvalObserver adapter ref.TypeAdapter } -// Cost implements the Coster interface method. -func (e *evalWatchQual) Cost() (min, max int64) { - return estimateCost(e.Qualifier) +// Qualify observes the qualification of a object via a value computed at runtime. +func (e *evalWatchAttrQual) Qualify(vars Activation, obj any) (any, error) { + out, err := e.Attribute.Qualify(vars, obj) + var val ref.Val + if err != nil { + val = types.WrapErr(err) + } else { + val = e.adapter.NativeToValue(out) + } + e.observer(e.ID(), e.Attribute, val) + return out, err +} + +// QualifyIfPresent conditionally qualifies the variable and only records a value if one is present. +func (e *evalWatchAttrQual) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) { + out, present, err := e.Attribute.QualifyIfPresent(vars, obj, presenceOnly) + var val ref.Val + if err != nil { + val = types.WrapErr(err) + } else if out != nil { + val = e.adapter.NativeToValue(out) + } else if presenceOnly { + val = types.Bool(present) + } + if present || presenceOnly { + e.observer(e.ID(), e.Attribute, val) + } + return out, present, err +} + +// evalWatchQual observes the qualification of an object by a value computed at runtime. +type evalWatchQual struct { + Qualifier + observer EvalObserver + adapter types.Adapter } // Qualify observes the qualification of a object via a value computed at runtime. @@ -1040,7 +1001,7 @@ func (e *evalWatchQual) Qualify(vars Activation, obj any) (any, error) { out, err := e.Qualifier.Qualify(vars, obj) var val ref.Val if err != nil { - val = types.NewErr(err.Error()) + val = types.WrapErr(err) } else { val = e.adapter.NativeToValue(out) } @@ -1048,6 +1009,23 @@ func (e *evalWatchQual) Qualify(vars Activation, obj any) (any, error) { return out, err } +// QualifyIfPresent conditionally qualifies the variable and only records a value if one is present. +func (e *evalWatchQual) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) { + out, present, err := e.Qualifier.QualifyIfPresent(vars, obj, presenceOnly) + var val ref.Val + if err != nil { + val = types.WrapErr(err) + } else if out != nil { + val = e.adapter.NativeToValue(out) + } else if presenceOnly { + val = types.Bool(present) + } + if present || presenceOnly { + e.observer(e.ID(), e.Qualifier, val) + } + return out, present, err +} + // evalWatchConst describes a watcher of an instConst Interpretable. type evalWatchConst struct { InterpretableConst @@ -1061,16 +1039,10 @@ func (e *evalWatchConst) Eval(vars Activation) ref.Val { return val } -// Cost implements the Coster interface method. -func (e *evalWatchConst) Cost() (min, max int64) { - return estimateCost(e.InterpretableConst) -} - // evalExhaustiveOr is just like evalOr, but does not short-circuit argument evaluation. type evalExhaustiveOr struct { - id int64 - lhs Interpretable - rhs Interpretable + id int64 + terms []Interpretable } // ID implements the Interpretable interface method. @@ -1080,43 +1052,44 @@ func (or *evalExhaustiveOr) ID() int64 { // Eval implements the Interpretable interface method. func (or *evalExhaustiveOr) Eval(ctx Activation) ref.Val { - lVal := or.lhs.Eval(ctx) - rVal := or.rhs.Eval(ctx) - lBool, lok := lVal.(types.Bool) - if lok && lBool == types.True { - return types.True + var err ref.Val = nil + var unk *types.Unknown + isTrue := false + for _, term := range or.terms { + val := term.Eval(ctx) + boolVal, ok := val.(types.Bool) + // flag the result as true + if ok && boolVal == types.True { + isTrue = true + } + if !ok && !isTrue { + isUnk := false + unk, isUnk = types.MaybeMergeUnknowns(val, unk) + if !isUnk && err == nil { + if types.IsError(val) { + err = val + } else { + err = types.MaybeNoSuchOverloadErr(val) + } + } + } } - rBool, rok := rVal.(types.Bool) - if rok && rBool == types.True { + if isTrue { return types.True } - if lok && rok { - return types.False - } - if types.IsUnknown(lVal) { - return lVal - } - if types.IsUnknown(rVal) { - return rVal + if unk != nil { + return unk } - // TODO: Combine the errors into a set in the future. - // If the left-hand side is non-boolean return it as the error. - if types.IsError(lVal) { - return lVal + if err != nil { + return err } - return types.MaybeNoSuchOverloadErr(rVal) -} - -// Cost implements the Coster interface method. -func (or *evalExhaustiveOr) Cost() (min, max int64) { - return calExhaustiveBinaryOpsCost(or.lhs, or.rhs) + return types.False } // evalExhaustiveAnd is just like evalAnd, but does not short-circuit argument evaluation. type evalExhaustiveAnd struct { - id int64 - lhs Interpretable - rhs Interpretable + id int64 + terms []Interpretable } // ID implements the Interpretable interface method. @@ -1126,49 +1099,45 @@ func (and *evalExhaustiveAnd) ID() int64 { // Eval implements the Interpretable interface method. func (and *evalExhaustiveAnd) Eval(ctx Activation) ref.Val { - lVal := and.lhs.Eval(ctx) - rVal := and.rhs.Eval(ctx) - lBool, lok := lVal.(types.Bool) - if lok && lBool == types.False { - return types.False + var err ref.Val = nil + var unk *types.Unknown + isFalse := false + for _, term := range and.terms { + val := term.Eval(ctx) + boolVal, ok := val.(types.Bool) + // short-circuit on false. + if ok && boolVal == types.False { + isFalse = true + } + if !ok && !isFalse { + isUnk := false + unk, isUnk = types.MaybeMergeUnknowns(val, unk) + if !isUnk && err == nil { + if types.IsError(val) { + err = val + } else { + err = types.MaybeNoSuchOverloadErr(val) + } + } + } } - rBool, rok := rVal.(types.Bool) - if rok && rBool == types.False { + if isFalse { return types.False } - if lok && rok { - return types.True - } - if types.IsUnknown(lVal) { - return lVal - } - if types.IsUnknown(rVal) { - return rVal + if unk != nil { + return unk } - // TODO: Combine the errors into a set in the future. - // If the left-hand side is non-boolean return it as the error. - if types.IsError(lVal) { - return lVal + if err != nil { + return err } - return types.MaybeNoSuchOverloadErr(rVal) -} - -// Cost implements the Coster interface method. -func (and *evalExhaustiveAnd) Cost() (min, max int64) { - return calExhaustiveBinaryOpsCost(and.lhs, and.rhs) -} - -func calExhaustiveBinaryOpsCost(lhs, rhs Interpretable) (min, max int64) { - lMin, lMax := estimateCost(lhs) - rMin, rMax := estimateCost(rhs) - return lMin + rMin + 1, lMax + rMax + 1 + return types.True } // evalExhaustiveConditional is like evalConditional, but does not short-circuit argument // evaluation. type evalExhaustiveConditional struct { id int64 - adapter ref.TypeAdapter + adapter types.Adapter attr *conditionalAttribute } @@ -1188,28 +1157,25 @@ func (cond *evalExhaustiveConditional) Eval(ctx Activation) ref.Val { } if cBool { if tErr != nil { - return types.NewErr(tErr.Error()) + return types.WrapErr(tErr) } return cond.adapter.NativeToValue(tVal) } if fErr != nil { - return types.NewErr(fErr.Error()) + return types.WrapErr(fErr) } return cond.adapter.NativeToValue(fVal) } -// Cost implements the Coster interface method. -func (cond *evalExhaustiveConditional) Cost() (min, max int64) { - return cond.attr.Cost() -} - // evalAttr evaluates an Attribute value. type evalAttr struct { - adapter ref.TypeAdapter + adapter types.Adapter attr Attribute optional bool } +var _ InterpretableAttribute = &evalAttr{} + // ID of the attribute instruction. func (a *evalAttr) ID() int64 { return a.attr.ID() @@ -1228,20 +1194,15 @@ func (a *evalAttr) Attr() Attribute { } // Adapter implements the InterpretableAttribute interface method. -func (a *evalAttr) Adapter() ref.TypeAdapter { +func (a *evalAttr) Adapter() types.Adapter { return a.adapter } -// Cost implements the Coster interface method. -func (a *evalAttr) Cost() (min, max int64) { - return estimateCost(a.attr) -} - // Eval implements the Interpretable interface method. func (a *evalAttr) Eval(ctx Activation) ref.Val { v, err := a.attr.Resolve(ctx) if err != nil { - return types.NewErr(err.Error()) + return types.WrapErr(err) } return a.adapter.NativeToValue(v) } @@ -1265,6 +1226,37 @@ func (a *evalAttr) Resolve(ctx Activation) (any, error) { return a.attr.Resolve(ctx) } +type evalWatchConstructor struct { + constructor InterpretableConstructor + observer EvalObserver +} + +// InitVals implements the InterpretableConstructor InitVals function. +func (c *evalWatchConstructor) InitVals() []Interpretable { + return c.constructor.InitVals() +} + +// Type implements the InterpretableConstructor Type function. +func (c *evalWatchConstructor) Type() ref.Type { + return c.constructor.Type() +} + +// ID implements the Interpretable ID function. +func (c *evalWatchConstructor) ID() int64 { + return c.constructor.ID() +} + +// Eval implements the Interpretable Eval function. +func (c *evalWatchConstructor) Eval(ctx Activation) ref.Val { + val := c.constructor.Eval(ctx) + c.observer(c.ID(), c.constructor, val) + return val +} + func invalidOptionalEntryInit(field any, value ref.Val) ref.Val { return types.NewErr("cannot initialize optional entry '%v' from non-optional value %v", field, value) } + +func invalidOptionalElementInit(value ref.Val) ref.Val { + return types.NewErr("cannot initialize optional list element from non-optional value %v", value) +} diff --git a/vendor/github.com/google/cel-go/interpreter/interpreter.go b/vendor/github.com/google/cel-go/interpreter/interpreter.go index 707a6105a..00fc74732 100644 --- a/vendor/github.com/google/cel-go/interpreter/interpreter.go +++ b/vendor/github.com/google/cel-go/interpreter/interpreter.go @@ -18,9 +18,10 @@ package interpreter import ( + "github.com/google/cel-go/common/ast" "github.com/google/cel-go/common/containers" + "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/interpreter/functions" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) @@ -29,7 +30,7 @@ import ( type Interpreter interface { // NewInterpretable creates an Interpretable from a checked expression and an // optional list of InterpretableDecorator values. - NewInterpretable(checked *exprpb.CheckedExpr, decorators ...InterpretableDecorator) (Interpretable, error) + NewInterpretable(checked *ast.CheckedAST, decorators ...InterpretableDecorator) (Interpretable, error) // NewUncheckedInterpretable returns an Interpretable from a parsed expression // and an optional list of InterpretableDecorator values. @@ -154,8 +155,8 @@ func CompileRegexConstants(regexOptimizations ...*RegexOptimization) Interpretab type exprInterpreter struct { dispatcher Dispatcher container *containers.Container - provider ref.TypeProvider - adapter ref.TypeAdapter + provider types.Provider + adapter types.Adapter attrFactory AttributeFactory } @@ -163,8 +164,8 @@ type exprInterpreter struct { // throughout the Eval of all Interpretable instances generated from it. func NewInterpreter(dispatcher Dispatcher, container *containers.Container, - provider ref.TypeProvider, - adapter ref.TypeAdapter, + provider types.Provider, + adapter types.Adapter, attrFactory AttributeFactory) Interpreter { return &exprInterpreter{ dispatcher: dispatcher, @@ -174,20 +175,9 @@ func NewInterpreter(dispatcher Dispatcher, attrFactory: attrFactory} } -// NewStandardInterpreter builds a Dispatcher and TypeProvider with support for all of the CEL -// builtins defined in the language definition. -func NewStandardInterpreter(container *containers.Container, - provider ref.TypeProvider, - adapter ref.TypeAdapter, - resolver AttributeFactory) Interpreter { - dispatcher := NewDispatcher() - dispatcher.Add(functions.StandardOverloads()...) - return NewInterpreter(dispatcher, container, provider, adapter, resolver) -} - // NewIntepretable implements the Interpreter interface method. func (i *exprInterpreter) NewInterpretable( - checked *exprpb.CheckedExpr, + checked *ast.CheckedAST, decorators ...InterpretableDecorator) (Interpretable, error) { p := newPlanner( i.dispatcher, @@ -197,7 +187,7 @@ func (i *exprInterpreter) NewInterpretable( i.container, checked, decorators...) - return p.Plan(checked.GetExpr()) + return p.Plan(checked.Expr) } // NewUncheckedIntepretable implements the Interpreter interface method. diff --git a/vendor/github.com/google/cel-go/interpreter/planner.go b/vendor/github.com/google/cel-go/interpreter/planner.go index 9c6bbb622..757cd080e 100644 --- a/vendor/github.com/google/cel-go/interpreter/planner.go +++ b/vendor/github.com/google/cel-go/interpreter/planner.go @@ -18,11 +18,12 @@ import ( "fmt" "strings" + "github.com/google/cel-go/common/ast" "github.com/google/cel-go/common/containers" + "github.com/google/cel-go/common/functions" "github.com/google/cel-go/common/operators" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/interpreter/functions" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) @@ -38,11 +39,11 @@ type interpretablePlanner interface { // functions, types, and namespaced identifiers at plan time rather than at runtime since // it only needs to be done once and may be semi-expensive to compute. func newPlanner(disp Dispatcher, - provider ref.TypeProvider, - adapter ref.TypeAdapter, + provider types.Provider, + adapter types.Adapter, attrFactory AttributeFactory, cont *containers.Container, - checked *exprpb.CheckedExpr, + checked *ast.CheckedAST, decorators ...InterpretableDecorator) interpretablePlanner { return &planner{ disp: disp, @@ -50,8 +51,8 @@ func newPlanner(disp Dispatcher, adapter: adapter, attrFactory: attrFactory, container: cont, - refMap: checked.GetReferenceMap(), - typeMap: checked.GetTypeMap(), + refMap: checked.ReferenceMap, + typeMap: checked.TypeMap, decorators: decorators, } } @@ -60,8 +61,8 @@ func newPlanner(disp Dispatcher, // TypeAdapter, and Container to resolve functions and types at plan time. Namespaces present in // Select expressions are resolved lazily at evaluation time. func newUncheckedPlanner(disp Dispatcher, - provider ref.TypeProvider, - adapter ref.TypeAdapter, + provider types.Provider, + adapter types.Adapter, attrFactory AttributeFactory, cont *containers.Container, decorators ...InterpretableDecorator) interpretablePlanner { @@ -71,8 +72,8 @@ func newUncheckedPlanner(disp Dispatcher, adapter: adapter, attrFactory: attrFactory, container: cont, - refMap: make(map[int64]*exprpb.Reference), - typeMap: make(map[int64]*exprpb.Type), + refMap: make(map[int64]*ast.ReferenceInfo), + typeMap: make(map[int64]*types.Type), decorators: decorators, } } @@ -80,12 +81,12 @@ func newUncheckedPlanner(disp Dispatcher, // planner is an implementation of the interpretablePlanner interface. type planner struct { disp Dispatcher - provider ref.TypeProvider - adapter ref.TypeAdapter + provider types.Provider + adapter types.Adapter attrFactory AttributeFactory container *containers.Container - refMap map[int64]*exprpb.Reference - typeMap map[int64]*exprpb.Type + refMap map[int64]*ast.ReferenceInfo + typeMap map[int64]*types.Type decorators []InterpretableDecorator } @@ -144,22 +145,19 @@ func (p *planner) planIdent(expr *exprpb.Expr) (Interpretable, error) { }, nil } -func (p *planner) planCheckedIdent(id int64, identRef *exprpb.Reference) (Interpretable, error) { +func (p *planner) planCheckedIdent(id int64, identRef *ast.ReferenceInfo) (Interpretable, error) { // Plan a constant reference if this is the case for this simple identifier. - if identRef.GetValue() != nil { - return p.Plan(&exprpb.Expr{Id: id, - ExprKind: &exprpb.Expr_ConstExpr{ - ConstExpr: identRef.GetValue(), - }}) + if identRef.Value != nil { + return NewConstValue(id, identRef.Value), nil } // Check to see whether the type map indicates this is a type name. All types should be // registered with the provider. cType := p.typeMap[id] - if cType.GetType() != nil { - cVal, found := p.provider.FindIdent(identRef.GetName()) + if cType.Kind() == types.TypeKind { + cVal, found := p.provider.FindIdent(identRef.Name) if !found { - return nil, fmt.Errorf("reference to undefined type: %s", identRef.GetName()) + return nil, fmt.Errorf("reference to undefined type: %s", identRef.Name) } return NewConstValue(id, cVal), nil } @@ -167,7 +165,7 @@ func (p *planner) planCheckedIdent(id int64, identRef *exprpb.Reference) (Interp // Otherwise, return the attribute for the resolved identifier name. return &evalAttr{ adapter: p.adapter, - attr: p.attrFactory.AbsoluteAttribute(id, identRef.GetName()), + attr: p.attrFactory.AbsoluteAttribute(id, identRef.Name), }, nil } @@ -217,18 +215,14 @@ func (p *planner) planSelect(expr *exprpb.Expr) (Interpretable, error) { if err != nil { return nil, err } - - // Return the test only eval expression. + // Modify the attribute to be test-only. if sel.GetTestOnly() { - return &evalTestOnly{ - id: expr.GetId(), - field: types.String(sel.GetField()), - attr: attr, - qual: qual, - }, nil + attr = &evalTestOnly{ + id: expr.GetId(), + InterpretableAttribute: attr, + } } - - // Otherwise, append the qualifier on the attribute. + // Append the qualifier on the attribute. _, err = attr.AddQualifier(qual) return attr, err } @@ -434,18 +428,16 @@ func (p *planner) planCallNotEqual(expr *exprpb.Expr, args []Interpretable) (Int // planCallLogicalAnd generates a logical and (&&) Interpretable. func (p *planner) planCallLogicalAnd(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) { return &evalAnd{ - id: expr.GetId(), - lhs: args[0], - rhs: args[1], + id: expr.GetId(), + terms: args, }, nil } // planCallLogicalOr generates a logical or (||) Interpretable. func (p *planner) planCallLogicalOr(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) { return &evalOr{ - id: expr.GetId(), - lhs: args[0], - rhs: args[1], + id: expr.GetId(), + terms: args, }, nil } @@ -481,7 +473,7 @@ func (p *planner) planCallConditional(expr *exprpb.Expr, args []Interpretable) ( func (p *planner) planCallIndex(expr *exprpb.Expr, args []Interpretable, optional bool) (Interpretable, error) { op := args[0] ind := args[1] - opType := p.typeMap[expr.GetCallExpr().GetTarget().GetId()] + opType := p.typeMap[op.ID()] // Establish the attribute reference. var err error @@ -515,8 +507,17 @@ func (p *planner) planCallIndex(expr *exprpb.Expr, args []Interpretable, optiona // planCreateList generates a list construction Interpretable. func (p *planner) planCreateList(expr *exprpb.Expr) (Interpretable, error) { list := expr.GetListExpr() - elems := make([]Interpretable, len(list.GetElements())) - for i, elem := range list.GetElements() { + optionalIndices := list.GetOptionalIndices() + elements := list.GetElements() + optionals := make([]bool, len(elements)) + for _, index := range optionalIndices { + if index < 0 || index >= int32(len(elements)) { + return nil, fmt.Errorf("optional index %d out of element bounds [0, %d]", index, len(elements)) + } + optionals[index] = true + } + elems := make([]Interpretable, len(elements)) + for i, elem := range elements { elemVal, err := p.Plan(elem) if err != nil { return nil, err @@ -524,9 +525,11 @@ func (p *planner) planCreateList(expr *exprpb.Expr) (Interpretable, error) { elems[i] = elemVal } return &evalList{ - id: expr.GetId(), - elems: elems, - adapter: p.adapter, + id: expr.GetId(), + elems: elems, + optionals: optionals, + hasOptionals: len(optionals) != 0, + adapter: p.adapter, }, nil } @@ -555,11 +558,12 @@ func (p *planner) planCreateStruct(expr *exprpb.Expr) (Interpretable, error) { optionals[i] = entry.GetOptionalEntry() } return &evalMap{ - id: expr.GetId(), - keys: keys, - vals: vals, - optionals: optionals, - adapter: p.adapter, + id: expr.GetId(), + keys: keys, + vals: vals, + optionals: optionals, + hasOptionals: len(optionals) != 0, + adapter: p.adapter, }, nil } @@ -584,12 +588,13 @@ func (p *planner) planCreateObj(expr *exprpb.Expr) (Interpretable, error) { optionals[i] = entry.GetOptionalEntry() } return &evalObj{ - id: expr.GetId(), - typeName: typeName, - fields: fields, - vals: vals, - optionals: optionals, - provider: p.provider, + id: expr.GetId(), + typeName: typeName, + fields: fields, + vals: vals, + optionals: optionals, + hasOptionals: len(optionals) != 0, + provider: p.provider, }, nil } @@ -667,7 +672,7 @@ func (p *planner) constValue(c *exprpb.Constant) (ref.Val, error) { // namespace resolution rules to it in a scan over possible matching types in the TypeProvider. func (p *planner) resolveTypeName(typeName string) (string, bool) { for _, qualifiedTypeName := range p.container.ResolveCandidateNames(typeName) { - if _, found := p.provider.FindType(qualifiedTypeName); found { + if _, found := p.provider.FindStructType(qualifiedTypeName); found { return qualifiedTypeName, true } } @@ -694,8 +699,8 @@ func (p *planner) resolveFunction(expr *exprpb.Expr) (*exprpb.Expr, string, stri // function name as the fnName value. oRef, hasOverload := p.refMap[expr.GetId()] if hasOverload { - if len(oRef.GetOverloadId()) == 1 { - return target, fnName, oRef.GetOverloadId()[0] + if len(oRef.OverloadIDs) == 1 { + return target, fnName, oRef.OverloadIDs[0] } // Note, this namespaced function name will not appear as a fully qualified name in ASTs // built and stored before cel-go v0.5.0; however, this functionality did not work at all diff --git a/vendor/github.com/google/cel-go/interpreter/prune.go b/vendor/github.com/google/cel-go/interpreter/prune.go index eab46e0c0..b8834b1cb 100644 --- a/vendor/github.com/google/cel-go/interpreter/prune.go +++ b/vendor/github.com/google/cel-go/interpreter/prune.go @@ -16,6 +16,7 @@ package interpreter import ( "github.com/google/cel-go/common/operators" + "github.com/google/cel-go/common/overloads" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/common/types/traits" @@ -26,6 +27,7 @@ import ( type astPruner struct { expr *exprpb.Expr + macroCalls map[int64]*exprpb.Expr state EvalState nextExprID int64 } @@ -65,13 +67,22 @@ type astPruner struct { // compiled and constant folded expressions, but is not willing to constant // fold(and thus cache results of) some external calls, then they can prepare // the overloads accordingly. -func PruneAst(expr *exprpb.Expr, state EvalState) *exprpb.Expr { +func PruneAst(expr *exprpb.Expr, macroCalls map[int64]*exprpb.Expr, state EvalState) *exprpb.ParsedExpr { + pruneState := NewEvalState() + for _, id := range state.IDs() { + v, _ := state.Value(id) + pruneState.SetValue(id, v) + } pruner := &astPruner{ expr: expr, - state: state, - nextExprID: 1} - newExpr, _ := pruner.prune(expr) - return newExpr + macroCalls: macroCalls, + state: pruneState, + nextExprID: getMaxID(expr)} + newExpr, _ := pruner.maybePrune(expr) + return &exprpb.ParsedExpr{ + Expr: newExpr, + SourceInfo: &exprpb.SourceInfo{MacroCalls: pruner.macroCalls}, + } } func (p *astPruner) createLiteral(id int64, val *exprpb.Constant) *exprpb.Expr { @@ -84,28 +95,50 @@ func (p *astPruner) createLiteral(id int64, val *exprpb.Constant) *exprpb.Expr { } func (p *astPruner) maybeCreateLiteral(id int64, val ref.Val) (*exprpb.Expr, bool) { - switch val.Type() { - case types.BoolType: + switch v := val.(type) { + case types.Bool: + p.state.SetValue(id, val) return p.createLiteral(id, - &exprpb.Constant{ConstantKind: &exprpb.Constant_BoolValue{BoolValue: val.Value().(bool)}}), true - case types.IntType: + &exprpb.Constant{ConstantKind: &exprpb.Constant_BoolValue{BoolValue: bool(v)}}), true + case types.Bytes: + p.state.SetValue(id, val) return p.createLiteral(id, - &exprpb.Constant{ConstantKind: &exprpb.Constant_Int64Value{Int64Value: val.Value().(int64)}}), true - case types.UintType: + &exprpb.Constant{ConstantKind: &exprpb.Constant_BytesValue{BytesValue: []byte(v)}}), true + case types.Double: + p.state.SetValue(id, val) return p.createLiteral(id, - &exprpb.Constant{ConstantKind: &exprpb.Constant_Uint64Value{Uint64Value: val.Value().(uint64)}}), true - case types.StringType: + &exprpb.Constant{ConstantKind: &exprpb.Constant_DoubleValue{DoubleValue: float64(v)}}), true + case types.Duration: + p.state.SetValue(id, val) + durationString := string(v.ConvertToType(types.StringType).(types.String)) + return &exprpb.Expr{ + Id: id, + ExprKind: &exprpb.Expr_CallExpr{ + CallExpr: &exprpb.Expr_Call{ + Function: overloads.TypeConvertDuration, + Args: []*exprpb.Expr{ + p.createLiteral(p.nextID(), + &exprpb.Constant{ConstantKind: &exprpb.Constant_StringValue{StringValue: durationString}}), + }, + }, + }, + }, true + case types.Int: + p.state.SetValue(id, val) return p.createLiteral(id, - &exprpb.Constant{ConstantKind: &exprpb.Constant_StringValue{StringValue: val.Value().(string)}}), true - case types.DoubleType: + &exprpb.Constant{ConstantKind: &exprpb.Constant_Int64Value{Int64Value: int64(v)}}), true + case types.Uint: + p.state.SetValue(id, val) return p.createLiteral(id, - &exprpb.Constant{ConstantKind: &exprpb.Constant_DoubleValue{DoubleValue: val.Value().(float64)}}), true - case types.BytesType: + &exprpb.Constant{ConstantKind: &exprpb.Constant_Uint64Value{Uint64Value: uint64(v)}}), true + case types.String: + p.state.SetValue(id, val) return p.createLiteral(id, - &exprpb.Constant{ConstantKind: &exprpb.Constant_BytesValue{BytesValue: val.Value().([]byte)}}), true - case types.NullType: + &exprpb.Constant{ConstantKind: &exprpb.Constant_StringValue{StringValue: string(v)}}), true + case types.Null: + p.state.SetValue(id, val) return p.createLiteral(id, - &exprpb.Constant{ConstantKind: &exprpb.Constant_NullValue{NullValue: val.Value().(structpb.NullValue)}}), true + &exprpb.Constant{ConstantKind: &exprpb.Constant_NullValue{NullValue: v.Value().(structpb.NullValue)}}), true } // Attempt to build a list literal. @@ -123,6 +156,7 @@ func (p *astPruner) maybeCreateLiteral(id int64, val ref.Val) (*exprpb.Expr, boo } elemExprs[i] = elemExpr } + p.state.SetValue(id, val) return &exprpb.Expr{ Id: id, ExprKind: &exprpb.Expr_ListExpr{ @@ -162,6 +196,7 @@ func (p *astPruner) maybeCreateLiteral(id int64, val ref.Val) (*exprpb.Expr, boo entries[i] = entry i++ } + p.state.SetValue(id, val) return &exprpb.Expr{ Id: id, ExprKind: &exprpb.Expr_StructExpr{ @@ -177,70 +212,152 @@ func (p *astPruner) maybeCreateLiteral(id int64, val ref.Val) (*exprpb.Expr, boo return nil, false } -func (p *astPruner) maybePruneAndOr(node *exprpb.Expr) (*exprpb.Expr, bool) { - if !p.existsWithUnknownValue(node.GetId()) { +func (p *astPruner) maybePruneOptional(elem *exprpb.Expr) (*exprpb.Expr, bool) { + elemVal, found := p.value(elem.GetId()) + if found && elemVal.Type() == types.OptionalType { + opt := elemVal.(*types.Optional) + if !opt.HasValue() { + return nil, true + } + if newElem, pruned := p.maybeCreateLiteral(elem.GetId(), opt.GetValue()); pruned { + return newElem, true + } + } + return elem, false +} + +func (p *astPruner) maybePruneIn(node *exprpb.Expr) (*exprpb.Expr, bool) { + // elem in list + call := node.GetCallExpr() + val, exists := p.maybeValue(call.GetArgs()[1].GetId()) + if !exists { + return nil, false + } + if sz, ok := val.(traits.Sizer); ok && sz.Size() == types.IntZero { + return p.maybeCreateLiteral(node.GetId(), types.False) + } + return nil, false +} + +func (p *astPruner) maybePruneLogicalNot(node *exprpb.Expr) (*exprpb.Expr, bool) { + call := node.GetCallExpr() + arg := call.GetArgs()[0] + val, exists := p.maybeValue(arg.GetId()) + if !exists { return nil, false } + if b, ok := val.(types.Bool); ok { + return p.maybeCreateLiteral(node.GetId(), !b) + } + return nil, false +} +func (p *astPruner) maybePruneOr(node *exprpb.Expr) (*exprpb.Expr, bool) { call := node.GetCallExpr() // We know result is unknown, so we have at least one unknown arg // and if one side is a known value, we know we can ignore it. - if p.existsWithKnownValue(call.Args[0].GetId()) { - return call.Args[1], true + if v, exists := p.maybeValue(call.GetArgs()[0].GetId()); exists { + if v == types.True { + return p.maybeCreateLiteral(node.GetId(), types.True) + } + return call.GetArgs()[1], true } - if p.existsWithKnownValue(call.Args[1].GetId()) { - return call.Args[0], true + if v, exists := p.maybeValue(call.GetArgs()[1].GetId()); exists { + if v == types.True { + return p.maybeCreateLiteral(node.GetId(), types.True) + } + return call.GetArgs()[0], true } return nil, false } -func (p *astPruner) maybePruneConditional(node *exprpb.Expr) (*exprpb.Expr, bool) { - if !p.existsWithUnknownValue(node.GetId()) { - return nil, false +func (p *astPruner) maybePruneAnd(node *exprpb.Expr) (*exprpb.Expr, bool) { + call := node.GetCallExpr() + // We know result is unknown, so we have at least one unknown arg + // and if one side is a known value, we know we can ignore it. + if v, exists := p.maybeValue(call.GetArgs()[0].GetId()); exists { + if v == types.False { + return p.maybeCreateLiteral(node.GetId(), types.False) + } + return call.GetArgs()[1], true + } + if v, exists := p.maybeValue(call.GetArgs()[1].GetId()); exists { + if v == types.False { + return p.maybeCreateLiteral(node.GetId(), types.False) + } + return call.GetArgs()[0], true } + return nil, false +} +func (p *astPruner) maybePruneConditional(node *exprpb.Expr) (*exprpb.Expr, bool) { call := node.GetCallExpr() - condVal, condValueExists := p.value(call.Args[0].GetId()) - if !condValueExists || types.IsUnknownOrError(condVal) { + cond, exists := p.maybeValue(call.GetArgs()[0].GetId()) + if !exists { return nil, false } - - if condVal.Value().(bool) { - return call.Args[1], true + if cond.Value().(bool) { + return call.GetArgs()[1], true } - return call.Args[2], true + return call.GetArgs()[2], true } func (p *astPruner) maybePruneFunction(node *exprpb.Expr) (*exprpb.Expr, bool) { + if _, exists := p.value(node.GetId()); !exists { + return nil, false + } call := node.GetCallExpr() - if call.Function == operators.LogicalOr || call.Function == operators.LogicalAnd { - return p.maybePruneAndOr(node) + if call.Function == operators.LogicalOr { + return p.maybePruneOr(node) + } + if call.Function == operators.LogicalAnd { + return p.maybePruneAnd(node) } if call.Function == operators.Conditional { return p.maybePruneConditional(node) } - + if call.Function == operators.In { + return p.maybePruneIn(node) + } + if call.Function == operators.LogicalNot { + return p.maybePruneLogicalNot(node) + } return nil, false } +func (p *astPruner) maybePrune(node *exprpb.Expr) (*exprpb.Expr, bool) { + return p.prune(node) +} + func (p *astPruner) prune(node *exprpb.Expr) (*exprpb.Expr, bool) { if node == nil { return node, false } - val, valueExists := p.value(node.GetId()) - if valueExists && !types.IsUnknownOrError(val) { + val, valueExists := p.maybeValue(node.GetId()) + if valueExists { if newNode, ok := p.maybeCreateLiteral(node.GetId(), val); ok { + delete(p.macroCalls, node.GetId()) return newNode, true } } + if macro, found := p.macroCalls[node.GetId()]; found { + // Ensure that intermediate values for the comprehension are cleared during pruning + compre := node.GetComprehensionExpr() + if compre != nil { + visit(macro, clearIterVarVisitor(compre.IterVar, p.state)) + } + // prune the expression in terms of the macro call instead of the expanded form. + if newMacro, pruned := p.prune(macro); pruned { + p.macroCalls[node.GetId()] = newMacro + } + } // We have either an unknown/error value, or something we don't want to // transform, or expression was not evaluated. If possible, drill down // more. - switch node.GetExprKind().(type) { case *exprpb.Expr_SelectExpr: - if operand, pruned := p.prune(node.GetSelectExpr().GetOperand()); pruned { + if operand, pruned := p.maybePrune(node.GetSelectExpr().GetOperand()); pruned { return &exprpb.Expr{ Id: node.GetId(), ExprKind: &exprpb.Expr_SelectExpr{ @@ -253,10 +370,6 @@ func (p *astPruner) prune(node *exprpb.Expr) (*exprpb.Expr, bool) { }, true } case *exprpb.Expr_CallExpr: - if newExpr, pruned := p.maybePruneFunction(node); pruned { - newExpr, _ = p.prune(newExpr) - return newExpr, true - } var prunedCall bool call := node.GetCallExpr() args := call.GetArgs() @@ -268,40 +381,75 @@ func (p *astPruner) prune(node *exprpb.Expr) (*exprpb.Expr, bool) { } for i, arg := range args { newArgs[i] = arg - if newArg, prunedArg := p.prune(arg); prunedArg { + if newArg, prunedArg := p.maybePrune(arg); prunedArg { prunedCall = true newArgs[i] = newArg } } - if newTarget, prunedTarget := p.prune(call.GetTarget()); prunedTarget { + if newTarget, prunedTarget := p.maybePrune(call.GetTarget()); prunedTarget { prunedCall = true newCall.Target = newTarget } + newNode := &exprpb.Expr{ + Id: node.GetId(), + ExprKind: &exprpb.Expr_CallExpr{ + CallExpr: newCall, + }, + } + if newExpr, pruned := p.maybePruneFunction(newNode); pruned { + newExpr, _ = p.maybePrune(newExpr) + return newExpr, true + } if prunedCall { - return &exprpb.Expr{ - Id: node.GetId(), - ExprKind: &exprpb.Expr_CallExpr{ - CallExpr: newCall, - }, - }, true + return newNode, true } case *exprpb.Expr_ListExpr: elems := node.GetListExpr().GetElements() - newElems := make([]*exprpb.Expr, len(elems)) + optIndices := node.GetListExpr().GetOptionalIndices() + optIndexMap := map[int32]bool{} + for _, i := range optIndices { + optIndexMap[i] = true + } + newOptIndexMap := make(map[int32]bool, len(optIndexMap)) + newElems := make([]*exprpb.Expr, 0, len(elems)) var prunedList bool + + prunedIdx := 0 for i, elem := range elems { - newElems[i] = elem - if newElem, prunedElem := p.prune(elem); prunedElem { - newElems[i] = newElem + _, isOpt := optIndexMap[int32(i)] + if isOpt { + newElem, pruned := p.maybePruneOptional(elem) + if pruned { + prunedList = true + if newElem != nil { + newElems = append(newElems, newElem) + prunedIdx++ + } + continue + } + newOptIndexMap[int32(prunedIdx)] = true + } + if newElem, prunedElem := p.maybePrune(elem); prunedElem { + newElems = append(newElems, newElem) prunedList = true + } else { + newElems = append(newElems, elem) } + prunedIdx++ + } + optIndices = make([]int32, len(newOptIndexMap)) + idx := 0 + for i := range newOptIndexMap { + optIndices[idx] = i + idx++ } if prunedList { return &exprpb.Expr{ Id: node.GetId(), ExprKind: &exprpb.Expr_ListExpr{ ListExpr: &exprpb.Expr_CreateList{ - Elements: newElems, + Elements: newElems, + OptionalIndices: optIndices, }, }, }, true @@ -313,8 +461,8 @@ func (p *astPruner) prune(node *exprpb.Expr) (*exprpb.Expr, bool) { newEntries := make([]*exprpb.Expr_CreateStruct_Entry, len(entries)) for i, entry := range entries { newEntries[i] = entry - newKey, prunedKey := p.prune(entry.GetMapKey()) - newValue, prunedValue := p.prune(entry.GetValue()) + newKey, prunedKey := p.maybePrune(entry.GetMapKey()) + newValue, prunedValue := p.maybePrune(entry.GetValue()) if !prunedKey && !prunedValue { continue } @@ -331,6 +479,7 @@ func (p *astPruner) prune(node *exprpb.Expr) (*exprpb.Expr, bool) { MapKey: newKey, } } + newEntry.OptionalEntry = entry.GetOptionalEntry() newEntries[i] = newEntry } if prunedStruct { @@ -349,7 +498,7 @@ func (p *astPruner) prune(node *exprpb.Expr) (*exprpb.Expr, bool) { // Only the range of the comprehension is pruned since the state tracking only records // the last iteration of the comprehension and not each step in the evaluation which // means that the any residuals computed in between might be inaccurate. - if newRange, pruned := p.prune(compre.GetIterRange()); pruned { + if newRange, pruned := p.maybePrune(compre.GetIterRange()); pruned { return &exprpb.Expr{ Id: node.GetId(), ExprKind: &exprpb.Expr_ComprehensionExpr{ @@ -374,24 +523,97 @@ func (p *astPruner) value(id int64) (ref.Val, bool) { return val, (found && val != nil) } -func (p *astPruner) existsWithUnknownValue(id int64) bool { - val, valueExists := p.value(id) - return valueExists && types.IsUnknown(val) +func (p *astPruner) maybeValue(id int64) (ref.Val, bool) { + val, found := p.value(id) + if !found || types.IsUnknownOrError(val) { + return nil, false + } + return val, true +} + +func (p *astPruner) nextID() int64 { + next := p.nextExprID + p.nextExprID++ + return next +} + +type astVisitor struct { + // visitEntry is called on every expr node, including those within a map/struct entry. + visitExpr func(expr *exprpb.Expr) + // visitEntry is called before entering the key, value of a map/struct entry. + visitEntry func(entry *exprpb.Expr_CreateStruct_Entry) } -func (p *astPruner) existsWithKnownValue(id int64) bool { - val, valueExists := p.value(id) - return valueExists && !types.IsUnknown(val) +func getMaxID(expr *exprpb.Expr) int64 { + maxID := int64(1) + visit(expr, maxIDVisitor(&maxID)) + return maxID } -func (p *astPruner) nextID() int64 { - for { - _, found := p.state.Value(p.nextExprID) - if !found { - next := p.nextExprID - p.nextExprID++ - return next +func clearIterVarVisitor(varName string, state EvalState) astVisitor { + return astVisitor{ + visitExpr: func(e *exprpb.Expr) { + ident := e.GetIdentExpr() + if ident != nil && ident.GetName() == varName { + state.SetValue(e.GetId(), nil) + } + }, + } +} + +func maxIDVisitor(maxID *int64) astVisitor { + return astVisitor{ + visitExpr: func(e *exprpb.Expr) { + if e.GetId() >= *maxID { + *maxID = e.GetId() + 1 + } + }, + visitEntry: func(e *exprpb.Expr_CreateStruct_Entry) { + if e.GetId() >= *maxID { + *maxID = e.GetId() + 1 + } + }, + } +} + +func visit(expr *exprpb.Expr, visitor astVisitor) { + exprs := []*exprpb.Expr{expr} + for len(exprs) != 0 { + e := exprs[0] + if visitor.visitExpr != nil { + visitor.visitExpr(e) + } + exprs = exprs[1:] + switch e.GetExprKind().(type) { + case *exprpb.Expr_SelectExpr: + exprs = append(exprs, e.GetSelectExpr().GetOperand()) + case *exprpb.Expr_CallExpr: + call := e.GetCallExpr() + if call.GetTarget() != nil { + exprs = append(exprs, call.GetTarget()) + } + exprs = append(exprs, call.GetArgs()...) + case *exprpb.Expr_ComprehensionExpr: + compre := e.GetComprehensionExpr() + exprs = append(exprs, + compre.GetIterRange(), + compre.GetAccuInit(), + compre.GetLoopCondition(), + compre.GetLoopStep(), + compre.GetResult()) + case *exprpb.Expr_ListExpr: + list := e.GetListExpr() + exprs = append(exprs, list.GetElements()...) + case *exprpb.Expr_StructExpr: + for _, entry := range e.GetStructExpr().GetEntries() { + if visitor.visitEntry != nil { + visitor.visitEntry(entry) + } + if entry.GetMapKey() != nil { + exprs = append(exprs, entry.GetMapKey()) + } + exprs = append(exprs, entry.GetValue()) + } } - p.nextExprID++ } } diff --git a/vendor/github.com/google/cel-go/interpreter/runtimecost.go b/vendor/github.com/google/cel-go/interpreter/runtimecost.go index 42e64a44e..96faed2e5 100644 --- a/vendor/github.com/google/cel-go/interpreter/runtimecost.go +++ b/vendor/github.com/google/cel-go/interpreter/runtimecost.go @@ -53,6 +53,11 @@ func CostObserver(tracker *CostTracker) EvalObserver { tracker.stack.drop(t.Attr().ID()) tracker.cost += common.SelectAndIdentCost } + if !tracker.presenceTestHasCost { + if _, isTestOnly := programStep.(*evalTestOnly); isTestOnly { + tracker.cost -= common.SelectAndIdentCost + } + } case *evalExhaustiveConditional: // Ternary has no direct cost. All cost is from the conditional and the true/false branch expressions. tracker.stack.drop(t.attr.falsy.ID(), t.attr.truthy.ID(), t.attr.expr.ID()) @@ -60,13 +65,21 @@ func CostObserver(tracker *CostTracker) EvalObserver { // While the field names are identical, the boolean operation eval structs do not share an interface and so // must be handled individually. case *evalOr: - tracker.stack.drop(t.rhs.ID(), t.lhs.ID()) + for _, term := range t.terms { + tracker.stack.drop(term.ID()) + } case *evalAnd: - tracker.stack.drop(t.rhs.ID(), t.lhs.ID()) + for _, term := range t.terms { + tracker.stack.drop(term.ID()) + } case *evalExhaustiveOr: - tracker.stack.drop(t.rhs.ID(), t.lhs.ID()) + for _, term := range t.terms { + tracker.stack.drop(term.ID()) + } case *evalExhaustiveAnd: - tracker.stack.drop(t.rhs.ID(), t.lhs.ID()) + for _, term := range t.terms { + tracker.stack.drop(term.ID()) + } case *evalFold: tracker.stack.drop(t.iterRange.ID()) case Qualifier: @@ -95,21 +108,58 @@ func CostObserver(tracker *CostTracker) EvalObserver { return observer } -// CostTracker represents the information needed for tacking runtime cost +// CostTrackerOption configures the behavior of CostTracker objects. +type CostTrackerOption func(*CostTracker) error + +// CostTrackerLimit sets the runtime limit on the evaluation cost during execution and will terminate the expression +// evaluation if the limit is exceeded. +func CostTrackerLimit(limit uint64) CostTrackerOption { + return func(tracker *CostTracker) error { + tracker.Limit = &limit + return nil + } +} + +// PresenceTestHasCost determines whether presence testing has a cost of one or zero. +// Defaults to presence test has a cost of one. +func PresenceTestHasCost(hasCost bool) CostTrackerOption { + return func(tracker *CostTracker) error { + tracker.presenceTestHasCost = hasCost + return nil + } +} + +// NewCostTracker creates a new CostTracker with a given estimator and a set of functional CostTrackerOption values. +func NewCostTracker(estimator ActualCostEstimator, opts ...CostTrackerOption) (*CostTracker, error) { + tracker := &CostTracker{ + Estimator: estimator, + presenceTestHasCost: true, + } + for _, opt := range opts { + err := opt(tracker) + if err != nil { + return nil, err + } + } + return tracker, nil +} + +// CostTracker represents the information needed for tracking runtime cost. type CostTracker struct { - Estimator ActualCostEstimator - Limit *uint64 + Estimator ActualCostEstimator + Limit *uint64 + presenceTestHasCost bool cost uint64 stack refValStack } // ActualCost returns the runtime cost -func (c CostTracker) ActualCost() uint64 { +func (c *CostTracker) ActualCost() uint64 { return c.cost } -func (c CostTracker) costCall(call InterpretableCall, argValues []ref.Val, result ref.Val) uint64 { +func (c *CostTracker) costCall(call InterpretableCall, argValues []ref.Val, result ref.Val) uint64 { var cost uint64 if c.Estimator != nil { callCost := c.Estimator.CallCost(call.Function(), call.OverloadID(), argValues, result) @@ -122,7 +172,7 @@ func (c CostTracker) costCall(call InterpretableCall, argValues []ref.Val, resul // if user has their own implementation of ActualCostEstimator, make sure to cover the mapping between overloadId and cost calculation switch call.OverloadID() { // O(n) functions - case overloads.StartsWithString, overloads.EndsWithString, overloads.StringToBytes, overloads.BytesToString: + case overloads.StartsWithString, overloads.EndsWithString, overloads.StringToBytes, overloads.BytesToString, overloads.ExtQuoteString, overloads.ExtFormatString: cost += uint64(math.Ceil(float64(c.actualSize(argValues[0])) * common.StringTraversalCostFactor)) case overloads.InList: // If a list is composed entirely of constant values this is O(1), but we don't account for that here. @@ -179,7 +229,7 @@ func (c CostTracker) costCall(call InterpretableCall, argValues []ref.Val, resul } // actualSize returns the size of value -func (c CostTracker) actualSize(value ref.Val) uint64 { +func (c *CostTracker) actualSize(value ref.Val) uint64 { if sz, ok := value.(traits.Sizer); ok { return uint64(sz.Size().(types.Int)) } diff --git a/vendor/github.com/google/cel-go/parser/BUILD.bazel b/vendor/github.com/google/cel-go/parser/BUILD.bazel index b5c15fa57..67ecc9554 100644 --- a/vendor/github.com/google/cel-go/parser/BUILD.bazel +++ b/vendor/github.com/google/cel-go/parser/BUILD.bazel @@ -23,8 +23,8 @@ go_library( "//common/operators:go_default_library", "//common/runes:go_default_library", "//parser/gen:go_default_library", - "@com_github_antlr_antlr4_runtime_go_antlr//:go_default_library", - "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@com_github_antlr_antlr4_runtime_go_antlr_v4//:go_default_library", + "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//types/known/structpb:go_default_library", ], @@ -46,7 +46,7 @@ go_test( "//common/debug:go_default_library", "//parser/gen:go_default_library", "//test:go_default_library", - "@com_github_antlr_antlr4_runtime_go_antlr//:go_default_library", + "@com_github_antlr_antlr4_runtime_go_antlr_v4//:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//testing/protocmp:go_default_library", ], diff --git a/vendor/github.com/google/cel-go/parser/errors.go b/vendor/github.com/google/cel-go/parser/errors.go index ce49bb87f..93ae7a3ad 100644 --- a/vendor/github.com/google/cel-go/parser/errors.go +++ b/vendor/github.com/google/cel-go/parser/errors.go @@ -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...) } diff --git a/vendor/github.com/google/cel-go/parser/gen/BUILD.bazel b/vendor/github.com/google/cel-go/parser/gen/BUILD.bazel index 22711310c..654d1de7a 100644 --- a/vendor/github.com/google/cel-go/parser/gen/BUILD.bazel +++ b/vendor/github.com/google/cel-go/parser/gen/BUILD.bazel @@ -21,6 +21,6 @@ go_library( ], importpath = "github.com/google/cel-go/parser/gen", deps = [ - "@com_github_antlr_antlr4_runtime_go_antlr//:go_default_library", + "@com_github_antlr_antlr4_runtime_go_antlr_v4//:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/parser/gen/CEL.g4 b/vendor/github.com/google/cel-go/parser/gen/CEL.g4 index dada9e9f3..b011da803 100644 --- a/vendor/github.com/google/cel-go/parser/gen/CEL.g4 +++ b/vendor/github.com/google/cel-go/parser/gen/CEL.g4 @@ -52,15 +52,15 @@ unary member : primary # PrimaryExpr - | member op=('.'|'.?') id=IDENTIFIER # Select + | member op='.' (opt='?')? id=IDENTIFIER # Select | member op='.' id=IDENTIFIER open='(' args=exprList? ')' # MemberCall - | member op=('['|'[?') index=expr ']' # Index + | member op='[' (opt='?')? index=expr ']' # Index ; primary : leadingDot='.'? id=IDENTIFIER (op='(' args=exprList? ')')? # IdentOrGlobalCall | '(' e=expr ')' # Nested - | op='[' elems=exprList? ','? ']' # CreateList + | op='[' elems=listInit? ','? ']' # CreateList | op='{' entries=mapInitializerList? ','? '}' # CreateStruct | leadingDot='.'? ids+=IDENTIFIER (ops+='.' ids+=IDENTIFIER)* op='{' entries=fieldInitializerList? ','? '}' # CreateMessage @@ -71,6 +71,10 @@ exprList : e+=expr (',' e+=expr)* ; +listInit + : elems+=optExpr (',' elems+=optExpr)* + ; + fieldInitializerList : fields+=optField cols+=':' values+=expr (',' fields+=optField cols+=':' values+=expr)* ; @@ -80,22 +84,22 @@ optField ; mapInitializerList - : keys+=optKey cols+=':' values+=expr (',' keys+=optKey cols+=':' values+=expr)* + : keys+=optExpr cols+=':' values+=expr (',' keys+=optExpr cols+=':' values+=expr)* ; -optKey - : (opt='?')? expr +optExpr + : (opt='?')? e=expr ; literal : sign=MINUS? tok=NUM_INT # Int - | tok=NUM_UINT # Uint + | tok=NUM_UINT # Uint | sign=MINUS? tok=NUM_FLOAT # Double - | tok=STRING # String - | tok=BYTES # Bytes - | tok=CEL_TRUE # BoolTrue - | tok=CEL_FALSE # BoolFalse - | tok=NUL # Null + | tok=STRING # String + | tok=BYTES # Bytes + | tok=CEL_TRUE # BoolTrue + | tok=CEL_FALSE # BoolFalse + | tok=NUL # Null ; // Lexer Rules diff --git a/vendor/github.com/google/cel-go/parser/gen/CEL.interp b/vendor/github.com/google/cel-go/parser/gen/CEL.interp index 6d3b68bb4..75b8bb3e2 100644 --- a/vendor/github.com/google/cel-go/parser/gen/CEL.interp +++ b/vendor/github.com/google/cel-go/parser/gen/CEL.interp @@ -1,7 +1,5 @@ token literal names: null -'.?' -'[?' '==' '!=' 'in' @@ -41,8 +39,6 @@ null token symbolic names: null -null -null EQUALS NOT_EQUALS IN @@ -91,12 +87,13 @@ unary member primary exprList +listInit fieldInitializerList optField mapInitializerList -optKey +optExpr literal atn: -[4, 1, 38, 235, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 40, 8, 1, 1, 2, 1, 2, 1, 2, 5, 2, 45, 8, 2, 10, 2, 12, 2, 48, 9, 2, 1, 3, 1, 3, 1, 3, 5, 3, 53, 8, 3, 10, 3, 12, 3, 56, 9, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 5, 4, 64, 8, 4, 10, 4, 12, 4, 67, 9, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 78, 8, 5, 10, 5, 12, 5, 81, 9, 5, 1, 6, 1, 6, 4, 6, 85, 8, 6, 11, 6, 12, 6, 86, 1, 6, 1, 6, 4, 6, 91, 8, 6, 11, 6, 12, 6, 92, 1, 6, 3, 6, 96, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 109, 8, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 5, 7, 117, 8, 7, 10, 7, 12, 7, 120, 9, 7, 1, 8, 3, 8, 123, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 128, 8, 8, 1, 8, 3, 8, 131, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 139, 8, 8, 1, 8, 3, 8, 142, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 147, 8, 8, 1, 8, 3, 8, 150, 8, 8, 1, 8, 1, 8, 3, 8, 154, 8, 8, 1, 8, 1, 8, 1, 8, 5, 8, 159, 8, 8, 10, 8, 12, 8, 162, 9, 8, 1, 8, 1, 8, 3, 8, 166, 8, 8, 1, 8, 3, 8, 169, 8, 8, 1, 8, 1, 8, 3, 8, 173, 8, 8, 1, 9, 1, 9, 1, 9, 5, 9, 178, 8, 9, 10, 9, 12, 9, 181, 9, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 5, 10, 191, 8, 10, 10, 10, 12, 10, 194, 9, 10, 1, 11, 3, 11, 197, 8, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 5, 12, 209, 8, 12, 10, 12, 12, 12, 212, 9, 12, 1, 13, 3, 13, 215, 8, 13, 1, 13, 1, 13, 1, 14, 3, 14, 220, 8, 14, 1, 14, 1, 14, 1, 14, 3, 14, 225, 8, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 3, 14, 233, 8, 14, 1, 14, 0, 3, 8, 10, 14, 15, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 0, 5, 1, 0, 3, 9, 1, 0, 25, 27, 2, 0, 20, 20, 24, 24, 2, 0, 1, 1, 18, 18, 2, 0, 2, 2, 12, 12, 263, 0, 30, 1, 0, 0, 0, 2, 33, 1, 0, 0, 0, 4, 41, 1, 0, 0, 0, 6, 49, 1, 0, 0, 0, 8, 57, 1, 0, 0, 0, 10, 68, 1, 0, 0, 0, 12, 95, 1, 0, 0, 0, 14, 97, 1, 0, 0, 0, 16, 172, 1, 0, 0, 0, 18, 174, 1, 0, 0, 0, 20, 182, 1, 0, 0, 0, 22, 196, 1, 0, 0, 0, 24, 200, 1, 0, 0, 0, 26, 214, 1, 0, 0, 0, 28, 232, 1, 0, 0, 0, 30, 31, 3, 2, 1, 0, 31, 32, 5, 0, 0, 1, 32, 1, 1, 0, 0, 0, 33, 39, 3, 4, 2, 0, 34, 35, 5, 22, 0, 0, 35, 36, 3, 4, 2, 0, 36, 37, 5, 23, 0, 0, 37, 38, 3, 2, 1, 0, 38, 40, 1, 0, 0, 0, 39, 34, 1, 0, 0, 0, 39, 40, 1, 0, 0, 0, 40, 3, 1, 0, 0, 0, 41, 46, 3, 6, 3, 0, 42, 43, 5, 11, 0, 0, 43, 45, 3, 6, 3, 0, 44, 42, 1, 0, 0, 0, 45, 48, 1, 0, 0, 0, 46, 44, 1, 0, 0, 0, 46, 47, 1, 0, 0, 0, 47, 5, 1, 0, 0, 0, 48, 46, 1, 0, 0, 0, 49, 54, 3, 8, 4, 0, 50, 51, 5, 10, 0, 0, 51, 53, 3, 8, 4, 0, 52, 50, 1, 0, 0, 0, 53, 56, 1, 0, 0, 0, 54, 52, 1, 0, 0, 0, 54, 55, 1, 0, 0, 0, 55, 7, 1, 0, 0, 0, 56, 54, 1, 0, 0, 0, 57, 58, 6, 4, -1, 0, 58, 59, 3, 10, 5, 0, 59, 65, 1, 0, 0, 0, 60, 61, 10, 1, 0, 0, 61, 62, 7, 0, 0, 0, 62, 64, 3, 8, 4, 2, 63, 60, 1, 0, 0, 0, 64, 67, 1, 0, 0, 0, 65, 63, 1, 0, 0, 0, 65, 66, 1, 0, 0, 0, 66, 9, 1, 0, 0, 0, 67, 65, 1, 0, 0, 0, 68, 69, 6, 5, -1, 0, 69, 70, 3, 12, 6, 0, 70, 79, 1, 0, 0, 0, 71, 72, 10, 2, 0, 0, 72, 73, 7, 1, 0, 0, 73, 78, 3, 10, 5, 3, 74, 75, 10, 1, 0, 0, 75, 76, 7, 2, 0, 0, 76, 78, 3, 10, 5, 2, 77, 71, 1, 0, 0, 0, 77, 74, 1, 0, 0, 0, 78, 81, 1, 0, 0, 0, 79, 77, 1, 0, 0, 0, 79, 80, 1, 0, 0, 0, 80, 11, 1, 0, 0, 0, 81, 79, 1, 0, 0, 0, 82, 96, 3, 14, 7, 0, 83, 85, 5, 21, 0, 0, 84, 83, 1, 0, 0, 0, 85, 86, 1, 0, 0, 0, 86, 84, 1, 0, 0, 0, 86, 87, 1, 0, 0, 0, 87, 88, 1, 0, 0, 0, 88, 96, 3, 14, 7, 0, 89, 91, 5, 20, 0, 0, 90, 89, 1, 0, 0, 0, 91, 92, 1, 0, 0, 0, 92, 90, 1, 0, 0, 0, 92, 93, 1, 0, 0, 0, 93, 94, 1, 0, 0, 0, 94, 96, 3, 14, 7, 0, 95, 82, 1, 0, 0, 0, 95, 84, 1, 0, 0, 0, 95, 90, 1, 0, 0, 0, 96, 13, 1, 0, 0, 0, 97, 98, 6, 7, -1, 0, 98, 99, 3, 16, 8, 0, 99, 118, 1, 0, 0, 0, 100, 101, 10, 3, 0, 0, 101, 102, 7, 3, 0, 0, 102, 117, 5, 38, 0, 0, 103, 104, 10, 2, 0, 0, 104, 105, 5, 18, 0, 0, 105, 106, 5, 38, 0, 0, 106, 108, 5, 16, 0, 0, 107, 109, 3, 18, 9, 0, 108, 107, 1, 0, 0, 0, 108, 109, 1, 0, 0, 0, 109, 110, 1, 0, 0, 0, 110, 117, 5, 17, 0, 0, 111, 112, 10, 1, 0, 0, 112, 113, 7, 4, 0, 0, 113, 114, 3, 2, 1, 0, 114, 115, 5, 13, 0, 0, 115, 117, 1, 0, 0, 0, 116, 100, 1, 0, 0, 0, 116, 103, 1, 0, 0, 0, 116, 111, 1, 0, 0, 0, 117, 120, 1, 0, 0, 0, 118, 116, 1, 0, 0, 0, 118, 119, 1, 0, 0, 0, 119, 15, 1, 0, 0, 0, 120, 118, 1, 0, 0, 0, 121, 123, 5, 18, 0, 0, 122, 121, 1, 0, 0, 0, 122, 123, 1, 0, 0, 0, 123, 124, 1, 0, 0, 0, 124, 130, 5, 38, 0, 0, 125, 127, 5, 16, 0, 0, 126, 128, 3, 18, 9, 0, 127, 126, 1, 0, 0, 0, 127, 128, 1, 0, 0, 0, 128, 129, 1, 0, 0, 0, 129, 131, 5, 17, 0, 0, 130, 125, 1, 0, 0, 0, 130, 131, 1, 0, 0, 0, 131, 173, 1, 0, 0, 0, 132, 133, 5, 16, 0, 0, 133, 134, 3, 2, 1, 0, 134, 135, 5, 17, 0, 0, 135, 173, 1, 0, 0, 0, 136, 138, 5, 12, 0, 0, 137, 139, 3, 18, 9, 0, 138, 137, 1, 0, 0, 0, 138, 139, 1, 0, 0, 0, 139, 141, 1, 0, 0, 0, 140, 142, 5, 19, 0, 0, 141, 140, 1, 0, 0, 0, 141, 142, 1, 0, 0, 0, 142, 143, 1, 0, 0, 0, 143, 173, 5, 13, 0, 0, 144, 146, 5, 14, 0, 0, 145, 147, 3, 24, 12, 0, 146, 145, 1, 0, 0, 0, 146, 147, 1, 0, 0, 0, 147, 149, 1, 0, 0, 0, 148, 150, 5, 19, 0, 0, 149, 148, 1, 0, 0, 0, 149, 150, 1, 0, 0, 0, 150, 151, 1, 0, 0, 0, 151, 173, 5, 15, 0, 0, 152, 154, 5, 18, 0, 0, 153, 152, 1, 0, 0, 0, 153, 154, 1, 0, 0, 0, 154, 155, 1, 0, 0, 0, 155, 160, 5, 38, 0, 0, 156, 157, 5, 18, 0, 0, 157, 159, 5, 38, 0, 0, 158, 156, 1, 0, 0, 0, 159, 162, 1, 0, 0, 0, 160, 158, 1, 0, 0, 0, 160, 161, 1, 0, 0, 0, 161, 163, 1, 0, 0, 0, 162, 160, 1, 0, 0, 0, 163, 165, 5, 14, 0, 0, 164, 166, 3, 20, 10, 0, 165, 164, 1, 0, 0, 0, 165, 166, 1, 0, 0, 0, 166, 168, 1, 0, 0, 0, 167, 169, 5, 19, 0, 0, 168, 167, 1, 0, 0, 0, 168, 169, 1, 0, 0, 0, 169, 170, 1, 0, 0, 0, 170, 173, 5, 15, 0, 0, 171, 173, 3, 28, 14, 0, 172, 122, 1, 0, 0, 0, 172, 132, 1, 0, 0, 0, 172, 136, 1, 0, 0, 0, 172, 144, 1, 0, 0, 0, 172, 153, 1, 0, 0, 0, 172, 171, 1, 0, 0, 0, 173, 17, 1, 0, 0, 0, 174, 179, 3, 2, 1, 0, 175, 176, 5, 19, 0, 0, 176, 178, 3, 2, 1, 0, 177, 175, 1, 0, 0, 0, 178, 181, 1, 0, 0, 0, 179, 177, 1, 0, 0, 0, 179, 180, 1, 0, 0, 0, 180, 19, 1, 0, 0, 0, 181, 179, 1, 0, 0, 0, 182, 183, 3, 22, 11, 0, 183, 184, 5, 23, 0, 0, 184, 192, 3, 2, 1, 0, 185, 186, 5, 19, 0, 0, 186, 187, 3, 22, 11, 0, 187, 188, 5, 23, 0, 0, 188, 189, 3, 2, 1, 0, 189, 191, 1, 0, 0, 0, 190, 185, 1, 0, 0, 0, 191, 194, 1, 0, 0, 0, 192, 190, 1, 0, 0, 0, 192, 193, 1, 0, 0, 0, 193, 21, 1, 0, 0, 0, 194, 192, 1, 0, 0, 0, 195, 197, 5, 22, 0, 0, 196, 195, 1, 0, 0, 0, 196, 197, 1, 0, 0, 0, 197, 198, 1, 0, 0, 0, 198, 199, 5, 38, 0, 0, 199, 23, 1, 0, 0, 0, 200, 201, 3, 26, 13, 0, 201, 202, 5, 23, 0, 0, 202, 210, 3, 2, 1, 0, 203, 204, 5, 19, 0, 0, 204, 205, 3, 26, 13, 0, 205, 206, 5, 23, 0, 0, 206, 207, 3, 2, 1, 0, 207, 209, 1, 0, 0, 0, 208, 203, 1, 0, 0, 0, 209, 212, 1, 0, 0, 0, 210, 208, 1, 0, 0, 0, 210, 211, 1, 0, 0, 0, 211, 25, 1, 0, 0, 0, 212, 210, 1, 0, 0, 0, 213, 215, 5, 22, 0, 0, 214, 213, 1, 0, 0, 0, 214, 215, 1, 0, 0, 0, 215, 216, 1, 0, 0, 0, 216, 217, 3, 2, 1, 0, 217, 27, 1, 0, 0, 0, 218, 220, 5, 20, 0, 0, 219, 218, 1, 0, 0, 0, 219, 220, 1, 0, 0, 0, 220, 221, 1, 0, 0, 0, 221, 233, 5, 34, 0, 0, 222, 233, 5, 35, 0, 0, 223, 225, 5, 20, 0, 0, 224, 223, 1, 0, 0, 0, 224, 225, 1, 0, 0, 0, 225, 226, 1, 0, 0, 0, 226, 233, 5, 33, 0, 0, 227, 233, 5, 36, 0, 0, 228, 233, 5, 37, 0, 0, 229, 233, 5, 28, 0, 0, 230, 233, 5, 29, 0, 0, 231, 233, 5, 30, 0, 0, 232, 219, 1, 0, 0, 0, 232, 222, 1, 0, 0, 0, 232, 224, 1, 0, 0, 0, 232, 227, 1, 0, 0, 0, 232, 228, 1, 0, 0, 0, 232, 229, 1, 0, 0, 0, 232, 230, 1, 0, 0, 0, 232, 231, 1, 0, 0, 0, 233, 29, 1, 0, 0, 0, 32, 39, 46, 54, 65, 77, 79, 86, 92, 95, 108, 116, 118, 122, 127, 130, 138, 141, 146, 149, 153, 160, 165, 168, 172, 179, 192, 196, 210, 214, 219, 224, 232] \ No newline at end of file +[4, 1, 36, 251, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 42, 8, 1, 1, 2, 1, 2, 1, 2, 5, 2, 47, 8, 2, 10, 2, 12, 2, 50, 9, 2, 1, 3, 1, 3, 1, 3, 5, 3, 55, 8, 3, 10, 3, 12, 3, 58, 9, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 5, 4, 66, 8, 4, 10, 4, 12, 4, 69, 9, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 80, 8, 5, 10, 5, 12, 5, 83, 9, 5, 1, 6, 1, 6, 4, 6, 87, 8, 6, 11, 6, 12, 6, 88, 1, 6, 1, 6, 4, 6, 93, 8, 6, 11, 6, 12, 6, 94, 1, 6, 3, 6, 98, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 106, 8, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 114, 8, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 120, 8, 7, 1, 7, 1, 7, 1, 7, 5, 7, 125, 8, 7, 10, 7, 12, 7, 128, 9, 7, 1, 8, 3, 8, 131, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 136, 8, 8, 1, 8, 3, 8, 139, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 147, 8, 8, 1, 8, 3, 8, 150, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 155, 8, 8, 1, 8, 3, 8, 158, 8, 8, 1, 8, 1, 8, 3, 8, 162, 8, 8, 1, 8, 1, 8, 1, 8, 5, 8, 167, 8, 8, 10, 8, 12, 8, 170, 9, 8, 1, 8, 1, 8, 3, 8, 174, 8, 8, 1, 8, 3, 8, 177, 8, 8, 1, 8, 1, 8, 3, 8, 181, 8, 8, 1, 9, 1, 9, 1, 9, 5, 9, 186, 8, 9, 10, 9, 12, 9, 189, 9, 9, 1, 10, 1, 10, 1, 10, 5, 10, 194, 8, 10, 10, 10, 12, 10, 197, 9, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 5, 11, 207, 8, 11, 10, 11, 12, 11, 210, 9, 11, 1, 12, 3, 12, 213, 8, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 5, 13, 225, 8, 13, 10, 13, 12, 13, 228, 9, 13, 1, 14, 3, 14, 231, 8, 14, 1, 14, 1, 14, 1, 15, 3, 15, 236, 8, 15, 1, 15, 1, 15, 1, 15, 3, 15, 241, 8, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 249, 8, 15, 1, 15, 0, 3, 8, 10, 14, 16, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 0, 3, 1, 0, 1, 7, 1, 0, 23, 25, 2, 0, 18, 18, 22, 22, 281, 0, 32, 1, 0, 0, 0, 2, 35, 1, 0, 0, 0, 4, 43, 1, 0, 0, 0, 6, 51, 1, 0, 0, 0, 8, 59, 1, 0, 0, 0, 10, 70, 1, 0, 0, 0, 12, 97, 1, 0, 0, 0, 14, 99, 1, 0, 0, 0, 16, 180, 1, 0, 0, 0, 18, 182, 1, 0, 0, 0, 20, 190, 1, 0, 0, 0, 22, 198, 1, 0, 0, 0, 24, 212, 1, 0, 0, 0, 26, 216, 1, 0, 0, 0, 28, 230, 1, 0, 0, 0, 30, 248, 1, 0, 0, 0, 32, 33, 3, 2, 1, 0, 33, 34, 5, 0, 0, 1, 34, 1, 1, 0, 0, 0, 35, 41, 3, 4, 2, 0, 36, 37, 5, 20, 0, 0, 37, 38, 3, 4, 2, 0, 38, 39, 5, 21, 0, 0, 39, 40, 3, 2, 1, 0, 40, 42, 1, 0, 0, 0, 41, 36, 1, 0, 0, 0, 41, 42, 1, 0, 0, 0, 42, 3, 1, 0, 0, 0, 43, 48, 3, 6, 3, 0, 44, 45, 5, 9, 0, 0, 45, 47, 3, 6, 3, 0, 46, 44, 1, 0, 0, 0, 47, 50, 1, 0, 0, 0, 48, 46, 1, 0, 0, 0, 48, 49, 1, 0, 0, 0, 49, 5, 1, 0, 0, 0, 50, 48, 1, 0, 0, 0, 51, 56, 3, 8, 4, 0, 52, 53, 5, 8, 0, 0, 53, 55, 3, 8, 4, 0, 54, 52, 1, 0, 0, 0, 55, 58, 1, 0, 0, 0, 56, 54, 1, 0, 0, 0, 56, 57, 1, 0, 0, 0, 57, 7, 1, 0, 0, 0, 58, 56, 1, 0, 0, 0, 59, 60, 6, 4, -1, 0, 60, 61, 3, 10, 5, 0, 61, 67, 1, 0, 0, 0, 62, 63, 10, 1, 0, 0, 63, 64, 7, 0, 0, 0, 64, 66, 3, 8, 4, 2, 65, 62, 1, 0, 0, 0, 66, 69, 1, 0, 0, 0, 67, 65, 1, 0, 0, 0, 67, 68, 1, 0, 0, 0, 68, 9, 1, 0, 0, 0, 69, 67, 1, 0, 0, 0, 70, 71, 6, 5, -1, 0, 71, 72, 3, 12, 6, 0, 72, 81, 1, 0, 0, 0, 73, 74, 10, 2, 0, 0, 74, 75, 7, 1, 0, 0, 75, 80, 3, 10, 5, 3, 76, 77, 10, 1, 0, 0, 77, 78, 7, 2, 0, 0, 78, 80, 3, 10, 5, 2, 79, 73, 1, 0, 0, 0, 79, 76, 1, 0, 0, 0, 80, 83, 1, 0, 0, 0, 81, 79, 1, 0, 0, 0, 81, 82, 1, 0, 0, 0, 82, 11, 1, 0, 0, 0, 83, 81, 1, 0, 0, 0, 84, 98, 3, 14, 7, 0, 85, 87, 5, 19, 0, 0, 86, 85, 1, 0, 0, 0, 87, 88, 1, 0, 0, 0, 88, 86, 1, 0, 0, 0, 88, 89, 1, 0, 0, 0, 89, 90, 1, 0, 0, 0, 90, 98, 3, 14, 7, 0, 91, 93, 5, 18, 0, 0, 92, 91, 1, 0, 0, 0, 93, 94, 1, 0, 0, 0, 94, 92, 1, 0, 0, 0, 94, 95, 1, 0, 0, 0, 95, 96, 1, 0, 0, 0, 96, 98, 3, 14, 7, 0, 97, 84, 1, 0, 0, 0, 97, 86, 1, 0, 0, 0, 97, 92, 1, 0, 0, 0, 98, 13, 1, 0, 0, 0, 99, 100, 6, 7, -1, 0, 100, 101, 3, 16, 8, 0, 101, 126, 1, 0, 0, 0, 102, 103, 10, 3, 0, 0, 103, 105, 5, 16, 0, 0, 104, 106, 5, 20, 0, 0, 105, 104, 1, 0, 0, 0, 105, 106, 1, 0, 0, 0, 106, 107, 1, 0, 0, 0, 107, 125, 5, 36, 0, 0, 108, 109, 10, 2, 0, 0, 109, 110, 5, 16, 0, 0, 110, 111, 5, 36, 0, 0, 111, 113, 5, 14, 0, 0, 112, 114, 3, 18, 9, 0, 113, 112, 1, 0, 0, 0, 113, 114, 1, 0, 0, 0, 114, 115, 1, 0, 0, 0, 115, 125, 5, 15, 0, 0, 116, 117, 10, 1, 0, 0, 117, 119, 5, 10, 0, 0, 118, 120, 5, 20, 0, 0, 119, 118, 1, 0, 0, 0, 119, 120, 1, 0, 0, 0, 120, 121, 1, 0, 0, 0, 121, 122, 3, 2, 1, 0, 122, 123, 5, 11, 0, 0, 123, 125, 1, 0, 0, 0, 124, 102, 1, 0, 0, 0, 124, 108, 1, 0, 0, 0, 124, 116, 1, 0, 0, 0, 125, 128, 1, 0, 0, 0, 126, 124, 1, 0, 0, 0, 126, 127, 1, 0, 0, 0, 127, 15, 1, 0, 0, 0, 128, 126, 1, 0, 0, 0, 129, 131, 5, 16, 0, 0, 130, 129, 1, 0, 0, 0, 130, 131, 1, 0, 0, 0, 131, 132, 1, 0, 0, 0, 132, 138, 5, 36, 0, 0, 133, 135, 5, 14, 0, 0, 134, 136, 3, 18, 9, 0, 135, 134, 1, 0, 0, 0, 135, 136, 1, 0, 0, 0, 136, 137, 1, 0, 0, 0, 137, 139, 5, 15, 0, 0, 138, 133, 1, 0, 0, 0, 138, 139, 1, 0, 0, 0, 139, 181, 1, 0, 0, 0, 140, 141, 5, 14, 0, 0, 141, 142, 3, 2, 1, 0, 142, 143, 5, 15, 0, 0, 143, 181, 1, 0, 0, 0, 144, 146, 5, 10, 0, 0, 145, 147, 3, 20, 10, 0, 146, 145, 1, 0, 0, 0, 146, 147, 1, 0, 0, 0, 147, 149, 1, 0, 0, 0, 148, 150, 5, 17, 0, 0, 149, 148, 1, 0, 0, 0, 149, 150, 1, 0, 0, 0, 150, 151, 1, 0, 0, 0, 151, 181, 5, 11, 0, 0, 152, 154, 5, 12, 0, 0, 153, 155, 3, 26, 13, 0, 154, 153, 1, 0, 0, 0, 154, 155, 1, 0, 0, 0, 155, 157, 1, 0, 0, 0, 156, 158, 5, 17, 0, 0, 157, 156, 1, 0, 0, 0, 157, 158, 1, 0, 0, 0, 158, 159, 1, 0, 0, 0, 159, 181, 5, 13, 0, 0, 160, 162, 5, 16, 0, 0, 161, 160, 1, 0, 0, 0, 161, 162, 1, 0, 0, 0, 162, 163, 1, 0, 0, 0, 163, 168, 5, 36, 0, 0, 164, 165, 5, 16, 0, 0, 165, 167, 5, 36, 0, 0, 166, 164, 1, 0, 0, 0, 167, 170, 1, 0, 0, 0, 168, 166, 1, 0, 0, 0, 168, 169, 1, 0, 0, 0, 169, 171, 1, 0, 0, 0, 170, 168, 1, 0, 0, 0, 171, 173, 5, 12, 0, 0, 172, 174, 3, 22, 11, 0, 173, 172, 1, 0, 0, 0, 173, 174, 1, 0, 0, 0, 174, 176, 1, 0, 0, 0, 175, 177, 5, 17, 0, 0, 176, 175, 1, 0, 0, 0, 176, 177, 1, 0, 0, 0, 177, 178, 1, 0, 0, 0, 178, 181, 5, 13, 0, 0, 179, 181, 3, 30, 15, 0, 180, 130, 1, 0, 0, 0, 180, 140, 1, 0, 0, 0, 180, 144, 1, 0, 0, 0, 180, 152, 1, 0, 0, 0, 180, 161, 1, 0, 0, 0, 180, 179, 1, 0, 0, 0, 181, 17, 1, 0, 0, 0, 182, 187, 3, 2, 1, 0, 183, 184, 5, 17, 0, 0, 184, 186, 3, 2, 1, 0, 185, 183, 1, 0, 0, 0, 186, 189, 1, 0, 0, 0, 187, 185, 1, 0, 0, 0, 187, 188, 1, 0, 0, 0, 188, 19, 1, 0, 0, 0, 189, 187, 1, 0, 0, 0, 190, 195, 3, 28, 14, 0, 191, 192, 5, 17, 0, 0, 192, 194, 3, 28, 14, 0, 193, 191, 1, 0, 0, 0, 194, 197, 1, 0, 0, 0, 195, 193, 1, 0, 0, 0, 195, 196, 1, 0, 0, 0, 196, 21, 1, 0, 0, 0, 197, 195, 1, 0, 0, 0, 198, 199, 3, 24, 12, 0, 199, 200, 5, 21, 0, 0, 200, 208, 3, 2, 1, 0, 201, 202, 5, 17, 0, 0, 202, 203, 3, 24, 12, 0, 203, 204, 5, 21, 0, 0, 204, 205, 3, 2, 1, 0, 205, 207, 1, 0, 0, 0, 206, 201, 1, 0, 0, 0, 207, 210, 1, 0, 0, 0, 208, 206, 1, 0, 0, 0, 208, 209, 1, 0, 0, 0, 209, 23, 1, 0, 0, 0, 210, 208, 1, 0, 0, 0, 211, 213, 5, 20, 0, 0, 212, 211, 1, 0, 0, 0, 212, 213, 1, 0, 0, 0, 213, 214, 1, 0, 0, 0, 214, 215, 5, 36, 0, 0, 215, 25, 1, 0, 0, 0, 216, 217, 3, 28, 14, 0, 217, 218, 5, 21, 0, 0, 218, 226, 3, 2, 1, 0, 219, 220, 5, 17, 0, 0, 220, 221, 3, 28, 14, 0, 221, 222, 5, 21, 0, 0, 222, 223, 3, 2, 1, 0, 223, 225, 1, 0, 0, 0, 224, 219, 1, 0, 0, 0, 225, 228, 1, 0, 0, 0, 226, 224, 1, 0, 0, 0, 226, 227, 1, 0, 0, 0, 227, 27, 1, 0, 0, 0, 228, 226, 1, 0, 0, 0, 229, 231, 5, 20, 0, 0, 230, 229, 1, 0, 0, 0, 230, 231, 1, 0, 0, 0, 231, 232, 1, 0, 0, 0, 232, 233, 3, 2, 1, 0, 233, 29, 1, 0, 0, 0, 234, 236, 5, 18, 0, 0, 235, 234, 1, 0, 0, 0, 235, 236, 1, 0, 0, 0, 236, 237, 1, 0, 0, 0, 237, 249, 5, 32, 0, 0, 238, 249, 5, 33, 0, 0, 239, 241, 5, 18, 0, 0, 240, 239, 1, 0, 0, 0, 240, 241, 1, 0, 0, 0, 241, 242, 1, 0, 0, 0, 242, 249, 5, 31, 0, 0, 243, 249, 5, 34, 0, 0, 244, 249, 5, 35, 0, 0, 245, 249, 5, 26, 0, 0, 246, 249, 5, 27, 0, 0, 247, 249, 5, 28, 0, 0, 248, 235, 1, 0, 0, 0, 248, 238, 1, 0, 0, 0, 248, 240, 1, 0, 0, 0, 248, 243, 1, 0, 0, 0, 248, 244, 1, 0, 0, 0, 248, 245, 1, 0, 0, 0, 248, 246, 1, 0, 0, 0, 248, 247, 1, 0, 0, 0, 249, 31, 1, 0, 0, 0, 35, 41, 48, 56, 67, 79, 81, 88, 94, 97, 105, 113, 119, 124, 126, 130, 135, 138, 146, 149, 154, 157, 161, 168, 173, 176, 180, 187, 195, 208, 212, 226, 230, 235, 240, 248] \ No newline at end of file diff --git a/vendor/github.com/google/cel-go/parser/gen/CEL.tokens b/vendor/github.com/google/cel-go/parser/gen/CEL.tokens index c80bfb323..b305bdad3 100644 --- a/vendor/github.com/google/cel-go/parser/gen/CEL.tokens +++ b/vendor/github.com/google/cel-go/parser/gen/CEL.tokens @@ -1,68 +1,64 @@ -T__0=1 -T__1=2 -EQUALS=3 -NOT_EQUALS=4 -IN=5 -LESS=6 -LESS_EQUALS=7 -GREATER_EQUALS=8 -GREATER=9 -LOGICAL_AND=10 -LOGICAL_OR=11 -LBRACKET=12 -RPRACKET=13 -LBRACE=14 -RBRACE=15 -LPAREN=16 -RPAREN=17 -DOT=18 -COMMA=19 -MINUS=20 -EXCLAM=21 -QUESTIONMARK=22 -COLON=23 -PLUS=24 -STAR=25 -SLASH=26 -PERCENT=27 -CEL_TRUE=28 -CEL_FALSE=29 -NUL=30 -WHITESPACE=31 -COMMENT=32 -NUM_FLOAT=33 -NUM_INT=34 -NUM_UINT=35 -STRING=36 -BYTES=37 -IDENTIFIER=38 -'.?'=1 -'[?'=2 -'=='=3 -'!='=4 -'in'=5 -'<'=6 -'<='=7 -'>='=8 -'>'=9 -'&&'=10 -'||'=11 -'['=12 -']'=13 -'{'=14 -'}'=15 -'('=16 -')'=17 -'.'=18 -','=19 -'-'=20 -'!'=21 -'?'=22 -':'=23 -'+'=24 -'*'=25 -'/'=26 -'%'=27 -'true'=28 -'false'=29 -'null'=30 +EQUALS=1 +NOT_EQUALS=2 +IN=3 +LESS=4 +LESS_EQUALS=5 +GREATER_EQUALS=6 +GREATER=7 +LOGICAL_AND=8 +LOGICAL_OR=9 +LBRACKET=10 +RPRACKET=11 +LBRACE=12 +RBRACE=13 +LPAREN=14 +RPAREN=15 +DOT=16 +COMMA=17 +MINUS=18 +EXCLAM=19 +QUESTIONMARK=20 +COLON=21 +PLUS=22 +STAR=23 +SLASH=24 +PERCENT=25 +CEL_TRUE=26 +CEL_FALSE=27 +NUL=28 +WHITESPACE=29 +COMMENT=30 +NUM_FLOAT=31 +NUM_INT=32 +NUM_UINT=33 +STRING=34 +BYTES=35 +IDENTIFIER=36 +'=='=1 +'!='=2 +'in'=3 +'<'=4 +'<='=5 +'>='=6 +'>'=7 +'&&'=8 +'||'=9 +'['=10 +']'=11 +'{'=12 +'}'=13 +'('=14 +')'=15 +'.'=16 +','=17 +'-'=18 +'!'=19 +'?'=20 +':'=21 +'+'=22 +'*'=23 +'/'=24 +'%'=25 +'true'=26 +'false'=27 +'null'=28 diff --git a/vendor/github.com/google/cel-go/parser/gen/CELLexer.interp b/vendor/github.com/google/cel-go/parser/gen/CELLexer.interp index b94305cea..26e7f471e 100644 --- a/vendor/github.com/google/cel-go/parser/gen/CELLexer.interp +++ b/vendor/github.com/google/cel-go/parser/gen/CELLexer.interp @@ -1,7 +1,5 @@ token literal names: null -'.?' -'[?' '==' '!=' 'in' @@ -41,8 +39,6 @@ null token symbolic names: null -null -null EQUALS NOT_EQUALS IN @@ -81,8 +77,6 @@ BYTES IDENTIFIER rule names: -T__0 -T__1 EQUALS NOT_EQUALS IN @@ -139,4 +133,4 @@ mode names: DEFAULT_MODE atn: -[4, 0, 38, 433, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 31, 1, 31, 1, 32, 1, 32, 1, 33, 1, 33, 3, 33, 187, 8, 33, 1, 33, 4, 33, 190, 8, 33, 11, 33, 12, 33, 191, 1, 34, 1, 34, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 202, 8, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 3, 40, 235, 8, 40, 1, 41, 4, 41, 238, 8, 41, 11, 41, 12, 41, 239, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 5, 42, 248, 8, 42, 10, 42, 12, 42, 251, 9, 42, 1, 42, 1, 42, 1, 43, 4, 43, 256, 8, 43, 11, 43, 12, 43, 257, 1, 43, 1, 43, 4, 43, 262, 8, 43, 11, 43, 12, 43, 263, 1, 43, 3, 43, 267, 8, 43, 1, 43, 4, 43, 270, 8, 43, 11, 43, 12, 43, 271, 1, 43, 1, 43, 1, 43, 1, 43, 4, 43, 278, 8, 43, 11, 43, 12, 43, 279, 1, 43, 3, 43, 283, 8, 43, 3, 43, 285, 8, 43, 1, 44, 4, 44, 288, 8, 44, 11, 44, 12, 44, 289, 1, 44, 1, 44, 1, 44, 1, 44, 4, 44, 296, 8, 44, 11, 44, 12, 44, 297, 3, 44, 300, 8, 44, 1, 45, 4, 45, 303, 8, 45, 11, 45, 12, 45, 304, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 4, 45, 313, 8, 45, 11, 45, 12, 45, 314, 1, 45, 1, 45, 3, 45, 319, 8, 45, 1, 46, 1, 46, 1, 46, 5, 46, 324, 8, 46, 10, 46, 12, 46, 327, 9, 46, 1, 46, 1, 46, 1, 46, 1, 46, 5, 46, 333, 8, 46, 10, 46, 12, 46, 336, 9, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 5, 46, 345, 8, 46, 10, 46, 12, 46, 348, 9, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 5, 46, 359, 8, 46, 10, 46, 12, 46, 362, 9, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 5, 46, 370, 8, 46, 10, 46, 12, 46, 373, 9, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 5, 46, 380, 8, 46, 10, 46, 12, 46, 383, 9, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 5, 46, 393, 8, 46, 10, 46, 12, 46, 396, 9, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 5, 46, 408, 8, 46, 10, 46, 12, 46, 411, 9, 46, 1, 46, 1, 46, 1, 46, 1, 46, 3, 46, 417, 8, 46, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 3, 48, 424, 8, 48, 1, 48, 1, 48, 1, 48, 5, 48, 429, 8, 48, 10, 48, 12, 48, 432, 9, 48, 4, 346, 360, 394, 409, 0, 49, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 0, 63, 0, 65, 0, 67, 0, 69, 0, 71, 0, 73, 0, 75, 0, 77, 0, 79, 0, 81, 0, 83, 31, 85, 32, 87, 33, 89, 34, 91, 35, 93, 36, 95, 37, 97, 38, 1, 0, 16, 2, 0, 65, 90, 97, 122, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 82, 82, 114, 114, 10, 0, 34, 34, 39, 39, 63, 63, 92, 92, 96, 98, 102, 102, 110, 110, 114, 114, 116, 116, 118, 118, 2, 0, 88, 88, 120, 120, 3, 0, 9, 10, 12, 13, 32, 32, 1, 0, 10, 10, 2, 0, 85, 85, 117, 117, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 4, 0, 10, 10, 13, 13, 39, 39, 92, 92, 1, 0, 92, 92, 3, 0, 10, 10, 13, 13, 34, 34, 3, 0, 10, 10, 13, 13, 39, 39, 2, 0, 66, 66, 98, 98, 466, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 1, 99, 1, 0, 0, 0, 3, 102, 1, 0, 0, 0, 5, 105, 1, 0, 0, 0, 7, 108, 1, 0, 0, 0, 9, 111, 1, 0, 0, 0, 11, 114, 1, 0, 0, 0, 13, 116, 1, 0, 0, 0, 15, 119, 1, 0, 0, 0, 17, 122, 1, 0, 0, 0, 19, 124, 1, 0, 0, 0, 21, 127, 1, 0, 0, 0, 23, 130, 1, 0, 0, 0, 25, 132, 1, 0, 0, 0, 27, 134, 1, 0, 0, 0, 29, 136, 1, 0, 0, 0, 31, 138, 1, 0, 0, 0, 33, 140, 1, 0, 0, 0, 35, 142, 1, 0, 0, 0, 37, 144, 1, 0, 0, 0, 39, 146, 1, 0, 0, 0, 41, 148, 1, 0, 0, 0, 43, 150, 1, 0, 0, 0, 45, 152, 1, 0, 0, 0, 47, 154, 1, 0, 0, 0, 49, 156, 1, 0, 0, 0, 51, 158, 1, 0, 0, 0, 53, 160, 1, 0, 0, 0, 55, 162, 1, 0, 0, 0, 57, 167, 1, 0, 0, 0, 59, 173, 1, 0, 0, 0, 61, 178, 1, 0, 0, 0, 63, 180, 1, 0, 0, 0, 65, 182, 1, 0, 0, 0, 67, 184, 1, 0, 0, 0, 69, 193, 1, 0, 0, 0, 71, 195, 1, 0, 0, 0, 73, 201, 1, 0, 0, 0, 75, 203, 1, 0, 0, 0, 77, 206, 1, 0, 0, 0, 79, 211, 1, 0, 0, 0, 81, 234, 1, 0, 0, 0, 83, 237, 1, 0, 0, 0, 85, 243, 1, 0, 0, 0, 87, 284, 1, 0, 0, 0, 89, 299, 1, 0, 0, 0, 91, 318, 1, 0, 0, 0, 93, 416, 1, 0, 0, 0, 95, 418, 1, 0, 0, 0, 97, 423, 1, 0, 0, 0, 99, 100, 5, 46, 0, 0, 100, 101, 5, 63, 0, 0, 101, 2, 1, 0, 0, 0, 102, 103, 5, 91, 0, 0, 103, 104, 5, 63, 0, 0, 104, 4, 1, 0, 0, 0, 105, 106, 5, 61, 0, 0, 106, 107, 5, 61, 0, 0, 107, 6, 1, 0, 0, 0, 108, 109, 5, 33, 0, 0, 109, 110, 5, 61, 0, 0, 110, 8, 1, 0, 0, 0, 111, 112, 5, 105, 0, 0, 112, 113, 5, 110, 0, 0, 113, 10, 1, 0, 0, 0, 114, 115, 5, 60, 0, 0, 115, 12, 1, 0, 0, 0, 116, 117, 5, 60, 0, 0, 117, 118, 5, 61, 0, 0, 118, 14, 1, 0, 0, 0, 119, 120, 5, 62, 0, 0, 120, 121, 5, 61, 0, 0, 121, 16, 1, 0, 0, 0, 122, 123, 5, 62, 0, 0, 123, 18, 1, 0, 0, 0, 124, 125, 5, 38, 0, 0, 125, 126, 5, 38, 0, 0, 126, 20, 1, 0, 0, 0, 127, 128, 5, 124, 0, 0, 128, 129, 5, 124, 0, 0, 129, 22, 1, 0, 0, 0, 130, 131, 5, 91, 0, 0, 131, 24, 1, 0, 0, 0, 132, 133, 5, 93, 0, 0, 133, 26, 1, 0, 0, 0, 134, 135, 5, 123, 0, 0, 135, 28, 1, 0, 0, 0, 136, 137, 5, 125, 0, 0, 137, 30, 1, 0, 0, 0, 138, 139, 5, 40, 0, 0, 139, 32, 1, 0, 0, 0, 140, 141, 5, 41, 0, 0, 141, 34, 1, 0, 0, 0, 142, 143, 5, 46, 0, 0, 143, 36, 1, 0, 0, 0, 144, 145, 5, 44, 0, 0, 145, 38, 1, 0, 0, 0, 146, 147, 5, 45, 0, 0, 147, 40, 1, 0, 0, 0, 148, 149, 5, 33, 0, 0, 149, 42, 1, 0, 0, 0, 150, 151, 5, 63, 0, 0, 151, 44, 1, 0, 0, 0, 152, 153, 5, 58, 0, 0, 153, 46, 1, 0, 0, 0, 154, 155, 5, 43, 0, 0, 155, 48, 1, 0, 0, 0, 156, 157, 5, 42, 0, 0, 157, 50, 1, 0, 0, 0, 158, 159, 5, 47, 0, 0, 159, 52, 1, 0, 0, 0, 160, 161, 5, 37, 0, 0, 161, 54, 1, 0, 0, 0, 162, 163, 5, 116, 0, 0, 163, 164, 5, 114, 0, 0, 164, 165, 5, 117, 0, 0, 165, 166, 5, 101, 0, 0, 166, 56, 1, 0, 0, 0, 167, 168, 5, 102, 0, 0, 168, 169, 5, 97, 0, 0, 169, 170, 5, 108, 0, 0, 170, 171, 5, 115, 0, 0, 171, 172, 5, 101, 0, 0, 172, 58, 1, 0, 0, 0, 173, 174, 5, 110, 0, 0, 174, 175, 5, 117, 0, 0, 175, 176, 5, 108, 0, 0, 176, 177, 5, 108, 0, 0, 177, 60, 1, 0, 0, 0, 178, 179, 5, 92, 0, 0, 179, 62, 1, 0, 0, 0, 180, 181, 7, 0, 0, 0, 181, 64, 1, 0, 0, 0, 182, 183, 2, 48, 57, 0, 183, 66, 1, 0, 0, 0, 184, 186, 7, 1, 0, 0, 185, 187, 7, 2, 0, 0, 186, 185, 1, 0, 0, 0, 186, 187, 1, 0, 0, 0, 187, 189, 1, 0, 0, 0, 188, 190, 3, 65, 32, 0, 189, 188, 1, 0, 0, 0, 190, 191, 1, 0, 0, 0, 191, 189, 1, 0, 0, 0, 191, 192, 1, 0, 0, 0, 192, 68, 1, 0, 0, 0, 193, 194, 7, 3, 0, 0, 194, 70, 1, 0, 0, 0, 195, 196, 7, 4, 0, 0, 196, 72, 1, 0, 0, 0, 197, 202, 3, 75, 37, 0, 198, 202, 3, 79, 39, 0, 199, 202, 3, 81, 40, 0, 200, 202, 3, 77, 38, 0, 201, 197, 1, 0, 0, 0, 201, 198, 1, 0, 0, 0, 201, 199, 1, 0, 0, 0, 201, 200, 1, 0, 0, 0, 202, 74, 1, 0, 0, 0, 203, 204, 3, 61, 30, 0, 204, 205, 7, 5, 0, 0, 205, 76, 1, 0, 0, 0, 206, 207, 3, 61, 30, 0, 207, 208, 2, 48, 51, 0, 208, 209, 2, 48, 55, 0, 209, 210, 2, 48, 55, 0, 210, 78, 1, 0, 0, 0, 211, 212, 3, 61, 30, 0, 212, 213, 7, 6, 0, 0, 213, 214, 3, 69, 34, 0, 214, 215, 3, 69, 34, 0, 215, 80, 1, 0, 0, 0, 216, 217, 3, 61, 30, 0, 217, 218, 5, 117, 0, 0, 218, 219, 3, 69, 34, 0, 219, 220, 3, 69, 34, 0, 220, 221, 3, 69, 34, 0, 221, 222, 3, 69, 34, 0, 222, 235, 1, 0, 0, 0, 223, 224, 3, 61, 30, 0, 224, 225, 5, 85, 0, 0, 225, 226, 3, 69, 34, 0, 226, 227, 3, 69, 34, 0, 227, 228, 3, 69, 34, 0, 228, 229, 3, 69, 34, 0, 229, 230, 3, 69, 34, 0, 230, 231, 3, 69, 34, 0, 231, 232, 3, 69, 34, 0, 232, 233, 3, 69, 34, 0, 233, 235, 1, 0, 0, 0, 234, 216, 1, 0, 0, 0, 234, 223, 1, 0, 0, 0, 235, 82, 1, 0, 0, 0, 236, 238, 7, 7, 0, 0, 237, 236, 1, 0, 0, 0, 238, 239, 1, 0, 0, 0, 239, 237, 1, 0, 0, 0, 239, 240, 1, 0, 0, 0, 240, 241, 1, 0, 0, 0, 241, 242, 6, 41, 0, 0, 242, 84, 1, 0, 0, 0, 243, 244, 5, 47, 0, 0, 244, 245, 5, 47, 0, 0, 245, 249, 1, 0, 0, 0, 246, 248, 8, 8, 0, 0, 247, 246, 1, 0, 0, 0, 248, 251, 1, 0, 0, 0, 249, 247, 1, 0, 0, 0, 249, 250, 1, 0, 0, 0, 250, 252, 1, 0, 0, 0, 251, 249, 1, 0, 0, 0, 252, 253, 6, 42, 0, 0, 253, 86, 1, 0, 0, 0, 254, 256, 3, 65, 32, 0, 255, 254, 1, 0, 0, 0, 256, 257, 1, 0, 0, 0, 257, 255, 1, 0, 0, 0, 257, 258, 1, 0, 0, 0, 258, 259, 1, 0, 0, 0, 259, 261, 5, 46, 0, 0, 260, 262, 3, 65, 32, 0, 261, 260, 1, 0, 0, 0, 262, 263, 1, 0, 0, 0, 263, 261, 1, 0, 0, 0, 263, 264, 1, 0, 0, 0, 264, 266, 1, 0, 0, 0, 265, 267, 3, 67, 33, 0, 266, 265, 1, 0, 0, 0, 266, 267, 1, 0, 0, 0, 267, 285, 1, 0, 0, 0, 268, 270, 3, 65, 32, 0, 269, 268, 1, 0, 0, 0, 270, 271, 1, 0, 0, 0, 271, 269, 1, 0, 0, 0, 271, 272, 1, 0, 0, 0, 272, 273, 1, 0, 0, 0, 273, 274, 3, 67, 33, 0, 274, 285, 1, 0, 0, 0, 275, 277, 5, 46, 0, 0, 276, 278, 3, 65, 32, 0, 277, 276, 1, 0, 0, 0, 278, 279, 1, 0, 0, 0, 279, 277, 1, 0, 0, 0, 279, 280, 1, 0, 0, 0, 280, 282, 1, 0, 0, 0, 281, 283, 3, 67, 33, 0, 282, 281, 1, 0, 0, 0, 282, 283, 1, 0, 0, 0, 283, 285, 1, 0, 0, 0, 284, 255, 1, 0, 0, 0, 284, 269, 1, 0, 0, 0, 284, 275, 1, 0, 0, 0, 285, 88, 1, 0, 0, 0, 286, 288, 3, 65, 32, 0, 287, 286, 1, 0, 0, 0, 288, 289, 1, 0, 0, 0, 289, 287, 1, 0, 0, 0, 289, 290, 1, 0, 0, 0, 290, 300, 1, 0, 0, 0, 291, 292, 5, 48, 0, 0, 292, 293, 5, 120, 0, 0, 293, 295, 1, 0, 0, 0, 294, 296, 3, 69, 34, 0, 295, 294, 1, 0, 0, 0, 296, 297, 1, 0, 0, 0, 297, 295, 1, 0, 0, 0, 297, 298, 1, 0, 0, 0, 298, 300, 1, 0, 0, 0, 299, 287, 1, 0, 0, 0, 299, 291, 1, 0, 0, 0, 300, 90, 1, 0, 0, 0, 301, 303, 3, 65, 32, 0, 302, 301, 1, 0, 0, 0, 303, 304, 1, 0, 0, 0, 304, 302, 1, 0, 0, 0, 304, 305, 1, 0, 0, 0, 305, 306, 1, 0, 0, 0, 306, 307, 7, 9, 0, 0, 307, 319, 1, 0, 0, 0, 308, 309, 5, 48, 0, 0, 309, 310, 5, 120, 0, 0, 310, 312, 1, 0, 0, 0, 311, 313, 3, 69, 34, 0, 312, 311, 1, 0, 0, 0, 313, 314, 1, 0, 0, 0, 314, 312, 1, 0, 0, 0, 314, 315, 1, 0, 0, 0, 315, 316, 1, 0, 0, 0, 316, 317, 7, 9, 0, 0, 317, 319, 1, 0, 0, 0, 318, 302, 1, 0, 0, 0, 318, 308, 1, 0, 0, 0, 319, 92, 1, 0, 0, 0, 320, 325, 5, 34, 0, 0, 321, 324, 3, 73, 36, 0, 322, 324, 8, 10, 0, 0, 323, 321, 1, 0, 0, 0, 323, 322, 1, 0, 0, 0, 324, 327, 1, 0, 0, 0, 325, 323, 1, 0, 0, 0, 325, 326, 1, 0, 0, 0, 326, 328, 1, 0, 0, 0, 327, 325, 1, 0, 0, 0, 328, 417, 5, 34, 0, 0, 329, 334, 5, 39, 0, 0, 330, 333, 3, 73, 36, 0, 331, 333, 8, 11, 0, 0, 332, 330, 1, 0, 0, 0, 332, 331, 1, 0, 0, 0, 333, 336, 1, 0, 0, 0, 334, 332, 1, 0, 0, 0, 334, 335, 1, 0, 0, 0, 335, 337, 1, 0, 0, 0, 336, 334, 1, 0, 0, 0, 337, 417, 5, 39, 0, 0, 338, 339, 5, 34, 0, 0, 339, 340, 5, 34, 0, 0, 340, 341, 5, 34, 0, 0, 341, 346, 1, 0, 0, 0, 342, 345, 3, 73, 36, 0, 343, 345, 8, 12, 0, 0, 344, 342, 1, 0, 0, 0, 344, 343, 1, 0, 0, 0, 345, 348, 1, 0, 0, 0, 346, 347, 1, 0, 0, 0, 346, 344, 1, 0, 0, 0, 347, 349, 1, 0, 0, 0, 348, 346, 1, 0, 0, 0, 349, 350, 5, 34, 0, 0, 350, 351, 5, 34, 0, 0, 351, 417, 5, 34, 0, 0, 352, 353, 5, 39, 0, 0, 353, 354, 5, 39, 0, 0, 354, 355, 5, 39, 0, 0, 355, 360, 1, 0, 0, 0, 356, 359, 3, 73, 36, 0, 357, 359, 8, 12, 0, 0, 358, 356, 1, 0, 0, 0, 358, 357, 1, 0, 0, 0, 359, 362, 1, 0, 0, 0, 360, 361, 1, 0, 0, 0, 360, 358, 1, 0, 0, 0, 361, 363, 1, 0, 0, 0, 362, 360, 1, 0, 0, 0, 363, 364, 5, 39, 0, 0, 364, 365, 5, 39, 0, 0, 365, 417, 5, 39, 0, 0, 366, 367, 3, 71, 35, 0, 367, 371, 5, 34, 0, 0, 368, 370, 8, 13, 0, 0, 369, 368, 1, 0, 0, 0, 370, 373, 1, 0, 0, 0, 371, 369, 1, 0, 0, 0, 371, 372, 1, 0, 0, 0, 372, 374, 1, 0, 0, 0, 373, 371, 1, 0, 0, 0, 374, 375, 5, 34, 0, 0, 375, 417, 1, 0, 0, 0, 376, 377, 3, 71, 35, 0, 377, 381, 5, 39, 0, 0, 378, 380, 8, 14, 0, 0, 379, 378, 1, 0, 0, 0, 380, 383, 1, 0, 0, 0, 381, 379, 1, 0, 0, 0, 381, 382, 1, 0, 0, 0, 382, 384, 1, 0, 0, 0, 383, 381, 1, 0, 0, 0, 384, 385, 5, 39, 0, 0, 385, 417, 1, 0, 0, 0, 386, 387, 3, 71, 35, 0, 387, 388, 5, 34, 0, 0, 388, 389, 5, 34, 0, 0, 389, 390, 5, 34, 0, 0, 390, 394, 1, 0, 0, 0, 391, 393, 9, 0, 0, 0, 392, 391, 1, 0, 0, 0, 393, 396, 1, 0, 0, 0, 394, 395, 1, 0, 0, 0, 394, 392, 1, 0, 0, 0, 395, 397, 1, 0, 0, 0, 396, 394, 1, 0, 0, 0, 397, 398, 5, 34, 0, 0, 398, 399, 5, 34, 0, 0, 399, 400, 5, 34, 0, 0, 400, 417, 1, 0, 0, 0, 401, 402, 3, 71, 35, 0, 402, 403, 5, 39, 0, 0, 403, 404, 5, 39, 0, 0, 404, 405, 5, 39, 0, 0, 405, 409, 1, 0, 0, 0, 406, 408, 9, 0, 0, 0, 407, 406, 1, 0, 0, 0, 408, 411, 1, 0, 0, 0, 409, 410, 1, 0, 0, 0, 409, 407, 1, 0, 0, 0, 410, 412, 1, 0, 0, 0, 411, 409, 1, 0, 0, 0, 412, 413, 5, 39, 0, 0, 413, 414, 5, 39, 0, 0, 414, 415, 5, 39, 0, 0, 415, 417, 1, 0, 0, 0, 416, 320, 1, 0, 0, 0, 416, 329, 1, 0, 0, 0, 416, 338, 1, 0, 0, 0, 416, 352, 1, 0, 0, 0, 416, 366, 1, 0, 0, 0, 416, 376, 1, 0, 0, 0, 416, 386, 1, 0, 0, 0, 416, 401, 1, 0, 0, 0, 417, 94, 1, 0, 0, 0, 418, 419, 7, 15, 0, 0, 419, 420, 3, 93, 46, 0, 420, 96, 1, 0, 0, 0, 421, 424, 3, 63, 31, 0, 422, 424, 5, 95, 0, 0, 423, 421, 1, 0, 0, 0, 423, 422, 1, 0, 0, 0, 424, 430, 1, 0, 0, 0, 425, 429, 3, 63, 31, 0, 426, 429, 3, 65, 32, 0, 427, 429, 5, 95, 0, 0, 428, 425, 1, 0, 0, 0, 428, 426, 1, 0, 0, 0, 428, 427, 1, 0, 0, 0, 429, 432, 1, 0, 0, 0, 430, 428, 1, 0, 0, 0, 430, 431, 1, 0, 0, 0, 431, 98, 1, 0, 0, 0, 432, 430, 1, 0, 0, 0, 36, 0, 186, 191, 201, 234, 239, 249, 257, 263, 266, 271, 279, 282, 284, 289, 297, 299, 304, 314, 318, 323, 325, 332, 334, 344, 346, 358, 360, 371, 381, 394, 409, 416, 423, 428, 430, 1, 0, 1, 0] \ No newline at end of file +[4, 0, 36, 423, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, 1, 30, 1, 31, 1, 31, 3, 31, 177, 8, 31, 1, 31, 4, 31, 180, 8, 31, 11, 31, 12, 31, 181, 1, 32, 1, 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 3, 34, 192, 8, 34, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 3, 38, 225, 8, 38, 1, 39, 4, 39, 228, 8, 39, 11, 39, 12, 39, 229, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 5, 40, 238, 8, 40, 10, 40, 12, 40, 241, 9, 40, 1, 40, 1, 40, 1, 41, 4, 41, 246, 8, 41, 11, 41, 12, 41, 247, 1, 41, 1, 41, 4, 41, 252, 8, 41, 11, 41, 12, 41, 253, 1, 41, 3, 41, 257, 8, 41, 1, 41, 4, 41, 260, 8, 41, 11, 41, 12, 41, 261, 1, 41, 1, 41, 1, 41, 1, 41, 4, 41, 268, 8, 41, 11, 41, 12, 41, 269, 1, 41, 3, 41, 273, 8, 41, 3, 41, 275, 8, 41, 1, 42, 4, 42, 278, 8, 42, 11, 42, 12, 42, 279, 1, 42, 1, 42, 1, 42, 1, 42, 4, 42, 286, 8, 42, 11, 42, 12, 42, 287, 3, 42, 290, 8, 42, 1, 43, 4, 43, 293, 8, 43, 11, 43, 12, 43, 294, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 4, 43, 303, 8, 43, 11, 43, 12, 43, 304, 1, 43, 1, 43, 3, 43, 309, 8, 43, 1, 44, 1, 44, 1, 44, 5, 44, 314, 8, 44, 10, 44, 12, 44, 317, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 323, 8, 44, 10, 44, 12, 44, 326, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 335, 8, 44, 10, 44, 12, 44, 338, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 349, 8, 44, 10, 44, 12, 44, 352, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 360, 8, 44, 10, 44, 12, 44, 363, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 370, 8, 44, 10, 44, 12, 44, 373, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 383, 8, 44, 10, 44, 12, 44, 386, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 398, 8, 44, 10, 44, 12, 44, 401, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 3, 44, 407, 8, 44, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 3, 46, 414, 8, 46, 1, 46, 1, 46, 1, 46, 5, 46, 419, 8, 46, 10, 46, 12, 46, 422, 9, 46, 4, 336, 350, 384, 399, 0, 47, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 0, 59, 0, 61, 0, 63, 0, 65, 0, 67, 0, 69, 0, 71, 0, 73, 0, 75, 0, 77, 0, 79, 29, 81, 30, 83, 31, 85, 32, 87, 33, 89, 34, 91, 35, 93, 36, 1, 0, 16, 2, 0, 65, 90, 97, 122, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 82, 82, 114, 114, 10, 0, 34, 34, 39, 39, 63, 63, 92, 92, 96, 98, 102, 102, 110, 110, 114, 114, 116, 116, 118, 118, 2, 0, 88, 88, 120, 120, 3, 0, 9, 10, 12, 13, 32, 32, 1, 0, 10, 10, 2, 0, 85, 85, 117, 117, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 4, 0, 10, 10, 13, 13, 39, 39, 92, 92, 1, 0, 92, 92, 3, 0, 10, 10, 13, 13, 34, 34, 3, 0, 10, 10, 13, 13, 39, 39, 2, 0, 66, 66, 98, 98, 456, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 1, 95, 1, 0, 0, 0, 3, 98, 1, 0, 0, 0, 5, 101, 1, 0, 0, 0, 7, 104, 1, 0, 0, 0, 9, 106, 1, 0, 0, 0, 11, 109, 1, 0, 0, 0, 13, 112, 1, 0, 0, 0, 15, 114, 1, 0, 0, 0, 17, 117, 1, 0, 0, 0, 19, 120, 1, 0, 0, 0, 21, 122, 1, 0, 0, 0, 23, 124, 1, 0, 0, 0, 25, 126, 1, 0, 0, 0, 27, 128, 1, 0, 0, 0, 29, 130, 1, 0, 0, 0, 31, 132, 1, 0, 0, 0, 33, 134, 1, 0, 0, 0, 35, 136, 1, 0, 0, 0, 37, 138, 1, 0, 0, 0, 39, 140, 1, 0, 0, 0, 41, 142, 1, 0, 0, 0, 43, 144, 1, 0, 0, 0, 45, 146, 1, 0, 0, 0, 47, 148, 1, 0, 0, 0, 49, 150, 1, 0, 0, 0, 51, 152, 1, 0, 0, 0, 53, 157, 1, 0, 0, 0, 55, 163, 1, 0, 0, 0, 57, 168, 1, 0, 0, 0, 59, 170, 1, 0, 0, 0, 61, 172, 1, 0, 0, 0, 63, 174, 1, 0, 0, 0, 65, 183, 1, 0, 0, 0, 67, 185, 1, 0, 0, 0, 69, 191, 1, 0, 0, 0, 71, 193, 1, 0, 0, 0, 73, 196, 1, 0, 0, 0, 75, 201, 1, 0, 0, 0, 77, 224, 1, 0, 0, 0, 79, 227, 1, 0, 0, 0, 81, 233, 1, 0, 0, 0, 83, 274, 1, 0, 0, 0, 85, 289, 1, 0, 0, 0, 87, 308, 1, 0, 0, 0, 89, 406, 1, 0, 0, 0, 91, 408, 1, 0, 0, 0, 93, 413, 1, 0, 0, 0, 95, 96, 5, 61, 0, 0, 96, 97, 5, 61, 0, 0, 97, 2, 1, 0, 0, 0, 98, 99, 5, 33, 0, 0, 99, 100, 5, 61, 0, 0, 100, 4, 1, 0, 0, 0, 101, 102, 5, 105, 0, 0, 102, 103, 5, 110, 0, 0, 103, 6, 1, 0, 0, 0, 104, 105, 5, 60, 0, 0, 105, 8, 1, 0, 0, 0, 106, 107, 5, 60, 0, 0, 107, 108, 5, 61, 0, 0, 108, 10, 1, 0, 0, 0, 109, 110, 5, 62, 0, 0, 110, 111, 5, 61, 0, 0, 111, 12, 1, 0, 0, 0, 112, 113, 5, 62, 0, 0, 113, 14, 1, 0, 0, 0, 114, 115, 5, 38, 0, 0, 115, 116, 5, 38, 0, 0, 116, 16, 1, 0, 0, 0, 117, 118, 5, 124, 0, 0, 118, 119, 5, 124, 0, 0, 119, 18, 1, 0, 0, 0, 120, 121, 5, 91, 0, 0, 121, 20, 1, 0, 0, 0, 122, 123, 5, 93, 0, 0, 123, 22, 1, 0, 0, 0, 124, 125, 5, 123, 0, 0, 125, 24, 1, 0, 0, 0, 126, 127, 5, 125, 0, 0, 127, 26, 1, 0, 0, 0, 128, 129, 5, 40, 0, 0, 129, 28, 1, 0, 0, 0, 130, 131, 5, 41, 0, 0, 131, 30, 1, 0, 0, 0, 132, 133, 5, 46, 0, 0, 133, 32, 1, 0, 0, 0, 134, 135, 5, 44, 0, 0, 135, 34, 1, 0, 0, 0, 136, 137, 5, 45, 0, 0, 137, 36, 1, 0, 0, 0, 138, 139, 5, 33, 0, 0, 139, 38, 1, 0, 0, 0, 140, 141, 5, 63, 0, 0, 141, 40, 1, 0, 0, 0, 142, 143, 5, 58, 0, 0, 143, 42, 1, 0, 0, 0, 144, 145, 5, 43, 0, 0, 145, 44, 1, 0, 0, 0, 146, 147, 5, 42, 0, 0, 147, 46, 1, 0, 0, 0, 148, 149, 5, 47, 0, 0, 149, 48, 1, 0, 0, 0, 150, 151, 5, 37, 0, 0, 151, 50, 1, 0, 0, 0, 152, 153, 5, 116, 0, 0, 153, 154, 5, 114, 0, 0, 154, 155, 5, 117, 0, 0, 155, 156, 5, 101, 0, 0, 156, 52, 1, 0, 0, 0, 157, 158, 5, 102, 0, 0, 158, 159, 5, 97, 0, 0, 159, 160, 5, 108, 0, 0, 160, 161, 5, 115, 0, 0, 161, 162, 5, 101, 0, 0, 162, 54, 1, 0, 0, 0, 163, 164, 5, 110, 0, 0, 164, 165, 5, 117, 0, 0, 165, 166, 5, 108, 0, 0, 166, 167, 5, 108, 0, 0, 167, 56, 1, 0, 0, 0, 168, 169, 5, 92, 0, 0, 169, 58, 1, 0, 0, 0, 170, 171, 7, 0, 0, 0, 171, 60, 1, 0, 0, 0, 172, 173, 2, 48, 57, 0, 173, 62, 1, 0, 0, 0, 174, 176, 7, 1, 0, 0, 175, 177, 7, 2, 0, 0, 176, 175, 1, 0, 0, 0, 176, 177, 1, 0, 0, 0, 177, 179, 1, 0, 0, 0, 178, 180, 3, 61, 30, 0, 179, 178, 1, 0, 0, 0, 180, 181, 1, 0, 0, 0, 181, 179, 1, 0, 0, 0, 181, 182, 1, 0, 0, 0, 182, 64, 1, 0, 0, 0, 183, 184, 7, 3, 0, 0, 184, 66, 1, 0, 0, 0, 185, 186, 7, 4, 0, 0, 186, 68, 1, 0, 0, 0, 187, 192, 3, 71, 35, 0, 188, 192, 3, 75, 37, 0, 189, 192, 3, 77, 38, 0, 190, 192, 3, 73, 36, 0, 191, 187, 1, 0, 0, 0, 191, 188, 1, 0, 0, 0, 191, 189, 1, 0, 0, 0, 191, 190, 1, 0, 0, 0, 192, 70, 1, 0, 0, 0, 193, 194, 3, 57, 28, 0, 194, 195, 7, 5, 0, 0, 195, 72, 1, 0, 0, 0, 196, 197, 3, 57, 28, 0, 197, 198, 2, 48, 51, 0, 198, 199, 2, 48, 55, 0, 199, 200, 2, 48, 55, 0, 200, 74, 1, 0, 0, 0, 201, 202, 3, 57, 28, 0, 202, 203, 7, 6, 0, 0, 203, 204, 3, 65, 32, 0, 204, 205, 3, 65, 32, 0, 205, 76, 1, 0, 0, 0, 206, 207, 3, 57, 28, 0, 207, 208, 5, 117, 0, 0, 208, 209, 3, 65, 32, 0, 209, 210, 3, 65, 32, 0, 210, 211, 3, 65, 32, 0, 211, 212, 3, 65, 32, 0, 212, 225, 1, 0, 0, 0, 213, 214, 3, 57, 28, 0, 214, 215, 5, 85, 0, 0, 215, 216, 3, 65, 32, 0, 216, 217, 3, 65, 32, 0, 217, 218, 3, 65, 32, 0, 218, 219, 3, 65, 32, 0, 219, 220, 3, 65, 32, 0, 220, 221, 3, 65, 32, 0, 221, 222, 3, 65, 32, 0, 222, 223, 3, 65, 32, 0, 223, 225, 1, 0, 0, 0, 224, 206, 1, 0, 0, 0, 224, 213, 1, 0, 0, 0, 225, 78, 1, 0, 0, 0, 226, 228, 7, 7, 0, 0, 227, 226, 1, 0, 0, 0, 228, 229, 1, 0, 0, 0, 229, 227, 1, 0, 0, 0, 229, 230, 1, 0, 0, 0, 230, 231, 1, 0, 0, 0, 231, 232, 6, 39, 0, 0, 232, 80, 1, 0, 0, 0, 233, 234, 5, 47, 0, 0, 234, 235, 5, 47, 0, 0, 235, 239, 1, 0, 0, 0, 236, 238, 8, 8, 0, 0, 237, 236, 1, 0, 0, 0, 238, 241, 1, 0, 0, 0, 239, 237, 1, 0, 0, 0, 239, 240, 1, 0, 0, 0, 240, 242, 1, 0, 0, 0, 241, 239, 1, 0, 0, 0, 242, 243, 6, 40, 0, 0, 243, 82, 1, 0, 0, 0, 244, 246, 3, 61, 30, 0, 245, 244, 1, 0, 0, 0, 246, 247, 1, 0, 0, 0, 247, 245, 1, 0, 0, 0, 247, 248, 1, 0, 0, 0, 248, 249, 1, 0, 0, 0, 249, 251, 5, 46, 0, 0, 250, 252, 3, 61, 30, 0, 251, 250, 1, 0, 0, 0, 252, 253, 1, 0, 0, 0, 253, 251, 1, 0, 0, 0, 253, 254, 1, 0, 0, 0, 254, 256, 1, 0, 0, 0, 255, 257, 3, 63, 31, 0, 256, 255, 1, 0, 0, 0, 256, 257, 1, 0, 0, 0, 257, 275, 1, 0, 0, 0, 258, 260, 3, 61, 30, 0, 259, 258, 1, 0, 0, 0, 260, 261, 1, 0, 0, 0, 261, 259, 1, 0, 0, 0, 261, 262, 1, 0, 0, 0, 262, 263, 1, 0, 0, 0, 263, 264, 3, 63, 31, 0, 264, 275, 1, 0, 0, 0, 265, 267, 5, 46, 0, 0, 266, 268, 3, 61, 30, 0, 267, 266, 1, 0, 0, 0, 268, 269, 1, 0, 0, 0, 269, 267, 1, 0, 0, 0, 269, 270, 1, 0, 0, 0, 270, 272, 1, 0, 0, 0, 271, 273, 3, 63, 31, 0, 272, 271, 1, 0, 0, 0, 272, 273, 1, 0, 0, 0, 273, 275, 1, 0, 0, 0, 274, 245, 1, 0, 0, 0, 274, 259, 1, 0, 0, 0, 274, 265, 1, 0, 0, 0, 275, 84, 1, 0, 0, 0, 276, 278, 3, 61, 30, 0, 277, 276, 1, 0, 0, 0, 278, 279, 1, 0, 0, 0, 279, 277, 1, 0, 0, 0, 279, 280, 1, 0, 0, 0, 280, 290, 1, 0, 0, 0, 281, 282, 5, 48, 0, 0, 282, 283, 5, 120, 0, 0, 283, 285, 1, 0, 0, 0, 284, 286, 3, 65, 32, 0, 285, 284, 1, 0, 0, 0, 286, 287, 1, 0, 0, 0, 287, 285, 1, 0, 0, 0, 287, 288, 1, 0, 0, 0, 288, 290, 1, 0, 0, 0, 289, 277, 1, 0, 0, 0, 289, 281, 1, 0, 0, 0, 290, 86, 1, 0, 0, 0, 291, 293, 3, 61, 30, 0, 292, 291, 1, 0, 0, 0, 293, 294, 1, 0, 0, 0, 294, 292, 1, 0, 0, 0, 294, 295, 1, 0, 0, 0, 295, 296, 1, 0, 0, 0, 296, 297, 7, 9, 0, 0, 297, 309, 1, 0, 0, 0, 298, 299, 5, 48, 0, 0, 299, 300, 5, 120, 0, 0, 300, 302, 1, 0, 0, 0, 301, 303, 3, 65, 32, 0, 302, 301, 1, 0, 0, 0, 303, 304, 1, 0, 0, 0, 304, 302, 1, 0, 0, 0, 304, 305, 1, 0, 0, 0, 305, 306, 1, 0, 0, 0, 306, 307, 7, 9, 0, 0, 307, 309, 1, 0, 0, 0, 308, 292, 1, 0, 0, 0, 308, 298, 1, 0, 0, 0, 309, 88, 1, 0, 0, 0, 310, 315, 5, 34, 0, 0, 311, 314, 3, 69, 34, 0, 312, 314, 8, 10, 0, 0, 313, 311, 1, 0, 0, 0, 313, 312, 1, 0, 0, 0, 314, 317, 1, 0, 0, 0, 315, 313, 1, 0, 0, 0, 315, 316, 1, 0, 0, 0, 316, 318, 1, 0, 0, 0, 317, 315, 1, 0, 0, 0, 318, 407, 5, 34, 0, 0, 319, 324, 5, 39, 0, 0, 320, 323, 3, 69, 34, 0, 321, 323, 8, 11, 0, 0, 322, 320, 1, 0, 0, 0, 322, 321, 1, 0, 0, 0, 323, 326, 1, 0, 0, 0, 324, 322, 1, 0, 0, 0, 324, 325, 1, 0, 0, 0, 325, 327, 1, 0, 0, 0, 326, 324, 1, 0, 0, 0, 327, 407, 5, 39, 0, 0, 328, 329, 5, 34, 0, 0, 329, 330, 5, 34, 0, 0, 330, 331, 5, 34, 0, 0, 331, 336, 1, 0, 0, 0, 332, 335, 3, 69, 34, 0, 333, 335, 8, 12, 0, 0, 334, 332, 1, 0, 0, 0, 334, 333, 1, 0, 0, 0, 335, 338, 1, 0, 0, 0, 336, 337, 1, 0, 0, 0, 336, 334, 1, 0, 0, 0, 337, 339, 1, 0, 0, 0, 338, 336, 1, 0, 0, 0, 339, 340, 5, 34, 0, 0, 340, 341, 5, 34, 0, 0, 341, 407, 5, 34, 0, 0, 342, 343, 5, 39, 0, 0, 343, 344, 5, 39, 0, 0, 344, 345, 5, 39, 0, 0, 345, 350, 1, 0, 0, 0, 346, 349, 3, 69, 34, 0, 347, 349, 8, 12, 0, 0, 348, 346, 1, 0, 0, 0, 348, 347, 1, 0, 0, 0, 349, 352, 1, 0, 0, 0, 350, 351, 1, 0, 0, 0, 350, 348, 1, 0, 0, 0, 351, 353, 1, 0, 0, 0, 352, 350, 1, 0, 0, 0, 353, 354, 5, 39, 0, 0, 354, 355, 5, 39, 0, 0, 355, 407, 5, 39, 0, 0, 356, 357, 3, 67, 33, 0, 357, 361, 5, 34, 0, 0, 358, 360, 8, 13, 0, 0, 359, 358, 1, 0, 0, 0, 360, 363, 1, 0, 0, 0, 361, 359, 1, 0, 0, 0, 361, 362, 1, 0, 0, 0, 362, 364, 1, 0, 0, 0, 363, 361, 1, 0, 0, 0, 364, 365, 5, 34, 0, 0, 365, 407, 1, 0, 0, 0, 366, 367, 3, 67, 33, 0, 367, 371, 5, 39, 0, 0, 368, 370, 8, 14, 0, 0, 369, 368, 1, 0, 0, 0, 370, 373, 1, 0, 0, 0, 371, 369, 1, 0, 0, 0, 371, 372, 1, 0, 0, 0, 372, 374, 1, 0, 0, 0, 373, 371, 1, 0, 0, 0, 374, 375, 5, 39, 0, 0, 375, 407, 1, 0, 0, 0, 376, 377, 3, 67, 33, 0, 377, 378, 5, 34, 0, 0, 378, 379, 5, 34, 0, 0, 379, 380, 5, 34, 0, 0, 380, 384, 1, 0, 0, 0, 381, 383, 9, 0, 0, 0, 382, 381, 1, 0, 0, 0, 383, 386, 1, 0, 0, 0, 384, 385, 1, 0, 0, 0, 384, 382, 1, 0, 0, 0, 385, 387, 1, 0, 0, 0, 386, 384, 1, 0, 0, 0, 387, 388, 5, 34, 0, 0, 388, 389, 5, 34, 0, 0, 389, 390, 5, 34, 0, 0, 390, 407, 1, 0, 0, 0, 391, 392, 3, 67, 33, 0, 392, 393, 5, 39, 0, 0, 393, 394, 5, 39, 0, 0, 394, 395, 5, 39, 0, 0, 395, 399, 1, 0, 0, 0, 396, 398, 9, 0, 0, 0, 397, 396, 1, 0, 0, 0, 398, 401, 1, 0, 0, 0, 399, 400, 1, 0, 0, 0, 399, 397, 1, 0, 0, 0, 400, 402, 1, 0, 0, 0, 401, 399, 1, 0, 0, 0, 402, 403, 5, 39, 0, 0, 403, 404, 5, 39, 0, 0, 404, 405, 5, 39, 0, 0, 405, 407, 1, 0, 0, 0, 406, 310, 1, 0, 0, 0, 406, 319, 1, 0, 0, 0, 406, 328, 1, 0, 0, 0, 406, 342, 1, 0, 0, 0, 406, 356, 1, 0, 0, 0, 406, 366, 1, 0, 0, 0, 406, 376, 1, 0, 0, 0, 406, 391, 1, 0, 0, 0, 407, 90, 1, 0, 0, 0, 408, 409, 7, 15, 0, 0, 409, 410, 3, 89, 44, 0, 410, 92, 1, 0, 0, 0, 411, 414, 3, 59, 29, 0, 412, 414, 5, 95, 0, 0, 413, 411, 1, 0, 0, 0, 413, 412, 1, 0, 0, 0, 414, 420, 1, 0, 0, 0, 415, 419, 3, 59, 29, 0, 416, 419, 3, 61, 30, 0, 417, 419, 5, 95, 0, 0, 418, 415, 1, 0, 0, 0, 418, 416, 1, 0, 0, 0, 418, 417, 1, 0, 0, 0, 419, 422, 1, 0, 0, 0, 420, 418, 1, 0, 0, 0, 420, 421, 1, 0, 0, 0, 421, 94, 1, 0, 0, 0, 422, 420, 1, 0, 0, 0, 36, 0, 176, 181, 191, 224, 229, 239, 247, 253, 256, 261, 269, 272, 274, 279, 287, 289, 294, 304, 308, 313, 315, 322, 324, 334, 336, 348, 350, 361, 371, 384, 399, 406, 413, 418, 420, 1, 0, 1, 0] \ No newline at end of file diff --git a/vendor/github.com/google/cel-go/parser/gen/CELLexer.tokens b/vendor/github.com/google/cel-go/parser/gen/CELLexer.tokens index c80bfb323..b305bdad3 100644 --- a/vendor/github.com/google/cel-go/parser/gen/CELLexer.tokens +++ b/vendor/github.com/google/cel-go/parser/gen/CELLexer.tokens @@ -1,68 +1,64 @@ -T__0=1 -T__1=2 -EQUALS=3 -NOT_EQUALS=4 -IN=5 -LESS=6 -LESS_EQUALS=7 -GREATER_EQUALS=8 -GREATER=9 -LOGICAL_AND=10 -LOGICAL_OR=11 -LBRACKET=12 -RPRACKET=13 -LBRACE=14 -RBRACE=15 -LPAREN=16 -RPAREN=17 -DOT=18 -COMMA=19 -MINUS=20 -EXCLAM=21 -QUESTIONMARK=22 -COLON=23 -PLUS=24 -STAR=25 -SLASH=26 -PERCENT=27 -CEL_TRUE=28 -CEL_FALSE=29 -NUL=30 -WHITESPACE=31 -COMMENT=32 -NUM_FLOAT=33 -NUM_INT=34 -NUM_UINT=35 -STRING=36 -BYTES=37 -IDENTIFIER=38 -'.?'=1 -'[?'=2 -'=='=3 -'!='=4 -'in'=5 -'<'=6 -'<='=7 -'>='=8 -'>'=9 -'&&'=10 -'||'=11 -'['=12 -']'=13 -'{'=14 -'}'=15 -'('=16 -')'=17 -'.'=18 -','=19 -'-'=20 -'!'=21 -'?'=22 -':'=23 -'+'=24 -'*'=25 -'/'=26 -'%'=27 -'true'=28 -'false'=29 -'null'=30 +EQUALS=1 +NOT_EQUALS=2 +IN=3 +LESS=4 +LESS_EQUALS=5 +GREATER_EQUALS=6 +GREATER=7 +LOGICAL_AND=8 +LOGICAL_OR=9 +LBRACKET=10 +RPRACKET=11 +LBRACE=12 +RBRACE=13 +LPAREN=14 +RPAREN=15 +DOT=16 +COMMA=17 +MINUS=18 +EXCLAM=19 +QUESTIONMARK=20 +COLON=21 +PLUS=22 +STAR=23 +SLASH=24 +PERCENT=25 +CEL_TRUE=26 +CEL_FALSE=27 +NUL=28 +WHITESPACE=29 +COMMENT=30 +NUM_FLOAT=31 +NUM_INT=32 +NUM_UINT=33 +STRING=34 +BYTES=35 +IDENTIFIER=36 +'=='=1 +'!='=2 +'in'=3 +'<'=4 +'<='=5 +'>='=6 +'>'=7 +'&&'=8 +'||'=9 +'['=10 +']'=11 +'{'=12 +'}'=13 +'('=14 +')'=15 +'.'=16 +','=17 +'-'=18 +'!'=19 +'?'=20 +':'=21 +'+'=22 +'*'=23 +'/'=24 +'%'=25 +'true'=26 +'false'=27 +'null'=28 diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go b/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go index f4b9b08da..0247f470a 100644 --- a/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go +++ b/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go @@ -1,7 +1,7 @@ -// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.10.1. DO NOT EDIT. +// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.12.0. DO NOT EDIT. package gen // CEL -import "github.com/antlr/antlr4/runtime/Go/antlr" +import "github.com/antlr/antlr4/runtime/Go/antlr/v4" // BaseCELListener is a complete listener for a parse tree produced by CELParser. type BaseCELListener struct{} @@ -140,6 +140,12 @@ func (s *BaseCELListener) EnterExprList(ctx *ExprListContext) {} // ExitExprList is called when production exprList is exited. func (s *BaseCELListener) ExitExprList(ctx *ExprListContext) {} +// EnterListInit is called when production listInit is entered. +func (s *BaseCELListener) EnterListInit(ctx *ListInitContext) {} + +// ExitListInit is called when production listInit is exited. +func (s *BaseCELListener) ExitListInit(ctx *ListInitContext) {} + // EnterFieldInitializerList is called when production fieldInitializerList is entered. func (s *BaseCELListener) EnterFieldInitializerList(ctx *FieldInitializerListContext) {} @@ -158,11 +164,11 @@ func (s *BaseCELListener) EnterMapInitializerList(ctx *MapInitializerListContext // ExitMapInitializerList is called when production mapInitializerList is exited. func (s *BaseCELListener) ExitMapInitializerList(ctx *MapInitializerListContext) {} -// EnterOptKey is called when production optKey is entered. -func (s *BaseCELListener) EnterOptKey(ctx *OptKeyContext) {} +// EnterOptExpr is called when production optExpr is entered. +func (s *BaseCELListener) EnterOptExpr(ctx *OptExprContext) {} -// ExitOptKey is called when production optKey is exited. -func (s *BaseCELListener) ExitOptKey(ctx *OptKeyContext) {} +// ExitOptExpr is called when production optExpr is exited. +func (s *BaseCELListener) ExitOptExpr(ctx *OptExprContext) {} // EnterInt is called when production Int is entered. func (s *BaseCELListener) EnterInt(ctx *IntContext) {} diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go b/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go index 98f9f993e..52a7f4dc5 100644 --- a/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go +++ b/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go @@ -1,7 +1,7 @@ -// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.10.1. DO NOT EDIT. +// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.12.0. DO NOT EDIT. package gen // CEL -import "github.com/antlr/antlr4/runtime/Go/antlr" +import "github.com/antlr/antlr4/runtime/Go/antlr/v4" type BaseCELVisitor struct { *antlr.BaseParseTreeVisitor @@ -87,6 +87,10 @@ func (v *BaseCELVisitor) VisitExprList(ctx *ExprListContext) interface{} { return v.VisitChildren(ctx) } +func (v *BaseCELVisitor) VisitListInit(ctx *ListInitContext) interface{} { + return v.VisitChildren(ctx) +} + func (v *BaseCELVisitor) VisitFieldInitializerList(ctx *FieldInitializerListContext) interface{} { return v.VisitChildren(ctx) } @@ -99,7 +103,7 @@ func (v *BaseCELVisitor) VisitMapInitializerList(ctx *MapInitializerListContext) return v.VisitChildren(ctx) } -func (v *BaseCELVisitor) VisitOptKey(ctx *OptKeyContext) interface{} { +func (v *BaseCELVisitor) VisitOptExpr(ctx *OptExprContext) interface{} { return v.VisitChildren(ctx) } diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go b/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go index 63319af75..98ddc06d0 100644 --- a/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go +++ b/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go @@ -1,4 +1,4 @@ -// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.10.1. DO NOT EDIT. +// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.12.0. DO NOT EDIT. package gen @@ -7,7 +7,7 @@ import ( "sync" "unicode" - "github.com/antlr/antlr4/runtime/Go/antlr" + "github.com/antlr/antlr4/runtime/Go/antlr/v4" ) // Suppress unused import error @@ -44,13 +44,12 @@ func cellexerLexerInit() { "DEFAULT_MODE", } staticData.literalNames = []string{ - "", "'.?'", "'[?'", "'=='", "'!='", "'in'", "'<'", "'<='", "'>='", "'>'", - "'&&'", "'||'", "'['", "']'", "'{'", "'}'", "'('", "')'", "'.'", "','", - "'-'", "'!'", "'?'", "':'", "'+'", "'*'", "'/'", "'%'", "'true'", "'false'", - "'null'", + "", "'=='", "'!='", "'in'", "'<'", "'<='", "'>='", "'>'", "'&&'", "'||'", + "'['", "']'", "'{'", "'}'", "'('", "')'", "'.'", "','", "'-'", "'!'", + "'?'", "':'", "'+'", "'*'", "'/'", "'%'", "'true'", "'false'", "'null'", } staticData.symbolicNames = []string{ - "", "", "", "EQUALS", "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", "GREATER_EQUALS", + "", "EQUALS", "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", "GREATER_EQUALS", "GREATER", "LOGICAL_AND", "LOGICAL_OR", "LBRACKET", "RPRACKET", "LBRACE", "RBRACE", "LPAREN", "RPAREN", "DOT", "COMMA", "MINUS", "EXCLAM", "QUESTIONMARK", "COLON", "PLUS", "STAR", "SLASH", "PERCENT", "CEL_TRUE", "CEL_FALSE", @@ -58,18 +57,18 @@ func cellexerLexerInit() { "STRING", "BYTES", "IDENTIFIER", } staticData.ruleNames = []string{ - "T__0", "T__1", "EQUALS", "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", - "GREATER_EQUALS", "GREATER", "LOGICAL_AND", "LOGICAL_OR", "LBRACKET", - "RPRACKET", "LBRACE", "RBRACE", "LPAREN", "RPAREN", "DOT", "COMMA", - "MINUS", "EXCLAM", "QUESTIONMARK", "COLON", "PLUS", "STAR", "SLASH", - "PERCENT", "CEL_TRUE", "CEL_FALSE", "NUL", "BACKSLASH", "LETTER", "DIGIT", - "EXPONENT", "HEXDIGIT", "RAW", "ESC_SEQ", "ESC_CHAR_SEQ", "ESC_OCT_SEQ", - "ESC_BYTE_SEQ", "ESC_UNI_SEQ", "WHITESPACE", "COMMENT", "NUM_FLOAT", - "NUM_INT", "NUM_UINT", "STRING", "BYTES", "IDENTIFIER", + "EQUALS", "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", "GREATER_EQUALS", + "GREATER", "LOGICAL_AND", "LOGICAL_OR", "LBRACKET", "RPRACKET", "LBRACE", + "RBRACE", "LPAREN", "RPAREN", "DOT", "COMMA", "MINUS", "EXCLAM", "QUESTIONMARK", + "COLON", "PLUS", "STAR", "SLASH", "PERCENT", "CEL_TRUE", "CEL_FALSE", + "NUL", "BACKSLASH", "LETTER", "DIGIT", "EXPONENT", "HEXDIGIT", "RAW", + "ESC_SEQ", "ESC_CHAR_SEQ", "ESC_OCT_SEQ", "ESC_BYTE_SEQ", "ESC_UNI_SEQ", + "WHITESPACE", "COMMENT", "NUM_FLOAT", "NUM_INT", "NUM_UINT", "STRING", + "BYTES", "IDENTIFIER", } staticData.predictionContextCache = antlr.NewPredictionContextCache() staticData.serializedATN = []int32{ - 4, 0, 38, 433, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, + 4, 0, 36, 423, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, @@ -78,199 +77,195 @@ func cellexerLexerInit() { 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, - 2, 47, 7, 47, 2, 48, 7, 48, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 1, - 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, - 6, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, - 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 1, - 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, - 1, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, - 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, - 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 31, 1, 31, 1, - 32, 1, 32, 1, 33, 1, 33, 3, 33, 187, 8, 33, 1, 33, 4, 33, 190, 8, 33, 11, - 33, 12, 33, 191, 1, 34, 1, 34, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, - 3, 36, 202, 8, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, - 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, - 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, - 40, 1, 40, 1, 40, 3, 40, 235, 8, 40, 1, 41, 4, 41, 238, 8, 41, 11, 41, - 12, 41, 239, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 5, 42, 248, 8, 42, - 10, 42, 12, 42, 251, 9, 42, 1, 42, 1, 42, 1, 43, 4, 43, 256, 8, 43, 11, - 43, 12, 43, 257, 1, 43, 1, 43, 4, 43, 262, 8, 43, 11, 43, 12, 43, 263, - 1, 43, 3, 43, 267, 8, 43, 1, 43, 4, 43, 270, 8, 43, 11, 43, 12, 43, 271, - 1, 43, 1, 43, 1, 43, 1, 43, 4, 43, 278, 8, 43, 11, 43, 12, 43, 279, 1, - 43, 3, 43, 283, 8, 43, 3, 43, 285, 8, 43, 1, 44, 4, 44, 288, 8, 44, 11, - 44, 12, 44, 289, 1, 44, 1, 44, 1, 44, 1, 44, 4, 44, 296, 8, 44, 11, 44, - 12, 44, 297, 3, 44, 300, 8, 44, 1, 45, 4, 45, 303, 8, 45, 11, 45, 12, 45, - 304, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 4, 45, 313, 8, 45, 11, 45, - 12, 45, 314, 1, 45, 1, 45, 3, 45, 319, 8, 45, 1, 46, 1, 46, 1, 46, 5, 46, - 324, 8, 46, 10, 46, 12, 46, 327, 9, 46, 1, 46, 1, 46, 1, 46, 1, 46, 5, - 46, 333, 8, 46, 10, 46, 12, 46, 336, 9, 46, 1, 46, 1, 46, 1, 46, 1, 46, - 1, 46, 1, 46, 1, 46, 5, 46, 345, 8, 46, 10, 46, 12, 46, 348, 9, 46, 1, - 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 5, 46, 359, - 8, 46, 10, 46, 12, 46, 362, 9, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, - 46, 5, 46, 370, 8, 46, 10, 46, 12, 46, 373, 9, 46, 1, 46, 1, 46, 1, 46, - 1, 46, 1, 46, 5, 46, 380, 8, 46, 10, 46, 12, 46, 383, 9, 46, 1, 46, 1, - 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 5, 46, 393, 8, 46, 10, 46, - 12, 46, 396, 9, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, - 46, 1, 46, 1, 46, 5, 46, 408, 8, 46, 10, 46, 12, 46, 411, 9, 46, 1, 46, - 1, 46, 1, 46, 1, 46, 3, 46, 417, 8, 46, 1, 47, 1, 47, 1, 47, 1, 48, 1, - 48, 3, 48, 424, 8, 48, 1, 48, 1, 48, 1, 48, 5, 48, 429, 8, 48, 10, 48, - 12, 48, 432, 9, 48, 4, 346, 360, 394, 409, 0, 49, 1, 1, 3, 2, 5, 3, 7, + 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, + 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, + 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, + 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, + 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, + 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, + 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 29, 1, 29, + 1, 30, 1, 30, 1, 31, 1, 31, 3, 31, 177, 8, 31, 1, 31, 4, 31, 180, 8, 31, + 11, 31, 12, 31, 181, 1, 32, 1, 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, + 34, 3, 34, 192, 8, 34, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, + 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, + 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, + 1, 38, 1, 38, 1, 38, 3, 38, 225, 8, 38, 1, 39, 4, 39, 228, 8, 39, 11, 39, + 12, 39, 229, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 5, 40, 238, 8, 40, + 10, 40, 12, 40, 241, 9, 40, 1, 40, 1, 40, 1, 41, 4, 41, 246, 8, 41, 11, + 41, 12, 41, 247, 1, 41, 1, 41, 4, 41, 252, 8, 41, 11, 41, 12, 41, 253, + 1, 41, 3, 41, 257, 8, 41, 1, 41, 4, 41, 260, 8, 41, 11, 41, 12, 41, 261, + 1, 41, 1, 41, 1, 41, 1, 41, 4, 41, 268, 8, 41, 11, 41, 12, 41, 269, 1, + 41, 3, 41, 273, 8, 41, 3, 41, 275, 8, 41, 1, 42, 4, 42, 278, 8, 42, 11, + 42, 12, 42, 279, 1, 42, 1, 42, 1, 42, 1, 42, 4, 42, 286, 8, 42, 11, 42, + 12, 42, 287, 3, 42, 290, 8, 42, 1, 43, 4, 43, 293, 8, 43, 11, 43, 12, 43, + 294, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 4, 43, 303, 8, 43, 11, 43, + 12, 43, 304, 1, 43, 1, 43, 3, 43, 309, 8, 43, 1, 44, 1, 44, 1, 44, 5, 44, + 314, 8, 44, 10, 44, 12, 44, 317, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, + 44, 323, 8, 44, 10, 44, 12, 44, 326, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, + 1, 44, 1, 44, 1, 44, 5, 44, 335, 8, 44, 10, 44, 12, 44, 338, 9, 44, 1, + 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 349, + 8, 44, 10, 44, 12, 44, 352, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, + 44, 5, 44, 360, 8, 44, 10, 44, 12, 44, 363, 9, 44, 1, 44, 1, 44, 1, 44, + 1, 44, 1, 44, 5, 44, 370, 8, 44, 10, 44, 12, 44, 373, 9, 44, 1, 44, 1, + 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 383, 8, 44, 10, 44, + 12, 44, 386, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, + 44, 1, 44, 1, 44, 5, 44, 398, 8, 44, 10, 44, 12, 44, 401, 9, 44, 1, 44, + 1, 44, 1, 44, 1, 44, 3, 44, 407, 8, 44, 1, 45, 1, 45, 1, 45, 1, 46, 1, + 46, 3, 46, 414, 8, 46, 1, 46, 1, 46, 1, 46, 5, 46, 419, 8, 46, 10, 46, + 12, 46, 422, 9, 46, 4, 336, 350, 384, 399, 0, 47, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, - 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 0, 63, - 0, 65, 0, 67, 0, 69, 0, 71, 0, 73, 0, 75, 0, 77, 0, 79, 0, 81, 0, 83, 31, - 85, 32, 87, 33, 89, 34, 91, 35, 93, 36, 95, 37, 97, 38, 1, 0, 16, 2, 0, - 65, 90, 97, 122, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 3, 0, 48, - 57, 65, 70, 97, 102, 2, 0, 82, 82, 114, 114, 10, 0, 34, 34, 39, 39, 63, - 63, 92, 92, 96, 98, 102, 102, 110, 110, 114, 114, 116, 116, 118, 118, 2, - 0, 88, 88, 120, 120, 3, 0, 9, 10, 12, 13, 32, 32, 1, 0, 10, 10, 2, 0, 85, - 85, 117, 117, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 4, 0, 10, 10, 13, 13, - 39, 39, 92, 92, 1, 0, 92, 92, 3, 0, 10, 10, 13, 13, 34, 34, 3, 0, 10, 10, - 13, 13, 39, 39, 2, 0, 66, 66, 98, 98, 466, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, - 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, - 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, - 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, - 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, - 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, - 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, - 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, - 0, 0, 0, 59, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, - 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, - 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 1, 99, 1, 0, 0, 0, 3, 102, 1, 0, 0, 0, 5, - 105, 1, 0, 0, 0, 7, 108, 1, 0, 0, 0, 9, 111, 1, 0, 0, 0, 11, 114, 1, 0, - 0, 0, 13, 116, 1, 0, 0, 0, 15, 119, 1, 0, 0, 0, 17, 122, 1, 0, 0, 0, 19, - 124, 1, 0, 0, 0, 21, 127, 1, 0, 0, 0, 23, 130, 1, 0, 0, 0, 25, 132, 1, - 0, 0, 0, 27, 134, 1, 0, 0, 0, 29, 136, 1, 0, 0, 0, 31, 138, 1, 0, 0, 0, - 33, 140, 1, 0, 0, 0, 35, 142, 1, 0, 0, 0, 37, 144, 1, 0, 0, 0, 39, 146, - 1, 0, 0, 0, 41, 148, 1, 0, 0, 0, 43, 150, 1, 0, 0, 0, 45, 152, 1, 0, 0, - 0, 47, 154, 1, 0, 0, 0, 49, 156, 1, 0, 0, 0, 51, 158, 1, 0, 0, 0, 53, 160, - 1, 0, 0, 0, 55, 162, 1, 0, 0, 0, 57, 167, 1, 0, 0, 0, 59, 173, 1, 0, 0, - 0, 61, 178, 1, 0, 0, 0, 63, 180, 1, 0, 0, 0, 65, 182, 1, 0, 0, 0, 67, 184, - 1, 0, 0, 0, 69, 193, 1, 0, 0, 0, 71, 195, 1, 0, 0, 0, 73, 201, 1, 0, 0, - 0, 75, 203, 1, 0, 0, 0, 77, 206, 1, 0, 0, 0, 79, 211, 1, 0, 0, 0, 81, 234, - 1, 0, 0, 0, 83, 237, 1, 0, 0, 0, 85, 243, 1, 0, 0, 0, 87, 284, 1, 0, 0, - 0, 89, 299, 1, 0, 0, 0, 91, 318, 1, 0, 0, 0, 93, 416, 1, 0, 0, 0, 95, 418, - 1, 0, 0, 0, 97, 423, 1, 0, 0, 0, 99, 100, 5, 46, 0, 0, 100, 101, 5, 63, - 0, 0, 101, 2, 1, 0, 0, 0, 102, 103, 5, 91, 0, 0, 103, 104, 5, 63, 0, 0, - 104, 4, 1, 0, 0, 0, 105, 106, 5, 61, 0, 0, 106, 107, 5, 61, 0, 0, 107, - 6, 1, 0, 0, 0, 108, 109, 5, 33, 0, 0, 109, 110, 5, 61, 0, 0, 110, 8, 1, - 0, 0, 0, 111, 112, 5, 105, 0, 0, 112, 113, 5, 110, 0, 0, 113, 10, 1, 0, - 0, 0, 114, 115, 5, 60, 0, 0, 115, 12, 1, 0, 0, 0, 116, 117, 5, 60, 0, 0, - 117, 118, 5, 61, 0, 0, 118, 14, 1, 0, 0, 0, 119, 120, 5, 62, 0, 0, 120, - 121, 5, 61, 0, 0, 121, 16, 1, 0, 0, 0, 122, 123, 5, 62, 0, 0, 123, 18, - 1, 0, 0, 0, 124, 125, 5, 38, 0, 0, 125, 126, 5, 38, 0, 0, 126, 20, 1, 0, - 0, 0, 127, 128, 5, 124, 0, 0, 128, 129, 5, 124, 0, 0, 129, 22, 1, 0, 0, - 0, 130, 131, 5, 91, 0, 0, 131, 24, 1, 0, 0, 0, 132, 133, 5, 93, 0, 0, 133, - 26, 1, 0, 0, 0, 134, 135, 5, 123, 0, 0, 135, 28, 1, 0, 0, 0, 136, 137, - 5, 125, 0, 0, 137, 30, 1, 0, 0, 0, 138, 139, 5, 40, 0, 0, 139, 32, 1, 0, - 0, 0, 140, 141, 5, 41, 0, 0, 141, 34, 1, 0, 0, 0, 142, 143, 5, 46, 0, 0, - 143, 36, 1, 0, 0, 0, 144, 145, 5, 44, 0, 0, 145, 38, 1, 0, 0, 0, 146, 147, - 5, 45, 0, 0, 147, 40, 1, 0, 0, 0, 148, 149, 5, 33, 0, 0, 149, 42, 1, 0, - 0, 0, 150, 151, 5, 63, 0, 0, 151, 44, 1, 0, 0, 0, 152, 153, 5, 58, 0, 0, - 153, 46, 1, 0, 0, 0, 154, 155, 5, 43, 0, 0, 155, 48, 1, 0, 0, 0, 156, 157, - 5, 42, 0, 0, 157, 50, 1, 0, 0, 0, 158, 159, 5, 47, 0, 0, 159, 52, 1, 0, - 0, 0, 160, 161, 5, 37, 0, 0, 161, 54, 1, 0, 0, 0, 162, 163, 5, 116, 0, - 0, 163, 164, 5, 114, 0, 0, 164, 165, 5, 117, 0, 0, 165, 166, 5, 101, 0, - 0, 166, 56, 1, 0, 0, 0, 167, 168, 5, 102, 0, 0, 168, 169, 5, 97, 0, 0, - 169, 170, 5, 108, 0, 0, 170, 171, 5, 115, 0, 0, 171, 172, 5, 101, 0, 0, - 172, 58, 1, 0, 0, 0, 173, 174, 5, 110, 0, 0, 174, 175, 5, 117, 0, 0, 175, - 176, 5, 108, 0, 0, 176, 177, 5, 108, 0, 0, 177, 60, 1, 0, 0, 0, 178, 179, - 5, 92, 0, 0, 179, 62, 1, 0, 0, 0, 180, 181, 7, 0, 0, 0, 181, 64, 1, 0, - 0, 0, 182, 183, 2, 48, 57, 0, 183, 66, 1, 0, 0, 0, 184, 186, 7, 1, 0, 0, - 185, 187, 7, 2, 0, 0, 186, 185, 1, 0, 0, 0, 186, 187, 1, 0, 0, 0, 187, - 189, 1, 0, 0, 0, 188, 190, 3, 65, 32, 0, 189, 188, 1, 0, 0, 0, 190, 191, - 1, 0, 0, 0, 191, 189, 1, 0, 0, 0, 191, 192, 1, 0, 0, 0, 192, 68, 1, 0, - 0, 0, 193, 194, 7, 3, 0, 0, 194, 70, 1, 0, 0, 0, 195, 196, 7, 4, 0, 0, - 196, 72, 1, 0, 0, 0, 197, 202, 3, 75, 37, 0, 198, 202, 3, 79, 39, 0, 199, - 202, 3, 81, 40, 0, 200, 202, 3, 77, 38, 0, 201, 197, 1, 0, 0, 0, 201, 198, - 1, 0, 0, 0, 201, 199, 1, 0, 0, 0, 201, 200, 1, 0, 0, 0, 202, 74, 1, 0, - 0, 0, 203, 204, 3, 61, 30, 0, 204, 205, 7, 5, 0, 0, 205, 76, 1, 0, 0, 0, - 206, 207, 3, 61, 30, 0, 207, 208, 2, 48, 51, 0, 208, 209, 2, 48, 55, 0, - 209, 210, 2, 48, 55, 0, 210, 78, 1, 0, 0, 0, 211, 212, 3, 61, 30, 0, 212, - 213, 7, 6, 0, 0, 213, 214, 3, 69, 34, 0, 214, 215, 3, 69, 34, 0, 215, 80, - 1, 0, 0, 0, 216, 217, 3, 61, 30, 0, 217, 218, 5, 117, 0, 0, 218, 219, 3, - 69, 34, 0, 219, 220, 3, 69, 34, 0, 220, 221, 3, 69, 34, 0, 221, 222, 3, - 69, 34, 0, 222, 235, 1, 0, 0, 0, 223, 224, 3, 61, 30, 0, 224, 225, 5, 85, - 0, 0, 225, 226, 3, 69, 34, 0, 226, 227, 3, 69, 34, 0, 227, 228, 3, 69, - 34, 0, 228, 229, 3, 69, 34, 0, 229, 230, 3, 69, 34, 0, 230, 231, 3, 69, - 34, 0, 231, 232, 3, 69, 34, 0, 232, 233, 3, 69, 34, 0, 233, 235, 1, 0, - 0, 0, 234, 216, 1, 0, 0, 0, 234, 223, 1, 0, 0, 0, 235, 82, 1, 0, 0, 0, - 236, 238, 7, 7, 0, 0, 237, 236, 1, 0, 0, 0, 238, 239, 1, 0, 0, 0, 239, - 237, 1, 0, 0, 0, 239, 240, 1, 0, 0, 0, 240, 241, 1, 0, 0, 0, 241, 242, - 6, 41, 0, 0, 242, 84, 1, 0, 0, 0, 243, 244, 5, 47, 0, 0, 244, 245, 5, 47, - 0, 0, 245, 249, 1, 0, 0, 0, 246, 248, 8, 8, 0, 0, 247, 246, 1, 0, 0, 0, - 248, 251, 1, 0, 0, 0, 249, 247, 1, 0, 0, 0, 249, 250, 1, 0, 0, 0, 250, - 252, 1, 0, 0, 0, 251, 249, 1, 0, 0, 0, 252, 253, 6, 42, 0, 0, 253, 86, - 1, 0, 0, 0, 254, 256, 3, 65, 32, 0, 255, 254, 1, 0, 0, 0, 256, 257, 1, - 0, 0, 0, 257, 255, 1, 0, 0, 0, 257, 258, 1, 0, 0, 0, 258, 259, 1, 0, 0, - 0, 259, 261, 5, 46, 0, 0, 260, 262, 3, 65, 32, 0, 261, 260, 1, 0, 0, 0, - 262, 263, 1, 0, 0, 0, 263, 261, 1, 0, 0, 0, 263, 264, 1, 0, 0, 0, 264, - 266, 1, 0, 0, 0, 265, 267, 3, 67, 33, 0, 266, 265, 1, 0, 0, 0, 266, 267, - 1, 0, 0, 0, 267, 285, 1, 0, 0, 0, 268, 270, 3, 65, 32, 0, 269, 268, 1, - 0, 0, 0, 270, 271, 1, 0, 0, 0, 271, 269, 1, 0, 0, 0, 271, 272, 1, 0, 0, - 0, 272, 273, 1, 0, 0, 0, 273, 274, 3, 67, 33, 0, 274, 285, 1, 0, 0, 0, - 275, 277, 5, 46, 0, 0, 276, 278, 3, 65, 32, 0, 277, 276, 1, 0, 0, 0, 278, - 279, 1, 0, 0, 0, 279, 277, 1, 0, 0, 0, 279, 280, 1, 0, 0, 0, 280, 282, - 1, 0, 0, 0, 281, 283, 3, 67, 33, 0, 282, 281, 1, 0, 0, 0, 282, 283, 1, - 0, 0, 0, 283, 285, 1, 0, 0, 0, 284, 255, 1, 0, 0, 0, 284, 269, 1, 0, 0, - 0, 284, 275, 1, 0, 0, 0, 285, 88, 1, 0, 0, 0, 286, 288, 3, 65, 32, 0, 287, - 286, 1, 0, 0, 0, 288, 289, 1, 0, 0, 0, 289, 287, 1, 0, 0, 0, 289, 290, - 1, 0, 0, 0, 290, 300, 1, 0, 0, 0, 291, 292, 5, 48, 0, 0, 292, 293, 5, 120, - 0, 0, 293, 295, 1, 0, 0, 0, 294, 296, 3, 69, 34, 0, 295, 294, 1, 0, 0, - 0, 296, 297, 1, 0, 0, 0, 297, 295, 1, 0, 0, 0, 297, 298, 1, 0, 0, 0, 298, - 300, 1, 0, 0, 0, 299, 287, 1, 0, 0, 0, 299, 291, 1, 0, 0, 0, 300, 90, 1, - 0, 0, 0, 301, 303, 3, 65, 32, 0, 302, 301, 1, 0, 0, 0, 303, 304, 1, 0, - 0, 0, 304, 302, 1, 0, 0, 0, 304, 305, 1, 0, 0, 0, 305, 306, 1, 0, 0, 0, - 306, 307, 7, 9, 0, 0, 307, 319, 1, 0, 0, 0, 308, 309, 5, 48, 0, 0, 309, - 310, 5, 120, 0, 0, 310, 312, 1, 0, 0, 0, 311, 313, 3, 69, 34, 0, 312, 311, - 1, 0, 0, 0, 313, 314, 1, 0, 0, 0, 314, 312, 1, 0, 0, 0, 314, 315, 1, 0, - 0, 0, 315, 316, 1, 0, 0, 0, 316, 317, 7, 9, 0, 0, 317, 319, 1, 0, 0, 0, - 318, 302, 1, 0, 0, 0, 318, 308, 1, 0, 0, 0, 319, 92, 1, 0, 0, 0, 320, 325, - 5, 34, 0, 0, 321, 324, 3, 73, 36, 0, 322, 324, 8, 10, 0, 0, 323, 321, 1, - 0, 0, 0, 323, 322, 1, 0, 0, 0, 324, 327, 1, 0, 0, 0, 325, 323, 1, 0, 0, - 0, 325, 326, 1, 0, 0, 0, 326, 328, 1, 0, 0, 0, 327, 325, 1, 0, 0, 0, 328, - 417, 5, 34, 0, 0, 329, 334, 5, 39, 0, 0, 330, 333, 3, 73, 36, 0, 331, 333, - 8, 11, 0, 0, 332, 330, 1, 0, 0, 0, 332, 331, 1, 0, 0, 0, 333, 336, 1, 0, - 0, 0, 334, 332, 1, 0, 0, 0, 334, 335, 1, 0, 0, 0, 335, 337, 1, 0, 0, 0, - 336, 334, 1, 0, 0, 0, 337, 417, 5, 39, 0, 0, 338, 339, 5, 34, 0, 0, 339, - 340, 5, 34, 0, 0, 340, 341, 5, 34, 0, 0, 341, 346, 1, 0, 0, 0, 342, 345, - 3, 73, 36, 0, 343, 345, 8, 12, 0, 0, 344, 342, 1, 0, 0, 0, 344, 343, 1, - 0, 0, 0, 345, 348, 1, 0, 0, 0, 346, 347, 1, 0, 0, 0, 346, 344, 1, 0, 0, - 0, 347, 349, 1, 0, 0, 0, 348, 346, 1, 0, 0, 0, 349, 350, 5, 34, 0, 0, 350, - 351, 5, 34, 0, 0, 351, 417, 5, 34, 0, 0, 352, 353, 5, 39, 0, 0, 353, 354, - 5, 39, 0, 0, 354, 355, 5, 39, 0, 0, 355, 360, 1, 0, 0, 0, 356, 359, 3, - 73, 36, 0, 357, 359, 8, 12, 0, 0, 358, 356, 1, 0, 0, 0, 358, 357, 1, 0, - 0, 0, 359, 362, 1, 0, 0, 0, 360, 361, 1, 0, 0, 0, 360, 358, 1, 0, 0, 0, - 361, 363, 1, 0, 0, 0, 362, 360, 1, 0, 0, 0, 363, 364, 5, 39, 0, 0, 364, - 365, 5, 39, 0, 0, 365, 417, 5, 39, 0, 0, 366, 367, 3, 71, 35, 0, 367, 371, - 5, 34, 0, 0, 368, 370, 8, 13, 0, 0, 369, 368, 1, 0, 0, 0, 370, 373, 1, - 0, 0, 0, 371, 369, 1, 0, 0, 0, 371, 372, 1, 0, 0, 0, 372, 374, 1, 0, 0, - 0, 373, 371, 1, 0, 0, 0, 374, 375, 5, 34, 0, 0, 375, 417, 1, 0, 0, 0, 376, - 377, 3, 71, 35, 0, 377, 381, 5, 39, 0, 0, 378, 380, 8, 14, 0, 0, 379, 378, - 1, 0, 0, 0, 380, 383, 1, 0, 0, 0, 381, 379, 1, 0, 0, 0, 381, 382, 1, 0, - 0, 0, 382, 384, 1, 0, 0, 0, 383, 381, 1, 0, 0, 0, 384, 385, 5, 39, 0, 0, - 385, 417, 1, 0, 0, 0, 386, 387, 3, 71, 35, 0, 387, 388, 5, 34, 0, 0, 388, - 389, 5, 34, 0, 0, 389, 390, 5, 34, 0, 0, 390, 394, 1, 0, 0, 0, 391, 393, - 9, 0, 0, 0, 392, 391, 1, 0, 0, 0, 393, 396, 1, 0, 0, 0, 394, 395, 1, 0, - 0, 0, 394, 392, 1, 0, 0, 0, 395, 397, 1, 0, 0, 0, 396, 394, 1, 0, 0, 0, - 397, 398, 5, 34, 0, 0, 398, 399, 5, 34, 0, 0, 399, 400, 5, 34, 0, 0, 400, - 417, 1, 0, 0, 0, 401, 402, 3, 71, 35, 0, 402, 403, 5, 39, 0, 0, 403, 404, - 5, 39, 0, 0, 404, 405, 5, 39, 0, 0, 405, 409, 1, 0, 0, 0, 406, 408, 9, - 0, 0, 0, 407, 406, 1, 0, 0, 0, 408, 411, 1, 0, 0, 0, 409, 410, 1, 0, 0, - 0, 409, 407, 1, 0, 0, 0, 410, 412, 1, 0, 0, 0, 411, 409, 1, 0, 0, 0, 412, - 413, 5, 39, 0, 0, 413, 414, 5, 39, 0, 0, 414, 415, 5, 39, 0, 0, 415, 417, - 1, 0, 0, 0, 416, 320, 1, 0, 0, 0, 416, 329, 1, 0, 0, 0, 416, 338, 1, 0, - 0, 0, 416, 352, 1, 0, 0, 0, 416, 366, 1, 0, 0, 0, 416, 376, 1, 0, 0, 0, - 416, 386, 1, 0, 0, 0, 416, 401, 1, 0, 0, 0, 417, 94, 1, 0, 0, 0, 418, 419, - 7, 15, 0, 0, 419, 420, 3, 93, 46, 0, 420, 96, 1, 0, 0, 0, 421, 424, 3, - 63, 31, 0, 422, 424, 5, 95, 0, 0, 423, 421, 1, 0, 0, 0, 423, 422, 1, 0, - 0, 0, 424, 430, 1, 0, 0, 0, 425, 429, 3, 63, 31, 0, 426, 429, 3, 65, 32, - 0, 427, 429, 5, 95, 0, 0, 428, 425, 1, 0, 0, 0, 428, 426, 1, 0, 0, 0, 428, - 427, 1, 0, 0, 0, 429, 432, 1, 0, 0, 0, 430, 428, 1, 0, 0, 0, 430, 431, - 1, 0, 0, 0, 431, 98, 1, 0, 0, 0, 432, 430, 1, 0, 0, 0, 36, 0, 186, 191, - 201, 234, 239, 249, 257, 263, 266, 271, 279, 282, 284, 289, 297, 299, 304, - 314, 318, 323, 325, 332, 334, 344, 346, 358, 360, 371, 381, 394, 409, 416, - 423, 428, 430, 1, 0, 1, 0, + 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 0, 59, 0, 61, 0, 63, 0, + 65, 0, 67, 0, 69, 0, 71, 0, 73, 0, 75, 0, 77, 0, 79, 29, 81, 30, 83, 31, + 85, 32, 87, 33, 89, 34, 91, 35, 93, 36, 1, 0, 16, 2, 0, 65, 90, 97, 122, + 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 3, 0, 48, 57, 65, 70, 97, + 102, 2, 0, 82, 82, 114, 114, 10, 0, 34, 34, 39, 39, 63, 63, 92, 92, 96, + 98, 102, 102, 110, 110, 114, 114, 116, 116, 118, 118, 2, 0, 88, 88, 120, + 120, 3, 0, 9, 10, 12, 13, 32, 32, 1, 0, 10, 10, 2, 0, 85, 85, 117, 117, + 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 4, 0, 10, 10, 13, 13, 39, 39, 92, + 92, 1, 0, 92, 92, 3, 0, 10, 10, 13, 13, 34, 34, 3, 0, 10, 10, 13, 13, 39, + 39, 2, 0, 66, 66, 98, 98, 456, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, + 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, + 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, + 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, + 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, + 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, + 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, + 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, + 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, + 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 1, 95, 1, 0, 0, 0, + 3, 98, 1, 0, 0, 0, 5, 101, 1, 0, 0, 0, 7, 104, 1, 0, 0, 0, 9, 106, 1, 0, + 0, 0, 11, 109, 1, 0, 0, 0, 13, 112, 1, 0, 0, 0, 15, 114, 1, 0, 0, 0, 17, + 117, 1, 0, 0, 0, 19, 120, 1, 0, 0, 0, 21, 122, 1, 0, 0, 0, 23, 124, 1, + 0, 0, 0, 25, 126, 1, 0, 0, 0, 27, 128, 1, 0, 0, 0, 29, 130, 1, 0, 0, 0, + 31, 132, 1, 0, 0, 0, 33, 134, 1, 0, 0, 0, 35, 136, 1, 0, 0, 0, 37, 138, + 1, 0, 0, 0, 39, 140, 1, 0, 0, 0, 41, 142, 1, 0, 0, 0, 43, 144, 1, 0, 0, + 0, 45, 146, 1, 0, 0, 0, 47, 148, 1, 0, 0, 0, 49, 150, 1, 0, 0, 0, 51, 152, + 1, 0, 0, 0, 53, 157, 1, 0, 0, 0, 55, 163, 1, 0, 0, 0, 57, 168, 1, 0, 0, + 0, 59, 170, 1, 0, 0, 0, 61, 172, 1, 0, 0, 0, 63, 174, 1, 0, 0, 0, 65, 183, + 1, 0, 0, 0, 67, 185, 1, 0, 0, 0, 69, 191, 1, 0, 0, 0, 71, 193, 1, 0, 0, + 0, 73, 196, 1, 0, 0, 0, 75, 201, 1, 0, 0, 0, 77, 224, 1, 0, 0, 0, 79, 227, + 1, 0, 0, 0, 81, 233, 1, 0, 0, 0, 83, 274, 1, 0, 0, 0, 85, 289, 1, 0, 0, + 0, 87, 308, 1, 0, 0, 0, 89, 406, 1, 0, 0, 0, 91, 408, 1, 0, 0, 0, 93, 413, + 1, 0, 0, 0, 95, 96, 5, 61, 0, 0, 96, 97, 5, 61, 0, 0, 97, 2, 1, 0, 0, 0, + 98, 99, 5, 33, 0, 0, 99, 100, 5, 61, 0, 0, 100, 4, 1, 0, 0, 0, 101, 102, + 5, 105, 0, 0, 102, 103, 5, 110, 0, 0, 103, 6, 1, 0, 0, 0, 104, 105, 5, + 60, 0, 0, 105, 8, 1, 0, 0, 0, 106, 107, 5, 60, 0, 0, 107, 108, 5, 61, 0, + 0, 108, 10, 1, 0, 0, 0, 109, 110, 5, 62, 0, 0, 110, 111, 5, 61, 0, 0, 111, + 12, 1, 0, 0, 0, 112, 113, 5, 62, 0, 0, 113, 14, 1, 0, 0, 0, 114, 115, 5, + 38, 0, 0, 115, 116, 5, 38, 0, 0, 116, 16, 1, 0, 0, 0, 117, 118, 5, 124, + 0, 0, 118, 119, 5, 124, 0, 0, 119, 18, 1, 0, 0, 0, 120, 121, 5, 91, 0, + 0, 121, 20, 1, 0, 0, 0, 122, 123, 5, 93, 0, 0, 123, 22, 1, 0, 0, 0, 124, + 125, 5, 123, 0, 0, 125, 24, 1, 0, 0, 0, 126, 127, 5, 125, 0, 0, 127, 26, + 1, 0, 0, 0, 128, 129, 5, 40, 0, 0, 129, 28, 1, 0, 0, 0, 130, 131, 5, 41, + 0, 0, 131, 30, 1, 0, 0, 0, 132, 133, 5, 46, 0, 0, 133, 32, 1, 0, 0, 0, + 134, 135, 5, 44, 0, 0, 135, 34, 1, 0, 0, 0, 136, 137, 5, 45, 0, 0, 137, + 36, 1, 0, 0, 0, 138, 139, 5, 33, 0, 0, 139, 38, 1, 0, 0, 0, 140, 141, 5, + 63, 0, 0, 141, 40, 1, 0, 0, 0, 142, 143, 5, 58, 0, 0, 143, 42, 1, 0, 0, + 0, 144, 145, 5, 43, 0, 0, 145, 44, 1, 0, 0, 0, 146, 147, 5, 42, 0, 0, 147, + 46, 1, 0, 0, 0, 148, 149, 5, 47, 0, 0, 149, 48, 1, 0, 0, 0, 150, 151, 5, + 37, 0, 0, 151, 50, 1, 0, 0, 0, 152, 153, 5, 116, 0, 0, 153, 154, 5, 114, + 0, 0, 154, 155, 5, 117, 0, 0, 155, 156, 5, 101, 0, 0, 156, 52, 1, 0, 0, + 0, 157, 158, 5, 102, 0, 0, 158, 159, 5, 97, 0, 0, 159, 160, 5, 108, 0, + 0, 160, 161, 5, 115, 0, 0, 161, 162, 5, 101, 0, 0, 162, 54, 1, 0, 0, 0, + 163, 164, 5, 110, 0, 0, 164, 165, 5, 117, 0, 0, 165, 166, 5, 108, 0, 0, + 166, 167, 5, 108, 0, 0, 167, 56, 1, 0, 0, 0, 168, 169, 5, 92, 0, 0, 169, + 58, 1, 0, 0, 0, 170, 171, 7, 0, 0, 0, 171, 60, 1, 0, 0, 0, 172, 173, 2, + 48, 57, 0, 173, 62, 1, 0, 0, 0, 174, 176, 7, 1, 0, 0, 175, 177, 7, 2, 0, + 0, 176, 175, 1, 0, 0, 0, 176, 177, 1, 0, 0, 0, 177, 179, 1, 0, 0, 0, 178, + 180, 3, 61, 30, 0, 179, 178, 1, 0, 0, 0, 180, 181, 1, 0, 0, 0, 181, 179, + 1, 0, 0, 0, 181, 182, 1, 0, 0, 0, 182, 64, 1, 0, 0, 0, 183, 184, 7, 3, + 0, 0, 184, 66, 1, 0, 0, 0, 185, 186, 7, 4, 0, 0, 186, 68, 1, 0, 0, 0, 187, + 192, 3, 71, 35, 0, 188, 192, 3, 75, 37, 0, 189, 192, 3, 77, 38, 0, 190, + 192, 3, 73, 36, 0, 191, 187, 1, 0, 0, 0, 191, 188, 1, 0, 0, 0, 191, 189, + 1, 0, 0, 0, 191, 190, 1, 0, 0, 0, 192, 70, 1, 0, 0, 0, 193, 194, 3, 57, + 28, 0, 194, 195, 7, 5, 0, 0, 195, 72, 1, 0, 0, 0, 196, 197, 3, 57, 28, + 0, 197, 198, 2, 48, 51, 0, 198, 199, 2, 48, 55, 0, 199, 200, 2, 48, 55, + 0, 200, 74, 1, 0, 0, 0, 201, 202, 3, 57, 28, 0, 202, 203, 7, 6, 0, 0, 203, + 204, 3, 65, 32, 0, 204, 205, 3, 65, 32, 0, 205, 76, 1, 0, 0, 0, 206, 207, + 3, 57, 28, 0, 207, 208, 5, 117, 0, 0, 208, 209, 3, 65, 32, 0, 209, 210, + 3, 65, 32, 0, 210, 211, 3, 65, 32, 0, 211, 212, 3, 65, 32, 0, 212, 225, + 1, 0, 0, 0, 213, 214, 3, 57, 28, 0, 214, 215, 5, 85, 0, 0, 215, 216, 3, + 65, 32, 0, 216, 217, 3, 65, 32, 0, 217, 218, 3, 65, 32, 0, 218, 219, 3, + 65, 32, 0, 219, 220, 3, 65, 32, 0, 220, 221, 3, 65, 32, 0, 221, 222, 3, + 65, 32, 0, 222, 223, 3, 65, 32, 0, 223, 225, 1, 0, 0, 0, 224, 206, 1, 0, + 0, 0, 224, 213, 1, 0, 0, 0, 225, 78, 1, 0, 0, 0, 226, 228, 7, 7, 0, 0, + 227, 226, 1, 0, 0, 0, 228, 229, 1, 0, 0, 0, 229, 227, 1, 0, 0, 0, 229, + 230, 1, 0, 0, 0, 230, 231, 1, 0, 0, 0, 231, 232, 6, 39, 0, 0, 232, 80, + 1, 0, 0, 0, 233, 234, 5, 47, 0, 0, 234, 235, 5, 47, 0, 0, 235, 239, 1, + 0, 0, 0, 236, 238, 8, 8, 0, 0, 237, 236, 1, 0, 0, 0, 238, 241, 1, 0, 0, + 0, 239, 237, 1, 0, 0, 0, 239, 240, 1, 0, 0, 0, 240, 242, 1, 0, 0, 0, 241, + 239, 1, 0, 0, 0, 242, 243, 6, 40, 0, 0, 243, 82, 1, 0, 0, 0, 244, 246, + 3, 61, 30, 0, 245, 244, 1, 0, 0, 0, 246, 247, 1, 0, 0, 0, 247, 245, 1, + 0, 0, 0, 247, 248, 1, 0, 0, 0, 248, 249, 1, 0, 0, 0, 249, 251, 5, 46, 0, + 0, 250, 252, 3, 61, 30, 0, 251, 250, 1, 0, 0, 0, 252, 253, 1, 0, 0, 0, + 253, 251, 1, 0, 0, 0, 253, 254, 1, 0, 0, 0, 254, 256, 1, 0, 0, 0, 255, + 257, 3, 63, 31, 0, 256, 255, 1, 0, 0, 0, 256, 257, 1, 0, 0, 0, 257, 275, + 1, 0, 0, 0, 258, 260, 3, 61, 30, 0, 259, 258, 1, 0, 0, 0, 260, 261, 1, + 0, 0, 0, 261, 259, 1, 0, 0, 0, 261, 262, 1, 0, 0, 0, 262, 263, 1, 0, 0, + 0, 263, 264, 3, 63, 31, 0, 264, 275, 1, 0, 0, 0, 265, 267, 5, 46, 0, 0, + 266, 268, 3, 61, 30, 0, 267, 266, 1, 0, 0, 0, 268, 269, 1, 0, 0, 0, 269, + 267, 1, 0, 0, 0, 269, 270, 1, 0, 0, 0, 270, 272, 1, 0, 0, 0, 271, 273, + 3, 63, 31, 0, 272, 271, 1, 0, 0, 0, 272, 273, 1, 0, 0, 0, 273, 275, 1, + 0, 0, 0, 274, 245, 1, 0, 0, 0, 274, 259, 1, 0, 0, 0, 274, 265, 1, 0, 0, + 0, 275, 84, 1, 0, 0, 0, 276, 278, 3, 61, 30, 0, 277, 276, 1, 0, 0, 0, 278, + 279, 1, 0, 0, 0, 279, 277, 1, 0, 0, 0, 279, 280, 1, 0, 0, 0, 280, 290, + 1, 0, 0, 0, 281, 282, 5, 48, 0, 0, 282, 283, 5, 120, 0, 0, 283, 285, 1, + 0, 0, 0, 284, 286, 3, 65, 32, 0, 285, 284, 1, 0, 0, 0, 286, 287, 1, 0, + 0, 0, 287, 285, 1, 0, 0, 0, 287, 288, 1, 0, 0, 0, 288, 290, 1, 0, 0, 0, + 289, 277, 1, 0, 0, 0, 289, 281, 1, 0, 0, 0, 290, 86, 1, 0, 0, 0, 291, 293, + 3, 61, 30, 0, 292, 291, 1, 0, 0, 0, 293, 294, 1, 0, 0, 0, 294, 292, 1, + 0, 0, 0, 294, 295, 1, 0, 0, 0, 295, 296, 1, 0, 0, 0, 296, 297, 7, 9, 0, + 0, 297, 309, 1, 0, 0, 0, 298, 299, 5, 48, 0, 0, 299, 300, 5, 120, 0, 0, + 300, 302, 1, 0, 0, 0, 301, 303, 3, 65, 32, 0, 302, 301, 1, 0, 0, 0, 303, + 304, 1, 0, 0, 0, 304, 302, 1, 0, 0, 0, 304, 305, 1, 0, 0, 0, 305, 306, + 1, 0, 0, 0, 306, 307, 7, 9, 0, 0, 307, 309, 1, 0, 0, 0, 308, 292, 1, 0, + 0, 0, 308, 298, 1, 0, 0, 0, 309, 88, 1, 0, 0, 0, 310, 315, 5, 34, 0, 0, + 311, 314, 3, 69, 34, 0, 312, 314, 8, 10, 0, 0, 313, 311, 1, 0, 0, 0, 313, + 312, 1, 0, 0, 0, 314, 317, 1, 0, 0, 0, 315, 313, 1, 0, 0, 0, 315, 316, + 1, 0, 0, 0, 316, 318, 1, 0, 0, 0, 317, 315, 1, 0, 0, 0, 318, 407, 5, 34, + 0, 0, 319, 324, 5, 39, 0, 0, 320, 323, 3, 69, 34, 0, 321, 323, 8, 11, 0, + 0, 322, 320, 1, 0, 0, 0, 322, 321, 1, 0, 0, 0, 323, 326, 1, 0, 0, 0, 324, + 322, 1, 0, 0, 0, 324, 325, 1, 0, 0, 0, 325, 327, 1, 0, 0, 0, 326, 324, + 1, 0, 0, 0, 327, 407, 5, 39, 0, 0, 328, 329, 5, 34, 0, 0, 329, 330, 5, + 34, 0, 0, 330, 331, 5, 34, 0, 0, 331, 336, 1, 0, 0, 0, 332, 335, 3, 69, + 34, 0, 333, 335, 8, 12, 0, 0, 334, 332, 1, 0, 0, 0, 334, 333, 1, 0, 0, + 0, 335, 338, 1, 0, 0, 0, 336, 337, 1, 0, 0, 0, 336, 334, 1, 0, 0, 0, 337, + 339, 1, 0, 0, 0, 338, 336, 1, 0, 0, 0, 339, 340, 5, 34, 0, 0, 340, 341, + 5, 34, 0, 0, 341, 407, 5, 34, 0, 0, 342, 343, 5, 39, 0, 0, 343, 344, 5, + 39, 0, 0, 344, 345, 5, 39, 0, 0, 345, 350, 1, 0, 0, 0, 346, 349, 3, 69, + 34, 0, 347, 349, 8, 12, 0, 0, 348, 346, 1, 0, 0, 0, 348, 347, 1, 0, 0, + 0, 349, 352, 1, 0, 0, 0, 350, 351, 1, 0, 0, 0, 350, 348, 1, 0, 0, 0, 351, + 353, 1, 0, 0, 0, 352, 350, 1, 0, 0, 0, 353, 354, 5, 39, 0, 0, 354, 355, + 5, 39, 0, 0, 355, 407, 5, 39, 0, 0, 356, 357, 3, 67, 33, 0, 357, 361, 5, + 34, 0, 0, 358, 360, 8, 13, 0, 0, 359, 358, 1, 0, 0, 0, 360, 363, 1, 0, + 0, 0, 361, 359, 1, 0, 0, 0, 361, 362, 1, 0, 0, 0, 362, 364, 1, 0, 0, 0, + 363, 361, 1, 0, 0, 0, 364, 365, 5, 34, 0, 0, 365, 407, 1, 0, 0, 0, 366, + 367, 3, 67, 33, 0, 367, 371, 5, 39, 0, 0, 368, 370, 8, 14, 0, 0, 369, 368, + 1, 0, 0, 0, 370, 373, 1, 0, 0, 0, 371, 369, 1, 0, 0, 0, 371, 372, 1, 0, + 0, 0, 372, 374, 1, 0, 0, 0, 373, 371, 1, 0, 0, 0, 374, 375, 5, 39, 0, 0, + 375, 407, 1, 0, 0, 0, 376, 377, 3, 67, 33, 0, 377, 378, 5, 34, 0, 0, 378, + 379, 5, 34, 0, 0, 379, 380, 5, 34, 0, 0, 380, 384, 1, 0, 0, 0, 381, 383, + 9, 0, 0, 0, 382, 381, 1, 0, 0, 0, 383, 386, 1, 0, 0, 0, 384, 385, 1, 0, + 0, 0, 384, 382, 1, 0, 0, 0, 385, 387, 1, 0, 0, 0, 386, 384, 1, 0, 0, 0, + 387, 388, 5, 34, 0, 0, 388, 389, 5, 34, 0, 0, 389, 390, 5, 34, 0, 0, 390, + 407, 1, 0, 0, 0, 391, 392, 3, 67, 33, 0, 392, 393, 5, 39, 0, 0, 393, 394, + 5, 39, 0, 0, 394, 395, 5, 39, 0, 0, 395, 399, 1, 0, 0, 0, 396, 398, 9, + 0, 0, 0, 397, 396, 1, 0, 0, 0, 398, 401, 1, 0, 0, 0, 399, 400, 1, 0, 0, + 0, 399, 397, 1, 0, 0, 0, 400, 402, 1, 0, 0, 0, 401, 399, 1, 0, 0, 0, 402, + 403, 5, 39, 0, 0, 403, 404, 5, 39, 0, 0, 404, 405, 5, 39, 0, 0, 405, 407, + 1, 0, 0, 0, 406, 310, 1, 0, 0, 0, 406, 319, 1, 0, 0, 0, 406, 328, 1, 0, + 0, 0, 406, 342, 1, 0, 0, 0, 406, 356, 1, 0, 0, 0, 406, 366, 1, 0, 0, 0, + 406, 376, 1, 0, 0, 0, 406, 391, 1, 0, 0, 0, 407, 90, 1, 0, 0, 0, 408, 409, + 7, 15, 0, 0, 409, 410, 3, 89, 44, 0, 410, 92, 1, 0, 0, 0, 411, 414, 3, + 59, 29, 0, 412, 414, 5, 95, 0, 0, 413, 411, 1, 0, 0, 0, 413, 412, 1, 0, + 0, 0, 414, 420, 1, 0, 0, 0, 415, 419, 3, 59, 29, 0, 416, 419, 3, 61, 30, + 0, 417, 419, 5, 95, 0, 0, 418, 415, 1, 0, 0, 0, 418, 416, 1, 0, 0, 0, 418, + 417, 1, 0, 0, 0, 419, 422, 1, 0, 0, 0, 420, 418, 1, 0, 0, 0, 420, 421, + 1, 0, 0, 0, 421, 94, 1, 0, 0, 0, 422, 420, 1, 0, 0, 0, 36, 0, 176, 181, + 191, 224, 229, 239, 247, 253, 256, 261, 269, 272, 274, 279, 287, 289, 294, + 304, 308, 313, 315, 322, 324, 334, 336, 348, 350, 361, 371, 384, 399, 406, + 413, 418, 420, 1, 0, 1, 0, } deserializer := antlr.NewATNDeserializer(nil) staticData.atn = deserializer.Deserialize(staticData.serializedATN) @@ -311,42 +306,40 @@ func NewCELLexer(input antlr.CharStream) *CELLexer { // CELLexer tokens. const ( - CELLexerT__0 = 1 - CELLexerT__1 = 2 - CELLexerEQUALS = 3 - CELLexerNOT_EQUALS = 4 - CELLexerIN = 5 - CELLexerLESS = 6 - CELLexerLESS_EQUALS = 7 - CELLexerGREATER_EQUALS = 8 - CELLexerGREATER = 9 - CELLexerLOGICAL_AND = 10 - CELLexerLOGICAL_OR = 11 - CELLexerLBRACKET = 12 - CELLexerRPRACKET = 13 - CELLexerLBRACE = 14 - CELLexerRBRACE = 15 - CELLexerLPAREN = 16 - CELLexerRPAREN = 17 - CELLexerDOT = 18 - CELLexerCOMMA = 19 - CELLexerMINUS = 20 - CELLexerEXCLAM = 21 - CELLexerQUESTIONMARK = 22 - CELLexerCOLON = 23 - CELLexerPLUS = 24 - CELLexerSTAR = 25 - CELLexerSLASH = 26 - CELLexerPERCENT = 27 - CELLexerCEL_TRUE = 28 - CELLexerCEL_FALSE = 29 - CELLexerNUL = 30 - CELLexerWHITESPACE = 31 - CELLexerCOMMENT = 32 - CELLexerNUM_FLOAT = 33 - CELLexerNUM_INT = 34 - CELLexerNUM_UINT = 35 - CELLexerSTRING = 36 - CELLexerBYTES = 37 - CELLexerIDENTIFIER = 38 + CELLexerEQUALS = 1 + CELLexerNOT_EQUALS = 2 + CELLexerIN = 3 + CELLexerLESS = 4 + CELLexerLESS_EQUALS = 5 + CELLexerGREATER_EQUALS = 6 + CELLexerGREATER = 7 + CELLexerLOGICAL_AND = 8 + CELLexerLOGICAL_OR = 9 + CELLexerLBRACKET = 10 + CELLexerRPRACKET = 11 + CELLexerLBRACE = 12 + CELLexerRBRACE = 13 + CELLexerLPAREN = 14 + CELLexerRPAREN = 15 + CELLexerDOT = 16 + CELLexerCOMMA = 17 + CELLexerMINUS = 18 + CELLexerEXCLAM = 19 + CELLexerQUESTIONMARK = 20 + CELLexerCOLON = 21 + CELLexerPLUS = 22 + CELLexerSTAR = 23 + CELLexerSLASH = 24 + CELLexerPERCENT = 25 + CELLexerCEL_TRUE = 26 + CELLexerCEL_FALSE = 27 + CELLexerNUL = 28 + CELLexerWHITESPACE = 29 + CELLexerCOMMENT = 30 + CELLexerNUM_FLOAT = 31 + CELLexerNUM_INT = 32 + CELLexerNUM_UINT = 33 + CELLexerSTRING = 34 + CELLexerBYTES = 35 + CELLexerIDENTIFIER = 36 ) diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_listener.go b/vendor/github.com/google/cel-go/parser/gen/cel_listener.go index 8557fbad7..73b7f1d39 100644 --- a/vendor/github.com/google/cel-go/parser/gen/cel_listener.go +++ b/vendor/github.com/google/cel-go/parser/gen/cel_listener.go @@ -1,7 +1,7 @@ -// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.10.1. DO NOT EDIT. +// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.12.0. DO NOT EDIT. package gen // CEL -import "github.com/antlr/antlr4/runtime/Go/antlr" +import "github.com/antlr/antlr4/runtime/Go/antlr/v4" // CELListener is a complete listener for a parse tree produced by CELParser. type CELListener interface { @@ -67,6 +67,9 @@ type CELListener interface { // EnterExprList is called when entering the exprList production. EnterExprList(c *ExprListContext) + // EnterListInit is called when entering the listInit production. + EnterListInit(c *ListInitContext) + // EnterFieldInitializerList is called when entering the fieldInitializerList production. EnterFieldInitializerList(c *FieldInitializerListContext) @@ -76,8 +79,8 @@ type CELListener interface { // EnterMapInitializerList is called when entering the mapInitializerList production. EnterMapInitializerList(c *MapInitializerListContext) - // EnterOptKey is called when entering the optKey production. - EnterOptKey(c *OptKeyContext) + // EnterOptExpr is called when entering the optExpr production. + EnterOptExpr(c *OptExprContext) // EnterInt is called when entering the Int production. EnterInt(c *IntContext) @@ -163,6 +166,9 @@ type CELListener interface { // ExitExprList is called when exiting the exprList production. ExitExprList(c *ExprListContext) + // ExitListInit is called when exiting the listInit production. + ExitListInit(c *ListInitContext) + // ExitFieldInitializerList is called when exiting the fieldInitializerList production. ExitFieldInitializerList(c *FieldInitializerListContext) @@ -172,8 +178,8 @@ type CELListener interface { // ExitMapInitializerList is called when exiting the mapInitializerList production. ExitMapInitializerList(c *MapInitializerListContext) - // ExitOptKey is called when exiting the optKey production. - ExitOptKey(c *OptKeyContext) + // ExitOptExpr is called when exiting the optExpr production. + ExitOptExpr(c *OptExprContext) // ExitInt is called when exiting the Int production. ExitInt(c *IntContext) diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_parser.go b/vendor/github.com/google/cel-go/parser/gen/cel_parser.go index f821f5ae8..0cb6c8eae 100644 --- a/vendor/github.com/google/cel-go/parser/gen/cel_parser.go +++ b/vendor/github.com/google/cel-go/parser/gen/cel_parser.go @@ -1,4 +1,4 @@ -// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.10.1. DO NOT EDIT. +// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.12.0. DO NOT EDIT. package gen // CEL import ( @@ -6,7 +6,7 @@ import ( "strconv" "sync" - "github.com/antlr/antlr4/runtime/Go/antlr" + "github.com/antlr/antlr4/runtime/Go/antlr/v4" ) // Suppress unused import errors @@ -32,13 +32,12 @@ var celParserStaticData struct { func celParserInit() { staticData := &celParserStaticData staticData.literalNames = []string{ - "", "'.?'", "'[?'", "'=='", "'!='", "'in'", "'<'", "'<='", "'>='", "'>'", - "'&&'", "'||'", "'['", "']'", "'{'", "'}'", "'('", "')'", "'.'", "','", - "'-'", "'!'", "'?'", "':'", "'+'", "'*'", "'/'", "'%'", "'true'", "'false'", - "'null'", + "", "'=='", "'!='", "'in'", "'<'", "'<='", "'>='", "'>'", "'&&'", "'||'", + "'['", "']'", "'{'", "'}'", "'('", "')'", "'.'", "','", "'-'", "'!'", + "'?'", "':'", "'+'", "'*'", "'/'", "'%'", "'true'", "'false'", "'null'", } staticData.symbolicNames = []string{ - "", "", "", "EQUALS", "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", "GREATER_EQUALS", + "", "EQUALS", "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", "GREATER_EQUALS", "GREATER", "LOGICAL_AND", "LOGICAL_OR", "LBRACKET", "RPRACKET", "LBRACE", "RBRACE", "LPAREN", "RPAREN", "DOT", "COMMA", "MINUS", "EXCLAM", "QUESTIONMARK", "COLON", "PLUS", "STAR", "SLASH", "PERCENT", "CEL_TRUE", "CEL_FALSE", @@ -47,118 +46,125 @@ func celParserInit() { } staticData.ruleNames = []string{ "start", "expr", "conditionalOr", "conditionalAnd", "relation", "calc", - "unary", "member", "primary", "exprList", "fieldInitializerList", "optField", - "mapInitializerList", "optKey", "literal", + "unary", "member", "primary", "exprList", "listInit", "fieldInitializerList", + "optField", "mapInitializerList", "optExpr", "literal", } staticData.predictionContextCache = antlr.NewPredictionContextCache() staticData.serializedATN = []int32{ - 4, 1, 38, 235, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, + 4, 1, 36, 251, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, - 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 1, 0, 1, 0, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 40, 8, 1, 1, 2, 1, 2, 1, - 2, 5, 2, 45, 8, 2, 10, 2, 12, 2, 48, 9, 2, 1, 3, 1, 3, 1, 3, 5, 3, 53, - 8, 3, 10, 3, 12, 3, 56, 9, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 5, 4, - 64, 8, 4, 10, 4, 12, 4, 67, 9, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, - 5, 1, 5, 1, 5, 5, 5, 78, 8, 5, 10, 5, 12, 5, 81, 9, 5, 1, 6, 1, 6, 4, 6, - 85, 8, 6, 11, 6, 12, 6, 86, 1, 6, 1, 6, 4, 6, 91, 8, 6, 11, 6, 12, 6, 92, - 1, 6, 3, 6, 96, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, - 7, 1, 7, 1, 7, 3, 7, 109, 8, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 5, - 7, 117, 8, 7, 10, 7, 12, 7, 120, 9, 7, 1, 8, 3, 8, 123, 8, 8, 1, 8, 1, - 8, 1, 8, 3, 8, 128, 8, 8, 1, 8, 3, 8, 131, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, - 1, 8, 1, 8, 3, 8, 139, 8, 8, 1, 8, 3, 8, 142, 8, 8, 1, 8, 1, 8, 1, 8, 3, - 8, 147, 8, 8, 1, 8, 3, 8, 150, 8, 8, 1, 8, 1, 8, 3, 8, 154, 8, 8, 1, 8, - 1, 8, 1, 8, 5, 8, 159, 8, 8, 10, 8, 12, 8, 162, 9, 8, 1, 8, 1, 8, 3, 8, - 166, 8, 8, 1, 8, 3, 8, 169, 8, 8, 1, 8, 1, 8, 3, 8, 173, 8, 8, 1, 9, 1, - 9, 1, 9, 5, 9, 178, 8, 9, 10, 9, 12, 9, 181, 9, 9, 1, 10, 1, 10, 1, 10, - 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 5, 10, 191, 8, 10, 10, 10, 12, 10, 194, - 9, 10, 1, 11, 3, 11, 197, 8, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, - 12, 1, 12, 1, 12, 1, 12, 1, 12, 5, 12, 209, 8, 12, 10, 12, 12, 12, 212, - 9, 12, 1, 13, 3, 13, 215, 8, 13, 1, 13, 1, 13, 1, 14, 3, 14, 220, 8, 14, - 1, 14, 1, 14, 1, 14, 3, 14, 225, 8, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, - 14, 1, 14, 3, 14, 233, 8, 14, 1, 14, 0, 3, 8, 10, 14, 15, 0, 2, 4, 6, 8, - 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 0, 5, 1, 0, 3, 9, 1, 0, 25, 27, - 2, 0, 20, 20, 24, 24, 2, 0, 1, 1, 18, 18, 2, 0, 2, 2, 12, 12, 263, 0, 30, - 1, 0, 0, 0, 2, 33, 1, 0, 0, 0, 4, 41, 1, 0, 0, 0, 6, 49, 1, 0, 0, 0, 8, - 57, 1, 0, 0, 0, 10, 68, 1, 0, 0, 0, 12, 95, 1, 0, 0, 0, 14, 97, 1, 0, 0, - 0, 16, 172, 1, 0, 0, 0, 18, 174, 1, 0, 0, 0, 20, 182, 1, 0, 0, 0, 22, 196, - 1, 0, 0, 0, 24, 200, 1, 0, 0, 0, 26, 214, 1, 0, 0, 0, 28, 232, 1, 0, 0, - 0, 30, 31, 3, 2, 1, 0, 31, 32, 5, 0, 0, 1, 32, 1, 1, 0, 0, 0, 33, 39, 3, - 4, 2, 0, 34, 35, 5, 22, 0, 0, 35, 36, 3, 4, 2, 0, 36, 37, 5, 23, 0, 0, - 37, 38, 3, 2, 1, 0, 38, 40, 1, 0, 0, 0, 39, 34, 1, 0, 0, 0, 39, 40, 1, - 0, 0, 0, 40, 3, 1, 0, 0, 0, 41, 46, 3, 6, 3, 0, 42, 43, 5, 11, 0, 0, 43, - 45, 3, 6, 3, 0, 44, 42, 1, 0, 0, 0, 45, 48, 1, 0, 0, 0, 46, 44, 1, 0, 0, - 0, 46, 47, 1, 0, 0, 0, 47, 5, 1, 0, 0, 0, 48, 46, 1, 0, 0, 0, 49, 54, 3, - 8, 4, 0, 50, 51, 5, 10, 0, 0, 51, 53, 3, 8, 4, 0, 52, 50, 1, 0, 0, 0, 53, - 56, 1, 0, 0, 0, 54, 52, 1, 0, 0, 0, 54, 55, 1, 0, 0, 0, 55, 7, 1, 0, 0, - 0, 56, 54, 1, 0, 0, 0, 57, 58, 6, 4, -1, 0, 58, 59, 3, 10, 5, 0, 59, 65, - 1, 0, 0, 0, 60, 61, 10, 1, 0, 0, 61, 62, 7, 0, 0, 0, 62, 64, 3, 8, 4, 2, - 63, 60, 1, 0, 0, 0, 64, 67, 1, 0, 0, 0, 65, 63, 1, 0, 0, 0, 65, 66, 1, - 0, 0, 0, 66, 9, 1, 0, 0, 0, 67, 65, 1, 0, 0, 0, 68, 69, 6, 5, -1, 0, 69, - 70, 3, 12, 6, 0, 70, 79, 1, 0, 0, 0, 71, 72, 10, 2, 0, 0, 72, 73, 7, 1, - 0, 0, 73, 78, 3, 10, 5, 3, 74, 75, 10, 1, 0, 0, 75, 76, 7, 2, 0, 0, 76, - 78, 3, 10, 5, 2, 77, 71, 1, 0, 0, 0, 77, 74, 1, 0, 0, 0, 78, 81, 1, 0, - 0, 0, 79, 77, 1, 0, 0, 0, 79, 80, 1, 0, 0, 0, 80, 11, 1, 0, 0, 0, 81, 79, - 1, 0, 0, 0, 82, 96, 3, 14, 7, 0, 83, 85, 5, 21, 0, 0, 84, 83, 1, 0, 0, - 0, 85, 86, 1, 0, 0, 0, 86, 84, 1, 0, 0, 0, 86, 87, 1, 0, 0, 0, 87, 88, - 1, 0, 0, 0, 88, 96, 3, 14, 7, 0, 89, 91, 5, 20, 0, 0, 90, 89, 1, 0, 0, - 0, 91, 92, 1, 0, 0, 0, 92, 90, 1, 0, 0, 0, 92, 93, 1, 0, 0, 0, 93, 94, - 1, 0, 0, 0, 94, 96, 3, 14, 7, 0, 95, 82, 1, 0, 0, 0, 95, 84, 1, 0, 0, 0, - 95, 90, 1, 0, 0, 0, 96, 13, 1, 0, 0, 0, 97, 98, 6, 7, -1, 0, 98, 99, 3, - 16, 8, 0, 99, 118, 1, 0, 0, 0, 100, 101, 10, 3, 0, 0, 101, 102, 7, 3, 0, - 0, 102, 117, 5, 38, 0, 0, 103, 104, 10, 2, 0, 0, 104, 105, 5, 18, 0, 0, - 105, 106, 5, 38, 0, 0, 106, 108, 5, 16, 0, 0, 107, 109, 3, 18, 9, 0, 108, - 107, 1, 0, 0, 0, 108, 109, 1, 0, 0, 0, 109, 110, 1, 0, 0, 0, 110, 117, - 5, 17, 0, 0, 111, 112, 10, 1, 0, 0, 112, 113, 7, 4, 0, 0, 113, 114, 3, - 2, 1, 0, 114, 115, 5, 13, 0, 0, 115, 117, 1, 0, 0, 0, 116, 100, 1, 0, 0, - 0, 116, 103, 1, 0, 0, 0, 116, 111, 1, 0, 0, 0, 117, 120, 1, 0, 0, 0, 118, - 116, 1, 0, 0, 0, 118, 119, 1, 0, 0, 0, 119, 15, 1, 0, 0, 0, 120, 118, 1, - 0, 0, 0, 121, 123, 5, 18, 0, 0, 122, 121, 1, 0, 0, 0, 122, 123, 1, 0, 0, - 0, 123, 124, 1, 0, 0, 0, 124, 130, 5, 38, 0, 0, 125, 127, 5, 16, 0, 0, - 126, 128, 3, 18, 9, 0, 127, 126, 1, 0, 0, 0, 127, 128, 1, 0, 0, 0, 128, - 129, 1, 0, 0, 0, 129, 131, 5, 17, 0, 0, 130, 125, 1, 0, 0, 0, 130, 131, - 1, 0, 0, 0, 131, 173, 1, 0, 0, 0, 132, 133, 5, 16, 0, 0, 133, 134, 3, 2, - 1, 0, 134, 135, 5, 17, 0, 0, 135, 173, 1, 0, 0, 0, 136, 138, 5, 12, 0, - 0, 137, 139, 3, 18, 9, 0, 138, 137, 1, 0, 0, 0, 138, 139, 1, 0, 0, 0, 139, - 141, 1, 0, 0, 0, 140, 142, 5, 19, 0, 0, 141, 140, 1, 0, 0, 0, 141, 142, - 1, 0, 0, 0, 142, 143, 1, 0, 0, 0, 143, 173, 5, 13, 0, 0, 144, 146, 5, 14, - 0, 0, 145, 147, 3, 24, 12, 0, 146, 145, 1, 0, 0, 0, 146, 147, 1, 0, 0, - 0, 147, 149, 1, 0, 0, 0, 148, 150, 5, 19, 0, 0, 149, 148, 1, 0, 0, 0, 149, - 150, 1, 0, 0, 0, 150, 151, 1, 0, 0, 0, 151, 173, 5, 15, 0, 0, 152, 154, - 5, 18, 0, 0, 153, 152, 1, 0, 0, 0, 153, 154, 1, 0, 0, 0, 154, 155, 1, 0, - 0, 0, 155, 160, 5, 38, 0, 0, 156, 157, 5, 18, 0, 0, 157, 159, 5, 38, 0, - 0, 158, 156, 1, 0, 0, 0, 159, 162, 1, 0, 0, 0, 160, 158, 1, 0, 0, 0, 160, - 161, 1, 0, 0, 0, 161, 163, 1, 0, 0, 0, 162, 160, 1, 0, 0, 0, 163, 165, - 5, 14, 0, 0, 164, 166, 3, 20, 10, 0, 165, 164, 1, 0, 0, 0, 165, 166, 1, - 0, 0, 0, 166, 168, 1, 0, 0, 0, 167, 169, 5, 19, 0, 0, 168, 167, 1, 0, 0, - 0, 168, 169, 1, 0, 0, 0, 169, 170, 1, 0, 0, 0, 170, 173, 5, 15, 0, 0, 171, - 173, 3, 28, 14, 0, 172, 122, 1, 0, 0, 0, 172, 132, 1, 0, 0, 0, 172, 136, - 1, 0, 0, 0, 172, 144, 1, 0, 0, 0, 172, 153, 1, 0, 0, 0, 172, 171, 1, 0, - 0, 0, 173, 17, 1, 0, 0, 0, 174, 179, 3, 2, 1, 0, 175, 176, 5, 19, 0, 0, - 176, 178, 3, 2, 1, 0, 177, 175, 1, 0, 0, 0, 178, 181, 1, 0, 0, 0, 179, - 177, 1, 0, 0, 0, 179, 180, 1, 0, 0, 0, 180, 19, 1, 0, 0, 0, 181, 179, 1, - 0, 0, 0, 182, 183, 3, 22, 11, 0, 183, 184, 5, 23, 0, 0, 184, 192, 3, 2, - 1, 0, 185, 186, 5, 19, 0, 0, 186, 187, 3, 22, 11, 0, 187, 188, 5, 23, 0, - 0, 188, 189, 3, 2, 1, 0, 189, 191, 1, 0, 0, 0, 190, 185, 1, 0, 0, 0, 191, - 194, 1, 0, 0, 0, 192, 190, 1, 0, 0, 0, 192, 193, 1, 0, 0, 0, 193, 21, 1, - 0, 0, 0, 194, 192, 1, 0, 0, 0, 195, 197, 5, 22, 0, 0, 196, 195, 1, 0, 0, - 0, 196, 197, 1, 0, 0, 0, 197, 198, 1, 0, 0, 0, 198, 199, 5, 38, 0, 0, 199, - 23, 1, 0, 0, 0, 200, 201, 3, 26, 13, 0, 201, 202, 5, 23, 0, 0, 202, 210, - 3, 2, 1, 0, 203, 204, 5, 19, 0, 0, 204, 205, 3, 26, 13, 0, 205, 206, 5, - 23, 0, 0, 206, 207, 3, 2, 1, 0, 207, 209, 1, 0, 0, 0, 208, 203, 1, 0, 0, - 0, 209, 212, 1, 0, 0, 0, 210, 208, 1, 0, 0, 0, 210, 211, 1, 0, 0, 0, 211, - 25, 1, 0, 0, 0, 212, 210, 1, 0, 0, 0, 213, 215, 5, 22, 0, 0, 214, 213, - 1, 0, 0, 0, 214, 215, 1, 0, 0, 0, 215, 216, 1, 0, 0, 0, 216, 217, 3, 2, - 1, 0, 217, 27, 1, 0, 0, 0, 218, 220, 5, 20, 0, 0, 219, 218, 1, 0, 0, 0, - 219, 220, 1, 0, 0, 0, 220, 221, 1, 0, 0, 0, 221, 233, 5, 34, 0, 0, 222, - 233, 5, 35, 0, 0, 223, 225, 5, 20, 0, 0, 224, 223, 1, 0, 0, 0, 224, 225, - 1, 0, 0, 0, 225, 226, 1, 0, 0, 0, 226, 233, 5, 33, 0, 0, 227, 233, 5, 36, - 0, 0, 228, 233, 5, 37, 0, 0, 229, 233, 5, 28, 0, 0, 230, 233, 5, 29, 0, - 0, 231, 233, 5, 30, 0, 0, 232, 219, 1, 0, 0, 0, 232, 222, 1, 0, 0, 0, 232, - 224, 1, 0, 0, 0, 232, 227, 1, 0, 0, 0, 232, 228, 1, 0, 0, 0, 232, 229, - 1, 0, 0, 0, 232, 230, 1, 0, 0, 0, 232, 231, 1, 0, 0, 0, 233, 29, 1, 0, - 0, 0, 32, 39, 46, 54, 65, 77, 79, 86, 92, 95, 108, 116, 118, 122, 127, - 130, 138, 141, 146, 149, 153, 160, 165, 168, 172, 179, 192, 196, 210, 214, - 219, 224, 232, + 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, + 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 42, 8, 1, 1, + 2, 1, 2, 1, 2, 5, 2, 47, 8, 2, 10, 2, 12, 2, 50, 9, 2, 1, 3, 1, 3, 1, 3, + 5, 3, 55, 8, 3, 10, 3, 12, 3, 58, 9, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, + 4, 5, 4, 66, 8, 4, 10, 4, 12, 4, 69, 9, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, + 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 80, 8, 5, 10, 5, 12, 5, 83, 9, 5, 1, 6, 1, + 6, 4, 6, 87, 8, 6, 11, 6, 12, 6, 88, 1, 6, 1, 6, 4, 6, 93, 8, 6, 11, 6, + 12, 6, 94, 1, 6, 3, 6, 98, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, + 7, 106, 8, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 114, 8, 7, 1, 7, + 1, 7, 1, 7, 1, 7, 3, 7, 120, 8, 7, 1, 7, 1, 7, 1, 7, 5, 7, 125, 8, 7, 10, + 7, 12, 7, 128, 9, 7, 1, 8, 3, 8, 131, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 136, + 8, 8, 1, 8, 3, 8, 139, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, + 147, 8, 8, 1, 8, 3, 8, 150, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 155, 8, 8, 1, + 8, 3, 8, 158, 8, 8, 1, 8, 1, 8, 3, 8, 162, 8, 8, 1, 8, 1, 8, 1, 8, 5, 8, + 167, 8, 8, 10, 8, 12, 8, 170, 9, 8, 1, 8, 1, 8, 3, 8, 174, 8, 8, 1, 8, + 3, 8, 177, 8, 8, 1, 8, 1, 8, 3, 8, 181, 8, 8, 1, 9, 1, 9, 1, 9, 5, 9, 186, + 8, 9, 10, 9, 12, 9, 189, 9, 9, 1, 10, 1, 10, 1, 10, 5, 10, 194, 8, 10, + 10, 10, 12, 10, 197, 9, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, + 11, 1, 11, 5, 11, 207, 8, 11, 10, 11, 12, 11, 210, 9, 11, 1, 12, 3, 12, + 213, 8, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, + 13, 1, 13, 5, 13, 225, 8, 13, 10, 13, 12, 13, 228, 9, 13, 1, 14, 3, 14, + 231, 8, 14, 1, 14, 1, 14, 1, 15, 3, 15, 236, 8, 15, 1, 15, 1, 15, 1, 15, + 3, 15, 241, 8, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 249, + 8, 15, 1, 15, 0, 3, 8, 10, 14, 16, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, + 22, 24, 26, 28, 30, 0, 3, 1, 0, 1, 7, 1, 0, 23, 25, 2, 0, 18, 18, 22, 22, + 281, 0, 32, 1, 0, 0, 0, 2, 35, 1, 0, 0, 0, 4, 43, 1, 0, 0, 0, 6, 51, 1, + 0, 0, 0, 8, 59, 1, 0, 0, 0, 10, 70, 1, 0, 0, 0, 12, 97, 1, 0, 0, 0, 14, + 99, 1, 0, 0, 0, 16, 180, 1, 0, 0, 0, 18, 182, 1, 0, 0, 0, 20, 190, 1, 0, + 0, 0, 22, 198, 1, 0, 0, 0, 24, 212, 1, 0, 0, 0, 26, 216, 1, 0, 0, 0, 28, + 230, 1, 0, 0, 0, 30, 248, 1, 0, 0, 0, 32, 33, 3, 2, 1, 0, 33, 34, 5, 0, + 0, 1, 34, 1, 1, 0, 0, 0, 35, 41, 3, 4, 2, 0, 36, 37, 5, 20, 0, 0, 37, 38, + 3, 4, 2, 0, 38, 39, 5, 21, 0, 0, 39, 40, 3, 2, 1, 0, 40, 42, 1, 0, 0, 0, + 41, 36, 1, 0, 0, 0, 41, 42, 1, 0, 0, 0, 42, 3, 1, 0, 0, 0, 43, 48, 3, 6, + 3, 0, 44, 45, 5, 9, 0, 0, 45, 47, 3, 6, 3, 0, 46, 44, 1, 0, 0, 0, 47, 50, + 1, 0, 0, 0, 48, 46, 1, 0, 0, 0, 48, 49, 1, 0, 0, 0, 49, 5, 1, 0, 0, 0, + 50, 48, 1, 0, 0, 0, 51, 56, 3, 8, 4, 0, 52, 53, 5, 8, 0, 0, 53, 55, 3, + 8, 4, 0, 54, 52, 1, 0, 0, 0, 55, 58, 1, 0, 0, 0, 56, 54, 1, 0, 0, 0, 56, + 57, 1, 0, 0, 0, 57, 7, 1, 0, 0, 0, 58, 56, 1, 0, 0, 0, 59, 60, 6, 4, -1, + 0, 60, 61, 3, 10, 5, 0, 61, 67, 1, 0, 0, 0, 62, 63, 10, 1, 0, 0, 63, 64, + 7, 0, 0, 0, 64, 66, 3, 8, 4, 2, 65, 62, 1, 0, 0, 0, 66, 69, 1, 0, 0, 0, + 67, 65, 1, 0, 0, 0, 67, 68, 1, 0, 0, 0, 68, 9, 1, 0, 0, 0, 69, 67, 1, 0, + 0, 0, 70, 71, 6, 5, -1, 0, 71, 72, 3, 12, 6, 0, 72, 81, 1, 0, 0, 0, 73, + 74, 10, 2, 0, 0, 74, 75, 7, 1, 0, 0, 75, 80, 3, 10, 5, 3, 76, 77, 10, 1, + 0, 0, 77, 78, 7, 2, 0, 0, 78, 80, 3, 10, 5, 2, 79, 73, 1, 0, 0, 0, 79, + 76, 1, 0, 0, 0, 80, 83, 1, 0, 0, 0, 81, 79, 1, 0, 0, 0, 81, 82, 1, 0, 0, + 0, 82, 11, 1, 0, 0, 0, 83, 81, 1, 0, 0, 0, 84, 98, 3, 14, 7, 0, 85, 87, + 5, 19, 0, 0, 86, 85, 1, 0, 0, 0, 87, 88, 1, 0, 0, 0, 88, 86, 1, 0, 0, 0, + 88, 89, 1, 0, 0, 0, 89, 90, 1, 0, 0, 0, 90, 98, 3, 14, 7, 0, 91, 93, 5, + 18, 0, 0, 92, 91, 1, 0, 0, 0, 93, 94, 1, 0, 0, 0, 94, 92, 1, 0, 0, 0, 94, + 95, 1, 0, 0, 0, 95, 96, 1, 0, 0, 0, 96, 98, 3, 14, 7, 0, 97, 84, 1, 0, + 0, 0, 97, 86, 1, 0, 0, 0, 97, 92, 1, 0, 0, 0, 98, 13, 1, 0, 0, 0, 99, 100, + 6, 7, -1, 0, 100, 101, 3, 16, 8, 0, 101, 126, 1, 0, 0, 0, 102, 103, 10, + 3, 0, 0, 103, 105, 5, 16, 0, 0, 104, 106, 5, 20, 0, 0, 105, 104, 1, 0, + 0, 0, 105, 106, 1, 0, 0, 0, 106, 107, 1, 0, 0, 0, 107, 125, 5, 36, 0, 0, + 108, 109, 10, 2, 0, 0, 109, 110, 5, 16, 0, 0, 110, 111, 5, 36, 0, 0, 111, + 113, 5, 14, 0, 0, 112, 114, 3, 18, 9, 0, 113, 112, 1, 0, 0, 0, 113, 114, + 1, 0, 0, 0, 114, 115, 1, 0, 0, 0, 115, 125, 5, 15, 0, 0, 116, 117, 10, + 1, 0, 0, 117, 119, 5, 10, 0, 0, 118, 120, 5, 20, 0, 0, 119, 118, 1, 0, + 0, 0, 119, 120, 1, 0, 0, 0, 120, 121, 1, 0, 0, 0, 121, 122, 3, 2, 1, 0, + 122, 123, 5, 11, 0, 0, 123, 125, 1, 0, 0, 0, 124, 102, 1, 0, 0, 0, 124, + 108, 1, 0, 0, 0, 124, 116, 1, 0, 0, 0, 125, 128, 1, 0, 0, 0, 126, 124, + 1, 0, 0, 0, 126, 127, 1, 0, 0, 0, 127, 15, 1, 0, 0, 0, 128, 126, 1, 0, + 0, 0, 129, 131, 5, 16, 0, 0, 130, 129, 1, 0, 0, 0, 130, 131, 1, 0, 0, 0, + 131, 132, 1, 0, 0, 0, 132, 138, 5, 36, 0, 0, 133, 135, 5, 14, 0, 0, 134, + 136, 3, 18, 9, 0, 135, 134, 1, 0, 0, 0, 135, 136, 1, 0, 0, 0, 136, 137, + 1, 0, 0, 0, 137, 139, 5, 15, 0, 0, 138, 133, 1, 0, 0, 0, 138, 139, 1, 0, + 0, 0, 139, 181, 1, 0, 0, 0, 140, 141, 5, 14, 0, 0, 141, 142, 3, 2, 1, 0, + 142, 143, 5, 15, 0, 0, 143, 181, 1, 0, 0, 0, 144, 146, 5, 10, 0, 0, 145, + 147, 3, 20, 10, 0, 146, 145, 1, 0, 0, 0, 146, 147, 1, 0, 0, 0, 147, 149, + 1, 0, 0, 0, 148, 150, 5, 17, 0, 0, 149, 148, 1, 0, 0, 0, 149, 150, 1, 0, + 0, 0, 150, 151, 1, 0, 0, 0, 151, 181, 5, 11, 0, 0, 152, 154, 5, 12, 0, + 0, 153, 155, 3, 26, 13, 0, 154, 153, 1, 0, 0, 0, 154, 155, 1, 0, 0, 0, + 155, 157, 1, 0, 0, 0, 156, 158, 5, 17, 0, 0, 157, 156, 1, 0, 0, 0, 157, + 158, 1, 0, 0, 0, 158, 159, 1, 0, 0, 0, 159, 181, 5, 13, 0, 0, 160, 162, + 5, 16, 0, 0, 161, 160, 1, 0, 0, 0, 161, 162, 1, 0, 0, 0, 162, 163, 1, 0, + 0, 0, 163, 168, 5, 36, 0, 0, 164, 165, 5, 16, 0, 0, 165, 167, 5, 36, 0, + 0, 166, 164, 1, 0, 0, 0, 167, 170, 1, 0, 0, 0, 168, 166, 1, 0, 0, 0, 168, + 169, 1, 0, 0, 0, 169, 171, 1, 0, 0, 0, 170, 168, 1, 0, 0, 0, 171, 173, + 5, 12, 0, 0, 172, 174, 3, 22, 11, 0, 173, 172, 1, 0, 0, 0, 173, 174, 1, + 0, 0, 0, 174, 176, 1, 0, 0, 0, 175, 177, 5, 17, 0, 0, 176, 175, 1, 0, 0, + 0, 176, 177, 1, 0, 0, 0, 177, 178, 1, 0, 0, 0, 178, 181, 5, 13, 0, 0, 179, + 181, 3, 30, 15, 0, 180, 130, 1, 0, 0, 0, 180, 140, 1, 0, 0, 0, 180, 144, + 1, 0, 0, 0, 180, 152, 1, 0, 0, 0, 180, 161, 1, 0, 0, 0, 180, 179, 1, 0, + 0, 0, 181, 17, 1, 0, 0, 0, 182, 187, 3, 2, 1, 0, 183, 184, 5, 17, 0, 0, + 184, 186, 3, 2, 1, 0, 185, 183, 1, 0, 0, 0, 186, 189, 1, 0, 0, 0, 187, + 185, 1, 0, 0, 0, 187, 188, 1, 0, 0, 0, 188, 19, 1, 0, 0, 0, 189, 187, 1, + 0, 0, 0, 190, 195, 3, 28, 14, 0, 191, 192, 5, 17, 0, 0, 192, 194, 3, 28, + 14, 0, 193, 191, 1, 0, 0, 0, 194, 197, 1, 0, 0, 0, 195, 193, 1, 0, 0, 0, + 195, 196, 1, 0, 0, 0, 196, 21, 1, 0, 0, 0, 197, 195, 1, 0, 0, 0, 198, 199, + 3, 24, 12, 0, 199, 200, 5, 21, 0, 0, 200, 208, 3, 2, 1, 0, 201, 202, 5, + 17, 0, 0, 202, 203, 3, 24, 12, 0, 203, 204, 5, 21, 0, 0, 204, 205, 3, 2, + 1, 0, 205, 207, 1, 0, 0, 0, 206, 201, 1, 0, 0, 0, 207, 210, 1, 0, 0, 0, + 208, 206, 1, 0, 0, 0, 208, 209, 1, 0, 0, 0, 209, 23, 1, 0, 0, 0, 210, 208, + 1, 0, 0, 0, 211, 213, 5, 20, 0, 0, 212, 211, 1, 0, 0, 0, 212, 213, 1, 0, + 0, 0, 213, 214, 1, 0, 0, 0, 214, 215, 5, 36, 0, 0, 215, 25, 1, 0, 0, 0, + 216, 217, 3, 28, 14, 0, 217, 218, 5, 21, 0, 0, 218, 226, 3, 2, 1, 0, 219, + 220, 5, 17, 0, 0, 220, 221, 3, 28, 14, 0, 221, 222, 5, 21, 0, 0, 222, 223, + 3, 2, 1, 0, 223, 225, 1, 0, 0, 0, 224, 219, 1, 0, 0, 0, 225, 228, 1, 0, + 0, 0, 226, 224, 1, 0, 0, 0, 226, 227, 1, 0, 0, 0, 227, 27, 1, 0, 0, 0, + 228, 226, 1, 0, 0, 0, 229, 231, 5, 20, 0, 0, 230, 229, 1, 0, 0, 0, 230, + 231, 1, 0, 0, 0, 231, 232, 1, 0, 0, 0, 232, 233, 3, 2, 1, 0, 233, 29, 1, + 0, 0, 0, 234, 236, 5, 18, 0, 0, 235, 234, 1, 0, 0, 0, 235, 236, 1, 0, 0, + 0, 236, 237, 1, 0, 0, 0, 237, 249, 5, 32, 0, 0, 238, 249, 5, 33, 0, 0, + 239, 241, 5, 18, 0, 0, 240, 239, 1, 0, 0, 0, 240, 241, 1, 0, 0, 0, 241, + 242, 1, 0, 0, 0, 242, 249, 5, 31, 0, 0, 243, 249, 5, 34, 0, 0, 244, 249, + 5, 35, 0, 0, 245, 249, 5, 26, 0, 0, 246, 249, 5, 27, 0, 0, 247, 249, 5, + 28, 0, 0, 248, 235, 1, 0, 0, 0, 248, 238, 1, 0, 0, 0, 248, 240, 1, 0, 0, + 0, 248, 243, 1, 0, 0, 0, 248, 244, 1, 0, 0, 0, 248, 245, 1, 0, 0, 0, 248, + 246, 1, 0, 0, 0, 248, 247, 1, 0, 0, 0, 249, 31, 1, 0, 0, 0, 35, 41, 48, + 56, 67, 79, 81, 88, 94, 97, 105, 113, 119, 124, 126, 130, 135, 138, 146, + 149, 154, 157, 161, 168, 173, 176, 180, 187, 195, 208, 212, 226, 230, 235, + 240, 248, } deserializer := antlr.NewATNDeserializer(nil) staticData.atn = deserializer.Deserialize(staticData.serializedATN) @@ -197,44 +203,42 @@ func NewCELParser(input antlr.TokenStream) *CELParser { // CELParser tokens. const ( CELParserEOF = antlr.TokenEOF - CELParserT__0 = 1 - CELParserT__1 = 2 - CELParserEQUALS = 3 - CELParserNOT_EQUALS = 4 - CELParserIN = 5 - CELParserLESS = 6 - CELParserLESS_EQUALS = 7 - CELParserGREATER_EQUALS = 8 - CELParserGREATER = 9 - CELParserLOGICAL_AND = 10 - CELParserLOGICAL_OR = 11 - CELParserLBRACKET = 12 - CELParserRPRACKET = 13 - CELParserLBRACE = 14 - CELParserRBRACE = 15 - CELParserLPAREN = 16 - CELParserRPAREN = 17 - CELParserDOT = 18 - CELParserCOMMA = 19 - CELParserMINUS = 20 - CELParserEXCLAM = 21 - CELParserQUESTIONMARK = 22 - CELParserCOLON = 23 - CELParserPLUS = 24 - CELParserSTAR = 25 - CELParserSLASH = 26 - CELParserPERCENT = 27 - CELParserCEL_TRUE = 28 - CELParserCEL_FALSE = 29 - CELParserNUL = 30 - CELParserWHITESPACE = 31 - CELParserCOMMENT = 32 - CELParserNUM_FLOAT = 33 - CELParserNUM_INT = 34 - CELParserNUM_UINT = 35 - CELParserSTRING = 36 - CELParserBYTES = 37 - CELParserIDENTIFIER = 38 + CELParserEQUALS = 1 + CELParserNOT_EQUALS = 2 + CELParserIN = 3 + CELParserLESS = 4 + CELParserLESS_EQUALS = 5 + CELParserGREATER_EQUALS = 6 + CELParserGREATER = 7 + CELParserLOGICAL_AND = 8 + CELParserLOGICAL_OR = 9 + CELParserLBRACKET = 10 + CELParserRPRACKET = 11 + CELParserLBRACE = 12 + CELParserRBRACE = 13 + CELParserLPAREN = 14 + CELParserRPAREN = 15 + CELParserDOT = 16 + CELParserCOMMA = 17 + CELParserMINUS = 18 + CELParserEXCLAM = 19 + CELParserQUESTIONMARK = 20 + CELParserCOLON = 21 + CELParserPLUS = 22 + CELParserSTAR = 23 + CELParserSLASH = 24 + CELParserPERCENT = 25 + CELParserCEL_TRUE = 26 + CELParserCEL_FALSE = 27 + CELParserNUL = 28 + CELParserWHITESPACE = 29 + CELParserCOMMENT = 30 + CELParserNUM_FLOAT = 31 + CELParserNUM_INT = 32 + CELParserNUM_UINT = 33 + CELParserSTRING = 34 + CELParserBYTES = 35 + CELParserIDENTIFIER = 36 ) // CELParser rules. @@ -249,11 +253,12 @@ const ( CELParserRULE_member = 7 CELParserRULE_primary = 8 CELParserRULE_exprList = 9 - CELParserRULE_fieldInitializerList = 10 - CELParserRULE_optField = 11 - CELParserRULE_mapInitializerList = 12 - CELParserRULE_optKey = 13 - CELParserRULE_literal = 14 + CELParserRULE_listInit = 10 + CELParserRULE_fieldInitializerList = 11 + CELParserRULE_optField = 12 + CELParserRULE_mapInitializerList = 13 + CELParserRULE_optExpr = 14 + CELParserRULE_literal = 15 ) // IStartContext is an interface to support dynamic dispatch. @@ -269,6 +274,10 @@ type IStartContext interface { // SetE sets the e rule contexts. SetE(IExprContext) + // Getter signatures + EOF() antlr.TerminalNode + Expr() IExprContext + // IsStartContext differentiates from other interfaces. IsStartContext() } @@ -380,14 +389,14 @@ func (p *CELParser) Start() (localctx IStartContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(30) + p.SetState(32) var _x = p.Expr() localctx.(*StartContext).e = _x } { - p.SetState(31) + p.SetState(33) p.Match(CELParserEOF) } @@ -425,6 +434,13 @@ type IExprContext interface { // SetE2 sets the e2 rule contexts. SetE2(IExprContext) + // Getter signatures + AllConditionalOr() []IConditionalOrContext + ConditionalOr(i int) IConditionalOrContext + COLON() antlr.TerminalNode + QUESTIONMARK() antlr.TerminalNode + Expr() IExprContext + // IsExprContext differentiates from other interfaces. IsExprContext() } @@ -597,37 +613,37 @@ func (p *CELParser) Expr() (localctx IExprContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(33) + p.SetState(35) var _x = p.ConditionalOr() localctx.(*ExprContext).e = _x } - p.SetState(39) + p.SetState(41) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) if _la == CELParserQUESTIONMARK { { - p.SetState(34) + p.SetState(36) var _m = p.Match(CELParserQUESTIONMARK) localctx.(*ExprContext).op = _m } { - p.SetState(35) + p.SetState(37) var _x = p.ConditionalOr() localctx.(*ExprContext).e1 = _x } { - p.SetState(36) + p.SetState(38) p.Match(CELParserCOLON) } { - p.SetState(37) + p.SetState(39) var _x = p.Expr() @@ -646,11 +662,11 @@ type IConditionalOrContext interface { // GetParser returns the parser. GetParser() antlr.Parser - // GetS11 returns the s11 token. - GetS11() antlr.Token + // GetS9 returns the s9 token. + GetS9() antlr.Token - // SetS11 sets the s11 token. - SetS11(antlr.Token) + // SetS9 sets the s9 token. + SetS9(antlr.Token) // GetOps returns the ops token list. GetOps() []antlr.Token @@ -676,6 +692,12 @@ type IConditionalOrContext interface { // SetE1 sets the e1 rule context list. SetE1([]IConditionalAndContext) + // Getter signatures + AllConditionalAnd() []IConditionalAndContext + ConditionalAnd(i int) IConditionalAndContext + AllLOGICAL_OR() []antlr.TerminalNode + LOGICAL_OR(i int) antlr.TerminalNode + // IsConditionalOrContext differentiates from other interfaces. IsConditionalOrContext() } @@ -684,7 +706,7 @@ type ConditionalOrContext struct { *antlr.BaseParserRuleContext parser antlr.Parser e IConditionalAndContext - s11 antlr.Token + s9 antlr.Token ops []antlr.Token _conditionalAnd IConditionalAndContext e1 []IConditionalAndContext @@ -712,9 +734,9 @@ func NewConditionalOrContext(parser antlr.Parser, parent antlr.ParserRuleContext func (s *ConditionalOrContext) GetParser() antlr.Parser { return s.parser } -func (s *ConditionalOrContext) GetS11() antlr.Token { return s.s11 } +func (s *ConditionalOrContext) GetS9() antlr.Token { return s.s9 } -func (s *ConditionalOrContext) SetS11(v antlr.Token) { s.s11 = v } +func (s *ConditionalOrContext) SetS9(v antlr.Token) { s.s9 = v } func (s *ConditionalOrContext) GetOps() []antlr.Token { return s.ops } @@ -837,27 +859,27 @@ func (p *CELParser) ConditionalOr() (localctx IConditionalOrContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(41) + p.SetState(43) var _x = p.ConditionalAnd() localctx.(*ConditionalOrContext).e = _x } - p.SetState(46) + p.SetState(48) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CELParserLOGICAL_OR { { - p.SetState(42) + p.SetState(44) var _m = p.Match(CELParserLOGICAL_OR) - localctx.(*ConditionalOrContext).s11 = _m + localctx.(*ConditionalOrContext).s9 = _m } - localctx.(*ConditionalOrContext).ops = append(localctx.(*ConditionalOrContext).ops, localctx.(*ConditionalOrContext).s11) + localctx.(*ConditionalOrContext).ops = append(localctx.(*ConditionalOrContext).ops, localctx.(*ConditionalOrContext).s9) { - p.SetState(43) + p.SetState(45) var _x = p.ConditionalAnd() @@ -865,7 +887,7 @@ func (p *CELParser) ConditionalOr() (localctx IConditionalOrContext) { } localctx.(*ConditionalOrContext).e1 = append(localctx.(*ConditionalOrContext).e1, localctx.(*ConditionalOrContext)._conditionalAnd) - p.SetState(48) + p.SetState(50) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } @@ -880,11 +902,11 @@ type IConditionalAndContext interface { // GetParser returns the parser. GetParser() antlr.Parser - // GetS10 returns the s10 token. - GetS10() antlr.Token + // GetS8 returns the s8 token. + GetS8() antlr.Token - // SetS10 sets the s10 token. - SetS10(antlr.Token) + // SetS8 sets the s8 token. + SetS8(antlr.Token) // GetOps returns the ops token list. GetOps() []antlr.Token @@ -910,6 +932,12 @@ type IConditionalAndContext interface { // SetE1 sets the e1 rule context list. SetE1([]IRelationContext) + // Getter signatures + AllRelation() []IRelationContext + Relation(i int) IRelationContext + AllLOGICAL_AND() []antlr.TerminalNode + LOGICAL_AND(i int) antlr.TerminalNode + // IsConditionalAndContext differentiates from other interfaces. IsConditionalAndContext() } @@ -918,7 +946,7 @@ type ConditionalAndContext struct { *antlr.BaseParserRuleContext parser antlr.Parser e IRelationContext - s10 antlr.Token + s8 antlr.Token ops []antlr.Token _relation IRelationContext e1 []IRelationContext @@ -946,9 +974,9 @@ func NewConditionalAndContext(parser antlr.Parser, parent antlr.ParserRuleContex func (s *ConditionalAndContext) GetParser() antlr.Parser { return s.parser } -func (s *ConditionalAndContext) GetS10() antlr.Token { return s.s10 } +func (s *ConditionalAndContext) GetS8() antlr.Token { return s.s8 } -func (s *ConditionalAndContext) SetS10(v antlr.Token) { s.s10 = v } +func (s *ConditionalAndContext) SetS8(v antlr.Token) { s.s8 = v } func (s *ConditionalAndContext) GetOps() []antlr.Token { return s.ops } @@ -1071,27 +1099,27 @@ func (p *CELParser) ConditionalAnd() (localctx IConditionalAndContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(49) + p.SetState(51) var _x = p.relation(0) localctx.(*ConditionalAndContext).e = _x } - p.SetState(54) + p.SetState(56) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CELParserLOGICAL_AND { { - p.SetState(50) + p.SetState(52) var _m = p.Match(CELParserLOGICAL_AND) - localctx.(*ConditionalAndContext).s10 = _m + localctx.(*ConditionalAndContext).s8 = _m } - localctx.(*ConditionalAndContext).ops = append(localctx.(*ConditionalAndContext).ops, localctx.(*ConditionalAndContext).s10) + localctx.(*ConditionalAndContext).ops = append(localctx.(*ConditionalAndContext).ops, localctx.(*ConditionalAndContext).s8) { - p.SetState(51) + p.SetState(53) var _x = p.relation(0) @@ -1099,7 +1127,7 @@ func (p *CELParser) ConditionalAnd() (localctx IConditionalAndContext) { } localctx.(*ConditionalAndContext).e1 = append(localctx.(*ConditionalAndContext).e1, localctx.(*ConditionalAndContext)._relation) - p.SetState(56) + p.SetState(58) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } @@ -1120,6 +1148,18 @@ type IRelationContext interface { // SetOp sets the op token. SetOp(antlr.Token) + // Getter signatures + Calc() ICalcContext + AllRelation() []IRelationContext + Relation(i int) IRelationContext + LESS() antlr.TerminalNode + LESS_EQUALS() antlr.TerminalNode + GREATER_EQUALS() antlr.TerminalNode + GREATER() antlr.TerminalNode + EQUALS() antlr.TerminalNode + NOT_EQUALS() antlr.TerminalNode + IN() antlr.TerminalNode + // IsRelationContext differentiates from other interfaces. IsRelationContext() } @@ -1308,12 +1348,12 @@ func (p *CELParser) relation(_p int) (localctx IRelationContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(58) + p.SetState(60) p.calc(0) } p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) - p.SetState(65) + p.SetState(67) p.GetErrorHandler().Sync(p) _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 3, p.GetParserRuleContext()) @@ -1325,13 +1365,13 @@ func (p *CELParser) relation(_p int) (localctx IRelationContext) { _prevctx = localctx localctx = NewRelationContext(p, _parentctx, _parentState) p.PushNewRecursionContext(localctx, _startState, CELParserRULE_relation) - p.SetState(60) + p.SetState(62) if !(p.Precpred(p.GetParserRuleContext(), 1)) { panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 1)", "")) } { - p.SetState(61) + p.SetState(63) var _lt = p.GetTokenStream().LT(1) @@ -1339,7 +1379,7 @@ func (p *CELParser) relation(_p int) (localctx IRelationContext) { _la = p.GetTokenStream().LA(1) - if !(((_la)&-(0x1f+1)) == 0 && ((1< 1, and is recommended to be less than the default of 256. +// The limit must be >= 1, and is recommended to be less than the default of 256. func ErrorRecoveryLookaheadTokenLimit(limit int) Option { return func(opts *options) error { if limit < 1 { @@ -68,6 +70,19 @@ func ErrorRecoveryLimit(limit int) Option { } } +// ErrorReportingLimit limits the number of syntax error reports before terminating parsing. +// +// The limit must be at least 1. If unset, the limit will be 100. +func ErrorReportingLimit(limit int) Option { + return func(opts *options) error { + if limit < 1 { + return fmt.Errorf("error reporting limit must be at least 1: %d", limit) + } + opts.errorReportingLimit = limit + return nil + } +} + // ExpressionSizeCodePointLimit is an option which limits the maximum code point count of an // expression. func ExpressionSizeCodePointLimit(expressionSizeCodePointLimit int) Option { @@ -111,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 + } +} diff --git a/vendor/github.com/google/cel-go/parser/parser.go b/vendor/github.com/google/cel-go/parser/parser.go index 0d5679488..109326a93 100644 --- a/vendor/github.com/google/cel-go/parser/parser.go +++ b/vendor/github.com/google/cel-go/parser/parser.go @@ -23,7 +23,7 @@ import ( "strings" "sync" - "github.com/antlr/antlr4/runtime/Go/antlr" + antlr "github.com/antlr/antlr4/runtime/Go/antlr/v4" "github.com/google/cel-go/common" "github.com/google/cel-go/common/operators" @@ -47,6 +47,9 @@ func NewParser(opts ...Option) (*Parser, error) { return nil, err } } + if p.errorReportingLimit == 0 { + p.errorReportingLimit = 100 + } if p.maxRecursionDepth == 0 { p.maxRecursionDepth = 250 } @@ -86,15 +89,18 @@ 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, + errorReportingLimit: p.errorReportingLimit, errorRecoveryLimit: p.errorRecoveryLimit, errorRecoveryLookaheadTokenLimit: p.errorRecoveryTokenLookaheadLimit, populateMacroCalls: p.populateMacroCalls, enableOptionalSyntax: p.enableOptionalSyntax, + enableVariadicOperatorASTs: p.enableVariadicOperatorASTs, } buf, ok := source.(runes.Buffer) if !ok { @@ -111,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 @@ -200,6 +206,16 @@ func (rl *recursionListener) ExitEveryRule(ctx antlr.ParserRuleContext) { var _ antlr.ParseTreeListener = &recursionListener{} +type tooManyErrors struct { + errorReportingLimit int +} + +func (t *tooManyErrors) Error() string { + return fmt.Sprintf("More than %d syntax errors", t.errorReportingLimit) +} + +var _ error = &tooManyErrors{} + type recoveryLimitError struct { message string } @@ -274,11 +290,14 @@ type parser struct { helper *parserHelper macros map[string]Macro recursionDepth int + errorReports int maxRecursionDepth int + errorReportingLimit int errorRecoveryLimit int errorRecoveryLookaheadTokenLimit int populateMacroCalls bool enableOptionalSyntax bool + enableVariadicOperatorASTs bool } var ( @@ -306,14 +325,14 @@ func (p *parser) parse(expr runes.Buffer, desc string) *exprpb.Expr { lexer := lexerPool.Get().(*gen.CELLexer) prsr := parserPool.Get().(*gen.CELParser) - // Unfortunately ANTLR Go runtime is missing (*antlr.BaseParser).RemoveParseListeners, so this is - // good enough until that is exported. prsrListener := &recursionListener{ maxDepth: p.maxRecursionDepth, ruleTypeDepth: map[int]*int{}, } defer func() { + // Unfortunately ANTLR Go runtime is missing (*antlr.BaseParser).RemoveParseListeners, + // so this is good enough until that is exported. // Reset the lexer and parser before putting them back in the pool. lexer.RemoveErrorListeners() prsr.RemoveParseListener(prsrListener) @@ -341,9 +360,11 @@ 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: // do nothing, listeners already notified and error reported. default: @@ -431,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 := "<>" if t != nil { txt = fmt.Sprintf("<<%T>>", t) @@ -462,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) { @@ -470,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) { @@ -486,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. @@ -552,7 +573,7 @@ func (p *parser) VisitSelect(ctx *gen.SelectContext) any { return p.helper.newExpr(ctx) } id := ctx.GetId().GetText() - if ctx.GetOp().GetText() == ".?" { + if ctx.GetOpt() != nil { if !p.enableOptionalSyntax { return p.reportError(ctx.GetOp(), "unsupported syntax '.?'") } @@ -574,7 +595,7 @@ func (p *parser) VisitMemberCall(ctx *gen.MemberCallContext) any { } id := ctx.GetId().GetText() opID := p.helper.id(ctx.GetOpen()) - return p.receiverCallOrMacro(opID, id, operand, p.visitList(ctx.GetArgs())...) + return p.receiverCallOrMacro(opID, id, operand, p.visitExprList(ctx.GetArgs())...) } // Visit a parse tree produced by CELParser#Index. @@ -587,7 +608,7 @@ func (p *parser) VisitIndex(ctx *gen.IndexContext) any { opID := p.helper.id(ctx.GetOp()) index := p.Visit(ctx.GetIndex()).(*exprpb.Expr) operator := operators.Index - if ctx.GetOp().GetText() == "[?" { + if ctx.GetOpt() != nil { if !p.enableOptionalSyntax { return p.reportError(ctx.GetOp(), "unsupported syntax '[?'") } @@ -666,7 +687,7 @@ func (p *parser) VisitIdentOrGlobalCall(ctx *gen.IdentOrGlobalCallContext) any { identName += id if ctx.GetOp() != nil { opID := p.helper.id(ctx.GetOp()) - return p.globalCallOrMacro(opID, identName, p.visitList(ctx.GetArgs())...) + return p.globalCallOrMacro(opID, identName, p.visitExprList(ctx.GetArgs())...) } return p.helper.newIdent(ctx.GetId(), identName) } @@ -674,7 +695,8 @@ func (p *parser) VisitIdentOrGlobalCall(ctx *gen.IdentOrGlobalCallContext) any { // Visit a parse tree produced by CELParser#CreateList. func (p *parser) VisitCreateList(ctx *gen.CreateListContext) any { listID := p.helper.id(ctx.GetOp()) - return p.helper.newList(listID, p.visitList(ctx.GetElems())...) + elems, optionals := p.visitListInit(ctx.GetElems()) + return p.helper.newList(listID, elems, optionals...) } // Visit a parse tree produced by CELParser#CreateStruct. @@ -703,13 +725,13 @@ func (p *parser) VisitMapInitializerList(ctx *gen.MapInitializerListContext) any // This is the result of a syntax error detected elsewhere. return []*exprpb.Expr_CreateStruct_Entry{} } - optKey := keys[i].(*gen.OptKeyContext) + optKey := keys[i] optional := optKey.GetOpt() != nil if !p.enableOptionalSyntax && optional { p.reportError(optKey, "unsupported syntax '?'") continue } - key := p.Visit(optKey.Expr()).(*exprpb.Expr) + key := p.Visit(optKey.GetE()).(*exprpb.Expr) value := p.Visit(vals[i]).(*exprpb.Expr) entry := p.helper.newMapEntry(colID, key, value, optional) result[i] = entry @@ -796,13 +818,37 @@ func (p *parser) VisitNull(ctx *gen.NullContext) any { NullValue: structpb.NullValue_NULL_VALUE}}) } -func (p *parser) visitList(ctx gen.IExprListContext) []*exprpb.Expr { +func (p *parser) visitExprList(ctx gen.IExprListContext) []*exprpb.Expr { if ctx == nil { return []*exprpb.Expr{} } return p.visitSlice(ctx.GetE()) } +func (p *parser) visitListInit(ctx gen.IListInitContext) ([]*exprpb.Expr, []int32) { + if ctx == nil { + return []*exprpb.Expr{}, []int32{} + } + elements := ctx.GetElems() + result := make([]*exprpb.Expr, len(elements)) + optionals := []int32{} + for i, e := range elements { + ex := p.Visit(e.GetE()).(*exprpb.Expr) + if ex == nil { + return []*exprpb.Expr{}, []int32{} + } + result[i] = ex + if e.GetOpt() != nil { + if !p.enableOptionalSyntax { + p.reportError(e.GetOpt(), "unsupported syntax '?'") + continue + } + optionals = append(optionals, int32(i)) + } + } + return result, optionals +} + func (p *parser) visitSlice(expressions []gen.IExprContext) []*exprpb.Expr { if expressions == nil { return []*exprpb.Expr{} @@ -824,24 +870,29 @@ 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 } // ANTLR Parse listener implementations func (p *parser) SyntaxError(recognizer antlr.Recognizer, offendingSymbol any, line, column int, msg string, e antlr.RecognitionException) { - // TODO: Snippet l := p.helper.source.NewLocation(line, column) // Hack to keep existing error messages consistent with previous versions of CEL when a reserved word // is used as an identifier. This behavior needs to be overhauled to provide consistent, normalized error @@ -849,7 +900,16 @@ func (p *parser) SyntaxError(recognizer antlr.Recognizer, offendingSymbol any, l if strings.Contains(msg, "no viable alternative") { msg = reservedIdentifier.ReplaceAllString(msg, mismatchedReservedIdentifier) } - p.errors.syntaxError(l, msg) + // Ensure that no more than 100 syntax errors are reported as this will halt attempts to recover from a + // seriously broken expression. + if p.errorReports < p.errorReportingLimit { + p.errorReports++ + p.errors.syntaxError(l, msg) + } else { + tme := &tooManyErrors{errorReportingLimit: p.errorReportingLimit} + p.errors.syntaxError(l, tme.Error()) + panic(tme) + } } func (p *parser) ReportAmbiguity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, exact bool, ambigAlts *antlr.BitSet, configs antlr.ATNConfigSet) { diff --git a/vendor/github.com/google/cel-go/parser/unparser.go b/vendor/github.com/google/cel-go/parser/unparser.go index ea20efc98..c3c40a0dd 100644 --- a/vendor/github.com/google/cel-go/parser/unparser.go +++ b/vendor/github.com/google/cel-go/parser/unparser.go @@ -106,9 +106,15 @@ func (un *unparser) visitCall(expr *exprpb.Expr) error { // ternary operator case operators.Conditional: return un.visitCallConditional(expr) + // optional select operator + case operators.OptSelect: + return un.visitOptSelect(expr) // index operator case operators.Index: return un.visitCallIndex(expr) + // optional index operator + case operators.OptIndex: + return un.visitCallOptIndex(expr) // unary operators case operators.LogicalNot, operators.Negate: return un.visitCallUnary(expr) @@ -218,6 +224,14 @@ func (un *unparser) visitCallFunc(expr *exprpb.Expr) error { } func (un *unparser) visitCallIndex(expr *exprpb.Expr) error { + return un.visitCallIndexInternal(expr, "[") +} + +func (un *unparser) visitCallOptIndex(expr *exprpb.Expr) error { + return un.visitCallIndexInternal(expr, "[?") +} + +func (un *unparser) visitCallIndexInternal(expr *exprpb.Expr, op string) error { c := expr.GetCallExpr() args := c.GetArgs() nested := isBinaryOrTernaryOperator(args[0]) @@ -225,7 +239,7 @@ func (un *unparser) visitCallIndex(expr *exprpb.Expr) error { if err != nil { return err } - un.str.WriteString("[") + un.str.WriteString(op) err = un.visit(args[1]) if err != nil { return err @@ -262,6 +276,9 @@ func (un *unparser) visitConst(expr *exprpb.Expr) error { // represent the float using the minimum required digits d := strconv.FormatFloat(c.GetDoubleValue(), 'g', -1, 64) un.str.WriteString(d) + if !strings.Contains(d, ".") { + un.str.WriteString(".0") + } case *exprpb.Constant_Int64Value: i := strconv.FormatInt(c.GetInt64Value(), 10) un.str.WriteString(i) @@ -289,8 +306,15 @@ func (un *unparser) visitIdent(expr *exprpb.Expr) error { func (un *unparser) visitList(expr *exprpb.Expr) error { l := expr.GetListExpr() elems := l.GetElements() + optIndices := make(map[int]bool, len(elems)) + for _, idx := range l.GetOptionalIndices() { + optIndices[int(idx)] = true + } un.str.WriteString("[") for i, elem := range elems { + if optIndices[i] { + un.str.WriteString("?") + } err := un.visit(elem) if err != nil { return err @@ -303,20 +327,32 @@ func (un *unparser) visitList(expr *exprpb.Expr) error { return nil } +func (un *unparser) visitOptSelect(expr *exprpb.Expr) error { + c := expr.GetCallExpr() + args := c.GetArgs() + operand := args[0] + field := args[1].GetConstExpr().GetStringValue() + return un.visitSelectInternal(operand, false, ".?", field) +} + func (un *unparser) visitSelect(expr *exprpb.Expr) error { sel := expr.GetSelectExpr() + return un.visitSelectInternal(sel.GetOperand(), sel.GetTestOnly(), ".", sel.GetField()) +} + +func (un *unparser) visitSelectInternal(operand *exprpb.Expr, testOnly bool, op string, field string) error { // handle the case when the select expression was generated by the has() macro. - if sel.GetTestOnly() { + if testOnly { un.str.WriteString("has(") } - nested := !sel.GetTestOnly() && isBinaryOrTernaryOperator(sel.GetOperand()) - err := un.visitMaybeNested(sel.GetOperand(), nested) + nested := !testOnly && isBinaryOrTernaryOperator(operand) + err := un.visitMaybeNested(operand, nested) if err != nil { return err } - un.str.WriteString(".") - un.str.WriteString(sel.GetField()) - if sel.GetTestOnly() { + un.str.WriteString(op) + un.str.WriteString(field) + if testOnly { un.str.WriteString(")") } return nil @@ -339,6 +375,9 @@ func (un *unparser) visitStructMsg(expr *exprpb.Expr) error { un.str.WriteString("{") for i, entry := range entries { f := entry.GetFieldKey() + if entry.GetOptionalEntry() { + un.str.WriteString("?") + } un.str.WriteString(f) un.str.WriteString(": ") v := entry.GetValue() @@ -360,6 +399,9 @@ func (un *unparser) visitStructMap(expr *exprpb.Expr) error { un.str.WriteString("{") for i, entry := range entries { k := entry.GetMapKey() + if entry.GetOptionalEntry() { + un.str.WriteString("?") + } err := un.visit(k) if err != nil { return err diff --git a/vendor/golang.org/x/exp/LICENSE b/vendor/golang.org/x/exp/LICENSE new file mode 100644 index 000000000..6a66aea5e --- /dev/null +++ b/vendor/golang.org/x/exp/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/exp/PATENTS b/vendor/golang.org/x/exp/PATENTS new file mode 100644 index 000000000..733099041 --- /dev/null +++ b/vendor/golang.org/x/exp/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/exp/constraints/constraints.go b/vendor/golang.org/x/exp/constraints/constraints.go new file mode 100644 index 000000000..2c033dff4 --- /dev/null +++ b/vendor/golang.org/x/exp/constraints/constraints.go @@ -0,0 +1,50 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package constraints defines a set of useful constraints to be used +// with type parameters. +package constraints + +// Signed is a constraint that permits any signed integer type. +// If future releases of Go add new predeclared signed integer types, +// this constraint will be modified to include them. +type Signed interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 +} + +// Unsigned is a constraint that permits any unsigned integer type. +// If future releases of Go add new predeclared unsigned integer types, +// this constraint will be modified to include them. +type Unsigned interface { + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr +} + +// Integer is a constraint that permits any integer type. +// If future releases of Go add new predeclared integer types, +// this constraint will be modified to include them. +type Integer interface { + Signed | Unsigned +} + +// Float is a constraint that permits any floating-point type. +// If future releases of Go add new predeclared floating-point types, +// this constraint will be modified to include them. +type Float interface { + ~float32 | ~float64 +} + +// Complex is a constraint that permits any complex numeric type. +// If future releases of Go add new predeclared complex numeric types, +// this constraint will be modified to include them. +type Complex interface { + ~complex64 | ~complex128 +} + +// Ordered is a constraint that permits any ordered type: any type +// that supports the operators < <= >= >. +// If future releases of Go add new ordered types, +// this constraint will be modified to include them. +type Ordered interface { + Integer | Float | ~string +} diff --git a/vendor/golang.org/x/exp/slices/slices.go b/vendor/golang.org/x/exp/slices/slices.go new file mode 100644 index 000000000..8a237c5d6 --- /dev/null +++ b/vendor/golang.org/x/exp/slices/slices.go @@ -0,0 +1,218 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package slices defines various functions useful with slices of any type. +// Unless otherwise specified, these functions all apply to the elements +// of a slice at index 0 <= i < len(s). +// +// Note that the less function in IsSortedFunc, SortFunc, SortStableFunc requires a +// strict weak ordering (https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings), +// or the sorting may fail to sort correctly. A common case is when sorting slices of +// floating-point numbers containing NaN values. +package slices + +import "golang.org/x/exp/constraints" + +// Equal reports whether two slices are equal: the same length and all +// elements equal. If the lengths are different, Equal returns false. +// Otherwise, the elements are compared in increasing index order, and the +// comparison stops at the first unequal pair. +// Floating point NaNs are not considered equal. +func Equal[E comparable](s1, s2 []E) bool { + if len(s1) != len(s2) { + return false + } + for i := range s1 { + if s1[i] != s2[i] { + return false + } + } + return true +} + +// EqualFunc reports whether two slices are equal using a comparison +// function on each pair of elements. If the lengths are different, +// EqualFunc returns false. Otherwise, the elements are compared in +// increasing index order, and the comparison stops at the first index +// for which eq returns false. +func EqualFunc[E1, E2 any](s1 []E1, s2 []E2, eq func(E1, E2) bool) bool { + if len(s1) != len(s2) { + return false + } + for i, v1 := range s1 { + v2 := s2[i] + if !eq(v1, v2) { + return false + } + } + return true +} + +// Compare compares the elements of s1 and s2. +// The elements are compared sequentially, starting at index 0, +// until one element is not equal to the other. +// The result of comparing the first non-matching elements is returned. +// If both slices are equal until one of them ends, the shorter slice is +// considered less than the longer one. +// The result is 0 if s1 == s2, -1 if s1 < s2, and +1 if s1 > s2. +// Comparisons involving floating point NaNs are ignored. +func Compare[E constraints.Ordered](s1, s2 []E) int { + s2len := len(s2) + for i, v1 := range s1 { + if i >= s2len { + return +1 + } + v2 := s2[i] + switch { + case v1 < v2: + return -1 + case v1 > v2: + return +1 + } + } + if len(s1) < s2len { + return -1 + } + return 0 +} + +// CompareFunc is like Compare but uses a comparison function +// on each pair of elements. The elements are compared in increasing +// index order, and the comparisons stop after the first time cmp +// returns non-zero. +// The result is the first non-zero result of cmp; if cmp always +// returns 0 the result is 0 if len(s1) == len(s2), -1 if len(s1) < len(s2), +// and +1 if len(s1) > len(s2). +func CompareFunc[E1, E2 any](s1 []E1, s2 []E2, cmp func(E1, E2) int) int { + s2len := len(s2) + for i, v1 := range s1 { + if i >= s2len { + return +1 + } + v2 := s2[i] + if c := cmp(v1, v2); c != 0 { + return c + } + } + if len(s1) < s2len { + return -1 + } + return 0 +} + +// Index returns the index of the first occurrence of v in s, +// or -1 if not present. +func Index[E comparable](s []E, v E) int { + for i, vs := range s { + if v == vs { + return i + } + } + return -1 +} + +// IndexFunc returns the first index i satisfying f(s[i]), +// or -1 if none do. +func IndexFunc[E any](s []E, f func(E) bool) int { + for i, v := range s { + if f(v) { + return i + } + } + return -1 +} + +// Contains reports whether v is present in s. +func Contains[E comparable](s []E, v E) bool { + return Index(s, v) >= 0 +} + +// Insert inserts the values v... into s at index i, +// returning the modified slice. +// In the returned slice r, r[i] == v[0]. +// Insert panics if i is out of range. +// This function is O(len(s) + len(v)). +func Insert[S ~[]E, E any](s S, i int, v ...E) S { + tot := len(s) + len(v) + if tot <= cap(s) { + s2 := s[:tot] + copy(s2[i+len(v):], s[i:]) + copy(s2[i:], v) + return s2 + } + s2 := make(S, tot) + copy(s2, s[:i]) + copy(s2[i:], v) + copy(s2[i+len(v):], s[i:]) + return s2 +} + +// Delete removes the elements s[i:j] from s, returning the modified slice. +// Delete panics if s[i:j] is not a valid slice of s. +// Delete modifies the contents of the slice s; it does not create a new slice. +// Delete is O(len(s)-(j-i)), so if many items must be deleted, it is better to +// make a single call deleting them all together than to delete one at a time. +func Delete[S ~[]E, E any](s S, i, j int) S { + return append(s[:i], s[j:]...) +} + +// Clone returns a copy of the slice. +// The elements are copied using assignment, so this is a shallow clone. +func Clone[S ~[]E, E any](s S) S { + // Preserve nil in case it matters. + if s == nil { + return nil + } + return append(S([]E{}), s...) +} + +// Compact replaces consecutive runs of equal elements with a single copy. +// This is like the uniq command found on Unix. +// Compact modifies the contents of the slice s; it does not create a new slice. +func Compact[S ~[]E, E comparable](s S) S { + if len(s) == 0 { + return s + } + i := 1 + last := s[0] + for _, v := range s[1:] { + if v != last { + s[i] = v + i++ + last = v + } + } + return s[:i] +} + +// CompactFunc is like Compact but uses a comparison function. +func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S { + if len(s) == 0 { + return s + } + i := 1 + last := s[0] + for _, v := range s[1:] { + if !eq(v, last) { + s[i] = v + i++ + last = v + } + } + return s[:i] +} + +// Grow increases the slice's capacity, if necessary, to guarantee space for +// another n elements. After Grow(n), at least n elements can be appended +// to the slice without another allocation. Grow may modify elements of the +// slice between the length and the capacity. If n is negative or too large to +// allocate the memory, Grow panics. +func Grow[S ~[]E, E any](s S, n int) S { + return append(s, make(S, n)...)[:len(s)] +} + +// Clip removes unused capacity from the slice, returning s[:len(s):len(s)]. +func Clip[S ~[]E, E any](s S) S { + return s[:len(s):len(s)] +} diff --git a/vendor/golang.org/x/exp/slices/sort.go b/vendor/golang.org/x/exp/slices/sort.go new file mode 100644 index 000000000..c22e74bd1 --- /dev/null +++ b/vendor/golang.org/x/exp/slices/sort.go @@ -0,0 +1,127 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package slices + +import ( + "math/bits" + + "golang.org/x/exp/constraints" +) + +// Sort sorts a slice of any ordered type in ascending order. +// Sort may fail to sort correctly when sorting slices of floating-point +// numbers containing Not-a-number (NaN) values. +// Use slices.SortFunc(x, func(a, b float64) bool {return a < b || (math.IsNaN(a) && !math.IsNaN(b))}) +// instead if the input may contain NaNs. +func Sort[E constraints.Ordered](x []E) { + n := len(x) + pdqsortOrdered(x, 0, n, bits.Len(uint(n))) +} + +// SortFunc sorts the slice x in ascending order as determined by the less function. +// This sort is not guaranteed to be stable. +// +// SortFunc requires that less is a strict weak ordering. +// See https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings. +func SortFunc[E any](x []E, less func(a, b E) bool) { + n := len(x) + pdqsortLessFunc(x, 0, n, bits.Len(uint(n)), less) +} + +// SortStable sorts the slice x while keeping the original order of equal +// elements, using less to compare elements. +func SortStableFunc[E any](x []E, less func(a, b E) bool) { + stableLessFunc(x, len(x), less) +} + +// IsSorted reports whether x is sorted in ascending order. +func IsSorted[E constraints.Ordered](x []E) bool { + for i := len(x) - 1; i > 0; i-- { + if x[i] < x[i-1] { + return false + } + } + return true +} + +// IsSortedFunc reports whether x is sorted in ascending order, with less as the +// comparison function. +func IsSortedFunc[E any](x []E, less func(a, b E) bool) bool { + for i := len(x) - 1; i > 0; i-- { + if less(x[i], x[i-1]) { + return false + } + } + return true +} + +// BinarySearch searches for target in a sorted slice and returns the position +// where target is found, or the position where target would appear in the +// sort order; it also returns a bool saying whether the target is really found +// in the slice. The slice must be sorted in increasing order. +func BinarySearch[E constraints.Ordered](x []E, target E) (int, bool) { + // search returns the leftmost position where f returns true, or len(x) if f + // returns false for all x. This is the insertion position for target in x, + // and could point to an element that's either == target or not. + pos := search(len(x), func(i int) bool { return x[i] >= target }) + if pos >= len(x) || x[pos] != target { + return pos, false + } else { + return pos, true + } +} + +// BinarySearchFunc works like BinarySearch, but uses a custom comparison +// function. The slice must be sorted in increasing order, where "increasing" is +// defined by cmp. cmp(a, b) is expected to return an integer comparing the two +// parameters: 0 if a == b, a negative number if a < b and a positive number if +// a > b. +func BinarySearchFunc[E any](x []E, target E, cmp func(E, E) int) (int, bool) { + pos := search(len(x), func(i int) bool { return cmp(x[i], target) >= 0 }) + if pos >= len(x) || cmp(x[pos], target) != 0 { + return pos, false + } else { + return pos, true + } +} + +func search(n int, f func(int) bool) int { + // Define f(-1) == false and f(n) == true. + // Invariant: f(i-1) == false, f(j) == true. + i, j := 0, n + for i < j { + h := int(uint(i+j) >> 1) // avoid overflow when computing h + // i ≤ h < j + if !f(h) { + i = h + 1 // preserves f(i-1) == false + } else { + j = h // preserves f(j) == true + } + } + // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i. + return i +} + +type sortedHint int // hint for pdqsort when choosing the pivot + +const ( + unknownHint sortedHint = iota + increasingHint + decreasingHint +) + +// xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf +type xorshift uint64 + +func (r *xorshift) Next() uint64 { + *r ^= *r << 13 + *r ^= *r >> 17 + *r ^= *r << 5 + return uint64(*r) +} + +func nextPowerOfTwo(length int) uint { + return 1 << bits.Len(uint(length)) +} diff --git a/vendor/golang.org/x/exp/slices/zsortfunc.go b/vendor/golang.org/x/exp/slices/zsortfunc.go new file mode 100644 index 000000000..2a632476c --- /dev/null +++ b/vendor/golang.org/x/exp/slices/zsortfunc.go @@ -0,0 +1,479 @@ +// Code generated by gen_sort_variants.go; DO NOT EDIT. + +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package slices + +// insertionSortLessFunc sorts data[a:b] using insertion sort. +func insertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) bool) { + for i := a + 1; i < b; i++ { + for j := i; j > a && less(data[j], data[j-1]); j-- { + data[j], data[j-1] = data[j-1], data[j] + } + } +} + +// siftDownLessFunc implements the heap property on data[lo:hi]. +// first is an offset into the array where the root of the heap lies. +func siftDownLessFunc[E any](data []E, lo, hi, first int, less func(a, b E) bool) { + root := lo + for { + child := 2*root + 1 + if child >= hi { + break + } + if child+1 < hi && less(data[first+child], data[first+child+1]) { + child++ + } + if !less(data[first+root], data[first+child]) { + return + } + data[first+root], data[first+child] = data[first+child], data[first+root] + root = child + } +} + +func heapSortLessFunc[E any](data []E, a, b int, less func(a, b E) bool) { + first := a + lo := 0 + hi := b - a + + // Build heap with greatest element at top. + for i := (hi - 1) / 2; i >= 0; i-- { + siftDownLessFunc(data, i, hi, first, less) + } + + // Pop elements, largest first, into end of data. + for i := hi - 1; i >= 0; i-- { + data[first], data[first+i] = data[first+i], data[first] + siftDownLessFunc(data, lo, i, first, less) + } +} + +// pdqsortLessFunc sorts data[a:b]. +// The algorithm based on pattern-defeating quicksort(pdqsort), but without the optimizations from BlockQuicksort. +// pdqsort paper: https://arxiv.org/pdf/2106.05123.pdf +// C++ implementation: https://github.com/orlp/pdqsort +// Rust implementation: https://docs.rs/pdqsort/latest/pdqsort/ +// limit is the number of allowed bad (very unbalanced) pivots before falling back to heapsort. +func pdqsortLessFunc[E any](data []E, a, b, limit int, less func(a, b E) bool) { + const maxInsertion = 12 + + var ( + wasBalanced = true // whether the last partitioning was reasonably balanced + wasPartitioned = true // whether the slice was already partitioned + ) + + for { + length := b - a + + if length <= maxInsertion { + insertionSortLessFunc(data, a, b, less) + return + } + + // Fall back to heapsort if too many bad choices were made. + if limit == 0 { + heapSortLessFunc(data, a, b, less) + return + } + + // If the last partitioning was imbalanced, we need to breaking patterns. + if !wasBalanced { + breakPatternsLessFunc(data, a, b, less) + limit-- + } + + pivot, hint := choosePivotLessFunc(data, a, b, less) + if hint == decreasingHint { + reverseRangeLessFunc(data, a, b, less) + // The chosen pivot was pivot-a elements after the start of the array. + // After reversing it is pivot-a elements before the end of the array. + // The idea came from Rust's implementation. + pivot = (b - 1) - (pivot - a) + hint = increasingHint + } + + // The slice is likely already sorted. + if wasBalanced && wasPartitioned && hint == increasingHint { + if partialInsertionSortLessFunc(data, a, b, less) { + return + } + } + + // Probably the slice contains many duplicate elements, partition the slice into + // elements equal to and elements greater than the pivot. + if a > 0 && !less(data[a-1], data[pivot]) { + mid := partitionEqualLessFunc(data, a, b, pivot, less) + a = mid + continue + } + + mid, alreadyPartitioned := partitionLessFunc(data, a, b, pivot, less) + wasPartitioned = alreadyPartitioned + + leftLen, rightLen := mid-a, b-mid + balanceThreshold := length / 8 + if leftLen < rightLen { + wasBalanced = leftLen >= balanceThreshold + pdqsortLessFunc(data, a, mid, limit, less) + a = mid + 1 + } else { + wasBalanced = rightLen >= balanceThreshold + pdqsortLessFunc(data, mid+1, b, limit, less) + b = mid + } + } +} + +// partitionLessFunc does one quicksort partition. +// Let p = data[pivot] +// Moves elements in data[a:b] around, so that data[i]

    =p for inewpivot. +// On return, data[newpivot] = p +func partitionLessFunc[E any](data []E, a, b, pivot int, less func(a, b E) bool) (newpivot int, alreadyPartitioned bool) { + data[a], data[pivot] = data[pivot], data[a] + i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned + + for i <= j && less(data[i], data[a]) { + i++ + } + for i <= j && !less(data[j], data[a]) { + j-- + } + if i > j { + data[j], data[a] = data[a], data[j] + return j, true + } + data[i], data[j] = data[j], data[i] + i++ + j-- + + for { + for i <= j && less(data[i], data[a]) { + i++ + } + for i <= j && !less(data[j], data[a]) { + j-- + } + if i > j { + break + } + data[i], data[j] = data[j], data[i] + i++ + j-- + } + data[j], data[a] = data[a], data[j] + return j, false +} + +// partitionEqualLessFunc partitions data[a:b] into elements equal to data[pivot] followed by elements greater than data[pivot]. +// It assumed that data[a:b] does not contain elements smaller than the data[pivot]. +func partitionEqualLessFunc[E any](data []E, a, b, pivot int, less func(a, b E) bool) (newpivot int) { + data[a], data[pivot] = data[pivot], data[a] + i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned + + for { + for i <= j && !less(data[a], data[i]) { + i++ + } + for i <= j && less(data[a], data[j]) { + j-- + } + if i > j { + break + } + data[i], data[j] = data[j], data[i] + i++ + j-- + } + return i +} + +// partialInsertionSortLessFunc partially sorts a slice, returns true if the slice is sorted at the end. +func partialInsertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) bool) bool { + const ( + maxSteps = 5 // maximum number of adjacent out-of-order pairs that will get shifted + shortestShifting = 50 // don't shift any elements on short arrays + ) + i := a + 1 + for j := 0; j < maxSteps; j++ { + for i < b && !less(data[i], data[i-1]) { + i++ + } + + if i == b { + return true + } + + if b-a < shortestShifting { + return false + } + + data[i], data[i-1] = data[i-1], data[i] + + // Shift the smaller one to the left. + if i-a >= 2 { + for j := i - 1; j >= 1; j-- { + if !less(data[j], data[j-1]) { + break + } + data[j], data[j-1] = data[j-1], data[j] + } + } + // Shift the greater one to the right. + if b-i >= 2 { + for j := i + 1; j < b; j++ { + if !less(data[j], data[j-1]) { + break + } + data[j], data[j-1] = data[j-1], data[j] + } + } + } + return false +} + +// breakPatternsLessFunc scatters some elements around in an attempt to break some patterns +// that might cause imbalanced partitions in quicksort. +func breakPatternsLessFunc[E any](data []E, a, b int, less func(a, b E) bool) { + length := b - a + if length >= 8 { + random := xorshift(length) + modulus := nextPowerOfTwo(length) + + for idx := a + (length/4)*2 - 1; idx <= a+(length/4)*2+1; idx++ { + other := int(uint(random.Next()) & (modulus - 1)) + if other >= length { + other -= length + } + data[idx], data[a+other] = data[a+other], data[idx] + } + } +} + +// choosePivotLessFunc chooses a pivot in data[a:b]. +// +// [0,8): chooses a static pivot. +// [8,shortestNinther): uses the simple median-of-three method. +// [shortestNinther,∞): uses the Tukey ninther method. +func choosePivotLessFunc[E any](data []E, a, b int, less func(a, b E) bool) (pivot int, hint sortedHint) { + const ( + shortestNinther = 50 + maxSwaps = 4 * 3 + ) + + l := b - a + + var ( + swaps int + i = a + l/4*1 + j = a + l/4*2 + k = a + l/4*3 + ) + + if l >= 8 { + if l >= shortestNinther { + // Tukey ninther method, the idea came from Rust's implementation. + i = medianAdjacentLessFunc(data, i, &swaps, less) + j = medianAdjacentLessFunc(data, j, &swaps, less) + k = medianAdjacentLessFunc(data, k, &swaps, less) + } + // Find the median among i, j, k and stores it into j. + j = medianLessFunc(data, i, j, k, &swaps, less) + } + + switch swaps { + case 0: + return j, increasingHint + case maxSwaps: + return j, decreasingHint + default: + return j, unknownHint + } +} + +// order2LessFunc returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a. +func order2LessFunc[E any](data []E, a, b int, swaps *int, less func(a, b E) bool) (int, int) { + if less(data[b], data[a]) { + *swaps++ + return b, a + } + return a, b +} + +// medianLessFunc returns x where data[x] is the median of data[a],data[b],data[c], where x is a, b, or c. +func medianLessFunc[E any](data []E, a, b, c int, swaps *int, less func(a, b E) bool) int { + a, b = order2LessFunc(data, a, b, swaps, less) + b, c = order2LessFunc(data, b, c, swaps, less) + a, b = order2LessFunc(data, a, b, swaps, less) + return b +} + +// medianAdjacentLessFunc finds the median of data[a - 1], data[a], data[a + 1] and stores the index into a. +func medianAdjacentLessFunc[E any](data []E, a int, swaps *int, less func(a, b E) bool) int { + return medianLessFunc(data, a-1, a, a+1, swaps, less) +} + +func reverseRangeLessFunc[E any](data []E, a, b int, less func(a, b E) bool) { + i := a + j := b - 1 + for i < j { + data[i], data[j] = data[j], data[i] + i++ + j-- + } +} + +func swapRangeLessFunc[E any](data []E, a, b, n int, less func(a, b E) bool) { + for i := 0; i < n; i++ { + data[a+i], data[b+i] = data[b+i], data[a+i] + } +} + +func stableLessFunc[E any](data []E, n int, less func(a, b E) bool) { + blockSize := 20 // must be > 0 + a, b := 0, blockSize + for b <= n { + insertionSortLessFunc(data, a, b, less) + a = b + b += blockSize + } + insertionSortLessFunc(data, a, n, less) + + for blockSize < n { + a, b = 0, 2*blockSize + for b <= n { + symMergeLessFunc(data, a, a+blockSize, b, less) + a = b + b += 2 * blockSize + } + if m := a + blockSize; m < n { + symMergeLessFunc(data, a, m, n, less) + } + blockSize *= 2 + } +} + +// symMergeLessFunc merges the two sorted subsequences data[a:m] and data[m:b] using +// the SymMerge algorithm from Pok-Son Kim and Arne Kutzner, "Stable Minimum +// Storage Merging by Symmetric Comparisons", in Susanne Albers and Tomasz +// Radzik, editors, Algorithms - ESA 2004, volume 3221 of Lecture Notes in +// Computer Science, pages 714-723. Springer, 2004. +// +// Let M = m-a and N = b-n. Wolog M < N. +// The recursion depth is bound by ceil(log(N+M)). +// The algorithm needs O(M*log(N/M + 1)) calls to data.Less. +// The algorithm needs O((M+N)*log(M)) calls to data.Swap. +// +// The paper gives O((M+N)*log(M)) as the number of assignments assuming a +// rotation algorithm which uses O(M+N+gcd(M+N)) assignments. The argumentation +// in the paper carries through for Swap operations, especially as the block +// swapping rotate uses only O(M+N) Swaps. +// +// symMerge assumes non-degenerate arguments: a < m && m < b. +// Having the caller check this condition eliminates many leaf recursion calls, +// which improves performance. +func symMergeLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) { + // Avoid unnecessary recursions of symMerge + // by direct insertion of data[a] into data[m:b] + // if data[a:m] only contains one element. + if m-a == 1 { + // Use binary search to find the lowest index i + // such that data[i] >= data[a] for m <= i < b. + // Exit the search loop with i == b in case no such index exists. + i := m + j := b + for i < j { + h := int(uint(i+j) >> 1) + if less(data[h], data[a]) { + i = h + 1 + } else { + j = h + } + } + // Swap values until data[a] reaches the position before i. + for k := a; k < i-1; k++ { + data[k], data[k+1] = data[k+1], data[k] + } + return + } + + // Avoid unnecessary recursions of symMerge + // by direct insertion of data[m] into data[a:m] + // if data[m:b] only contains one element. + if b-m == 1 { + // Use binary search to find the lowest index i + // such that data[i] > data[m] for a <= i < m. + // Exit the search loop with i == m in case no such index exists. + i := a + j := m + for i < j { + h := int(uint(i+j) >> 1) + if !less(data[m], data[h]) { + i = h + 1 + } else { + j = h + } + } + // Swap values until data[m] reaches the position i. + for k := m; k > i; k-- { + data[k], data[k-1] = data[k-1], data[k] + } + return + } + + mid := int(uint(a+b) >> 1) + n := mid + m + var start, r int + if m > mid { + start = n - b + r = mid + } else { + start = a + r = m + } + p := n - 1 + + for start < r { + c := int(uint(start+r) >> 1) + if !less(data[p-c], data[c]) { + start = c + 1 + } else { + r = c + } + } + + end := n - start + if start < m && m < end { + rotateLessFunc(data, start, m, end, less) + } + if a < start && start < mid { + symMergeLessFunc(data, a, start, mid, less) + } + if mid < end && end < b { + symMergeLessFunc(data, mid, end, b, less) + } +} + +// rotateLessFunc rotates two consecutive blocks u = data[a:m] and v = data[m:b] in data: +// Data of the form 'x u v y' is changed to 'x v u y'. +// rotate performs at most b-a many calls to data.Swap, +// and it assumes non-degenerate arguments: a < m && m < b. +func rotateLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) { + i := m - a + j := b - m + + for i != j { + if i > j { + swapRangeLessFunc(data, m-i, m, j, less) + i -= j + } else { + swapRangeLessFunc(data, m-i, m+j-i, i, less) + j -= i + } + } + // i == j + swapRangeLessFunc(data, m-i, m, i, less) +} diff --git a/vendor/golang.org/x/exp/slices/zsortordered.go b/vendor/golang.org/x/exp/slices/zsortordered.go new file mode 100644 index 000000000..efaa1c8b7 --- /dev/null +++ b/vendor/golang.org/x/exp/slices/zsortordered.go @@ -0,0 +1,481 @@ +// Code generated by gen_sort_variants.go; DO NOT EDIT. + +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package slices + +import "golang.org/x/exp/constraints" + +// insertionSortOrdered sorts data[a:b] using insertion sort. +func insertionSortOrdered[E constraints.Ordered](data []E, a, b int) { + for i := a + 1; i < b; i++ { + for j := i; j > a && (data[j] < data[j-1]); j-- { + data[j], data[j-1] = data[j-1], data[j] + } + } +} + +// siftDownOrdered implements the heap property on data[lo:hi]. +// first is an offset into the array where the root of the heap lies. +func siftDownOrdered[E constraints.Ordered](data []E, lo, hi, first int) { + root := lo + for { + child := 2*root + 1 + if child >= hi { + break + } + if child+1 < hi && (data[first+child] < data[first+child+1]) { + child++ + } + if !(data[first+root] < data[first+child]) { + return + } + data[first+root], data[first+child] = data[first+child], data[first+root] + root = child + } +} + +func heapSortOrdered[E constraints.Ordered](data []E, a, b int) { + first := a + lo := 0 + hi := b - a + + // Build heap with greatest element at top. + for i := (hi - 1) / 2; i >= 0; i-- { + siftDownOrdered(data, i, hi, first) + } + + // Pop elements, largest first, into end of data. + for i := hi - 1; i >= 0; i-- { + data[first], data[first+i] = data[first+i], data[first] + siftDownOrdered(data, lo, i, first) + } +} + +// pdqsortOrdered sorts data[a:b]. +// The algorithm based on pattern-defeating quicksort(pdqsort), but without the optimizations from BlockQuicksort. +// pdqsort paper: https://arxiv.org/pdf/2106.05123.pdf +// C++ implementation: https://github.com/orlp/pdqsort +// Rust implementation: https://docs.rs/pdqsort/latest/pdqsort/ +// limit is the number of allowed bad (very unbalanced) pivots before falling back to heapsort. +func pdqsortOrdered[E constraints.Ordered](data []E, a, b, limit int) { + const maxInsertion = 12 + + var ( + wasBalanced = true // whether the last partitioning was reasonably balanced + wasPartitioned = true // whether the slice was already partitioned + ) + + for { + length := b - a + + if length <= maxInsertion { + insertionSortOrdered(data, a, b) + return + } + + // Fall back to heapsort if too many bad choices were made. + if limit == 0 { + heapSortOrdered(data, a, b) + return + } + + // If the last partitioning was imbalanced, we need to breaking patterns. + if !wasBalanced { + breakPatternsOrdered(data, a, b) + limit-- + } + + pivot, hint := choosePivotOrdered(data, a, b) + if hint == decreasingHint { + reverseRangeOrdered(data, a, b) + // The chosen pivot was pivot-a elements after the start of the array. + // After reversing it is pivot-a elements before the end of the array. + // The idea came from Rust's implementation. + pivot = (b - 1) - (pivot - a) + hint = increasingHint + } + + // The slice is likely already sorted. + if wasBalanced && wasPartitioned && hint == increasingHint { + if partialInsertionSortOrdered(data, a, b) { + return + } + } + + // Probably the slice contains many duplicate elements, partition the slice into + // elements equal to and elements greater than the pivot. + if a > 0 && !(data[a-1] < data[pivot]) { + mid := partitionEqualOrdered(data, a, b, pivot) + a = mid + continue + } + + mid, alreadyPartitioned := partitionOrdered(data, a, b, pivot) + wasPartitioned = alreadyPartitioned + + leftLen, rightLen := mid-a, b-mid + balanceThreshold := length / 8 + if leftLen < rightLen { + wasBalanced = leftLen >= balanceThreshold + pdqsortOrdered(data, a, mid, limit) + a = mid + 1 + } else { + wasBalanced = rightLen >= balanceThreshold + pdqsortOrdered(data, mid+1, b, limit) + b = mid + } + } +} + +// partitionOrdered does one quicksort partition. +// Let p = data[pivot] +// Moves elements in data[a:b] around, so that data[i]

    =p for inewpivot. +// On return, data[newpivot] = p +func partitionOrdered[E constraints.Ordered](data []E, a, b, pivot int) (newpivot int, alreadyPartitioned bool) { + data[a], data[pivot] = data[pivot], data[a] + i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned + + for i <= j && (data[i] < data[a]) { + i++ + } + for i <= j && !(data[j] < data[a]) { + j-- + } + if i > j { + data[j], data[a] = data[a], data[j] + return j, true + } + data[i], data[j] = data[j], data[i] + i++ + j-- + + for { + for i <= j && (data[i] < data[a]) { + i++ + } + for i <= j && !(data[j] < data[a]) { + j-- + } + if i > j { + break + } + data[i], data[j] = data[j], data[i] + i++ + j-- + } + data[j], data[a] = data[a], data[j] + return j, false +} + +// partitionEqualOrdered partitions data[a:b] into elements equal to data[pivot] followed by elements greater than data[pivot]. +// It assumed that data[a:b] does not contain elements smaller than the data[pivot]. +func partitionEqualOrdered[E constraints.Ordered](data []E, a, b, pivot int) (newpivot int) { + data[a], data[pivot] = data[pivot], data[a] + i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned + + for { + for i <= j && !(data[a] < data[i]) { + i++ + } + for i <= j && (data[a] < data[j]) { + j-- + } + if i > j { + break + } + data[i], data[j] = data[j], data[i] + i++ + j-- + } + return i +} + +// partialInsertionSortOrdered partially sorts a slice, returns true if the slice is sorted at the end. +func partialInsertionSortOrdered[E constraints.Ordered](data []E, a, b int) bool { + const ( + maxSteps = 5 // maximum number of adjacent out-of-order pairs that will get shifted + shortestShifting = 50 // don't shift any elements on short arrays + ) + i := a + 1 + for j := 0; j < maxSteps; j++ { + for i < b && !(data[i] < data[i-1]) { + i++ + } + + if i == b { + return true + } + + if b-a < shortestShifting { + return false + } + + data[i], data[i-1] = data[i-1], data[i] + + // Shift the smaller one to the left. + if i-a >= 2 { + for j := i - 1; j >= 1; j-- { + if !(data[j] < data[j-1]) { + break + } + data[j], data[j-1] = data[j-1], data[j] + } + } + // Shift the greater one to the right. + if b-i >= 2 { + for j := i + 1; j < b; j++ { + if !(data[j] < data[j-1]) { + break + } + data[j], data[j-1] = data[j-1], data[j] + } + } + } + return false +} + +// breakPatternsOrdered scatters some elements around in an attempt to break some patterns +// that might cause imbalanced partitions in quicksort. +func breakPatternsOrdered[E constraints.Ordered](data []E, a, b int) { + length := b - a + if length >= 8 { + random := xorshift(length) + modulus := nextPowerOfTwo(length) + + for idx := a + (length/4)*2 - 1; idx <= a+(length/4)*2+1; idx++ { + other := int(uint(random.Next()) & (modulus - 1)) + if other >= length { + other -= length + } + data[idx], data[a+other] = data[a+other], data[idx] + } + } +} + +// choosePivotOrdered chooses a pivot in data[a:b]. +// +// [0,8): chooses a static pivot. +// [8,shortestNinther): uses the simple median-of-three method. +// [shortestNinther,∞): uses the Tukey ninther method. +func choosePivotOrdered[E constraints.Ordered](data []E, a, b int) (pivot int, hint sortedHint) { + const ( + shortestNinther = 50 + maxSwaps = 4 * 3 + ) + + l := b - a + + var ( + swaps int + i = a + l/4*1 + j = a + l/4*2 + k = a + l/4*3 + ) + + if l >= 8 { + if l >= shortestNinther { + // Tukey ninther method, the idea came from Rust's implementation. + i = medianAdjacentOrdered(data, i, &swaps) + j = medianAdjacentOrdered(data, j, &swaps) + k = medianAdjacentOrdered(data, k, &swaps) + } + // Find the median among i, j, k and stores it into j. + j = medianOrdered(data, i, j, k, &swaps) + } + + switch swaps { + case 0: + return j, increasingHint + case maxSwaps: + return j, decreasingHint + default: + return j, unknownHint + } +} + +// order2Ordered returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a. +func order2Ordered[E constraints.Ordered](data []E, a, b int, swaps *int) (int, int) { + if data[b] < data[a] { + *swaps++ + return b, a + } + return a, b +} + +// medianOrdered returns x where data[x] is the median of data[a],data[b],data[c], where x is a, b, or c. +func medianOrdered[E constraints.Ordered](data []E, a, b, c int, swaps *int) int { + a, b = order2Ordered(data, a, b, swaps) + b, c = order2Ordered(data, b, c, swaps) + a, b = order2Ordered(data, a, b, swaps) + return b +} + +// medianAdjacentOrdered finds the median of data[a - 1], data[a], data[a + 1] and stores the index into a. +func medianAdjacentOrdered[E constraints.Ordered](data []E, a int, swaps *int) int { + return medianOrdered(data, a-1, a, a+1, swaps) +} + +func reverseRangeOrdered[E constraints.Ordered](data []E, a, b int) { + i := a + j := b - 1 + for i < j { + data[i], data[j] = data[j], data[i] + i++ + j-- + } +} + +func swapRangeOrdered[E constraints.Ordered](data []E, a, b, n int) { + for i := 0; i < n; i++ { + data[a+i], data[b+i] = data[b+i], data[a+i] + } +} + +func stableOrdered[E constraints.Ordered](data []E, n int) { + blockSize := 20 // must be > 0 + a, b := 0, blockSize + for b <= n { + insertionSortOrdered(data, a, b) + a = b + b += blockSize + } + insertionSortOrdered(data, a, n) + + for blockSize < n { + a, b = 0, 2*blockSize + for b <= n { + symMergeOrdered(data, a, a+blockSize, b) + a = b + b += 2 * blockSize + } + if m := a + blockSize; m < n { + symMergeOrdered(data, a, m, n) + } + blockSize *= 2 + } +} + +// symMergeOrdered merges the two sorted subsequences data[a:m] and data[m:b] using +// the SymMerge algorithm from Pok-Son Kim and Arne Kutzner, "Stable Minimum +// Storage Merging by Symmetric Comparisons", in Susanne Albers and Tomasz +// Radzik, editors, Algorithms - ESA 2004, volume 3221 of Lecture Notes in +// Computer Science, pages 714-723. Springer, 2004. +// +// Let M = m-a and N = b-n. Wolog M < N. +// The recursion depth is bound by ceil(log(N+M)). +// The algorithm needs O(M*log(N/M + 1)) calls to data.Less. +// The algorithm needs O((M+N)*log(M)) calls to data.Swap. +// +// The paper gives O((M+N)*log(M)) as the number of assignments assuming a +// rotation algorithm which uses O(M+N+gcd(M+N)) assignments. The argumentation +// in the paper carries through for Swap operations, especially as the block +// swapping rotate uses only O(M+N) Swaps. +// +// symMerge assumes non-degenerate arguments: a < m && m < b. +// Having the caller check this condition eliminates many leaf recursion calls, +// which improves performance. +func symMergeOrdered[E constraints.Ordered](data []E, a, m, b int) { + // Avoid unnecessary recursions of symMerge + // by direct insertion of data[a] into data[m:b] + // if data[a:m] only contains one element. + if m-a == 1 { + // Use binary search to find the lowest index i + // such that data[i] >= data[a] for m <= i < b. + // Exit the search loop with i == b in case no such index exists. + i := m + j := b + for i < j { + h := int(uint(i+j) >> 1) + if data[h] < data[a] { + i = h + 1 + } else { + j = h + } + } + // Swap values until data[a] reaches the position before i. + for k := a; k < i-1; k++ { + data[k], data[k+1] = data[k+1], data[k] + } + return + } + + // Avoid unnecessary recursions of symMerge + // by direct insertion of data[m] into data[a:m] + // if data[m:b] only contains one element. + if b-m == 1 { + // Use binary search to find the lowest index i + // such that data[i] > data[m] for a <= i < m. + // Exit the search loop with i == m in case no such index exists. + i := a + j := m + for i < j { + h := int(uint(i+j) >> 1) + if !(data[m] < data[h]) { + i = h + 1 + } else { + j = h + } + } + // Swap values until data[m] reaches the position i. + for k := m; k > i; k-- { + data[k], data[k-1] = data[k-1], data[k] + } + return + } + + mid := int(uint(a+b) >> 1) + n := mid + m + var start, r int + if m > mid { + start = n - b + r = mid + } else { + start = a + r = m + } + p := n - 1 + + for start < r { + c := int(uint(start+r) >> 1) + if !(data[p-c] < data[c]) { + start = c + 1 + } else { + r = c + } + } + + end := n - start + if start < m && m < end { + rotateOrdered(data, start, m, end) + } + if a < start && start < mid { + symMergeOrdered(data, a, start, mid) + } + if mid < end && end < b { + symMergeOrdered(data, mid, end, b) + } +} + +// rotateOrdered rotates two consecutive blocks u = data[a:m] and v = data[m:b] in data: +// Data of the form 'x u v y' is changed to 'x v u y'. +// rotate performs at most b-a many calls to data.Swap, +// and it assumes non-degenerate arguments: a < m && m < b. +func rotateOrdered[E constraints.Ordered](data []E, a, m, b int) { + i := m - a + j := b - m + + for i != j { + if i > j { + swapRangeOrdered(data, m-i, m, j) + i -= j + } else { + swapRangeOrdered(data, m-i, m+j-i, i) + j -= i + } + } + // i == j + swapRangeOrdered(data, m-i, m, i) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 7b902919b..fcc104f39 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -63,9 +63,9 @@ github.com/Azure/go-autorest/logger # github.com/Azure/go-autorest/tracing v0.6.0 ## explicit; go 1.12 github.com/Azure/go-autorest/tracing -# github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 -## explicit; go 1.16 -github.com/antlr/antlr4/runtime/Go/antlr +# github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df +## explicit; go 1.18 +github.com/antlr/antlr4/runtime/Go/antlr/v4 # github.com/aws/aws-sdk-go-v2 v1.20.1 ## explicit; go 1.15 github.com/aws/aws-sdk-go-v2 @@ -383,23 +383,26 @@ github.com/golang/protobuf/ptypes/timestamp # github.com/google/btree v1.1.2 ## explicit; go 1.18 github.com/google/btree -# github.com/google/cel-go v0.13.0 +# github.com/google/cel-go v0.17.6 ## explicit; go 1.18 github.com/google/cel-go/cel github.com/google/cel-go/checker github.com/google/cel-go/checker/decls github.com/google/cel-go/common +github.com/google/cel-go/common/ast github.com/google/cel-go/common/containers github.com/google/cel-go/common/debug +github.com/google/cel-go/common/decls +github.com/google/cel-go/common/functions github.com/google/cel-go/common/operators github.com/google/cel-go/common/overloads github.com/google/cel-go/common/runes +github.com/google/cel-go/common/stdlib github.com/google/cel-go/common/types github.com/google/cel-go/common/types/pb github.com/google/cel-go/common/types/ref github.com/google/cel-go/common/types/traits github.com/google/cel-go/interpreter -github.com/google/cel-go/interpreter/functions github.com/google/cel-go/parser github.com/google/cel-go/parser/gen # github.com/google/gnostic v0.6.9 @@ -1039,6 +1042,10 @@ golang.org/x/crypto/pkcs12/internal/rc2 golang.org/x/crypto/salsa20/salsa golang.org/x/crypto/scrypt golang.org/x/crypto/sha3 +# golang.org/x/exp v0.0.0-20220823124025-807a23277127 +## explicit; go 1.18 +golang.org/x/exp/constraints +golang.org/x/exp/slices # golang.org/x/net v0.14.0 ## explicit; go 1.17 golang.org/x/net/context