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