From 9ace5c13b8f667d4ee767bf7b9fb526f2da3b99f Mon Sep 17 00:00:00 2001 From: Kevin McDermott Date: Tue, 26 Nov 2019 18:18:02 +0000 Subject: [PATCH] Add an interceptor to that can filter based on CEL expressions. This adds a cel interceptor, that uses a a CEL expression to filter request bodies. This implements issue #49. --- Gopkg.lock | 49 +- Gopkg.toml | 8 +- docs/cel_expressions.md | 84 + docs/eventlisteners.md | 29 + .../cel-eventlistener-interceptor.yaml | 15 + .../triggers/v1alpha1/event_listener_types.go | 6 + .../v1alpha1/event_listener_validation.go | 9 +- .../event_listener_validation_test.go | 23 + .../v1alpha1/zz_generated.deepcopy.go | 21 + pkg/interceptors/cel/cel.go | 150 + pkg/interceptors/cel/cel_test.go | 200 + pkg/sink/sink.go | 3 + test/builder/eventlistener.go | 14 + test/builder/eventlistener_test.go | 35 + vendor/github.com/antlr/antlr4/LICENSE.txt | 52 + .../github.com/antlr/antlr4/contributors.txt | 212 + .../antlr/antlr4/runtime/Go/antlr/atn.go | 152 + .../antlr4/runtime/Go/antlr/atn_config.go | 295 ++ .../antlr4/runtime/Go/antlr/atn_config_set.go | 387 ++ .../Go/antlr/atn_deserialization_options.go | 25 + .../runtime/Go/antlr/atn_deserializer.go | 828 ++++ .../antlr4/runtime/Go/antlr/atn_simulator.go | 50 + .../antlr4/runtime/Go/antlr/atn_state.go | 386 ++ .../antlr/antlr4/runtime/Go/antlr/atn_type.go | 11 + .../antlr4/runtime/Go/antlr/char_stream.go | 12 + .../runtime/Go/antlr/common_token_factory.go | 56 + .../runtime/Go/antlr/common_token_stream.go | 447 ++ .../antlr/antlr4/runtime/Go/antlr/dfa.go | 171 + .../antlr4/runtime/Go/antlr/dfa_serializer.go | 152 + .../antlr4/runtime/Go/antlr/dfa_state.go | 166 + .../Go/antlr/diagnostic_error_listener.go | 111 + .../antlr4/runtime/Go/antlr/error_listener.go | 108 + .../antlr4/runtime/Go/antlr/error_strategy.go | 758 +++ .../antlr/antlr4/runtime/Go/antlr/errors.go | 241 + .../antlr4/runtime/Go/antlr/file_stream.go | 49 + .../antlr4/runtime/Go/antlr/input_stream.go | 113 + .../antlr4/runtime/Go/antlr/int_stream.go | 16 + .../antlr4/runtime/Go/antlr/interval_set.go | 296 ++ .../antlr/antlr4/runtime/Go/antlr/lexer.go | 417 ++ .../antlr4/runtime/Go/antlr/lexer_action.go | 431 ++ .../runtime/Go/antlr/lexer_action_executor.go | 170 + .../runtime/Go/antlr/lexer_atn_simulator.go | 658 +++ .../antlr4/runtime/Go/antlr/ll1_analyzer.go | 215 + .../antlr/antlr4/runtime/Go/antlr/parser.go | 718 +++ .../runtime/Go/antlr/parser_atn_simulator.go | 1473 ++++++ .../runtime/Go/antlr/parser_rule_context.go | 362 ++ .../runtime/Go/antlr/prediction_context.go | 756 +++ .../runtime/Go/antlr/prediction_mode.go | 553 +++ .../antlr4/runtime/Go/antlr/recognizer.go | 217 + .../antlr4/runtime/Go/antlr/rule_context.go | 114 + .../runtime/Go/antlr/semantic_context.go | 455 ++ .../antlr/antlr4/runtime/Go/antlr/token.go | 210 + .../antlr4/runtime/Go/antlr/token_source.go | 17 + .../antlr4/runtime/Go/antlr/token_stream.go | 20 + .../runtime/Go/antlr/tokenstream_rewriter.go | 649 +++ .../antlr4/runtime/Go/antlr/trace_listener.go | 32 + .../antlr4/runtime/Go/antlr/transition.go | 421 ++ .../antlr/antlr4/runtime/Go/antlr/tree.go | 251 + .../antlr/antlr4/runtime/Go/antlr/trees.go | 137 + .../antlr/antlr4/runtime/Go/antlr/utils.go | 417 ++ .../golang/protobuf/descriptor/descriptor.go | 93 + .../golang/protobuf/jsonpb/jsonpb.go | 1284 ++++++ vendor/github.com/google/cel-go/LICENSE | 202 + vendor/github.com/google/cel-go/cel/cel.go | 19 + vendor/github.com/google/cel-go/cel/env.go | 283 ++ vendor/github.com/google/cel-go/cel/io.go | 77 + .../github.com/google/cel-go/cel/options.go | 249 + .../github.com/google/cel-go/cel/program.go | 244 + .../google/cel-go/checker/checker.go | 606 +++ .../google/cel-go/checker/decls/decls.go | 215 + .../google/cel-go/checker/decls/scopes.go | 115 + .../github.com/google/cel-go/checker/env.go | 352 ++ .../google/cel-go/checker/errors.go | 123 + .../google/cel-go/checker/mapping.go | 62 + .../google/cel-go/checker/printer.go | 71 + .../google/cel-go/checker/standard.go | 440 ++ .../github.com/google/cel-go/checker/types.go | 485 ++ .../google/cel-go/common/debug/debug.go | 305 ++ vendor/github.com/google/cel-go/common/doc.go | 17 + .../github.com/google/cel-go/common/error.go | 70 + .../github.com/google/cel-go/common/errors.go | 58 + .../google/cel-go/common/location.go | 51 + .../cel-go/common/operators/operators.go | 145 + .../cel-go/common/overloads/overloads.go | 273 ++ .../google/cel-go/common/packages/packager.go | 82 + .../github.com/google/cel-go/common/source.go | 189 + .../google/cel-go/common/types/any_value.go | 24 + .../google/cel-go/common/types/bool.go | 142 + .../google/cel-go/common/types/bytes.go | 132 + .../google/cel-go/common/types/doc.go | 17 + .../google/cel-go/common/types/double.go | 185 + .../google/cel-go/common/types/duration.go | 220 + .../google/cel-go/common/types/dyn.go | 33 + .../google/cel-go/common/types/err.go | 90 + .../google/cel-go/common/types/int.go | 243 + .../google/cel-go/common/types/iterator.go | 55 + .../google/cel-go/common/types/json_list.go | 217 + .../google/cel-go/common/types/json_struct.go | 218 + .../google/cel-go/common/types/json_value.go | 24 + .../google/cel-go/common/types/list.go | 523 +++ .../google/cel-go/common/types/map.go | 339 ++ .../google/cel-go/common/types/null.go | 101 + .../google/cel-go/common/types/object.go | 179 + .../google/cel-go/common/types/pb/checked.go | 90 + .../google/cel-go/common/types/pb/enum.go | 36 + .../google/cel-go/common/types/pb/file.go | 113 + .../google/cel-go/common/types/pb/pb.go | 149 + .../google/cel-go/common/types/pb/type.go | 381 ++ .../google/cel-go/common/types/provider.go | 518 +++ .../cel-go/common/types/ref/provider.go | 91 + .../cel-go/common/types/ref/reference.go | 59 + .../google/cel-go/common/types/string.go | 216 + .../google/cel-go/common/types/timestamp.go | 328 ++ .../cel-go/common/types/traits/comparer.go | 33 + .../cel-go/common/types/traits/container.go | 23 + .../common/types/traits/field_tester.go | 30 + .../cel-go/common/types/traits/indexer.go | 25 + .../cel-go/common/types/traits/iterator.go | 36 + .../cel-go/common/types/traits/lister.go | 27 + .../cel-go/common/types/traits/mapper.go | 33 + .../cel-go/common/types/traits/matcher.go | 23 + .../google/cel-go/common/types/traits/math.go | 62 + .../cel-go/common/types/traits/receiver.go | 24 + .../cel-go/common/types/traits/sizer.go | 25 + .../cel-go/common/types/traits/traits.go | 64 + .../google/cel-go/common/types/type.go | 104 + .../google/cel-go/common/types/uint.go | 210 + .../google/cel-go/common/types/unknown.go | 61 + .../google/cel-go/common/types/util.go | 38 + .../google/cel-go/interpreter/activation.go | 182 + .../google/cel-go/interpreter/decorators.go | 177 + .../google/cel-go/interpreter/dispatcher.go | 100 + .../google/cel-go/interpreter/evalstate.go | 75 + .../cel-go/interpreter/functions/functions.go | 58 + .../cel-go/interpreter/functions/standard.go | 260 ++ .../cel-go/interpreter/interpretable.go | 766 ++++ .../google/cel-go/interpreter/interpreter.go | 129 + .../google/cel-go/interpreter/planner.go | 622 +++ .../google/cel-go/interpreter/prune.go | 256 ++ .../github.com/google/cel-go/parser/errors.go | 42 + .../cel-go/parser/gen/cel_base_listener.go | 195 + .../cel-go/parser/gen/cel_base_visitor.go | 124 + .../google/cel-go/parser/gen/cel_lexer.go | 319 ++ .../google/cel-go/parser/gen/cel_listener.go | 183 + .../google/cel-go/parser/gen/cel_parser.go | 4065 +++++++++++++++++ .../google/cel-go/parser/gen/cel_visitor.go | 96 + .../github.com/google/cel-go/parser/helper.go | 392 ++ .../github.com/google/cel-go/parser/macro.go | 387 ++ .../github.com/google/cel-go/parser/parser.go | 607 +++ .../google/cel-go/parser/unescape.go | 237 + .../google/cel-go/parser/unparser.go | 475 ++ vendor/golang.org/x/text/width/gen.go | 115 + vendor/golang.org/x/text/width/gen_common.go | 96 + vendor/golang.org/x/text/width/gen_trieval.go | 34 + vendor/golang.org/x/text/width/kind_string.go | 28 + .../golang.org/x/text/width/tables10.0.0.go | 1318 ++++++ .../golang.org/x/text/width/tables11.0.0.go | 1330 ++++++ vendor/golang.org/x/text/width/tables9.0.0.go | 1286 ++++++ vendor/golang.org/x/text/width/transform.go | 239 + vendor/golang.org/x/text/width/trieval.go | 30 + vendor/golang.org/x/text/width/width.go | 206 + .../api/expr/v1alpha1/cel_service.pb.go | 195 + .../api/expr/v1alpha1/checked.pb.go | 1428 ++++++ .../expr/v1alpha1/conformance_service.pb.go | 799 ++++ .../googleapis/api/expr/v1alpha1/eval.pb.go | 427 ++ .../api/expr/v1alpha1/explain.pb.go | 157 + .../googleapis/api/expr/v1alpha1/syntax.pb.go | 1572 +++++++ .../googleapis/api/expr/v1alpha1/value.pb.go | 708 +++ 168 files changed, 45793 insertions(+), 6 deletions(-) create mode 100644 docs/cel_expressions.md create mode 100644 examples/eventlisteners/cel-eventlistener-interceptor.yaml create mode 100644 pkg/interceptors/cel/cel.go create mode 100644 pkg/interceptors/cel/cel_test.go create mode 100644 vendor/github.com/antlr/antlr4/LICENSE.txt create mode 100644 vendor/github.com/antlr/antlr4/contributors.txt create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config_set.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserialization_options.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserializer.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_simulator.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_state.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_type.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/char_stream.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_factory.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_stream.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_serializer.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_state.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/diagnostic_error_listener.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_listener.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_strategy.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/errors.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/file_stream.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/input_stream.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/int_stream.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/interval_set.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action_executor.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_atn_simulator.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/ll1_analyzer.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_atn_simulator.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_rule_context.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_context.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_mode.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/recognizer.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/rule_context.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/semantic_context.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/token.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_source.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_stream.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/tokenstream_rewriter.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/trace_listener.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/transition.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/tree.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/trees.go create mode 100644 vendor/github.com/antlr/antlr4/runtime/Go/antlr/utils.go create mode 100644 vendor/github.com/golang/protobuf/descriptor/descriptor.go create mode 100644 vendor/github.com/golang/protobuf/jsonpb/jsonpb.go create mode 100644 vendor/github.com/google/cel-go/LICENSE create mode 100644 vendor/github.com/google/cel-go/cel/cel.go create mode 100644 vendor/github.com/google/cel-go/cel/env.go create mode 100644 vendor/github.com/google/cel-go/cel/io.go create mode 100644 vendor/github.com/google/cel-go/cel/options.go create mode 100644 vendor/github.com/google/cel-go/cel/program.go create mode 100644 vendor/github.com/google/cel-go/checker/checker.go create mode 100644 vendor/github.com/google/cel-go/checker/decls/decls.go create mode 100644 vendor/github.com/google/cel-go/checker/decls/scopes.go create mode 100644 vendor/github.com/google/cel-go/checker/env.go create mode 100644 vendor/github.com/google/cel-go/checker/errors.go create mode 100644 vendor/github.com/google/cel-go/checker/mapping.go create mode 100644 vendor/github.com/google/cel-go/checker/printer.go create mode 100644 vendor/github.com/google/cel-go/checker/standard.go create mode 100644 vendor/github.com/google/cel-go/checker/types.go create mode 100644 vendor/github.com/google/cel-go/common/debug/debug.go create mode 100644 vendor/github.com/google/cel-go/common/doc.go create mode 100644 vendor/github.com/google/cel-go/common/error.go create mode 100644 vendor/github.com/google/cel-go/common/errors.go create mode 100644 vendor/github.com/google/cel-go/common/location.go create mode 100644 vendor/github.com/google/cel-go/common/operators/operators.go create mode 100644 vendor/github.com/google/cel-go/common/overloads/overloads.go create mode 100644 vendor/github.com/google/cel-go/common/packages/packager.go create mode 100644 vendor/github.com/google/cel-go/common/source.go create mode 100644 vendor/github.com/google/cel-go/common/types/any_value.go create mode 100644 vendor/github.com/google/cel-go/common/types/bool.go create mode 100644 vendor/github.com/google/cel-go/common/types/bytes.go create mode 100644 vendor/github.com/google/cel-go/common/types/doc.go create mode 100644 vendor/github.com/google/cel-go/common/types/double.go create mode 100644 vendor/github.com/google/cel-go/common/types/duration.go create mode 100644 vendor/github.com/google/cel-go/common/types/dyn.go create mode 100644 vendor/github.com/google/cel-go/common/types/err.go create mode 100644 vendor/github.com/google/cel-go/common/types/int.go create mode 100644 vendor/github.com/google/cel-go/common/types/iterator.go create mode 100644 vendor/github.com/google/cel-go/common/types/json_list.go create mode 100644 vendor/github.com/google/cel-go/common/types/json_struct.go create mode 100644 vendor/github.com/google/cel-go/common/types/json_value.go create mode 100644 vendor/github.com/google/cel-go/common/types/list.go create mode 100644 vendor/github.com/google/cel-go/common/types/map.go create mode 100644 vendor/github.com/google/cel-go/common/types/null.go create mode 100644 vendor/github.com/google/cel-go/common/types/object.go create mode 100644 vendor/github.com/google/cel-go/common/types/pb/checked.go create mode 100644 vendor/github.com/google/cel-go/common/types/pb/enum.go create mode 100644 vendor/github.com/google/cel-go/common/types/pb/file.go create mode 100644 vendor/github.com/google/cel-go/common/types/pb/pb.go create mode 100644 vendor/github.com/google/cel-go/common/types/pb/type.go create mode 100644 vendor/github.com/google/cel-go/common/types/provider.go create mode 100644 vendor/github.com/google/cel-go/common/types/ref/provider.go create mode 100644 vendor/github.com/google/cel-go/common/types/ref/reference.go create mode 100644 vendor/github.com/google/cel-go/common/types/string.go create mode 100644 vendor/github.com/google/cel-go/common/types/timestamp.go create mode 100644 vendor/github.com/google/cel-go/common/types/traits/comparer.go create mode 100644 vendor/github.com/google/cel-go/common/types/traits/container.go create mode 100644 vendor/github.com/google/cel-go/common/types/traits/field_tester.go create mode 100644 vendor/github.com/google/cel-go/common/types/traits/indexer.go create mode 100644 vendor/github.com/google/cel-go/common/types/traits/iterator.go create mode 100644 vendor/github.com/google/cel-go/common/types/traits/lister.go create mode 100644 vendor/github.com/google/cel-go/common/types/traits/mapper.go create mode 100644 vendor/github.com/google/cel-go/common/types/traits/matcher.go create mode 100644 vendor/github.com/google/cel-go/common/types/traits/math.go create mode 100644 vendor/github.com/google/cel-go/common/types/traits/receiver.go create mode 100644 vendor/github.com/google/cel-go/common/types/traits/sizer.go create mode 100644 vendor/github.com/google/cel-go/common/types/traits/traits.go create mode 100644 vendor/github.com/google/cel-go/common/types/type.go create mode 100644 vendor/github.com/google/cel-go/common/types/uint.go create mode 100644 vendor/github.com/google/cel-go/common/types/unknown.go create mode 100644 vendor/github.com/google/cel-go/common/types/util.go create mode 100644 vendor/github.com/google/cel-go/interpreter/activation.go create mode 100644 vendor/github.com/google/cel-go/interpreter/decorators.go create mode 100644 vendor/github.com/google/cel-go/interpreter/dispatcher.go create mode 100644 vendor/github.com/google/cel-go/interpreter/evalstate.go create mode 100644 vendor/github.com/google/cel-go/interpreter/functions/functions.go create mode 100644 vendor/github.com/google/cel-go/interpreter/functions/standard.go create mode 100644 vendor/github.com/google/cel-go/interpreter/interpretable.go create mode 100644 vendor/github.com/google/cel-go/interpreter/interpreter.go create mode 100644 vendor/github.com/google/cel-go/interpreter/planner.go create mode 100644 vendor/github.com/google/cel-go/interpreter/prune.go create mode 100644 vendor/github.com/google/cel-go/parser/errors.go create mode 100644 vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go create mode 100644 vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go create mode 100644 vendor/github.com/google/cel-go/parser/gen/cel_lexer.go create mode 100644 vendor/github.com/google/cel-go/parser/gen/cel_listener.go create mode 100644 vendor/github.com/google/cel-go/parser/gen/cel_parser.go create mode 100644 vendor/github.com/google/cel-go/parser/gen/cel_visitor.go create mode 100644 vendor/github.com/google/cel-go/parser/helper.go create mode 100644 vendor/github.com/google/cel-go/parser/macro.go create mode 100644 vendor/github.com/google/cel-go/parser/parser.go create mode 100644 vendor/github.com/google/cel-go/parser/unescape.go create mode 100644 vendor/github.com/google/cel-go/parser/unparser.go create mode 100644 vendor/golang.org/x/text/width/gen.go create mode 100644 vendor/golang.org/x/text/width/gen_common.go create mode 100644 vendor/golang.org/x/text/width/gen_trieval.go create mode 100644 vendor/golang.org/x/text/width/kind_string.go create mode 100644 vendor/golang.org/x/text/width/tables10.0.0.go create mode 100644 vendor/golang.org/x/text/width/tables11.0.0.go create mode 100644 vendor/golang.org/x/text/width/tables9.0.0.go create mode 100644 vendor/golang.org/x/text/width/transform.go create mode 100644 vendor/golang.org/x/text/width/trieval.go create mode 100644 vendor/golang.org/x/text/width/width.go create mode 100644 vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/cel_service.pb.go create mode 100644 vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/checked.pb.go create mode 100644 vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/conformance_service.pb.go create mode 100644 vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/eval.pb.go create mode 100644 vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/explain.pb.go create mode 100644 vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/syntax.pb.go create mode 100644 vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/value.pb.go diff --git a/Gopkg.lock b/Gopkg.lock index 93f8e518d..80efda8bb 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -34,6 +34,14 @@ revision = "6850d2e00d7dfe4886f7e4773bf9f05e39296d92" version = "v0.12.4" +[[projects]] + digest = "1:d04889482897652dedae6d8575b479c06fa3eb3c3abe248163b25d3df5fab43e" + name = "github.com/antlr/antlr4" + packages = ["runtime/Go/antlr"] + pruneopts = "NUT" + revision = "be58ebffde8e29c154192c019608f0a5b8e6a064" + version = "4.7.2" + [[projects]] digest = "1:c2cd958e29ac89c55ce0a2f8a51d0e69c251e00e56451c91d8a854bd81bd5908" name = "github.com/aws/aws-sdk-go" @@ -146,9 +154,11 @@ revision = "869f871628b6baa9cfbc11732cdf6546b17c1298" [[projects]] - digest = "1:f5a98770ab68c1146ee5cc14ed24aafa2bb1a2b3c89cbeadc9eb913b1f9d930a" + digest = "1:a677057cef8b68b66003c2775ed1126bbd7e9e372b54b7c1a7c5201a2f1f3eb0" name = "github.com/golang/protobuf" packages = [ + "descriptor", + "jsonpb", "proto", "protoc-gen-go/descriptor", "ptypes", @@ -171,6 +181,31 @@ revision = "4030bb1f1f0c35b30ca7009e9ebd06849dd45306" version = "v1.0.0" +[[projects]] + digest = "1:c7674816de688e36b654c01958a8c0dac70e49ab341437a1e6d601cc920dfd88" + name = "github.com/google/cel-go" + packages = [ + "cel", + "checker", + "checker/decls", + "common", + "common/debug", + "common/operators", + "common/overloads", + "common/packages", + "common/types", + "common/types/pb", + "common/types/ref", + "common/types/traits", + "interpreter", + "interpreter/functions", + "parser", + "parser/gen", + ] + pruneopts = "NUT" + revision = "1844753af07a48df9fdcc69ee23ccae9cd7de401" + version = "v0.3.2" + [[projects]] digest = "1:010d46ea3c1e730897e53058d1013a963f3f987675dda87df64f891b945281db" name = "github.com/google/go-cmp" @@ -615,7 +650,7 @@ revision = "51ab0e2deafac1f46c46ad59cf0921be2f180c3d" [[projects]] - digest = "1:8d8faad6b12a3a4c819a3f9618cb6ee1fa1cfc33253abeeea8b55336721e3405" + digest = "1:66a2f252a58b4fbbad0e4e180e1d85a83c222b6bce09c3dcdef3dc87c72eda7c" name = "golang.org/x/text" packages = [ "collate", @@ -634,6 +669,7 @@ "unicode/cldr", "unicode/norm", "unicode/rangetable", + "width", ] pruneopts = "NUT" revision = "342b2e1fbaa52c93f31447ad2c6abc048c63e475" @@ -719,12 +755,13 @@ version = "v1.6.1" [[projects]] - digest = "1:3689f4cc57cc55b4631efc4b778c47d2a888a7060b4108f42cf289a2033be5ba" + digest = "1:ae5bc763d1c7d01d18b2d0dc6e8b5c70f30af9bbba0d5283314386020d912e02" name = "google.golang.org/genproto" packages = [ "googleapis/api", "googleapis/api/annotations", "googleapis/api/distribution", + "googleapis/api/expr/v1alpha1", "googleapis/api/label", "googleapis/api/metric", "googleapis/api/monitoredres", @@ -1225,6 +1262,11 @@ analyzer-name = "dep" analyzer-version = 1 input-imports = [ + "github.com/google/cel-go/cel", + "github.com/google/cel-go/checker/decls", + "github.com/google/cel-go/common/types", + "github.com/google/cel-go/common/types/ref", + "github.com/google/cel-go/interpreter/functions", "github.com/google/go-cmp/cmp", "github.com/google/go-cmp/cmp/cmpopts", "github.com/google/go-github/github", @@ -1241,6 +1283,7 @@ "github.com/tektoncd/plumbing/scripts", "go.uber.org/zap", "golang.org/x/xerrors", + "google.golang.org/genproto/googleapis/api/expr/v1alpha1", "gopkg.in/yaml.v2", "k8s.io/api/apps/v1", "k8s.io/api/core/v1", diff --git a/Gopkg.toml b/Gopkg.toml index 381b00abe..b0b1fa2cc 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -11,7 +11,13 @@ required = [ "knative.dev/caching/pkg/apis/caching", "github.com/tektoncd/plumbing/scripts", "github.com/knative/test-infra/tools/dep-collector", - "github.com/google/go-github/github" + "github.com/google/go-github/github", + "github.com/google/cel-go/cel", + "github.com/google/cel-go/checker/decls", + "github.com/google/cel-go/common/types", + "github.com/google/cel-go/common/types/ref", + "github.com/google/cel-go/interpreter/functions", + "google.golang.org/genproto/googleapis/api/expr/v1alpha1", ] [[constraint]] diff --git a/docs/cel_expressions.md b/docs/cel_expressions.md new file mode 100644 index 000000000..b71d3277b --- /dev/null +++ b/docs/cel_expressions.md @@ -0,0 +1,84 @@ +# CEL expression extensions + +The CEL expression is configured to expose parts of the request, and some custom +functions to make matching easier. + +### List of extensions + +The body from the `http.Request` value is decoded to JSON and exposed, and the +headers are also available. + + + + + + + + + + + + + + + + + + + + +
SymbolTypeDescriptionExample
+ body + + map(string, dynamic) + + This is the decoded JSON body from the incoming http.Request exposed as a map of string keys to any value types. + +
body.value == 'test'
+
+ header + + map(string, list(string)) + + This is the request Header. + +
header['X-Test'][0] == 'test-value'
+
+ +NOTE: The header value is a Go `http.Header`, which is [defined](https://golang.org/pkg/net/http/#Header) as: + +```go +type Header map[string][]string +``` + +i.e. the header is a mapping of strings, to arrays of strings, see the `match` +function on headers below for an extension that makes looking up headers easier. + + +### List of extension functions + +This lists custom functions that can be used from CEL expressions in the +CEL interceptor. + + + + + + + + + + + + + + +
SymbolTypeDescriptionExample
+ match + + header.(string, string) -> bool + + Uses the canonical header matching from Go's http.Request to match the header against the value. + +
header.match('x-test', 'test-value')
+
diff --git a/docs/eventlisteners.md b/docs/eventlisteners.md index 10dcbecc8..c165000b1 100644 --- a/docs/eventlisteners.md +++ b/docs/eventlisteners.md @@ -194,3 +194,32 @@ spec: template: name: pipeline-template ``` + +### CEL Interceptors + +CEL interceptors parse expressions to filter requests based on JSON bodies and request headers, using the +[CEL](https://github.com/google/cel-go) expression language. + +Supported features include case-insensitive matching on request headers. + + +```YAML +apiVersion: tekton.dev/v1alpha1 +kind: EventListener +metadata: + name: cel-listener-interceptor +spec: + serviceAccountName: tekton-triggers-example-sa + triggers: + - name: cel-trig + interceptor: + cel: + filter: "headers.match('X-GitHub-Event', 'push')" + bindings: + - name: pipeline-binding + template: + name: pipeline-template +``` + +The `expression` must return a `true` value, otherwise the request will be filtered +out. diff --git a/examples/eventlisteners/cel-eventlistener-interceptor.yaml b/examples/eventlisteners/cel-eventlistener-interceptor.yaml new file mode 100644 index 000000000..a51af2e89 --- /dev/null +++ b/examples/eventlisteners/cel-eventlistener-interceptor.yaml @@ -0,0 +1,15 @@ +apiVersion: tekton.dev/v1alpha1 +kind: EventListener +metadata: + name: cel-listener-interceptor +spec: + serviceAccountName: tekton-triggers-example-sa + triggers: + - name: cel-trig + interceptor: + cel: + filter: "headers.match('X-GitHub-Event', 'push')" + bindings: + - name: pipeline-binding + template: + name: pipeline-template diff --git a/pkg/apis/triggers/v1alpha1/event_listener_types.go b/pkg/apis/triggers/v1alpha1/event_listener_types.go index 33d8fcbc7..9e4d85ad7 100644 --- a/pkg/apis/triggers/v1alpha1/event_listener_types.go +++ b/pkg/apis/triggers/v1alpha1/event_listener_types.go @@ -79,6 +79,7 @@ type EventInterceptor struct { Webhook *WebhookInterceptor `json:"webhook,omitempty"` GitHub *GitHubInterceptor `json:"github,omitempty"` GitLab *GitLabInterceptor `json:"gitlab,omitempty"` + CEL *CELInterceptor `json:"cel,omitempty"` } // WebhookInterceptor provides a webhook to intercept and pre-process events @@ -105,6 +106,11 @@ type GitLabInterceptor struct { EventTypes []string `json:"eventTypes,omitempty"` } +// CELInterceptor provides a webhook to intercept and pre-process events +type CELInterceptor struct { + Filter string `json:"filter,omitempty"` +} + // SecretRef contains the information required to reference a single secret string // This is needed because the other secretRef types are not cross-namespace and do not // actually contain the "SecretName" field, which allows us to access a single secret value. diff --git a/pkg/apis/triggers/v1alpha1/event_listener_validation.go b/pkg/apis/triggers/v1alpha1/event_listener_validation.go index 0a6d25543..6b569c1be 100644 --- a/pkg/apis/triggers/v1alpha1/event_listener_validation.go +++ b/pkg/apis/triggers/v1alpha1/event_listener_validation.go @@ -66,8 +66,7 @@ func (s *EventListenerSpec) validate(ctx context.Context, el *EventListener) *ap } func (i *EventInterceptor) validate(ctx context.Context, namespace string) *apis.FieldError { - // Validate at least one - if i.Webhook == nil && i.GitHub == nil && i.GitLab == nil { + if i.Webhook == nil && i.GitHub == nil && i.GitLab == nil && i.CEL == nil { return apis.ErrMissingField("interceptor") } @@ -126,5 +125,11 @@ func (i *EventInterceptor) validate(ctx context.Context, namespace string) *apis // if i.GitLab != nil { // // } + + if i.CEL != nil { + if i.CEL.Filter == "" { + return apis.ErrMissingField("interceptor.cel.filter") + } + } return nil } diff --git a/pkg/apis/triggers/v1alpha1/event_listener_validation_test.go b/pkg/apis/triggers/v1alpha1/event_listener_validation_test.go index 8d09f2263..ce7c2294a 100644 --- a/pkg/apis/triggers/v1alpha1/event_listener_validation_test.go +++ b/pkg/apis/triggers/v1alpha1/event_listener_validation_test.go @@ -59,6 +59,12 @@ func Test_EventListenerValidate(t *testing.T) { bldr.EventListenerTriggerInterceptor("svc", "v1", "Service", "namespace"), ), bldr.EventListenerTrigger("tb", "tt", "v1alpha1"))), + }, { + name: "Valid EventListener with CEL interceptor", + el: bldr.EventListener("name", "namespace", + bldr.EventListenerSpec( + bldr.EventListenerTrigger("tb", "tt", "v1alpha1", + bldr.EventListenerCELInterceptor("body.value == 'test'")))), }} for _, test := range tests { @@ -236,6 +242,23 @@ func TestEventListenerValidate_error(t *testing.T) { }}, }, }, + }, { + name: "CEL interceptor with no filter", + el: &v1alpha1.EventListener{ + ObjectMeta: metav1.ObjectMeta{ + Name: "name", + Namespace: "namespace", + }, + Spec: v1alpha1.EventListenerSpec{ + Triggers: []v1alpha1.EventListenerTrigger{{ + Bindings: []*v1alpha1.EventListenerBinding{{Name: "tb"}}, + Template: v1alpha1.EventListenerTemplate{Name: "tt"}, + Interceptor: &v1alpha1.EventInterceptor{ + CEL: &v1alpha1.CELInterceptor{}, + }, + }}, + }, + }, }} for _, test := range tests { diff --git a/pkg/apis/triggers/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/triggers/v1alpha1/zz_generated.deepcopy.go index f14e8d286..ceb92109f 100644 --- a/pkg/apis/triggers/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/triggers/v1alpha1/zz_generated.deepcopy.go @@ -28,6 +28,22 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CELInterceptor) DeepCopyInto(out *CELInterceptor) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CELInterceptor. +func (in *CELInterceptor) DeepCopy() *CELInterceptor { + if in == nil { + return nil + } + out := new(CELInterceptor) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *EventInterceptor) DeepCopyInto(out *EventInterceptor) { *out = *in @@ -46,6 +62,11 @@ func (in *EventInterceptor) DeepCopyInto(out *EventInterceptor) { *out = new(GitLabInterceptor) (*in).DeepCopyInto(*out) } + if in.CEL != nil { + in, out := &in.CEL, &out.CEL + *out = new(CELInterceptor) + **out = **in + } return } diff --git a/pkg/interceptors/cel/cel.go b/pkg/interceptors/cel/cel.go new file mode 100644 index 000000000..0d952949a --- /dev/null +++ b/pkg/interceptors/cel/cel.go @@ -0,0 +1,150 @@ +/* +Copyright 2019 The Tekton Authors + +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 ( + "encoding/json" + "fmt" + "net/http" + "reflect" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/checker/decls" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/interpreter/functions" + "github.com/tektoncd/triggers/pkg/interceptors" + "go.uber.org/zap" + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + "k8s.io/client-go/kubernetes" + + triggersv1 "github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1" +) + +// Interceptor implements a CEL based interceptor, that uses CEL expressions +// against the incoming body and headers to match, if the expression returns +// a true value, then the interception is "successful". +type Interceptor struct { + KubeClientSet kubernetes.Interface + Logger *zap.SugaredLogger + CEL *triggersv1.CELInterceptor + EventListenerNamespace string +} + +// NewInterceptor creates a prepopulated Interceptor. +func NewInterceptor(cel *triggersv1.CELInterceptor, k kubernetes.Interface, ns string, l *zap.SugaredLogger) interceptors.Interceptor { + return &Interceptor{ + Logger: l, + CEL: cel, + KubeClientSet: k, + EventListenerNamespace: ns, + } +} + +// ExecuteTrigger is an implementation of the Interceptor interface. +func (w *Interceptor) ExecuteTrigger(payload []byte, request *http.Request, _ *triggersv1.EventListenerTrigger, _ string) ([]byte, error) { + env, err := makeCelEnv() + if err != nil { + return nil, fmt.Errorf("error creating cel environment: %w", err) + } + + evalContext, err := makeEvalContext(payload, request) + if err != nil { + return nil, fmt.Errorf("error making the evaluation context: %w", err) + } + + out, err := evaluate(w.CEL.Filter, env, evalContext) + if err != nil { + return nil, fmt.Errorf("failed to evaluate expression '%s': %w", w.CEL.Filter, err) + } + + if out != types.True { + return nil, fmt.Errorf("expression %s did not return true", w.CEL.Filter) + + } + + return payload, nil +} + +func evaluate(expr string, env cel.Env, data map[string]interface{}) (ref.Val, error) { + parsed, issues := env.Parse(expr) + if issues != nil && issues.Err() != nil { + return nil, issues.Err() + } + + checked, issues := env.Check(parsed) + if issues != nil && issues.Err() != nil { + return nil, issues.Err() + } + + prg, err := env.Program(checked, embeddedFunctions()) + if err != nil { + return nil, err + } + + out, _, err := prg.Eval(data) + return out, err +} + +func embeddedFunctions() cel.ProgramOption { + return cel.Functions( + &functions.Overload{ + Operator: "match", + Function: matchHeader}, + ) + +} +func makeCelEnv() (cel.Env, error) { + mapStrDyn := decls.NewMapType(decls.String, decls.Dyn) + return cel.NewEnv( + cel.Declarations( + decls.NewIdent("body", mapStrDyn, nil), + decls.NewIdent("header", mapStrDyn, nil), + decls.NewFunction("match", + decls.NewInstanceOverload("match_map_string_string", + []*exprpb.Type{mapStrDyn, decls.String, decls.String}, decls.Bool)))) +} + +func makeEvalContext(body []byte, r *http.Request) (map[string]interface{}, error) { + var jsonMap map[string]interface{} + err := json.Unmarshal(body, &jsonMap) + if err != nil { + return nil, err + } + return map[string]interface{}{"body": jsonMap, "header": r.Header}, nil + +} + +func matchHeader(vals ...ref.Val) ref.Val { + h, err := vals[0].ConvertToNative(reflect.TypeOf(http.Header{})) + if err != nil { + return types.NewErr("failed to convert to http.Header: %w", err) + } + + key, ok := vals[1].(types.String) + if !ok { + return types.ValOrErr(key, "unexpected type '%v' passed to match", vals[1].Type()) + } + + val, ok := vals[2].(types.String) + if !ok { + return types.ValOrErr(val, "unexpected type '%v' passed to match", vals[2].Type()) + } + + return types.Bool(h.(http.Header).Get(string(key)) == string(val)) + +} diff --git a/pkg/interceptors/cel/cel_test.go b/pkg/interceptors/cel/cel_test.go new file mode 100644 index 000000000..dd624b869 --- /dev/null +++ b/pkg/interceptors/cel/cel_test.go @@ -0,0 +1,200 @@ +package cel + +import ( + "bytes" + "io/ioutil" + "net/http" + "reflect" + "testing" + + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + "github.com/tektoncd/pipeline/pkg/logging" + triggersv1 "github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1" + fakekubeclient "knative.dev/pkg/client/injection/kube/client/fake" + rtesting "knative.dev/pkg/reconciler/testing" +) + +// Allow configuration via a config map + +func TestInterceptor_ExecuteTrigger(t *testing.T) { + type args struct { + payload []byte + } + tests := []struct { + name string + CEL *triggersv1.CELInterceptor + args args + want []byte + wantErr bool + }{ + { + name: "simple body check with matching body", + CEL: &triggersv1.CELInterceptor{ + Filter: "body.value == 'testing'", + }, + args: args{ + payload: []byte(`{"value":"testing"}`), + }, + want: []byte(`{"value":"testing"}`), + wantErr: false, + }, + { + name: "simple body check with non-matching body", + CEL: &triggersv1.CELInterceptor{ + Filter: "body.value == 'test'", + }, + args: args{ + payload: []byte(`{"value":"testing"}`), + }, + wantErr: true, + }, + { + name: "simple header check with matching header", + CEL: &triggersv1.CELInterceptor{ + Filter: "header['X-Test'][0] == 'test-value'", + }, + args: args{ + payload: []byte(`{}`), + }, + want: []byte(`{}`), + wantErr: false, + }, + { + name: "simple header check with non matching header", + CEL: &triggersv1.CELInterceptor{ + Filter: "header['X-Test'][0] == 'unknown'", + }, + args: args{ + payload: []byte(`{}`), + }, + wantErr: true, + }, + { + name: "overloaded header check with case insensitive failed match", + CEL: &triggersv1.CELInterceptor{ + Filter: "header.match('x-test', 'no-match')", + }, + args: args{ + payload: []byte(`{}`), + }, + wantErr: true, + }, + { + name: "overloaded header check with case insensitive matching", + CEL: &triggersv1.CELInterceptor{ + Filter: "header.match('x-test', 'test-value')", + }, + args: args{ + payload: []byte(`{}`), + }, + want: []byte(`{}`), + wantErr: false, + }, + { + name: "body and header check", + CEL: &triggersv1.CELInterceptor{ + Filter: "header.match('x-test', 'test-value') && body.value == 'test'", + }, + args: args{ + payload: []byte(`{"value":"test"}`), + }, + want: []byte(`{"value":"test"}`), + wantErr: false, + }, + { + name: "unable to parse the expression", + CEL: &triggersv1.CELInterceptor{ + Filter: "header['X-Test", + }, + args: args{ + payload: []byte(`{"value":"test"}`), + }, + wantErr: true, + }, + { + name: "unable to parse the JSON body", + CEL: &triggersv1.CELInterceptor{ + Filter: "body.value == 'test'", + }, + args: args{ + payload: []byte(`{]`), + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx, _ := rtesting.SetupFakeContext(t) + logger, _ := logging.NewLogger("", "") + kubeClient := fakekubeclient.Get(ctx) + w := &Interceptor{ + KubeClientSet: kubeClient, + CEL: tt.CEL, + Logger: logger, + } + request := &http.Request{ + Body: ioutil.NopCloser(bytes.NewReader(tt.args.payload)), + Header: http.Header{ + "Content-Type": []string{"application/json"}, + "X-Test": []string{"test-value"}, + }, + } + got, err := w.ExecuteTrigger(tt.args.payload, request, nil, "") + if (err != nil) != tt.wantErr { + t.Errorf("Interceptor.ExecuteTrigger() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Interceptor.ExecuteTrigger() = %s, want %s", got, tt.want) + } + }) + } +} + +func TestFilterEvaluation(t *testing.T) { + jsonMap := map[string]interface{}{ + "value": "testing", + "sha": "ec26c3e57ca3a959ca5aad62de7213c562f8c821", + } + header := http.Header{} + evalEnv := map[string]interface{}{"body": jsonMap, "header": header} + env, err := makeCelEnv() + if err != nil { + t.Fatal(err) + } + tests := []struct { + name string + expr string + want ref.Val + }{ + { + name: "simple body value", + expr: "body.value", + want: types.String("testing"), + }, + { + name: "boolean body value", + expr: "body.value == 'testing'", + want: types.Bool(true), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := evaluate(tt.expr, env, evalEnv) + if err != nil { + t.Errorf("evaluate() got an error %s", err) + return + } + _, ok := got.(*types.Err) + if ok { + t.Errorf("error evaluating expression: %s", got) + return + } + + if !got.Equal(tt.want).(types.Bool) { + t.Errorf("evaluate() = %s, want %s", got, tt.want) + } + }) + } +} diff --git a/pkg/sink/sink.go b/pkg/sink/sink.go index 800a82e47..6ec1b8263 100644 --- a/pkg/sink/sink.go +++ b/pkg/sink/sink.go @@ -25,6 +25,7 @@ import ( triggersv1 "github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1" triggersclientset "github.com/tektoncd/triggers/pkg/client/clientset/versioned" "github.com/tektoncd/triggers/pkg/interceptors" + "github.com/tektoncd/triggers/pkg/interceptors/cel" "github.com/tektoncd/triggers/pkg/interceptors/github" "github.com/tektoncd/triggers/pkg/interceptors/gitlab" "github.com/tektoncd/triggers/pkg/interceptors/webhook" @@ -97,6 +98,8 @@ func (r Sink) HandleEvent(response http.ResponseWriter, request *http.Request) { interceptor = github.NewInterceptor(t.Interceptor.GitHub, r.KubeClientSet, r.EventListenerNamespace, log) case t.Interceptor.GitLab != nil: interceptor = gitlab.NewInterceptor(t.Interceptor.GitLab, r.KubeClientSet, r.EventListenerNamespace, log) + case t.Interceptor.CEL != nil: + interceptor = cel.NewInterceptor(t.Interceptor.CEL, r.KubeClientSet, r.EventListenerNamespace, log) } } go func(t triggersv1.EventListenerTrigger) { diff --git a/test/builder/eventlistener.go b/test/builder/eventlistener.go index 2d2ed0af5..264e25d60 100644 --- a/test/builder/eventlistener.go +++ b/test/builder/eventlistener.go @@ -197,3 +197,17 @@ func EventInterceptorParam(name, value string) EventInterceptorOp { } } } + +// EventListenerCELInterceptor adds a CEL filter to the EventListenerTrigger. +func EventListenerCELInterceptor(filter string, ops ...EventInterceptorOp) EventListenerTriggerOp { + return func(t *v1alpha1.EventListenerTrigger) { + t.Interceptor = &v1alpha1.EventInterceptor{ + CEL: &v1alpha1.CELInterceptor{ + Filter: filter, + }, + } + for _, op := range ops { + op(t.Interceptor) + } + } +} diff --git a/test/builder/eventlistener_test.go b/test/builder/eventlistener_test.go index 4c01564ed..9f34042c0 100644 --- a/test/builder/eventlistener_test.go +++ b/test/builder/eventlistener_test.go @@ -299,6 +299,41 @@ func TestEventListenerBuilder(t *testing.T) { ), ), ), + }, { + name: "One Trigger with CEL Interceptor", + normal: &v1alpha1.EventListener{ + ObjectMeta: metav1.ObjectMeta{ + Name: "name", + Namespace: "namespace", + }, + Spec: v1alpha1.EventListenerSpec{ + ServiceAccountName: "serviceAccount", + Triggers: []v1alpha1.EventListenerTrigger{{ + Name: "foo-trig", + Interceptor: &v1alpha1.EventInterceptor{ + CEL: &v1alpha1.CELInterceptor{ + Filter: "body.value == 'test'"}, + }, + Bindings: []*v1alpha1.EventListenerBinding{{ + Name: "tb1", + APIVersion: "v1alpha1", + }}, + Template: v1alpha1.EventListenerTemplate{ + Name: "tt1", + APIVersion: "v1alpha1", + }, + }}, + }, + }, + builder: EventListener("name", "namespace", + EventListenerSpec( + EventListenerServiceAccount("serviceAccount"), + EventListenerTrigger("tb1", "tt1", "v1alpha1", + EventListenerTriggerName("foo-trig"), + EventListenerCELInterceptor("body.value == 'test'"), + ), + ), + ), }, } for _, tt := range tests { diff --git a/vendor/github.com/antlr/antlr4/LICENSE.txt b/vendor/github.com/antlr/antlr4/LICENSE.txt new file mode 100644 index 000000000..2042d1bda --- /dev/null +++ b/vendor/github.com/antlr/antlr4/LICENSE.txt @@ -0,0 +1,52 @@ +[The "BSD 3-clause license"] +Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. 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. + 3. Neither the name of the copyright holder 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 AUTHOR ``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 AUTHOR 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. + +===== + +MIT License for codepointat.js from https://git.io/codepointat +MIT License for fromcodepoint.js from https://git.io/vDW1m + +Copyright Mathias Bynens + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/antlr/antlr4/contributors.txt b/vendor/github.com/antlr/antlr4/contributors.txt new file mode 100644 index 000000000..230e494f2 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/contributors.txt @@ -0,0 +1,212 @@ +ANTLR Project Contributors Certification of Origin and Rights + +All contributors to ANTLR v4 must formally agree to abide by this +certificate of origin by signing on the bottom with their github +userid, full name, email address (you can obscure your e-mail, but it +must be computable by human), and date. + +By signing this agreement, you are warranting and representing that +you have the right to release code contributions or other content free +of any obligations to third parties and are granting Terence Parr and +ANTLR project contributors, henceforth referred to as The ANTLR +Project, a license to incorporate it into The ANTLR Project tools +(such as ANTLRWorks and StringTemplate) or related works under the BSD +license. You understand that The ANTLR Project may or may not +incorporate your contribution and you warrant and represent the +following: + +1. I am the creator of all my contributions. I am the author of all + contributed work submitted and further warrant and represent that + such work is my original creation and I have the right to license + it to The ANTLR Project for release under the 3-clause BSD + license. I hereby grant The ANTLR Project a nonexclusive, + irrevocable, royalty-free, worldwide license to reproduce, + distribute, prepare derivative works, and otherwise use this + contribution as part of the ANTLR project, associated + documentation, books, and tools at no cost to The ANTLR Project. + +2. I have the right to submit. This submission does not violate the + rights of any person or entity and that I have legal authority over + this submission and to make this certification. + +3. If I violate another's rights, liability lies with me. I agree to + defend, indemnify, and hold The ANTLR Project and ANTLR users + harmless from any claim or demand, including reasonable attorney + fees, made by any third party due to or arising out of my violation + of these terms and conditions or my violation of the rights of + another person or entity. + +4. I understand and agree that this project and the contribution are + public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license indicated in the file. + +I have read this agreement and do so certify by adding my signoff to +the end of the following contributors list. + +CONTRIBUTORS: + +YYYY/MM/DD, github id, Full name, email +2012/07/12, parrt, Terence Parr, parrt@antlr.org +2012/09/18, sharwell, Sam Harwell, sam@tunnelvisionlabs.com +2012/10/10, stephengaito, Stephen Gaito, stephen@percepitsys.co.uk +2012/11/23, maguro, Alan Cabrera, adc@toolazydogs.com +2013/01/29, metadave, Dave Parfitt, diparfitt@gmail.com +2013/03/06, bkiers, Bart Kiers, bkiers@gmail.com +2013/08/20, cayhorstmann, Cay Horstmann, cay@horstmann.com +2014/03/18, aphyr, Kyle Kingsbury, aphyr@aphyr.com +2014/06/07, ericvergnaud, Eric Vergnaud, eric.vergnaud@wanadoo.fr +2014/07/04, jimidle, Jim Idle, jimi@Idle.ws +2014/01/01, danmclaughlin, Dan McLaughlin, dan.mclaughlin@gmail.com +2014/09/04. jeduden, Jan-Eric Duden, jeduden@gmail.com +2014/09/27, petrbel, Petr Bělohlávek, antlr@petrbel.cz +2014/10/18, sergiusignacius, Sérgio Silva, serge.a.silva@gmail.com +2014/10/26, bdkearns, Brian Kearns, bdkearns@gmail.com +2014/10/27, michaelpj, Michael Peyton Jones, michaelpj@gmail.com +2015/01/29, TomLottermann, Thomas Lottermann, tomlottermann@gmail.com +2015/02/15, pavlo, Pavlo Lysov, pavlikus@gmail.com +2015/03/07, RedTailedHawk, Lawrence Parker, larry@answerrocket.com +2015/04/03, rljacobson, Robert Jacobson, rljacobson@gmail.com +2015/04/06, ojakubcik, Ondrej Jakubcik, ojakubcik@gmail.com +2015/04/29, jszheng, Jinshan Zheng, zheng_js@hotmail.com +2015/05/08, ViceIce, Michael Kriese, michael.kriese@gmx.de +2015/05/09, lkraz, Luke Krasnoff, luke.krasnoff@gmail.com +2015/05/12, Pursuit92, Josh Chase, jcjoshuachase@gmail.com +2015/05/20, peturingi, Pétur Ingi Egilsson, petur@petur.eu +2015/05/27, jcbrinfo, Jean-Christophe Beaupré, jcbrinfo@users.noreply.github.com +2015/06/29, jvanzyl, Jason van Zyl, jason@takari.io +2015/08/18, krzkaczor, Krzysztof Kaczor, krzysztof@kaczor.io +2015/09/18, worsht, Rajiv Subrahmanyam, rajiv.public@gmail.com +2015/09/24, HSorensen, Henrik Sorensen, henrik.b.sorensen@gmail.com +2015/10/06, brwml, Bryan Wilhelm, bryan.wilhelm@microsoft.com +2015/10/08, fedotovalex, Alex Fedotov, me@alexfedotov.com +2015/10/12, KvanTTT, Ivan Kochurkin, ivan.kochurkin@gmail.com +2015/10/21, martin-probst, Martin Probst, martin-probst@web.de +2015/10/21, hkff, Walid Benghabrit, walid.benghabrit@mines-nantes.fr +2015/11/12, cooperra, Robbie Cooper, cooperra@users.noreply.github.com +2015/11/25, abego, Udo Borkowski, ub@abego.org +2015/12/17, sebadur, Sebastian Badur, sebadur@users.noreply.github.com +2015/12/23, pboyer, Peter Boyer, peter.b.boyer@gmail.com +2015/12/24, dtymon, David Tymon, david.tymon@gmail.com +2016/02/18, reitzig, Raphael Reitzig, reitzig[at]cs.uni-kl.de +2016/03/10, mike-lischke, Mike Lischke, mike@lischke-online.de +2016/03/27, beardlybread, Bradley Steinbacher, bradley.j.steinbacher@gmail.com +2016/03/29, msteiger, Martin Steiger, antlr@martin-steiger.de +2016/03/28, gagern, Martin von Gagern, gagern@ma.tum.de +2016/07/10, twz123, Tom Wieczorek, tom.wieczorek@zalando.de +2016/07/20, chrisheller, Chris Heller, chris.heller.greyheller@gmail.com +2016/07/20, nburles, Nathan Burles, nburles@gmail.com +2016/07/20, kosl90, Li Liqiang, kos1990l@gmail.com +2016/07/27, timoc, Tim O'Callaghan, timo@linux.com +2016/07/26, nic30, Michal Orsák, michal.o.socials@gmail.com +2016/07/18, willfaught, Will Faught, will.faught@gmail.com +2016/08/08, wjkohnen, Wolfgang Johannes Kohnen, wjkohnen-go-antlr@ko-sys.com +2016/08/11, BurtHarris, Ralph "Burt" Harris, Burt_Harris_antlr4@azxs.33mail.com +2016/08/19, andjo403, Andreas Jonson, andjo403@hotmail.com +2016/09/27, harriman, Kurt Harriman, harriman@acm.org +2016/10/13, cgudrian, Christian Gudrian, christian.gudrian@gmx.de +2016/10/13, nielsbasjes, Niels Basjes, niels@basjes.nl +2016/10/21, FloorGoddijn, Floor Goddijn, floor.goddijn[at]aimms.com +2016/11/01, RYDB3RG, Kai Stammerjohann, RYDB3RG@users.noreply.github.com +2016/11/05, runner-mei, meifakun, runner.mei@gmail.com +2016/11/15, hanjoes, Hanzhou Shi, hanzhou87@gmail.com +2016/11/16, sridharxp, Sridharan S, aurosridhar@gmail.com +2016/11/06, NoodleOfDeath, Thom Morgan, github@bytemeapp.com +2016/11/01, sebkur, Sebastian Kürten, sebastian@topobyte.de +2016/04/13, renatahodovan, Renata Hodovan, reni@inf.u-szeged.hu +2016/11/05, ewanmellor, Ewan Mellor, github@ewanmellor.org +2016/11/06, janyou, Janyou, janyou.antlr@outlook.com +2016/11/20, marcohu, Marco Hunsicker, antlr@hunsicker.de +2016/09/02, lygav, Vladimir (Vladi) Lyga, lyvladi@gmail.com +2016/09/23, ghosthope, Dmitry Shakhtanov, sudstrike@gmail.com +2016/11/25, MrSampson, Oliver Sampson, olsam@quickaudio.com +2016/11/29, millergarym, Gary Miller, miller.garym@gmail.com +2016/11/29, wxio, Gary Miller, gm@wx.io +2016/11/29, Naios, Denis Blank, naios@users.noreply.github.com +2016/12/01, samtatasurya, Samuel Tatasurya, xemradiant@gmail.com +2016/12/03, redxdev, Samuel Bloomberg, sam@redxdev.com +2016/12/11, Gaulouis, Gaulouis, gaulouis.com@gmail.com +2016/12/22, akosthekiss, Akos Kiss, akiss@inf.u-szeged.hu +2016/12/24, adrpo, Adrian Pop, adrian.pop@liu.se +2017/01/11, robertbrignull, Robert Brignull, robertbrignull@gmail.com +2017/01/13, marcelo-rocha, Marcelo Rocha, mcrocha@gmail.com +2017/01/23, bhamiltoncx, Ben Hamilton, bhamiltoncx+antlr@gmail.com +2017/01/18, mshockwave, Bekket McClane, yihshyng223@gmail.com +2017/02/10, lionelplessis, Lionel Plessis, lionelplessis@users.noreply.github.com +2017/02/14, lecode-official, David Neumann, david.neumann@lecode.de +2017/02/14, xied75, Dong Xie, xied75@gmail.com +2017/02/20, Thomasb81, Thomas Burg, thomasb81@gmail.com +2017/02/26, jvasileff, John Vasileff, john@vasileff.com +2017/03/08, harry-tallbelt, Igor Vysokopoyasny, harry.tallbelt@gmail.com +2017/03/09, teverett, Tom Everett, tom@khubla.com +2017/03/03, chund, Christian Hund, christian.hund@gmail.com +2017/03/15, robertvanderhulst, Robert van der Hulst, robert@xsharp.eu +2017/03/28, cmd-johnson, Jonas Auer, jonas.auer.94@gmail.com +2017/04/12, lys0716, Yishuang Lu, luyscmu@gmail.com +2017/04/30, shravanrn, Shravan Narayan, shravanrn@gmail.com +2017/05/11, jimallman, Jim Allman, jim@ibang.com +2017/05/26, waf, Will Fuqua, wafuqua@gmail.com +2017/05/29, kosak, Corey Kosak, kosak@kosak.com +2017/06/11, erikbra, Erik A. Brandstadmoen, erik@brandstadmoen.net +2017/06/10, jm-mikkelsen, Jan Martin Mikkelsen, janm@transactionware.com +2017/06/25, alimg, Alim Gökkaya, alim.gokkaya@gmail.com +2017/06/28, jBugman, Sergey Parshukov, codedby@bugman.me +2017/07/09, neatnerd, Mike Arshinskiy, neatnerd@users.noreply.github.com +2017/07/11, dhalperi, Daniel Halperin, daniel@halper.in +2017/07/17, vaibhavaingankar09, Vaibhav Vaingankar, vbhvvaingankar9@gmail.com +2017/07/23, venkatperi, Venkat Peri, venkatperi@gmail.com +2017/07/27, shirou, WAKAYAMA Shirou, shirou.faw@gmail.com +2017/07/09, neatnerd, Mike Arshinskiy, neatnerd@users.noreply.github.com +2017/07/27, matthauck, Matt Hauck, matthauck@gmail.com +2017/07/27, shirou, WAKAYAMA Shirou, shirou.faw@gmail.com +2017/08/20, tiagomazzutti, Tiago Mazzutti, tiagomzt@gmail.com +2017/08/20, milanaleksic, Milan Aleksic, milanaleksic@gmail.com +2017/08/29, Eddy Reyes, eddy@mindsight.io +2017/09/09, brauliobz, Bráulio Bezerra, brauliobezerra@gmail.com +2017/09/11, sachinjain024, Sachin Jain, sachinjain024@gmail.com +2017/09/25, kaedvann, Rostislav Listerenko, r.listerenko@gmail.com +2017/10/06, bramp, Andrew Brampton, brampton@gmail.com +2017/10/15, simkimsia, Sim Kim Sia, kimcity@gmail.com +2017/10/27, Griffon26, Maurice van der Pot, griffon26@kfk4ever.com +2017/05/29, rlfnb, Ralf Neeb, rlfnb@rlfnb.de +2017/10/29, gendalph, Максим Прохоренко, Maxim\dotProhorenko@gm@il.com +2017/11/02, jasonmoo, Jason Mooberry, jason.mooberry@gmail.com +2017/11/05, ajaypanyala, Ajay Panyala, ajay.panyala@gmail.com +2017/11/24, zqlu.cn, Zhiqiang Lu, zqlu.cn@gmail.com +2017/11/28, niccroad, Nicolas Croad, nic.croad@gmail.com +2017/12/01, DavidMoraisFerreira, David Morais Ferreira, david.moraisferreira@gmail.com +2017/12/01, SebastianLng, Sebastian Lang, sebastian.lang@outlook.com +2017/12/03, oranoran, Oran Epelbaum, oran / epelbaum me +2017/12/12, janlinde, Jan Lindemann, jan@janware.com +2017/12/13, enessoylu, Enes Soylu, enessoylutr@gmail.com +2017/12/20, kbsletten, Kyle Sletten, kbsletten@gmail.com +2017/12/27, jkmar, Jakub Marciniszyn, marciniszyn.jk@gmail.com +2018/03/08, dannoc, Daniel Clifford, danno@google.com +2018/03/10, uvguy, kangjoni76@gmail.com +2018/01/06, kasbah, Kaspar Emanuel, kaspar@monostable.co.uk +2018/01/15, xgcssch, Sönke Schau, xgcssch@users.noreply.github.com +2018/02/08, razfriman, Raz Friman, raz@razfriman.com +2018/02/11, io7m, Mark Raynsford, code@io7m.com +2018/04/24, solussd, Joe Smith, joe@uwcreations.com +2018/15/05, johnvanderholt, jan dillingh johnvanderholte@gmail.com +2018/06/14, scadgek, Sergey Chupov, scadgek@live.com +2018/06/16, EternalPhane, Zongyuan Zuo, eternalphane@gmail.com +2018/06/27, wu-sheng, Wu Sheng, wu.sheng@foxmail.com +2018/02/25, chaseoxide, Marcus Ong, taccs97[at]gmail[dot]com +2018/05/15, johnvanderholt, jan dillingh johnvanderholte@gmail.com +2018/06/16, EternalPhane, Zongyuan Zuo, eternalphane@gmail.com +2018/05/15, johnvanderholt, jan dillingh johnvanderholte@gmail.com +2018/05/17, sinopsysHK, Eric Bardes, sinofwd@gmail.com +2018/05/23, srvance, Stephen Vance, steve@vance.com +2018/06/14, alecont, Alessandro Contenti, alecontenti@hotmail.com +2018/06/16, EternalPhane, Zongyuan Zuo, eternalphane@gmail.com +2018/07/03, jgoppert, James Goppert, james.goppert@gmail.com +2018/07/27, Maksim Novikov, mnovikov.work@gmail.com +2018/07/31, Lucas Henrqiue, lucashenrique580@gmail.com +2018/08/03, ENDOH takanao, djmchl@gmail.com +2018/10/29, chrisaycock, Christopher Aycock, chris[at]chrisaycock[dot]com +2018/11/12, vinoski, Steve Vinoski, vinoski@ieee.org +2018/11/14, nxtstep, Adriaan (Arjan) Duz, codewithadriaan[et]gmail[dot]com +2018/11/15, amykyta3, Alex Mykyta, amykyta3@users.noreply.github.com +2018/11/29, hannemann-tamas, Ralf Hannemann-Tamas, ralf.ht@gmail.com \ No newline at end of file diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn.go new file mode 100644 index 000000000..1592212e1 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn.go @@ -0,0 +1,152 @@ +// Copyright (c) 2012-2017 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 + +var ATNInvalidAltNumber int + +type ATN struct { + // DecisionToState is the decision points for all rules, subrules, optional + // blocks, ()+, ()*, etc. Used to build DFA predictors for them. + DecisionToState []DecisionState + + // grammarType is the ATN type and is used for deserializing ATNs from strings. + grammarType int + + // lexerActions is referenced by action transitions in the ATN for lexer ATNs. + lexerActions []LexerAction + + // maxTokenType is the maximum value for any symbol recognized by a transition in the ATN. + maxTokenType int + + modeNameToStartState map[string]*TokensStartState + + modeToStartState []*TokensStartState + + // ruleToStartState maps from rule index to starting state number. + ruleToStartState []*RuleStartState + + // ruleToStopState maps from rule index to stop state number. + ruleToStopState []*RuleStopState + + // ruleToTokenType maps the rule index to the resulting token type for lexer + // ATNs. For parser ATNs, it maps the rule index to the generated bypass token + // type if ATNDeserializationOptions.isGenerateRuleBypassTransitions was + // specified, and otherwise is nil. + ruleToTokenType []int + + states []ATNState +} + +func NewATN(grammarType int, maxTokenType int) *ATN { + return &ATN{ + grammarType: grammarType, + maxTokenType: maxTokenType, + modeNameToStartState: make(map[string]*TokensStartState), + } +} + +// NextTokensInContext computes 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. +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 +// rule. +func (a *ATN) NextTokensNoContext(s ATNState) *IntervalSet { + if s.GetNextTokenWithinRule() != nil { + return s.GetNextTokenWithinRule() + } + + s.SetNextTokenWithinRule(a.NextTokensInContext(s, nil)) + s.GetNextTokenWithinRule().readOnly = true + + return s.GetNextTokenWithinRule() +} + +func (a *ATN) NextTokens(s ATNState, ctx RuleContext) *IntervalSet { + if ctx == nil { + return a.NextTokensNoContext(s) + } + + return a.NextTokensInContext(s, ctx) +} + +func (a *ATN) addState(state ATNState) { + if state != nil { + state.SetATN(a) + state.SetStateNumber(len(a.states)) + } + + a.states = append(a.states, state) +} + +func (a *ATN) removeState(state ATNState) { + a.states[state.GetStateNumber()] = nil // Just free the memory; don't shift states in the slice +} + +func (a *ATN) defineDecisionState(s DecisionState) int { + a.DecisionToState = append(a.DecisionToState, s) + s.setDecision(len(a.DecisionToState) - 1) + + return s.getDecision() +} + +func (a *ATN) getDecisionState(decision int) DecisionState { + if len(a.DecisionToState) == 0 { + return nil + } + + return a.DecisionToState[decision] +} + +// getExpectedTokens computes the set of input symbols which could follow ATN +// state number stateNumber in the specified full parse context ctx and returns +// the set of potentially valid input symbols which could follow the specified +// state in the specified context. This method considers the complete parser +// context, but does not evaluate semantic predicates (i.e. all predicates +// encountered during the calculation are assumed true). If a path in the ATN +// exists from the starting state to the RuleStopState of the outermost context +// without Matching any symbols, Token.EOF is added to the returned set. +// +// A nil ctx defaults to ParserRuleContext.EMPTY. +// +// It panics if the ATN does not contain state stateNumber. +func (a *ATN) getExpectedTokens(stateNumber int, ctx RuleContext) *IntervalSet { + if stateNumber < 0 || stateNumber >= len(a.states) { + panic("Invalid state number.") + } + + s := a.states[stateNumber] + following := a.NextTokens(s, nil) + + if !following.contains(TokenEpsilon) { + return following + } + + expected := NewIntervalSet() + + expected.addSet(following) + expected.removeOne(TokenEpsilon) + + for ctx != nil && ctx.GetInvokingState() >= 0 && following.contains(TokenEpsilon) { + invokingState := a.states[ctx.GetInvokingState()] + rt := invokingState.GetTransitions()[0] + + following = a.NextTokens(rt.(*RuleTransition).followState, nil) + expected.addSet(following) + expected.removeOne(TokenEpsilon) + ctx = ctx.GetParent().(RuleContext) + } + + if following.contains(TokenEpsilon) { + expected.addOne(TokenEOF) + } + + return expected +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config.go new file mode 100644 index 000000000..0535d5246 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config.go @@ -0,0 +1,295 @@ +// Copyright (c) 2012-2017 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" +) + +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 + + GetState() ATNState + GetAlt() int + GetSemanticContext() SemanticContext + + GetContext() PredictionContext + SetContext(PredictionContext) + + GetReachesIntoOuterContext() int + SetReachesIntoOuterContext(int) + + String() string + + getPrecedenceFilterSuppressed() bool + setPrecedenceFilterSuppressed(bool) +} + +type BaseATNConfig struct { + precedenceFilterSuppressed bool + state ATNState + alt int + context PredictionContext + semanticContext SemanticContext + reachesIntoOuterContext int +} + +func NewBaseATNConfig7(old *BaseATNConfig) *BaseATNConfig { // TODO: Dup + return &BaseATNConfig{ + state: old.state, + alt: old.alt, + context: old.context, + semanticContext: old.semanticContext, + reachesIntoOuterContext: old.reachesIntoOuterContext, + } +} + +func NewBaseATNConfig6(state ATNState, alt int, context PredictionContext) *BaseATNConfig { + return NewBaseATNConfig5(state, alt, context, SemanticContextNone) +} + +func NewBaseATNConfig5(state ATNState, alt int, context PredictionContext, semanticContext SemanticContext) *BaseATNConfig { + if semanticContext == nil { + panic("semanticContext cannot be nil") // TODO: Necessary? + } + + return &BaseATNConfig{state: state, alt: alt, context: context, semanticContext: semanticContext} +} + +func NewBaseATNConfig4(c ATNConfig, state ATNState) *BaseATNConfig { + return NewBaseATNConfig(c, state, c.GetContext(), c.GetSemanticContext()) +} + +func NewBaseATNConfig3(c ATNConfig, state ATNState, semanticContext SemanticContext) *BaseATNConfig { + return NewBaseATNConfig(c, state, c.GetContext(), semanticContext) +} + +func NewBaseATNConfig2(c ATNConfig, semanticContext SemanticContext) *BaseATNConfig { + return NewBaseATNConfig(c, c.GetState(), c.GetContext(), semanticContext) +} + +func NewBaseATNConfig1(c ATNConfig, state ATNState, context PredictionContext) *BaseATNConfig { + return NewBaseATNConfig(c, state, context, c.GetSemanticContext()) +} + +func NewBaseATNConfig(c ATNConfig, state ATNState, context PredictionContext, semanticContext SemanticContext) *BaseATNConfig { + if semanticContext == nil { + panic("semanticContext cannot be nil") + } + + return &BaseATNConfig{ + state: state, + alt: c.GetAlt(), + context: context, + semanticContext: semanticContext, + reachesIntoOuterContext: c.GetReachesIntoOuterContext(), + precedenceFilterSuppressed: c.getPrecedenceFilterSuppressed(), + } +} + +func (b *BaseATNConfig) getPrecedenceFilterSuppressed() bool { + return b.precedenceFilterSuppressed +} + +func (b *BaseATNConfig) setPrecedenceFilterSuppressed(v bool) { + b.precedenceFilterSuppressed = v +} + +func (b *BaseATNConfig) GetState() ATNState { + return b.state +} + +func (b *BaseATNConfig) GetAlt() int { + return b.alt +} + +func (b *BaseATNConfig) SetContext(v PredictionContext) { + b.context = v +} +func (b *BaseATNConfig) GetContext() PredictionContext { + return b.context +} + +func (b *BaseATNConfig) GetSemanticContext() SemanticContext { + return b.semanticContext +} + +func (b *BaseATNConfig) GetReachesIntoOuterContext() int { + return b.reachesIntoOuterContext +} + +func (b *BaseATNConfig) SetReachesIntoOuterContext(v int) { + b.reachesIntoOuterContext = v +} + +// 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 { + if b == o { + return true + } + + var other, ok = o.(*BaseATNConfig) + + if !ok { + return false + } + + var equal bool + + if b.context == nil { + equal = other.context == nil + } else { + 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) + sups = b.precedenceFilterSuppressed == other.precedenceFilterSuppressed + ) + + return nums && alts && cons && sups && equal +} + +func (b *BaseATNConfig) hash() int { + var c int + if b.context != nil { + 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()) + return murmurFinish(h, 4) +} + +func (b *BaseATNConfig) String() string { + var s1, s2, s3 string + + if b.context != nil { + s1 = ",[" + fmt.Sprint(b.context) + "]" + } + + if b.semanticContext != SemanticContextNone { + s2 = "," + fmt.Sprint(b.semanticContext) + } + + if b.reachesIntoOuterContext > 0 { + s3 = ",up=" + fmt.Sprint(b.reachesIntoOuterContext) + } + + return fmt.Sprintf("(%v,%v%v%v%v)", b.state, b.alt, s1, s2, s3) +} + +type LexerATNConfig struct { + *BaseATNConfig + lexerActionExecutor *LexerActionExecutor + passedThroughNonGreedyDecision bool +} + +func NewLexerATNConfig6(state ATNState, alt int, context PredictionContext) *LexerATNConfig { + return &LexerATNConfig{BaseATNConfig: NewBaseATNConfig5(state, alt, context, SemanticContextNone)} +} + +func NewLexerATNConfig5(state ATNState, alt int, context PredictionContext, lexerActionExecutor *LexerActionExecutor) *LexerATNConfig { + return &LexerATNConfig{ + BaseATNConfig: NewBaseATNConfig5(state, alt, context, SemanticContextNone), + lexerActionExecutor: lexerActionExecutor, + } +} + +func NewLexerATNConfig4(c *LexerATNConfig, state ATNState) *LexerATNConfig { + return &LexerATNConfig{ + BaseATNConfig: NewBaseATNConfig(c, state, c.GetContext(), c.GetSemanticContext()), + lexerActionExecutor: c.lexerActionExecutor, + passedThroughNonGreedyDecision: checkNonGreedyDecision(c, state), + } +} + +func NewLexerATNConfig3(c *LexerATNConfig, state ATNState, lexerActionExecutor *LexerActionExecutor) *LexerATNConfig { + return &LexerATNConfig{ + BaseATNConfig: NewBaseATNConfig(c, state, c.GetContext(), c.GetSemanticContext()), + lexerActionExecutor: lexerActionExecutor, + passedThroughNonGreedyDecision: checkNonGreedyDecision(c, state), + } +} + +func NewLexerATNConfig2(c *LexerATNConfig, state ATNState, context PredictionContext) *LexerATNConfig { + return &LexerATNConfig{ + BaseATNConfig: NewBaseATNConfig(c, state, context, c.GetSemanticContext()), + lexerActionExecutor: c.lexerActionExecutor, + passedThroughNonGreedyDecision: checkNonGreedyDecision(c, state), + } +} + +func NewLexerATNConfig1(state ATNState, alt int, context PredictionContext) *LexerATNConfig { + return &LexerATNConfig{BaseATNConfig: NewBaseATNConfig5(state, alt, context, SemanticContextNone)} +} + +func (l *LexerATNConfig) hash() int { + var f int + if l.passedThroughNonGreedyDecision { + f = 1 + } else { + f = 0 + } + h := murmurInit(7) + h = murmurUpdate(h, l.state.hash()) + h = murmurUpdate(h, l.alt) + h = murmurUpdate(h, l.context.hash()) + h = murmurUpdate(h, l.semanticContext.hash()) + h = murmurUpdate(h, f) + h = murmurUpdate(h, l.lexerActionExecutor.hash()) + h = murmurFinish(h, 6) + return h +} + +func (l *LexerATNConfig) equals(other interface{}) bool { + var othert, ok = other.(*LexerATNConfig) + + if l == other { + return true + } else if !ok { + return false + } else if l.passedThroughNonGreedyDecision != othert.passedThroughNonGreedyDecision { + return false + } + + var b bool + + if l.lexerActionExecutor != nil { + b = !l.lexerActionExecutor.equals(othert.lexerActionExecutor) + } else { + b = othert.lexerActionExecutor != nil + } + + if b { + return false + } + + return l.BaseATNConfig.equals(othert.BaseATNConfig) +} + + +func checkNonGreedyDecision(source *LexerATNConfig, target ATNState) bool { + var ds, ok = target.(DecisionState) + + return source.passedThroughNonGreedyDecision || (ok && ds.getNonGreedy()) +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config_set.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config_set.go new file mode 100644 index 000000000..d9f74755f --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config_set.go @@ -0,0 +1,387 @@ +// Copyright (c) 2012-2017 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" + +type ATNConfigSet interface { + hash() int + Add(ATNConfig, *DoubleDict) bool + AddAll([]ATNConfig) bool + + GetStates() *Set + GetPredicates() []SemanticContext + GetItems() []ATNConfig + + OptimizeConfigs(interpreter *BaseATNSimulator) + + Equals(other interface{}) bool + + Length() int + IsEmpty() bool + Contains(ATNConfig) bool + ContainsFast(ATNConfig) bool + Clear() + String() string + + HasSemanticContext() bool + SetHasSemanticContext(v bool) + + ReadOnly() bool + SetReadOnly(bool) + + GetConflictingAlts() *BitSet + SetConflictingAlts(*BitSet) + + FullContext() bool + + GetUniqueAlt() int + SetUniqueAlt(int) + + GetDipsIntoOuterContext() bool + SetDipsIntoOuterContext(bool) +} + +// BaseATNConfigSet is a specialized set of ATNConfig that tracks information +// about its elements and can combine similar configurations using a +// graph-structured stack. +type BaseATNConfigSet struct { + cachedHash int + + // configLookup is used to determine whether two BaseATNConfigSets are equal. We + // need all configurations with the same (s, i, _, semctx) to be equal. A key + // 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 + + // configs is the added elements. + configs []ATNConfig + + // TODO: These fields make me pretty uncomfortable, but it is nice to pack up + // info together because it saves recomputation. Can we track conflicts as they + // are added to save scanning configs later? + conflictingAlts *BitSet + + // dipsIntoOuterContext is used by parsers and lexers. In a lexer, it indicates + // we hit a pred while computing a closure operation. Do not make a DFA state + // from the BaseATNConfigSet in this case. TODO: How is this used by parsers? + dipsIntoOuterContext bool + + // fullCtx is whether it is part of a full context LL prediction. Used to + // determine how to merge $. It is a wildcard with SLL, but not for an LL + // context merge. + fullCtx bool + + // Used in parser and lexer. In lexer, it indicates we hit a pred + // while computing a closure operation. Don't make a DFA state from a. + hasSemanticContext bool + + // 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 + // in particular, which is assigned after readOnly. + readOnly bool + + // TODO: These fields make me pretty uncomfortable, but it is nice to pack up + // info together because it saves recomputation. Can we track conflicts as they + // are added to save scanning configs later? + uniqueAlt int +} + +func NewBaseATNConfigSet(fullCtx bool) *BaseATNConfigSet { + return &BaseATNConfigSet{ + cachedHash: -1, + configLookup: NewSet(nil, equalATNConfigs), + fullCtx: fullCtx, + } +} + +// Add merges contexts with existing configs for (s, i, pi, _), where s is the +// ATNConfig.state, i is the ATNConfig.alt, and pi is the +// ATNConfig.semanticContext. We use (s,i,pi) as the key. Updates +// dipsIntoOuterContext and hasSemanticContext when necessary. +func (b *BaseATNConfigSet) Add(config ATNConfig, mergeCache *DoubleDict) bool { + if b.readOnly { + panic("set is read-only") + } + + if config.GetSemanticContext() != SemanticContextNone { + b.hasSemanticContext = true + } + + if config.GetReachesIntoOuterContext() > 0 { + b.dipsIntoOuterContext = true + } + + existing := b.configLookup.add(config).(ATNConfig) + + if existing == config { + b.cachedHash = -1 + b.configs = append(b.configs, config) // Track order here + + return true + } + + // Merge a previous (s, i, pi, _) with it and save the result + rootIsWildcard := !b.fullCtx + merged := merge(existing.GetContext(), config.GetContext(), rootIsWildcard, mergeCache) + + // No need to check for existing.context because config.context is in the cache, + // since the only way to create new graphs is the "call rule" and here. We cache + // at both places. + existing.SetReachesIntoOuterContext(intMax(existing.GetReachesIntoOuterContext(), config.GetReachesIntoOuterContext())) + + // Preserve the precedence filter suppression during the merge + if config.getPrecedenceFilterSuppressed() { + existing.setPrecedenceFilterSuppressed(true) + } + + // Replace the context because there is no need to do alt mapping + existing.SetContext(merged) + + return true +} + +func (b *BaseATNConfigSet) GetStates() *Set { + states := NewSet(nil, nil) + + for i := 0; i < len(b.configs); i++ { + states.add(b.configs[i].GetState()) + } + + return states +} + +func (b *BaseATNConfigSet) HasSemanticContext() bool { + return b.hasSemanticContext +} + +func (b *BaseATNConfigSet) SetHasSemanticContext(v bool) { + b.hasSemanticContext = v +} + +func (b *BaseATNConfigSet) GetPredicates() []SemanticContext { + preds := make([]SemanticContext, 0) + + for i := 0; i < len(b.configs); i++ { + c := b.configs[i].GetSemanticContext() + + if c != SemanticContextNone { + preds = append(preds, c) + } + } + + return preds +} + +func (b *BaseATNConfigSet) GetItems() []ATNConfig { + return b.configs +} + +func (b *BaseATNConfigSet) OptimizeConfigs(interpreter *BaseATNSimulator) { + if b.readOnly { + panic("set is read-only") + } + + if b.configLookup.length() == 0 { + return + } + + for i := 0; i < len(b.configs); i++ { + config := b.configs[i] + + config.SetContext(interpreter.getCachedContext(config.GetContext())) + } +} + +func (b *BaseATNConfigSet) AddAll(coll []ATNConfig) bool { + for i := 0; i < len(coll); i++ { + b.Add(coll[i], nil) + } + + return false +} + +func (b *BaseATNConfigSet) Equals(other interface{}) bool { + if b == other { + return true + } else if _, ok := other.(*BaseATNConfigSet); !ok { + return false + } + + 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 +} + +func (b *BaseATNConfigSet) hash() int { + if b.readOnly { + if b.cachedHash == -1 { + b.cachedHash = b.hashCodeConfigs() + } + + return b.cachedHash + } + + return b.hashCodeConfigs() +} + +func (b *BaseATNConfigSet) hashCodeConfigs() int { + h := murmurInit(1) + for _, c := range b.configs { + if c != nil { + h = murmurUpdate(h, c.hash()) + } + } + return murmurFinish(h, len(b.configs)) +} + +func (b *BaseATNConfigSet) Length() int { + return len(b.configs) +} + +func (b *BaseATNConfigSet) IsEmpty() bool { + return len(b.configs) == 0 +} + +func (b *BaseATNConfigSet) Contains(item ATNConfig) bool { + if b.configLookup == nil { + panic("not implemented for read-only sets") + } + + return b.configLookup.contains(item) +} + +func (b *BaseATNConfigSet) ContainsFast(item ATNConfig) bool { + if b.configLookup == nil { + panic("not implemented for read-only sets") + } + + return b.configLookup.contains(item) // TODO: containsFast is not implemented for Set +} + +func (b *BaseATNConfigSet) Clear() { + if b.readOnly { + panic("set is read-only") + } + + b.configs = make([]ATNConfig, 0) + b.cachedHash = -1 + b.configLookup = NewSet(nil, equalATNConfigs) +} + +func (b *BaseATNConfigSet) FullContext() bool { + return b.fullCtx +} + +func (b *BaseATNConfigSet) GetDipsIntoOuterContext() bool { + return b.dipsIntoOuterContext +} + +func (b *BaseATNConfigSet) SetDipsIntoOuterContext(v bool) { + b.dipsIntoOuterContext = v +} + +func (b *BaseATNConfigSet) GetUniqueAlt() int { + return b.uniqueAlt +} + +func (b *BaseATNConfigSet) SetUniqueAlt(v int) { + b.uniqueAlt = v +} + +func (b *BaseATNConfigSet) GetConflictingAlts() *BitSet { + return b.conflictingAlts +} + +func (b *BaseATNConfigSet) SetConflictingAlts(v *BitSet) { + b.conflictingAlts = v +} + +func (b *BaseATNConfigSet) ReadOnly() bool { + return b.readOnly +} + +func (b *BaseATNConfigSet) SetReadOnly(readOnly bool) { + b.readOnly = readOnly + + if readOnly { + b.configLookup = nil // Read only, so no need for the lookup cache + } +} + +func (b *BaseATNConfigSet) String() string { + s := "[" + + for i, c := range b.configs { + s += c.String() + + if i != len(b.configs)-1 { + s += ", " + } + } + + s += "]" + + if b.hasSemanticContext { + s += ",hasSemanticContext=" + fmt.Sprint(b.hasSemanticContext) + } + + if b.uniqueAlt != ATNInvalidAltNumber { + s += ",uniqueAlt=" + fmt.Sprint(b.uniqueAlt) + } + + if b.conflictingAlts != nil { + s += ",conflictingAlts=" + b.conflictingAlts.String() + } + + if b.dipsIntoOuterContext { + s += ",dipsIntoOuterContext" + } + + return s +} + +type OrderedATNConfigSet struct { + *BaseATNConfigSet +} + +func NewOrderedATNConfigSet() *OrderedATNConfigSet { + b := NewBaseATNConfigSet(false) + + b.configLookup = NewSet(nil, nil) + + return &OrderedATNConfigSet{BaseATNConfigSet: b} +} + +func equalATNConfigs(a, b interface{}) bool { + if a == nil || b == nil { + return false + } + + if a == b { + return true + } + + var ai, ok = a.(ATNConfig) + var bi, ok1 = b.(ATNConfig) + + if !ok || !ok1 { + return false + } + + nums := ai.GetState().GetStateNumber() == bi.GetState().GetStateNumber() + alts := ai.GetAlt() == bi.GetAlt() + cons := ai.GetSemanticContext().equals(bi.GetSemanticContext()) + + return nums && alts && cons +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserialization_options.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserialization_options.go new file mode 100644 index 000000000..18b89efaf --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserialization_options.go @@ -0,0 +1,25 @@ +// Copyright (c) 2012-2017 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 + +var ATNDeserializationOptionsdefaultOptions = &ATNDeserializationOptions{true, false, false} + +type ATNDeserializationOptions struct { + readOnly bool + verifyATN bool + generateRuleBypassTransitions bool +} + +func NewATNDeserializationOptions(CopyFrom *ATNDeserializationOptions) *ATNDeserializationOptions { + o := new(ATNDeserializationOptions) + + if CopyFrom != nil { + o.readOnly = CopyFrom.readOnly + o.verifyATN = CopyFrom.verifyATN + o.generateRuleBypassTransitions = CopyFrom.generateRuleBypassTransitions + } + + return o +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserializer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserializer.go new file mode 100644 index 000000000..884d39cf7 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserializer.go @@ -0,0 +1,828 @@ +// Copyright (c) 2012-2017 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 ( + "encoding/hex" + "fmt" + "strconv" + "strings" + "unicode/utf16" +) + +// This is the earliest supported serialized UUID. +// stick to serialized version for now, we don't need a UUID instance +var BaseSerializedUUID = "AADB8D7E-AEEF-4415-AD2B-8204D6CF042E" +var AddedUnicodeSMP = "59627784-3BE5-417A-B9EB-8131A7286089" + +// This list contains all of the currently supported UUIDs, ordered by when +// the feature first appeared in this branch. +var SupportedUUIDs = []string{BaseSerializedUUID, AddedUnicodeSMP} + +var SerializedVersion = 3 + +// This is the current serialized UUID. +var SerializedUUID = AddedUnicodeSMP + +type LoopEndStateIntPair struct { + item0 *LoopEndState + item1 int +} + +type BlockStartStateIntPair struct { + item0 BlockStartState + item1 int +} + +type ATNDeserializer struct { + deserializationOptions *ATNDeserializationOptions + data []rune + pos int + uuid string +} + +func NewATNDeserializer(options *ATNDeserializationOptions) *ATNDeserializer { + if options == nil { + options = ATNDeserializationOptionsdefaultOptions + } + + return &ATNDeserializer{deserializationOptions: options} +} + +func stringInSlice(a string, list []string) int { + for i, b := range list { + if b == a { + return i + } + } + + return -1 +} + +// isFeatureSupported determines if a particular serialized representation of an +// ATN supports a particular feature, identified by the UUID used for +// serializing the ATN at the time the feature was first introduced. Feature is +// the UUID marking the first time the feature was supported in the serialized +// ATN. ActualUuid is the UUID of the actual serialized ATN which is currently +// being deserialized. It returns true if actualUuid represents a serialized ATN +// at or after the feature identified by feature was introduced, and otherwise +// false. +func (a *ATNDeserializer) isFeatureSupported(feature, actualUUID string) bool { + idx1 := stringInSlice(feature, SupportedUUIDs) + + if idx1 < 0 { + return false + } + + idx2 := stringInSlice(actualUUID, SupportedUUIDs) + + return idx2 >= idx1 +} + +func (a *ATNDeserializer) DeserializeFromUInt16(data []uint16) *ATN { + a.reset(utf16.Decode(data)) + a.checkVersion() + a.checkUUID() + + atn := a.readATN() + + a.readStates(atn) + a.readRules(atn) + a.readModes(atn) + + sets := make([]*IntervalSet, 0) + + // First, deserialize sets with 16-bit arguments <= U+FFFF. + sets = a.readSets(atn, sets, a.readInt) + // Next, if the ATN was serialized with the Unicode SMP feature, + // deserialize sets with 32-bit arguments <= U+10FFFF. + if (a.isFeatureSupported(AddedUnicodeSMP, a.uuid)) { + sets = a.readSets(atn, sets, a.readInt32) + } + + a.readEdges(atn, sets) + a.readDecisions(atn) + a.readLexerActions(atn) + a.markPrecedenceDecisions(atn) + a.verifyATN(atn) + + if a.deserializationOptions.generateRuleBypassTransitions && atn.grammarType == ATNTypeParser { + a.generateRuleBypassTransitions(atn) + // Re-verify after modification + a.verifyATN(atn) + } + + return atn + +} + +func (a *ATNDeserializer) reset(data []rune) { + temp := make([]rune, len(data)) + + for i, c := range data { + // Don't adjust the first value since that's the version number + if i == 0 { + temp[i] = c + } else if c > 1 { + temp[i] = c - 2 + } else { + temp[i] = c + 65533 + } + } + + a.data = temp + a.pos = 0 +} + +func (a *ATNDeserializer) checkVersion() { + version := a.readInt() + + if version != SerializedVersion { + panic("Could not deserialize ATN with version " + strconv.Itoa(version) + " (expected " + strconv.Itoa(SerializedVersion) + ").") + } +} + +func (a *ATNDeserializer) checkUUID() { + uuid := a.readUUID() + + if stringInSlice(uuid, SupportedUUIDs) < 0 { + panic("Could not deserialize ATN with UUID: " + uuid + " (expected " + SerializedUUID + " or a legacy UUID).") + } + + a.uuid = uuid +} + +func (a *ATNDeserializer) readATN() *ATN { + grammarType := a.readInt() + maxTokenType := a.readInt() + + return NewATN(grammarType, maxTokenType) +} + +func (a *ATNDeserializer) readStates(atn *ATN) { + loopBackStateNumbers := make([]LoopEndStateIntPair, 0) + endStateNumbers := make([]BlockStartStateIntPair, 0) + + nstates := a.readInt() + + for i := 0; i < nstates; i++ { + stype := a.readInt() + + // Ignore bad types of states + if stype == ATNStateInvalidType { + atn.addState(nil) + + continue + } + + ruleIndex := a.readInt() + + if ruleIndex == 0xFFFF { + ruleIndex = -1 + } + + s := a.stateFactory(stype, ruleIndex) + + if stype == ATNStateLoopEnd { + loopBackStateNumber := a.readInt() + + loopBackStateNumbers = append(loopBackStateNumbers, LoopEndStateIntPair{s.(*LoopEndState), loopBackStateNumber}) + } else if s2, ok := s.(BlockStartState); ok { + endStateNumber := a.readInt() + + endStateNumbers = append(endStateNumbers, BlockStartStateIntPair{s2, endStateNumber}) + } + + atn.addState(s) + } + + // Delay the assignment of loop back and end states until we know all the state + // instances have been initialized + for j := 0; j < len(loopBackStateNumbers); j++ { + pair := loopBackStateNumbers[j] + + pair.item0.loopBackState = atn.states[pair.item1] + } + + for j := 0; j < len(endStateNumbers); j++ { + pair := endStateNumbers[j] + + pair.item0.setEndState(atn.states[pair.item1].(*BlockEndState)) + } + + numNonGreedyStates := a.readInt() + + for j := 0; j < numNonGreedyStates; j++ { + stateNumber := a.readInt() + + atn.states[stateNumber].(DecisionState).setNonGreedy(true) + } + + numPrecedenceStates := a.readInt() + + for j := 0; j < numPrecedenceStates; j++ { + stateNumber := a.readInt() + + atn.states[stateNumber].(*RuleStartState).isPrecedenceRule = true + } +} + +func (a *ATNDeserializer) readRules(atn *ATN) { + nrules := a.readInt() + + if atn.grammarType == ATNTypeLexer { + atn.ruleToTokenType = make([]int, nrules) // TODO: initIntArray(nrules, 0) + } + + atn.ruleToStartState = make([]*RuleStartState, nrules) // TODO: initIntArray(nrules, 0) + + for i := 0; i < nrules; i++ { + s := a.readInt() + startState := atn.states[s].(*RuleStartState) + + atn.ruleToStartState[i] = startState + + if atn.grammarType == ATNTypeLexer { + tokenType := a.readInt() + + if tokenType == 0xFFFF { + tokenType = TokenEOF + } + + atn.ruleToTokenType[i] = tokenType + } + } + + atn.ruleToStopState = make([]*RuleStopState, nrules) //initIntArray(nrules, 0) + + for i := 0; i < len(atn.states); i++ { + state := atn.states[i] + + if s2, ok := state.(*RuleStopState); ok { + atn.ruleToStopState[s2.ruleIndex] = s2 + atn.ruleToStartState[s2.ruleIndex].stopState = s2 + } + } +} + +func (a *ATNDeserializer) readModes(atn *ATN) { + nmodes := a.readInt() + + for i := 0; i < nmodes; i++ { + s := a.readInt() + + atn.modeToStartState = append(atn.modeToStartState, atn.states[s].(*TokensStartState)) + } +} + +func (a *ATNDeserializer) readSets(atn *ATN, sets []*IntervalSet, readUnicode func() int) []*IntervalSet { + m := a.readInt() + + for i := 0; i < m; i++ { + iset := NewIntervalSet() + + sets = append(sets, iset) + + n := a.readInt() + containsEOF := a.readInt() + + if containsEOF != 0 { + iset.addOne(-1) + } + + for j := 0; j < n; j++ { + i1 := readUnicode() + i2 := readUnicode() + + iset.addRange(i1, i2) + } + } + + return sets +} + +func (a *ATNDeserializer) readEdges(atn *ATN, sets []*IntervalSet) { + nedges := a.readInt() + + for i := 0; i < nedges; i++ { + var ( + src = a.readInt() + trg = a.readInt() + ttype = a.readInt() + arg1 = a.readInt() + arg2 = a.readInt() + arg3 = a.readInt() + trans = a.edgeFactory(atn, ttype, src, trg, arg1, arg2, arg3, sets) + srcState = atn.states[src] + ) + + srcState.AddTransition(trans, -1) + } + + // Edges for rule stop states can be derived, so they are not serialized + for i := 0; i < len(atn.states); i++ { + state := atn.states[i] + + for j := 0; j < len(state.GetTransitions()); j++ { + var t, ok = state.GetTransitions()[j].(*RuleTransition) + + if !ok { + continue + } + + outermostPrecedenceReturn := -1 + + if atn.ruleToStartState[t.getTarget().GetRuleIndex()].isPrecedenceRule { + if t.precedence == 0 { + outermostPrecedenceReturn = t.getTarget().GetRuleIndex() + } + } + + trans := NewEpsilonTransition(t.followState, outermostPrecedenceReturn) + + atn.ruleToStopState[t.getTarget().GetRuleIndex()].AddTransition(trans, -1) + } + } + + for i := 0; i < len(atn.states); i++ { + state := atn.states[i] + + if s2, ok := state.(*BaseBlockStartState); ok { + // We need to know the end state to set its start state + if s2.endState == nil { + panic("IllegalState") + } + + // Block end states can only be associated to a single block start state + if s2.endState.startState != nil { + panic("IllegalState") + } + + s2.endState.startState = state + } + + if s2, ok := state.(*PlusLoopbackState); ok { + for j := 0; j < len(s2.GetTransitions()); j++ { + target := s2.GetTransitions()[j].getTarget() + + if t2, ok := target.(*PlusBlockStartState); ok { + t2.loopBackState = state + } + } + } else if s2, ok := state.(*StarLoopbackState); ok { + for j := 0; j < len(s2.GetTransitions()); j++ { + target := s2.GetTransitions()[j].getTarget() + + if t2, ok := target.(*StarLoopEntryState); ok { + t2.loopBackState = state + } + } + } + } +} + +func (a *ATNDeserializer) readDecisions(atn *ATN) { + ndecisions := a.readInt() + + for i := 0; i < ndecisions; i++ { + s := a.readInt() + decState := atn.states[s].(DecisionState) + + atn.DecisionToState = append(atn.DecisionToState, decState) + decState.setDecision(i) + } +} + +func (a *ATNDeserializer) readLexerActions(atn *ATN) { + if atn.grammarType == ATNTypeLexer { + count := a.readInt() + + atn.lexerActions = make([]LexerAction, count) // initIntArray(count, nil) + + for i := 0; i < count; i++ { + actionType := a.readInt() + data1 := a.readInt() + + if data1 == 0xFFFF { + data1 = -1 + } + + data2 := a.readInt() + + if data2 == 0xFFFF { + data2 = -1 + } + + lexerAction := a.lexerActionFactory(actionType, data1, data2) + + atn.lexerActions[i] = lexerAction + } + } +} + +func (a *ATNDeserializer) generateRuleBypassTransitions(atn *ATN) { + count := len(atn.ruleToStartState) + + for i := 0; i < count; i++ { + atn.ruleToTokenType[i] = atn.maxTokenType + i + 1 + } + + for i := 0; i < count; i++ { + a.generateRuleBypassTransition(atn, i) + } +} + +func (a *ATNDeserializer) generateRuleBypassTransition(atn *ATN, idx int) { + bypassStart := NewBasicBlockStartState() + + bypassStart.ruleIndex = idx + atn.addState(bypassStart) + + bypassStop := NewBlockEndState() + + bypassStop.ruleIndex = idx + atn.addState(bypassStop) + + bypassStart.endState = bypassStop + + atn.defineDecisionState(bypassStart.BaseDecisionState) + + bypassStop.startState = bypassStart + + var excludeTransition Transition + var endState ATNState + + if atn.ruleToStartState[idx].isPrecedenceRule { + // Wrap from the beginning of the rule to the StarLoopEntryState + endState = nil + + for i := 0; i < len(atn.states); i++ { + state := atn.states[i] + + if a.stateIsEndStateFor(state, idx) != nil { + endState = state + excludeTransition = state.(*StarLoopEntryState).loopBackState.GetTransitions()[0] + + break + } + } + + if excludeTransition == nil { + panic("Couldn't identify final state of the precedence rule prefix section.") + } + } else { + endState = atn.ruleToStopState[idx] + } + + // All non-excluded transitions that currently target end state need to target + // blockEnd instead + for i := 0; i < len(atn.states); i++ { + state := atn.states[i] + + for j := 0; j < len(state.GetTransitions()); j++ { + transition := state.GetTransitions()[j] + + if transition == excludeTransition { + continue + } + + if transition.getTarget() == endState { + transition.setTarget(bypassStop) + } + } + } + + // All transitions leaving the rule start state need to leave blockStart instead + ruleToStartState := atn.ruleToStartState[idx] + count := len(ruleToStartState.GetTransitions()) + + for count > 0 { + bypassStart.AddTransition(ruleToStartState.GetTransitions()[count-1], -1) + ruleToStartState.SetTransitions([]Transition{ruleToStartState.GetTransitions()[len(ruleToStartState.GetTransitions())-1]}) + } + + // Link the new states + atn.ruleToStartState[idx].AddTransition(NewEpsilonTransition(bypassStart, -1), -1) + bypassStop.AddTransition(NewEpsilonTransition(endState, -1), -1) + + MatchState := NewBasicState() + + atn.addState(MatchState) + MatchState.AddTransition(NewAtomTransition(bypassStop, atn.ruleToTokenType[idx]), -1) + bypassStart.AddTransition(NewEpsilonTransition(MatchState, -1), -1) +} + +func (a *ATNDeserializer) stateIsEndStateFor(state ATNState, idx int) ATNState { + if state.GetRuleIndex() != idx { + return nil + } + + if _, ok := state.(*StarLoopEntryState); !ok { + return nil + } + + maybeLoopEndState := state.GetTransitions()[len(state.GetTransitions())-1].getTarget() + + if _, ok := maybeLoopEndState.(*LoopEndState); !ok { + return nil + } + + var _, ok = maybeLoopEndState.GetTransitions()[0].getTarget().(*RuleStopState) + + if maybeLoopEndState.(*LoopEndState).epsilonOnlyTransitions && ok { + return state + } + + return nil +} + +// markPrecedenceDecisions analyzes the StarLoopEntryState states in the +// specified ATN to set the StarLoopEntryState.precedenceRuleDecision field to +// the correct value. +func (a *ATNDeserializer) markPrecedenceDecisions(atn *ATN) { + for _, state := range atn.states { + if _, ok := state.(*StarLoopEntryState); !ok { + continue + } + + // We analyze the ATN to determine if a ATN decision state is the + // decision for the closure block that determines whether a + // precedence rule should continue or complete. + if atn.ruleToStartState[state.GetRuleIndex()].isPrecedenceRule { + maybeLoopEndState := state.GetTransitions()[len(state.GetTransitions())-1].getTarget() + + if s3, ok := maybeLoopEndState.(*LoopEndState); ok { + var _, ok2 = maybeLoopEndState.GetTransitions()[0].getTarget().(*RuleStopState) + + if s3.epsilonOnlyTransitions && ok2 { + state.(*StarLoopEntryState).precedenceRuleDecision = true + } + } + } + } +} + +func (a *ATNDeserializer) verifyATN(atn *ATN) { + if !a.deserializationOptions.verifyATN { + return + } + + // Verify assumptions + for i := 0; i < len(atn.states); i++ { + state := atn.states[i] + + if state == nil { + continue + } + + a.checkCondition(state.GetEpsilonOnlyTransitions() || len(state.GetTransitions()) <= 1, "") + + switch s2 := state.(type) { + case *PlusBlockStartState: + a.checkCondition(s2.loopBackState != nil, "") + + case *StarLoopEntryState: + a.checkCondition(s2.loopBackState != nil, "") + a.checkCondition(len(s2.GetTransitions()) == 2, "") + + switch s2 := state.(type) { + case *StarBlockStartState: + var _, ok2 = s2.GetTransitions()[1].getTarget().(*LoopEndState) + + a.checkCondition(ok2, "") + a.checkCondition(!s2.nonGreedy, "") + + case *LoopEndState: + var s3, ok2 = s2.GetTransitions()[1].getTarget().(*StarBlockStartState) + + a.checkCondition(ok2, "") + a.checkCondition(s3.nonGreedy, "") + + default: + panic("IllegalState") + } + + case *StarLoopbackState: + a.checkCondition(len(state.GetTransitions()) == 1, "") + + var _, ok2 = state.GetTransitions()[0].getTarget().(*StarLoopEntryState) + + a.checkCondition(ok2, "") + + case *LoopEndState: + a.checkCondition(s2.loopBackState != nil, "") + + case *RuleStartState: + a.checkCondition(s2.stopState != nil, "") + + case *BaseBlockStartState: + a.checkCondition(s2.endState != nil, "") + + case *BlockEndState: + a.checkCondition(s2.startState != nil, "") + + case DecisionState: + a.checkCondition(len(s2.GetTransitions()) <= 1 || s2.getDecision() >= 0, "") + + default: + var _, ok = s2.(*RuleStopState) + + a.checkCondition(len(s2.GetTransitions()) <= 1 || ok, "") + } + } +} + +func (a *ATNDeserializer) checkCondition(condition bool, message string) { + if !condition { + if message == "" { + message = "IllegalState" + } + + panic(message) + } +} + +func (a *ATNDeserializer) readInt() int { + v := a.data[a.pos] + + a.pos++ + + return int(v) +} + +func (a *ATNDeserializer) readInt32() int { + var low = a.readInt() + var high = a.readInt() + return low | (high << 16) +} + +//TODO +//func (a *ATNDeserializer) readLong() int64 { +// panic("Not implemented") +// var low = a.readInt32() +// var high = a.readInt32() +// return (low & 0x00000000FFFFFFFF) | (high << int32) +//} + +func createByteToHex() []string { + bth := make([]string, 256) + + for i := 0; i < 256; i++ { + bth[i] = strings.ToUpper(hex.EncodeToString([]byte{byte(i)})) + } + + return bth +} + +var byteToHex = createByteToHex() + +func (a *ATNDeserializer) readUUID() string { + bb := make([]int, 16) + + for i := 7; i >= 0; i-- { + integer := a.readInt() + + bb[(2*i)+1] = integer & 0xFF + bb[2*i] = (integer >> 8) & 0xFF + } + + return byteToHex[bb[0]] + byteToHex[bb[1]] + + byteToHex[bb[2]] + byteToHex[bb[3]] + "-" + + byteToHex[bb[4]] + byteToHex[bb[5]] + "-" + + byteToHex[bb[6]] + byteToHex[bb[7]] + "-" + + byteToHex[bb[8]] + byteToHex[bb[9]] + "-" + + byteToHex[bb[10]] + byteToHex[bb[11]] + + byteToHex[bb[12]] + byteToHex[bb[13]] + + byteToHex[bb[14]] + byteToHex[bb[15]] +} + +func (a *ATNDeserializer) edgeFactory(atn *ATN, typeIndex, src, trg, arg1, arg2, arg3 int, sets []*IntervalSet) Transition { + target := atn.states[trg] + + switch typeIndex { + case TransitionEPSILON: + return NewEpsilonTransition(target, -1) + + case TransitionRANGE: + if arg3 != 0 { + return NewRangeTransition(target, TokenEOF, arg2) + } + + return NewRangeTransition(target, arg1, arg2) + + case TransitionRULE: + return NewRuleTransition(atn.states[arg1], arg2, arg3, target) + + case TransitionPREDICATE: + return NewPredicateTransition(target, arg1, arg2, arg3 != 0) + + case TransitionPRECEDENCE: + return NewPrecedencePredicateTransition(target, arg1) + + case TransitionATOM: + if arg3 != 0 { + return NewAtomTransition(target, TokenEOF) + } + + return NewAtomTransition(target, arg1) + + case TransitionACTION: + return NewActionTransition(target, arg1, arg2, arg3 != 0) + + case TransitionSET: + return NewSetTransition(target, sets[arg1]) + + case TransitionNOTSET: + return NewNotSetTransition(target, sets[arg1]) + + case TransitionWILDCARD: + return NewWildcardTransition(target) + } + + panic("The specified transition type is not valid.") +} + +func (a *ATNDeserializer) stateFactory(typeIndex, ruleIndex int) ATNState { + var s ATNState + + switch typeIndex { + case ATNStateInvalidType: + return nil + + case ATNStateBasic: + s = NewBasicState() + + case ATNStateRuleStart: + s = NewRuleStartState() + + case ATNStateBlockStart: + s = NewBasicBlockStartState() + + case ATNStatePlusBlockStart: + s = NewPlusBlockStartState() + + case ATNStateStarBlockStart: + s = NewStarBlockStartState() + + case ATNStateTokenStart: + s = NewTokensStartState() + + case ATNStateRuleStop: + s = NewRuleStopState() + + case ATNStateBlockEnd: + s = NewBlockEndState() + + case ATNStateStarLoopBack: + s = NewStarLoopbackState() + + case ATNStateStarLoopEntry: + s = NewStarLoopEntryState() + + case ATNStatePlusLoopBack: + s = NewPlusLoopbackState() + + case ATNStateLoopEnd: + s = NewLoopEndState() + + default: + panic(fmt.Sprintf("state type %d is invalid", typeIndex)) + } + + s.SetRuleIndex(ruleIndex) + + return s +} + +func (a *ATNDeserializer) lexerActionFactory(typeIndex, data1, data2 int) LexerAction { + switch typeIndex { + case LexerActionTypeChannel: + return NewLexerChannelAction(data1) + + case LexerActionTypeCustom: + return NewLexerCustomAction(data1, data2) + + case LexerActionTypeMode: + return NewLexerModeAction(data1) + + case LexerActionTypeMore: + return LexerMoreActionINSTANCE + + case LexerActionTypePopMode: + return LexerPopModeActionINSTANCE + + case LexerActionTypePushMode: + return NewLexerPushModeAction(data1) + + case LexerActionTypeSkip: + return LexerSkipActionINSTANCE + + case LexerActionTypeType: + return NewLexerTypeAction(data1) + + default: + panic(fmt.Sprintf("lexer action %d is invalid", typeIndex)) + } +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_simulator.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_simulator.go new file mode 100644 index 000000000..d5454d6d5 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_simulator.go @@ -0,0 +1,50 @@ +// Copyright (c) 2012-2017 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 + +var ATNSimulatorError = NewDFAState(0x7FFFFFFF, NewBaseATNConfigSet(false)) + +type IATNSimulator interface { + SharedContextCache() *PredictionContextCache + ATN() *ATN + DecisionToDFA() []*DFA +} + +type BaseATNSimulator struct { + atn *ATN + sharedContextCache *PredictionContextCache + decisionToDFA []*DFA +} + +func NewBaseATNSimulator(atn *ATN, sharedContextCache *PredictionContextCache) *BaseATNSimulator { + b := new(BaseATNSimulator) + + b.atn = atn + b.sharedContextCache = sharedContextCache + + return b +} + +func (b *BaseATNSimulator) getCachedContext(context PredictionContext) PredictionContext { + if b.sharedContextCache == nil { + return context + } + + visited := make(map[PredictionContext]PredictionContext) + + return getCachedBasePredictionContext(context, b.sharedContextCache, visited) +} + +func (b *BaseATNSimulator) SharedContextCache() *PredictionContextCache { + return b.sharedContextCache +} + +func (b *BaseATNSimulator) ATN() *ATN { + return b.atn +} + +func (b *BaseATNSimulator) DecisionToDFA() []*DFA { + return b.decisionToDFA +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_state.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_state.go new file mode 100644 index 000000000..563d5db38 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_state.go @@ -0,0 +1,386 @@ +// Copyright (c) 2012-2017 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 "strconv" + +// Constants for serialization. +const ( + ATNStateInvalidType = 0 + ATNStateBasic = 1 + ATNStateRuleStart = 2 + ATNStateBlockStart = 3 + ATNStatePlusBlockStart = 4 + ATNStateStarBlockStart = 5 + ATNStateTokenStart = 6 + ATNStateRuleStop = 7 + ATNStateBlockEnd = 8 + ATNStateStarLoopBack = 9 + ATNStateStarLoopEntry = 10 + ATNStatePlusLoopBack = 11 + ATNStateLoopEnd = 12 + + ATNStateInvalidStateNumber = -1 +) + +var ATNStateInitialNumTransitions = 4 + +type ATNState interface { + GetEpsilonOnlyTransitions() bool + + GetRuleIndex() int + SetRuleIndex(int) + + GetNextTokenWithinRule() *IntervalSet + SetNextTokenWithinRule(*IntervalSet) + + GetATN() *ATN + SetATN(*ATN) + + GetStateType() int + + GetStateNumber() int + SetStateNumber(int) + + GetTransitions() []Transition + SetTransitions([]Transition) + AddTransition(Transition, int) + + String() string + hash() int +} + +type BaseATNState struct { + // NextTokenWithinRule caches lookahead during parsing. Not used during construction. + NextTokenWithinRule *IntervalSet + + // atn is the current ATN. + atn *ATN + + epsilonOnlyTransitions bool + + // ruleIndex tracks the Rule index because there are no Rule objects at runtime. + ruleIndex int + + stateNumber int + + stateType int + + // Track the transitions emanating from this ATN state. + transitions []Transition +} + +func NewBaseATNState() *BaseATNState { + return &BaseATNState{stateNumber: ATNStateInvalidStateNumber, stateType: ATNStateInvalidType} +} + +func (as *BaseATNState) GetRuleIndex() int { + return as.ruleIndex +} + +func (as *BaseATNState) SetRuleIndex(v int) { + as.ruleIndex = v +} +func (as *BaseATNState) GetEpsilonOnlyTransitions() bool { + return as.epsilonOnlyTransitions +} + +func (as *BaseATNState) GetATN() *ATN { + return as.atn +} + +func (as *BaseATNState) SetATN(atn *ATN) { + as.atn = atn +} + +func (as *BaseATNState) GetTransitions() []Transition { + return as.transitions +} + +func (as *BaseATNState) SetTransitions(t []Transition) { + as.transitions = t +} + +func (as *BaseATNState) GetStateType() int { + return as.stateType +} + +func (as *BaseATNState) GetStateNumber() int { + return as.stateNumber +} + +func (as *BaseATNState) SetStateNumber(stateNumber int) { + as.stateNumber = stateNumber +} + +func (as *BaseATNState) GetNextTokenWithinRule() *IntervalSet { + return as.NextTokenWithinRule +} + +func (as *BaseATNState) SetNextTokenWithinRule(v *IntervalSet) { + as.NextTokenWithinRule = v +} + +func (as *BaseATNState) hash() int { + return as.stateNumber +} + +func (as *BaseATNState) String() string { + return strconv.Itoa(as.stateNumber) +} + +func (as *BaseATNState) equals(other interface{}) bool { + if ot, ok := other.(ATNState); ok { + return as.stateNumber == ot.GetStateNumber() + } + + return false +} + +func (as *BaseATNState) isNonGreedyExitState() bool { + return false +} + +func (as *BaseATNState) AddTransition(trans Transition, index int) { + if len(as.transitions) == 0 { + as.epsilonOnlyTransitions = trans.getIsEpsilon() + } else if as.epsilonOnlyTransitions != trans.getIsEpsilon() { + as.epsilonOnlyTransitions = false + } + + if index == -1 { + as.transitions = append(as.transitions, trans) + } else { + as.transitions = append(as.transitions[:index], append([]Transition{trans}, as.transitions[index:]...)...) + // TODO: as.transitions.splice(index, 1, trans) + } +} + +type BasicState struct { + *BaseATNState +} + +func NewBasicState() *BasicState { + b := NewBaseATNState() + + b.stateType = ATNStateBasic + + return &BasicState{BaseATNState: b} +} + +type DecisionState interface { + ATNState + + getDecision() int + setDecision(int) + + getNonGreedy() bool + setNonGreedy(bool) +} + +type BaseDecisionState struct { + *BaseATNState + decision int + nonGreedy bool +} + +func NewBaseDecisionState() *BaseDecisionState { + return &BaseDecisionState{BaseATNState: NewBaseATNState(), decision: -1} +} + +func (s *BaseDecisionState) getDecision() int { + return s.decision +} + +func (s *BaseDecisionState) setDecision(b int) { + s.decision = b +} + +func (s *BaseDecisionState) getNonGreedy() bool { + return s.nonGreedy +} + +func (s *BaseDecisionState) setNonGreedy(b bool) { + s.nonGreedy = b +} + +type BlockStartState interface { + DecisionState + + getEndState() *BlockEndState + setEndState(*BlockEndState) +} + +// BaseBlockStartState is the start of a regular (...) block. +type BaseBlockStartState struct { + *BaseDecisionState + endState *BlockEndState +} + +func NewBlockStartState() *BaseBlockStartState { + return &BaseBlockStartState{BaseDecisionState: NewBaseDecisionState()} +} + +func (s *BaseBlockStartState) getEndState() *BlockEndState { + return s.endState +} + +func (s *BaseBlockStartState) setEndState(b *BlockEndState) { + s.endState = b +} + +type BasicBlockStartState struct { + *BaseBlockStartState +} + +func NewBasicBlockStartState() *BasicBlockStartState { + b := NewBlockStartState() + + b.stateType = ATNStateBlockStart + + return &BasicBlockStartState{BaseBlockStartState: b} +} + +// BlockEndState is a terminal node of a simple (a|b|c) block. +type BlockEndState struct { + *BaseATNState + startState ATNState +} + +func NewBlockEndState() *BlockEndState { + b := NewBaseATNState() + + b.stateType = ATNStateBlockEnd + + return &BlockEndState{BaseATNState: b} +} + +// RuleStopState is the last node in the ATN for a rule, unless that rule is the +// start symbol. In that case, there is one transition to EOF. Later, we might +// encode references to all calls to this rule to compute FOLLOW sets for error +// handling. +type RuleStopState struct { + *BaseATNState +} + +func NewRuleStopState() *RuleStopState { + b := NewBaseATNState() + + b.stateType = ATNStateRuleStop + + return &RuleStopState{BaseATNState: b} +} + +type RuleStartState struct { + *BaseATNState + stopState ATNState + isPrecedenceRule bool +} + +func NewRuleStartState() *RuleStartState { + b := NewBaseATNState() + + b.stateType = ATNStateRuleStart + + return &RuleStartState{BaseATNState: b} +} + +// PlusLoopbackState is a decision state for A+ and (A|B)+. It has two +// transitions: one to the loop back to start of the block, and one to exit. +type PlusLoopbackState struct { + *BaseDecisionState +} + +func NewPlusLoopbackState() *PlusLoopbackState { + b := NewBaseDecisionState() + + b.stateType = ATNStatePlusLoopBack + + return &PlusLoopbackState{BaseDecisionState: b} +} + +// PlusBlockStartState is the start of a (A|B|...)+ loop. Technically it is a +// decision state; we don't use it for code generation. Somebody might need it, +// it is included for completeness. In reality, PlusLoopbackState is the real +// decision-making node for A+. +type PlusBlockStartState struct { + *BaseBlockStartState + loopBackState ATNState +} + +func NewPlusBlockStartState() *PlusBlockStartState { + b := NewBlockStartState() + + b.stateType = ATNStatePlusBlockStart + + return &PlusBlockStartState{BaseBlockStartState: b} +} + +// StarBlockStartState is the block that begins a closure loop. +type StarBlockStartState struct { + *BaseBlockStartState +} + +func NewStarBlockStartState() *StarBlockStartState { + b := NewBlockStartState() + + b.stateType = ATNStateStarBlockStart + + return &StarBlockStartState{BaseBlockStartState: b} +} + +type StarLoopbackState struct { + *BaseATNState +} + +func NewStarLoopbackState() *StarLoopbackState { + b := NewBaseATNState() + + b.stateType = ATNStateStarLoopBack + + return &StarLoopbackState{BaseATNState: b} +} + +type StarLoopEntryState struct { + *BaseDecisionState + loopBackState ATNState + precedenceRuleDecision bool +} + +func NewStarLoopEntryState() *StarLoopEntryState { + b := NewBaseDecisionState() + + b.stateType = ATNStateStarLoopEntry + + // False precedenceRuleDecision indicates whether s state can benefit from a precedence DFA during SLL decision making. + return &StarLoopEntryState{BaseDecisionState: b} +} + +// LoopEndState marks the end of a * or + loop. +type LoopEndState struct { + *BaseATNState + loopBackState ATNState +} + +func NewLoopEndState() *LoopEndState { + b := NewBaseATNState() + + b.stateType = ATNStateLoopEnd + + return &LoopEndState{BaseATNState: b} +} + +// TokensStartState is the Tokens rule start state linking to each lexer rule start state. +type TokensStartState struct { + *BaseDecisionState +} + +func NewTokensStartState() *TokensStartState { + b := NewBaseDecisionState() + + b.stateType = ATNStateTokenStart + + return &TokensStartState{BaseDecisionState: b} +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_type.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_type.go new file mode 100644 index 000000000..a7b48976b --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_type.go @@ -0,0 +1,11 @@ +// Copyright (c) 2012-2017 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 + +// Represent the type of recognizer an ATN applies to. +const ( + ATNTypeLexer = 0 + ATNTypeParser = 1 +) diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/char_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/char_stream.go new file mode 100644 index 000000000..70c1207f7 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/char_stream.go @@ -0,0 +1,12 @@ +// Copyright (c) 2012-2017 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 + +type CharStream interface { + IntStream + GetText(int, int) string + GetTextFromTokens(start, end Token) string + GetTextFromInterval(*Interval) string +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_factory.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_factory.go new file mode 100644 index 000000000..330ff8f31 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_factory.go @@ -0,0 +1,56 @@ +// Copyright (c) 2012-2017 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 + +// TokenFactory creates CommonToken objects. +type TokenFactory interface { + Create(source *TokenSourceCharStreamPair, ttype int, text string, channel, start, stop, line, column int) Token +} + +// CommonTokenFactory is the default TokenFactory implementation. +type CommonTokenFactory struct { + // copyText indicates whether CommonToken.setText should be called after + // constructing tokens to explicitly set the text. This is useful for cases + // where the input stream might not be able to provide arbitrary substrings of + // text from the input after the lexer creates a token (e.g. the + // implementation of CharStream.GetText in UnbufferedCharStream panics an + // UnsupportedOperationException). Explicitly setting the token text allows + // Token.GetText to be called at any time regardless of the input stream + // implementation. + // + // The default value is false to avoid the performance and memory overhead of + // copying text for every token unless explicitly requested. + copyText bool +} + +func NewCommonTokenFactory(copyText bool) *CommonTokenFactory { + return &CommonTokenFactory{copyText: copyText} +} + +// CommonTokenFactoryDEFAULT is the default CommonTokenFactory. It does not +// explicitly copy token text when constructing tokens. +var CommonTokenFactoryDEFAULT = NewCommonTokenFactory(false) + +func (c *CommonTokenFactory) Create(source *TokenSourceCharStreamPair, ttype int, text string, channel, start, stop, line, column int) Token { + t := NewCommonToken(source, ttype, channel, start, stop) + + t.line = line + t.column = column + + if text != "" { + t.SetText(text) + } else if c.copyText && source.charStream != nil { + t.SetText(source.charStream.GetTextFromInterval(NewInterval(start, stop))) + } + + return t +} + +func (c *CommonTokenFactory) createThin(ttype int, text string) Token { + t := NewCommonToken(nil, ttype, TokenDefaultChannel, -1, -1) + t.SetText(text) + + return t +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_stream.go new file mode 100644 index 000000000..c90e9b890 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_stream.go @@ -0,0 +1,447 @@ +// Copyright (c) 2012-2017 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 ( + "strconv" +) + +// CommonTokenStream is an implementation of TokenStream that loads tokens from +// a TokenSource on-demand and places the tokens in a buffer to provide access +// to any previous token by index. This token stream ignores the value of +// Token.getChannel. If your parser requires the token stream filter tokens to +// only those on a particular channel, such as Token.DEFAULT_CHANNEL or +// Token.HIDDEN_CHANNEL, use a filtering token stream such a CommonTokenStream. +type CommonTokenStream struct { + channel int + + // fetchedEOF indicates whether the Token.EOF token has been fetched from + // tokenSource and added to tokens. This field improves performance for the + // following cases: + // + // consume: The lookahead check in consume to preven consuming the EOF symbol is + // optimized by checking the values of fetchedEOF and p instead of calling LA. + // + // fetch: The check to prevent adding multiple EOF symbols into tokens is + // trivial with bt field. + fetchedEOF bool + + // index indexs into tokens of the current token (next token to consume). + // tokens[p] should be LT(1). It is set to -1 when the stream is first + // constructed or when SetTokenSource is called, indicating that the first token + // has not yet been fetched from the token source. For additional information, + // see the documentation of IntStream for a description of initializing methods. + index int + + // tokenSource is the TokenSource from which tokens for the bt stream are + // fetched. + tokenSource TokenSource + + // tokens is all tokens fetched from the token source. The list is considered a + // complete view of the input once fetchedEOF is set to true. + tokens []Token +} + +func NewCommonTokenStream(lexer Lexer, channel int) *CommonTokenStream { + return &CommonTokenStream{ + channel: channel, + index: -1, + tokenSource: lexer, + tokens: make([]Token, 0), + } +} + +func (c *CommonTokenStream) GetAllTokens() []Token { + return c.tokens +} + +func (c *CommonTokenStream) Mark() int { + return 0 +} + +func (c *CommonTokenStream) Release(marker int) {} + +func (c *CommonTokenStream) reset() { + c.Seek(0) +} + +func (c *CommonTokenStream) Seek(index int) { + c.lazyInit() + c.index = c.adjustSeekIndex(index) +} + +func (c *CommonTokenStream) Get(index int) Token { + c.lazyInit() + + return c.tokens[index] +} + +func (c *CommonTokenStream) Consume() { + SkipEOFCheck := false + + if c.index >= 0 { + if c.fetchedEOF { + // The last token in tokens is EOF. Skip the check if p indexes any fetched. + // token except the last. + SkipEOFCheck = c.index < len(c.tokens)-1 + } else { + // No EOF token in tokens. Skip the check if p indexes a fetched token. + SkipEOFCheck = c.index < len(c.tokens) + } + } else { + // Not yet initialized + SkipEOFCheck = false + } + + if !SkipEOFCheck && c.LA(1) == TokenEOF { + panic("cannot consume EOF") + } + + if c.Sync(c.index + 1) { + c.index = c.adjustSeekIndex(c.index + 1) + } +} + +// Sync makes sure index i in tokens has a token and returns true if a token is +// located at index i and otherwise false. +func (c *CommonTokenStream) Sync(i int) bool { + n := i - len(c.tokens) + 1 // TODO: How many more elements do we need? + + if n > 0 { + fetched := c.fetch(n) + return fetched >= n + } + + return true +} + +// fetch adds n elements to buffer and returns the actual number of elements +// added to the buffer. +func (c *CommonTokenStream) fetch(n int) int { + if c.fetchedEOF { + return 0 + } + + for i := 0; i < n; i++ { + t := c.tokenSource.NextToken() + + t.SetTokenIndex(len(c.tokens)) + c.tokens = append(c.tokens, t) + + if t.GetTokenType() == TokenEOF { + c.fetchedEOF = true + + return i + 1 + } + } + + return n +} + +// GetTokens gets all tokens from start to stop inclusive. +func (c *CommonTokenStream) GetTokens(start int, stop int, types *IntervalSet) []Token { + if start < 0 || stop < 0 { + return nil + } + + c.lazyInit() + + subset := make([]Token, 0) + + if stop >= len(c.tokens) { + stop = len(c.tokens) - 1 + } + + for i := start; i < stop; i++ { + t := c.tokens[i] + + if t.GetTokenType() == TokenEOF { + break + } + + if types == nil || types.contains(t.GetTokenType()) { + subset = append(subset, t) + } + } + + return subset +} + +func (c *CommonTokenStream) LA(i int) int { + return c.LT(i).GetTokenType() +} + +func (c *CommonTokenStream) lazyInit() { + if c.index == -1 { + c.setup() + } +} + +func (c *CommonTokenStream) setup() { + c.Sync(0) + c.index = c.adjustSeekIndex(0) +} + +func (c *CommonTokenStream) GetTokenSource() TokenSource { + return c.tokenSource +} + +// SetTokenSource resets the c token stream by setting its token source. +func (c *CommonTokenStream) SetTokenSource(tokenSource TokenSource) { + c.tokenSource = tokenSource + c.tokens = make([]Token, 0) + c.index = -1 +} + +// NextTokenOnChannel returns the index of the next token on channel given a +// starting index. Returns i if tokens[i] is on channel. Returns -1 if there are +// no tokens on channel between i and EOF. +func (c *CommonTokenStream) NextTokenOnChannel(i, channel int) int { + c.Sync(i) + + if i >= len(c.tokens) { + return -1 + } + + token := c.tokens[i] + + for token.GetChannel() != c.channel { + if token.GetTokenType() == TokenEOF { + return -1 + } + + i++ + c.Sync(i) + token = c.tokens[i] + } + + return i +} + +// previousTokenOnChannel returns the index of the previous token on channel +// given a starting index. Returns i if tokens[i] is on channel. Returns -1 if +// there are no tokens on channel between i and 0. +func (c *CommonTokenStream) previousTokenOnChannel(i, channel int) int { + for i >= 0 && c.tokens[i].GetChannel() != channel { + i-- + } + + return i +} + +// GetHiddenTokensToRight collects all tokens on a specified channel to the +// right of the current token up until we see a token on DEFAULT_TOKEN_CHANNEL +// or EOF. If channel is -1, it finds any non-default channel token. +func (c *CommonTokenStream) GetHiddenTokensToRight(tokenIndex, channel int) []Token { + c.lazyInit() + + if tokenIndex < 0 || tokenIndex >= len(c.tokens) { + panic(strconv.Itoa(tokenIndex) + " not in 0.." + strconv.Itoa(len(c.tokens)-1)) + } + + nextOnChannel := c.NextTokenOnChannel(tokenIndex+1, LexerDefaultTokenChannel) + from := tokenIndex + 1 + + // If no onchannel to the right, then nextOnChannel == -1, so set to to last token + var to int + + if nextOnChannel == -1 { + to = len(c.tokens) - 1 + } else { + to = nextOnChannel + } + + return c.filterForChannel(from, to, channel) +} + +// GetHiddenTokensToLeft collects all tokens on channel to the left of the +// current token until we see a token on DEFAULT_TOKEN_CHANNEL. If channel is +// -1, it finds any non default channel token. +func (c *CommonTokenStream) GetHiddenTokensToLeft(tokenIndex, channel int) []Token { + c.lazyInit() + + if tokenIndex < 0 || tokenIndex >= len(c.tokens) { + panic(strconv.Itoa(tokenIndex) + " not in 0.." + strconv.Itoa(len(c.tokens)-1)) + } + + prevOnChannel := c.previousTokenOnChannel(tokenIndex-1, LexerDefaultTokenChannel) + + if prevOnChannel == tokenIndex-1 { + return nil + } + + // If there are none on channel to the left and prevOnChannel == -1 then from = 0 + from := prevOnChannel + 1 + to := tokenIndex - 1 + + return c.filterForChannel(from, to, channel) +} + +func (c *CommonTokenStream) filterForChannel(left, right, channel int) []Token { + hidden := make([]Token, 0) + + for i := left; i < right+1; i++ { + t := c.tokens[i] + + if channel == -1 { + if t.GetChannel() != LexerDefaultTokenChannel { + hidden = append(hidden, t) + } + } else if t.GetChannel() == channel { + hidden = append(hidden, t) + } + } + + if len(hidden) == 0 { + return nil + } + + return hidden +} + +func (c *CommonTokenStream) GetSourceName() string { + return c.tokenSource.GetSourceName() +} + +func (c *CommonTokenStream) Size() int { + return len(c.tokens) +} + +func (c *CommonTokenStream) Index() int { + return c.index +} + +func (c *CommonTokenStream) GetAllText() string { + return c.GetTextFromInterval(nil) +} + +func (c *CommonTokenStream) GetTextFromTokens(start, end Token) string { + if start == nil || end == nil { + return "" + } + + return c.GetTextFromInterval(NewInterval(start.GetTokenIndex(), end.GetTokenIndex())) +} + +func (c *CommonTokenStream) GetTextFromRuleContext(interval RuleContext) string { + return c.GetTextFromInterval(interval.GetSourceInterval()) +} + +func (c *CommonTokenStream) GetTextFromInterval(interval *Interval) string { + c.lazyInit() + c.Fill() + + if interval == nil { + interval = NewInterval(0, len(c.tokens)-1) + } + + start := interval.Start + stop := interval.Stop + + if start < 0 || stop < 0 { + return "" + } + + if stop >= len(c.tokens) { + stop = len(c.tokens) - 1 + } + + s := "" + + for i := start; i < stop+1; i++ { + t := c.tokens[i] + + if t.GetTokenType() == TokenEOF { + break + } + + s += t.GetText() + } + + return s +} + +// Fill gets all tokens from the lexer until EOF. +func (c *CommonTokenStream) Fill() { + c.lazyInit() + + for c.fetch(1000) == 1000 { + continue + } +} + +func (c *CommonTokenStream) adjustSeekIndex(i int) int { + return c.NextTokenOnChannel(i, c.channel) +} + +func (c *CommonTokenStream) LB(k int) Token { + if k == 0 || c.index-k < 0 { + return nil + } + + i := c.index + n := 1 + + // Find k good tokens looking backward + for n <= k { + // Skip off-channel tokens + i = c.previousTokenOnChannel(i-1, c.channel) + n++ + } + + if i < 0 { + return nil + } + + return c.tokens[i] +} + +func (c *CommonTokenStream) LT(k int) Token { + c.lazyInit() + + if k == 0 { + return nil + } + + if k < 0 { + return c.LB(-k) + } + + i := c.index + n := 1 // We know tokens[n] is valid + + // Find k good tokens + for n < k { + // Skip off-channel tokens, but make sure to not look past EOF + if c.Sync(i + 1) { + i = c.NextTokenOnChannel(i+1, c.channel) + } + + n++ + } + + return c.tokens[i] +} + +// getNumberOfOnChannelTokens counts EOF once. +func (c *CommonTokenStream) getNumberOfOnChannelTokens() int { + var n int + + c.Fill() + + for i := 0; i < len(c.tokens); i++ { + t := c.tokens[i] + + if t.GetChannel() == c.channel { + n++ + } + + if t.GetTokenType() == TokenEOF { + break + } + } + + return n +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa.go new file mode 100644 index 000000000..d6079aa20 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa.go @@ -0,0 +1,171 @@ +// Copyright (c) 2012-2017 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" + "sync" +) + +type DFA struct { + // atnStartState is the ATN state in which this was created + atnStartState DecisionState + + 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 + statesMu sync.RWMutex + + s0 *DFAState + s0Mu sync.RWMutex + + // precedenceDfa is the backing field for isPrecedenceDfa and setPrecedenceDfa. + // True if the DFA is for a precedence decision and false otherwise. + precedenceDfa bool +} + +func NewDFA(atnStartState DecisionState, decision int) *DFA { + return &DFA{ + atnStartState: atnStartState, + decision: decision, + states: make(map[int]*DFAState), + } +} + +// getPrecedenceStartState gets the start state for the current precedence and +// returns the start state corresponding to the specified precedence if a start +// state exists for the specified precedence and nil otherwise. d must be a +// precedence DFA. See also isPrecedenceDfa. +func (d *DFA) getPrecedenceStartState(precedence int) *DFAState { + if !d.precedenceDfa { + panic("only precedence DFAs may contain a precedence start state") + } + + d.s0Mu.RLock() + defer d.s0Mu.RUnlock() + + // s0.edges is never nil for a precedence DFA + if precedence < 0 || precedence >= len(d.s0.edges) { + return nil + } + + return d.s0.edges[precedence] +} + +// setPrecedenceStartState sets the start state for the current precedence. d +// must be a precedence DFA. See also isPrecedenceDfa. +func (d *DFA) setPrecedenceStartState(precedence int, startState *DFAState) { + if !d.precedenceDfa { + panic("only precedence DFAs may contain a precedence start state") + } + + if precedence < 0 { + return + } + + d.s0Mu.Lock() + defer d.s0Mu.Unlock() + + // Synchronization on s0 here is ok. When the DFA is turned into a + // precedence DFA, s0 will be initialized once and not updated again. s0.edges + // is never nil for a precedence DFA. + if precedence >= len(d.s0.edges) { + d.s0.edges = append(d.s0.edges, make([]*DFAState, precedence+1-len(d.s0.edges))...) + } + + d.s0.edges[precedence] = startState +} + +// setPrecedenceDfa sets whether d is a precedence DFA. If precedenceDfa differs +// from the current DFA configuration, then d.states is cleared, the initial +// state s0 is set to a new DFAState with an empty outgoing DFAState.edges to +// store the start states for individual precedence values if precedenceDfa is +// true or nil otherwise, and d.precedenceDfa is updated. +func (d *DFA) setPrecedenceDfa(precedenceDfa bool) { + if d.precedenceDfa != precedenceDfa { + d.states = make(map[int]*DFAState) + + if precedenceDfa { + precedenceState := NewDFAState(-1, NewBaseATNConfigSet(false)) + + precedenceState.edges = make([]*DFAState, 0) + precedenceState.isAcceptState = false + precedenceState.requiresFullContext = false + d.s0 = precedenceState + } else { + d.s0 = nil + } + + d.precedenceDfa = precedenceDfa + } +} + +func (d *DFA) getS0() *DFAState { + d.s0Mu.RLock() + defer d.s0Mu.RUnlock() + return d.s0 +} + +func (d *DFA) setS0(s *DFAState) { + d.s0Mu.Lock() + defer d.s0Mu.Unlock() + d.s0 = s +} + +func (d *DFA) getState(hash int) (*DFAState, bool) { + d.statesMu.RLock() + defer d.statesMu.RUnlock() + s, ok := d.states[hash] + return s, ok +} + +func (d *DFA) setState(hash int, state *DFAState) { + d.statesMu.Lock() + defer d.statesMu.Unlock() + d.states[hash] = state +} + +func (d *DFA) numStates() int { + d.statesMu.RLock() + defer d.statesMu.RUnlock() + 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)) + + return vs +} + +func (d *DFA) String(literalNames []string, symbolicNames []string) string { + if d.s0 == nil { + return "" + } + + return NewDFASerializer(d, literalNames, symbolicNames).String() +} + +func (d *DFA) ToLexerString() string { + if d.s0 == nil { + return "" + } + + return NewLexerDFASerializer(d).String() +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_serializer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_serializer.go new file mode 100644 index 000000000..4c0f69022 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_serializer.go @@ -0,0 +1,152 @@ +// Copyright (c) 2012-2017 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" + "strconv" +) + +// DFASerializer is a DFA walker that knows how to dump them to serialized +// strings. +type DFASerializer struct { + dfa *DFA + literalNames []string + symbolicNames []string +} + +func NewDFASerializer(dfa *DFA, literalNames, symbolicNames []string) *DFASerializer { + if literalNames == nil { + literalNames = make([]string, 0) + } + + if symbolicNames == nil { + symbolicNames = make([]string, 0) + } + + return &DFASerializer{ + dfa: dfa, + literalNames: literalNames, + symbolicNames: symbolicNames, + } +} + +func (d *DFASerializer) String() string { + if d.dfa.s0 == nil { + return "" + } + + buf := "" + states := d.dfa.sortedStates() + + for _, s := range states { + if s.edges != nil { + n := len(s.edges) + + for j := 0; j < n; j++ { + t := s.edges[j] + + if t != nil && t.stateNumber != 0x7FFFFFFF { + buf += d.GetStateString(s) + buf += "-" + buf += d.getEdgeLabel(j) + buf += "->" + buf += d.GetStateString(t) + buf += "\n" + } + } + } + } + + if len(buf) == 0 { + return "" + } + + return buf +} + +func (d *DFASerializer) getEdgeLabel(i int) string { + if i == 0 { + return "EOF" + } else if d.literalNames != nil && i-1 < len(d.literalNames) { + return d.literalNames[i-1] + } else if d.symbolicNames != nil && i-1 < len(d.symbolicNames) { + return d.symbolicNames[i-1] + } + + return strconv.Itoa(i - 1) +} + +func (d *DFASerializer) GetStateString(s *DFAState) string { + var a, b string + + if s.isAcceptState { + a = ":" + } + + if s.requiresFullContext { + b = "^" + } + + baseStateStr := a + "s" + strconv.Itoa(s.stateNumber) + b + + if s.isAcceptState { + if s.predicates != nil { + return baseStateStr + "=>" + fmt.Sprint(s.predicates) + } + + return baseStateStr + "=>" + fmt.Sprint(s.prediction) + } + + return baseStateStr +} + +type LexerDFASerializer struct { + *DFASerializer +} + +func NewLexerDFASerializer(dfa *DFA) *LexerDFASerializer { + return &LexerDFASerializer{DFASerializer: NewDFASerializer(dfa, nil, nil)} +} + +func (l *LexerDFASerializer) getEdgeLabel(i int) string { + return "'" + string(i) + "'" +} + +func (l *LexerDFASerializer) String() string { + if l.dfa.s0 == nil { + return "" + } + + buf := "" + states := l.dfa.sortedStates() + + for i := 0; i < len(states); i++ { + s := states[i] + + if s.edges != nil { + n := len(s.edges) + + for j := 0; j < n; j++ { + t := s.edges[j] + + if t != nil && t.stateNumber != 0x7FFFFFFF { + buf += l.GetStateString(s) + buf += "-" + buf += l.getEdgeLabel(j) + buf += "->" + buf += l.GetStateString(t) + buf += "\n" + } + } + } + } + + if len(buf) == 0 { + return "" + } + + return buf +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_state.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_state.go new file mode 100644 index 000000000..38e918ad9 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_state.go @@ -0,0 +1,166 @@ +// Copyright (c) 2012-2017 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" +) + +// PredPrediction maps a predicate to a predicted alternative. +type PredPrediction struct { + alt int + pred SemanticContext +} + +func NewPredPrediction(pred SemanticContext, alt int) *PredPrediction { + return &PredPrediction{alt: alt, pred: pred} +} + +func (p *PredPrediction) String() string { + return "(" + fmt.Sprint(p.pred) + ", " + fmt.Sprint(p.alt) + ")" +} + +// DFAState represents a set of possible ATN configurations. As Aho, Sethi, +// Ullman p. 117 says: "The DFA uses its state to keep track of all possible +// states the ATN can be in after reading each input symbol. That is to say, +// after reading input a1a2..an, the DFA is in a state that represents the +// subset T of the states of the ATN that are reachable from the ATN's start +// state along some path labeled a1a2..an." In conventional NFA-to-DFA +// conversion, therefore, the subset T would be a bitset representing the set of +// states the ATN could be in. We need to track the alt predicted by each state +// as well, however. More importantly, we need to maintain a stack of states, +// tracking the closure operations as they jump from rule to rule, emulating +// rule invocations (method calls). I have to add a stack to simulate the proper +// lookahead sequences for the underlying LL grammar from which the ATN was +// derived. +// +// I use a set of ATNConfig objects, not simple states. An ATNConfig is both a +// state (ala normal conversion) and a RuleContext describing the chain of rules +// (if any) followed to arrive at that state. +// +// A DFAState may have multiple references to a particular state, but with +// different ATN contexts (with same or different alts) meaning that state was +// reached via a different set of rule invocations. +type DFAState struct { + stateNumber int + configs ATNConfigSet + + // edges elements point to the target of the symbol. Shift up by 1 so (-1) + // Token.EOF maps to the first element. + edges []*DFAState + + isAcceptState bool + + // prediction is the ttype we match or alt we predict if the state is accept. + // Set to ATN.INVALID_ALT_NUMBER when predicates != nil or + // requiresFullContext. + prediction int + + lexerActionExecutor *LexerActionExecutor + + // requiresFullContext indicates it was created during an SLL prediction that + // discovered a conflict between the configurations in the state. Future + // ParserATNSimulator.execATN invocations immediately jump doing + // full context prediction if true. + requiresFullContext bool + + // predicates is the predicates associated with the ATN configurations of the + // DFA state during SLL parsing. When we have predicates, requiresFullContext + // is false, since full context prediction evaluates predicates on-the-fly. If + // d is + // not nil, then prediction is ATN.INVALID_ALT_NUMBER. + // + // We only use these for non-requiresFullContext but conflicting states. That + // means we know from the context (it's $ or we don't dip into outer context) + // that it's an ambiguity not a conflict. + // + // This list is computed by + // ParserATNSimulator.predicateDFAState. + predicates []*PredPrediction +} + +func NewDFAState(stateNumber int, configs ATNConfigSet) *DFAState { + if configs == nil { + configs = NewBaseATNConfigSet(false) + } + + return &DFAState{configs: configs, stateNumber: stateNumber} +} + +// GetAltSet gets the set of all alts mentioned by all ATN configurations in d. +func (d *DFAState) GetAltSet() *Set { + alts := NewSet(nil, nil) + + if d.configs != nil { + for _, c := range d.configs.GetItems() { + alts.add(c.GetAlt()) + } + } + + if alts.length() == 0 { + return nil + } + + return alts +} + +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 { + if d.predicates != nil { + s = "=>" + fmt.Sprint(d.predicates) + } else { + s = "=>" + fmt.Sprint(d.prediction) + } + } + + return fmt.Sprintf("%d:%s%s", fmt.Sprint(d.configs), s) +} + +func (d *DFAState) hash() int { + h := murmurInit(11) + + c := 1 + if d.isAcceptState { + if d.predicates != nil { + for _, p := range d.predicates { + h = murmurUpdate(h, p.alt) + h = murmurUpdate(h, p.pred.hash()) + c += 2 + } + } else { + h = murmurUpdate(h, d.prediction) + c += 1 + } + } + + h = murmurUpdate(h, d.configs.hash()) + return murmurFinish(h, c) +} \ No newline at end of file diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/diagnostic_error_listener.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/diagnostic_error_listener.go new file mode 100644 index 000000000..1fec43d9d --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/diagnostic_error_listener.go @@ -0,0 +1,111 @@ +// Copyright (c) 2012-2017 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 ( + "strconv" +) + +// +// This implementation of {@link ANTLRErrorListener} can be used to identify +// certain potential correctness and performance problems in grammars. "reports" +// are made by calling {@link Parser//NotifyErrorListeners} with the appropriate +// message. +// +// + +type DiagnosticErrorListener struct { + *DefaultErrorListener + + exactOnly bool +} + +func NewDiagnosticErrorListener(exactOnly bool) *DiagnosticErrorListener { + + n := new(DiagnosticErrorListener) + + // whether all ambiguities or only exact ambiguities are Reported. + n.exactOnly = exactOnly + return n +} + +func (d *DiagnosticErrorListener) ReportAmbiguity(recognizer Parser, dfa *DFA, startIndex, stopIndex int, exact bool, ambigAlts *BitSet, configs ATNConfigSet) { + if d.exactOnly && !exact { + return + } + msg := "reportAmbiguity d=" + + d.getDecisionDescription(recognizer, dfa) + + ": ambigAlts=" + + d.getConflictingAlts(ambigAlts, configs).String() + + ", input='" + + recognizer.GetTokenStream().GetTextFromInterval(NewInterval(startIndex, stopIndex)) + "'" + recognizer.NotifyErrorListeners(msg, nil, nil) +} + +func (d *DiagnosticErrorListener) ReportAttemptingFullContext(recognizer Parser, dfa *DFA, startIndex, stopIndex int, conflictingAlts *BitSet, configs ATNConfigSet) { + + msg := "reportAttemptingFullContext d=" + + d.getDecisionDescription(recognizer, dfa) + + ", input='" + + recognizer.GetTokenStream().GetTextFromInterval(NewInterval(startIndex, stopIndex)) + "'" + recognizer.NotifyErrorListeners(msg, nil, nil) +} + +func (d *DiagnosticErrorListener) ReportContextSensitivity(recognizer Parser, dfa *DFA, startIndex, stopIndex, prediction int, configs ATNConfigSet) { + msg := "reportContextSensitivity d=" + + d.getDecisionDescription(recognizer, dfa) + + ", input='" + + recognizer.GetTokenStream().GetTextFromInterval(NewInterval(startIndex, stopIndex)) + "'" + recognizer.NotifyErrorListeners(msg, nil, nil) +} + +func (d *DiagnosticErrorListener) getDecisionDescription(recognizer Parser, dfa *DFA) string { + decision := dfa.decision + ruleIndex := dfa.atnStartState.GetRuleIndex() + + ruleNames := recognizer.GetRuleNames() + if ruleIndex < 0 || ruleIndex >= len(ruleNames) { + return strconv.Itoa(decision) + } + ruleName := ruleNames[ruleIndex] + if ruleName == "" { + return strconv.Itoa(decision) + } + 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. +// +// @param ReportedAlts The set of conflicting or ambiguous alternatives, as +// Reported by the parser. +// @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 + } + result := NewBitSet() + for _, c := range set.GetItems() { + result.add(c.GetAlt()) + } + + return result +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_listener.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_listener.go new file mode 100644 index 000000000..028e1a9d7 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_listener.go @@ -0,0 +1,108 @@ +// Copyright (c) 2012-2017 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" + "os" + "strconv" +) + +// Provides an empty default implementation of {@link ANTLRErrorListener}. The +// default implementation of each method does nothing, but can be overridden as +// necessary. + +type ErrorListener interface { + SyntaxError(recognizer Recognizer, offendingSymbol interface{}, line, column int, msg string, e RecognitionException) + ReportAmbiguity(recognizer Parser, dfa *DFA, startIndex, stopIndex int, exact bool, ambigAlts *BitSet, configs ATNConfigSet) + ReportAttemptingFullContext(recognizer Parser, dfa *DFA, startIndex, stopIndex int, conflictingAlts *BitSet, configs ATNConfigSet) + ReportContextSensitivity(recognizer Parser, dfa *DFA, startIndex, stopIndex, prediction int, configs ATNConfigSet) +} + +type DefaultErrorListener struct { +} + +func NewDefaultErrorListener() *DefaultErrorListener { + return new(DefaultErrorListener) +} + +func (d *DefaultErrorListener) SyntaxError(recognizer Recognizer, offendingSymbol interface{}, line, column int, msg string, e RecognitionException) { +} + +func (d *DefaultErrorListener) ReportAmbiguity(recognizer Parser, dfa *DFA, startIndex, stopIndex int, exact bool, ambigAlts *BitSet, configs ATNConfigSet) { +} + +func (d *DefaultErrorListener) ReportAttemptingFullContext(recognizer Parser, dfa *DFA, startIndex, stopIndex int, conflictingAlts *BitSet, configs ATNConfigSet) { +} + +func (d *DefaultErrorListener) ReportContextSensitivity(recognizer Parser, dfa *DFA, startIndex, stopIndex, prediction int, configs ATNConfigSet) { +} + +type ConsoleErrorListener struct { + *DefaultErrorListener +} + +func NewConsoleErrorListener() *ConsoleErrorListener { + return new(ConsoleErrorListener) +} + +// +// Provides a default instance of {@link ConsoleErrorListener}. +// +var ConsoleErrorListenerINSTANCE = NewConsoleErrorListener() + +// +// {@inheritDoc} +// +//

+// This implementation prints messages to {@link System//err} containing the +// values of {@code line}, {@code charPositionInLine}, and {@code msg} using +// the following format.

+// +//
+// 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) +} + +type ProxyErrorListener struct { + *DefaultErrorListener + delegates []ErrorListener +} + +func NewProxyErrorListener(delegates []ErrorListener) *ProxyErrorListener { + if delegates == nil { + panic("delegates is not provided") + } + l := new(ProxyErrorListener) + l.delegates = delegates + return l +} + +func (p *ProxyErrorListener) SyntaxError(recognizer Recognizer, offendingSymbol interface{}, line, column int, msg string, e RecognitionException) { + for _, d := range p.delegates { + d.SyntaxError(recognizer, offendingSymbol, line, column, msg, e) + } +} + +func (p *ProxyErrorListener) ReportAmbiguity(recognizer Parser, dfa *DFA, startIndex, stopIndex int, exact bool, ambigAlts *BitSet, configs ATNConfigSet) { + for _, d := range p.delegates { + d.ReportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs) + } +} + +func (p *ProxyErrorListener) ReportAttemptingFullContext(recognizer Parser, dfa *DFA, startIndex, stopIndex int, conflictingAlts *BitSet, configs ATNConfigSet) { + for _, d := range p.delegates { + d.ReportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs) + } +} + +func (p *ProxyErrorListener) ReportContextSensitivity(recognizer Parser, dfa *DFA, startIndex, stopIndex, prediction int, configs ATNConfigSet) { + for _, d := range p.delegates { + d.ReportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs) + } +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_strategy.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_strategy.go new file mode 100644 index 000000000..977a6e454 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_strategy.go @@ -0,0 +1,758 @@ +// Copyright (c) 2012-2017 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" + "reflect" + "strconv" + "strings" +) + +type ErrorStrategy interface { + reset(Parser) + RecoverInline(Parser) Token + Recover(Parser, RecognitionException) + Sync(Parser) + inErrorRecoveryMode(Parser) bool + ReportError(Parser, RecognitionException) + ReportMatch(Parser) +} + +// This is the default implementation of {@link ANTLRErrorStrategy} used for +// error Reporting and recovery in ANTLR parsers. +// +type DefaultErrorStrategy struct { + errorRecoveryMode bool + lastErrorIndex int + lastErrorStates *IntervalSet +} + +var _ ErrorStrategy = &DefaultErrorStrategy{} + +func NewDefaultErrorStrategy() *DefaultErrorStrategy { + + d := new(DefaultErrorStrategy) + + // Indicates whether the error strategy is currently "recovering from an + // error". This is used to suppress Reporting multiple error messages while + // attempting to recover from a detected syntax error. + // + // @see //inErrorRecoveryMode + // + d.errorRecoveryMode = false + + // The index into the input stream where the last error occurred. + // This is used to prevent infinite loops where an error is found + // but no token is consumed during recovery...another error is found, + // ad nauseum. This is a failsafe mechanism to guarantee that at least + // one token/tree node is consumed for two errors. + // + d.lastErrorIndex = -1 + d.lastErrorStates = nil + return d +} + +//

The default implementation simply calls {@link //endErrorCondition} to +// ensure that the handler is not in error recovery mode.

+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 +} + +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 +// in error recovery mode. Otherwise, it calls {@link //beginErrorCondition} +// and dispatches the Reporting task based on the runtime type of {@code e} +// according to the following table.

+// +// +// +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. + if d.inErrorRecoveryMode(recognizer) { + return // don't Report spurious errors + } + d.beginErrorCondition(recognizer) + + switch t := e.(type) { + default: + fmt.Println("unknown recognition error type: " + reflect.TypeOf(e).Name()) + // fmt.Println(e.stack) + recognizer.NotifyErrorListeners(e.GetMessage(), e.GetOffendingToken(), e) + case *NoViableAltException: + d.ReportNoViableAlternative(recognizer, t) + case *InputMisMatchException: + d.ReportInputMisMatch(recognizer, t) + case *FailedPredicateException: + d.ReportFailedPredicate(recognizer, t) + } +} + +// {@inheritDoc} +// +//

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() && + d.lastErrorStates != nil && d.lastErrorStates.contains(recognizer.GetState()) { + // uh oh, another error at same token index and previously-Visited + // state in ATN must be a case where LT(1) is in the recovery + // token set so nothing got consumed. Consume a single token + // at least to prevent an infinite loop d is a failsafe. + recognizer.Consume() + } + d.lastErrorIndex = recognizer.GetInputStream().Index() + if d.lastErrorStates == nil { + d.lastErrorStates = NewIntervalSet() + } + d.lastErrorStates.addOne(recognizer.GetState()) + followSet := d.getErrorRecoverySet(recognizer) + d.consumeUntil(recognizer, followSet) +} + +// The default implementation of {@link ANTLRErrorStrategy//Sync} makes sure +// that the current lookahead symbol is consistent with what were expecting +// at d point in the ATN. You can call d anytime but ANTLR only +// generates code to check before subrules/loops and each iteration. +// +//

Implements Jim Idle's magic Sync mechanism in closures and optional +// subrules. E.g.,

+// +//
+// a : Sync ( stuff Sync )*
+// Sync : {consume to what can follow Sync}
+// 
+// +// At the start of a sub rule upon error, {@link //Sync} performs single +// token deletion, if possible. If it can't do that, it bails on the current +// rule and uses the default error recovery, which consumes until the +// reSynchronization set of the current rule. +// +//

If the sub rule is optional ({@code (...)?}, {@code (...)*}, or block +// with an empty alternative), then the expected set includes what follows +// the subrule.

+// +//

During loop iteration, it consumes until it sees a token that can start a +// sub rule or what follows loop. Yes, that is pretty aggressive. We opt to +// stay in the loop as long as possible.

+// +//

ORIGINS

+// +//

Previous versions of ANTLR did a poor job of their recovery within loops. +// A single mismatch token or missing token would force the parser to bail +// out of the entire rules surrounding the loop. So, for rule

+// +//
+// classfunc : 'class' ID '{' member* '}'
+// 
+// +// input with an extra token between members would force the parser to +// consume until it found the next class definition rather than the next +// member definition of the current class. +// +//

This functionality cost a little bit of effort because the parser has to +// 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) { + return + } + + s := recognizer.GetInterpreter().atn.states[recognizer.GetState()] + la := recognizer.GetTokenStream().LA(1) + + // try cheaper subset first might get lucky. seems to shave a wee bit off + nextTokens := recognizer.GetATN().NextTokens(s, nil) + if nextTokens.contains(TokenEpsilon) || nextTokens.contains(la) { + return + } + + switch s.GetStateType() { + case ATNStateBlockStart, ATNStateStarBlockStart, ATNStatePlusBlockStart, ATNStateStarLoopEntry: + // Report error and recover if possible + if d.SingleTokenDeletion(recognizer) != nil { + return + } + panic(NewInputMisMatchException(recognizer)) + case ATNStatePlusLoopBack, ATNStateStarLoopBack: + d.ReportUnwantedToken(recognizer) + expecting := NewIntervalSet() + expecting.addSet(recognizer.GetExpectedTokens()) + whatFollowsLoopIterationOrRule := expecting.addSet(d.getErrorRecoverySet(recognizer)) + d.consumeUntil(recognizer, whatFollowsLoopIterationOrRule) + default: + // do nothing if we can't identify the exact kind of ATN state + } +} + +// This is called by {@link //ReportError} when the exception is a +// {@link NoViableAltException}. +// +// @see //ReportError +// +// @param recognizer the parser instance +// @param e the recognition exception +// +func (d *DefaultErrorStrategy) ReportNoViableAlternative(recognizer Parser, e *NoViableAltException) { + tokens := recognizer.GetTokenStream() + var input string + if tokens != nil { + if e.startToken.GetTokenType() == TokenEOF { + input = "" + } else { + input = tokens.GetTextFromTokens(e.startToken, e.offendingToken) + } + } else { + input = "" + } + msg := "no viable alternative at input " + d.escapeWSAndQuote(input) + recognizer.NotifyErrorListeners(msg, e.offendingToken, e) +} + +// +// This is called by {@link //ReportError} when the exception is an +// {@link InputMisMatchException}. +// +// @see //ReportError +// +// @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}. +// +// @see //ReportError +// +// @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 + recognizer.NotifyErrorListeners(msg, e.offendingToken, e) +} + +// This method is called to Report a syntax error which requires the removal +// of a token from the input stream. At the time d method is called, the +// erroneous symbol is current {@code LT(1)} symbol and has not yet been +// removed from the input stream. When d method returns, +// {@code recognizer} is in error recovery mode. +// +//

This method is called when {@link //singleTokenDeletion} identifies +// single-token deletion as a viable recovery strategy for a mismatched +// input error.

+// +//

The default implementation simply returns if the handler is already in +// error recovery mode. Otherwise, it calls {@link //beginErrorCondition} to +// enter error recovery mode, followed by calling +// {@link Parser//NotifyErrorListeners}.

+// +// @param recognizer the parser instance +// +func (d *DefaultErrorStrategy) ReportUnwantedToken(recognizer Parser) { + if d.inErrorRecoveryMode(recognizer) { + return + } + d.beginErrorCondition(recognizer) + t := recognizer.GetCurrentToken() + tokenName := d.GetTokenErrorDisplay(t) + expecting := d.GetExpectedTokens(recognizer) + msg := "extraneous input " + tokenName + " expecting " + + expecting.StringVerbose(recognizer.GetLiteralNames(), recognizer.GetSymbolicNames(), false) + recognizer.NotifyErrorListeners(msg, t, nil) +} + +// This method is called to Report a syntax error which requires the +// insertion of a missing token into the input stream. At the time d +// method is called, the missing token has not yet been inserted. When d +// method returns, {@code recognizer} is in error recovery mode. +// +//

This method is called when {@link //singleTokenInsertion} identifies +// single-token insertion as a viable recovery strategy for a mismatched +// input error.

+// +//

The default implementation simply returns if the handler is already in +// error recovery mode. Otherwise, it calls {@link //beginErrorCondition} to +// enter error recovery mode, followed by calling +// {@link Parser//NotifyErrorListeners}.

+// +// @param recognizer the parser instance +// +func (d *DefaultErrorStrategy) ReportMissingToken(recognizer Parser) { + if d.inErrorRecoveryMode(recognizer) { + return + } + d.beginErrorCondition(recognizer) + t := recognizer.GetCurrentToken() + expecting := d.GetExpectedTokens(recognizer) + msg := "missing " + expecting.StringVerbose(recognizer.GetLiteralNames(), recognizer.GetSymbolicNames(), false) + + " at " + d.GetTokenErrorDisplay(t) + recognizer.NotifyErrorListeners(msg, t, nil) +} + +//

The default implementation attempts to recover from the mismatched input +// by using single token insertion and deletion as described below. If the +// recovery attempt fails, d method panics an +// {@link InputMisMatchException}.

+// +//

EXTRA TOKEN (single token deletion)

+// +//

{@code LA(1)} is not what we are looking for. If {@code LA(2)} has the +// right token, however, then assume {@code LA(1)} is some extra spurious +// token and delete it. Then consume and return the next token (which was +// the {@code LA(2)} token) as the successful result of the Match operation.

+// +//

This recovery strategy is implemented by {@link +// //singleTokenDeletion}.

+// +//

MISSING TOKEN (single token insertion)

+// +//

If current token (at {@code LA(1)}) is consistent with what could come +// after the expected {@code LA(1)} token, then assume the token is missing +// and use the parser's {@link TokenFactory} to create it on the fly. The +// "insertion" is performed by returning the created token as the successful +// result of the Match operation.

+// +//

This recovery strategy is implemented by {@link +// //singleTokenInsertion}.

+// +//

EXAMPLE

+// +//

For example, Input {@code i=(3} is clearly missing the {@code ')'}. When +// the parser returns from the nested call to {@code expr}, it will have +// call chain:

+// +//
+// stat &rarr expr &rarr atom
+// 
+// +// and it will be trying to Match the {@code ')'} at d point in the +// derivation: +// +//
+// => 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)==''} +// 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) + if MatchedSymbol != nil { + // we have deleted the extra token. + // now, move past ttype token as if all were ok + recognizer.Consume() + return MatchedSymbol + } + // SINGLE TOKEN INSERTION + if d.SingleTokenInsertion(recognizer) { + return d.GetMissingSymbol(recognizer) + } + // even that didn't work must panic the exception + 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 +// method returns {@code true}, {@code recognizer} will be in error recovery +// mode. +// +//

This method determines whether or not single-token insertion is viable by +// checking if the {@code LA(1)} input symbol could be successfully Matched +// if it were instead the {@code LA(2)} symbol. If d method returns +// {@code true}, the caller is responsible for creating and inserting a +// token with the correct type to produce d behavior.

+// +// @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 + // ATN state, then we know we're missing a token error recovery + // is free to conjure up and insert the missing token + atn := recognizer.GetInterpreter().atn + currentState := atn.states[recognizer.GetState()] + next := currentState.GetTransitions()[0].getTarget() + expectingAtLL2 := atn.NextTokens(next, recognizer.GetParserRuleContext()) + if expectingAtLL2.contains(currentSymbolType) { + d.ReportMissingToken(recognizer) + return true + } + + return false +} + +// This method implements the single-token deletion inline error recovery +// strategy. It is called by {@link //recoverInline} to attempt to recover +// from mismatched input. If this method returns nil, the parser and error +// handler state will not have changed. If this method returns non-nil, +// {@code recognizer} will not be in error recovery mode since the +// returned token was a successful Match. +// +//

If the single-token deletion is successful, d method calls +// {@link //ReportUnwantedToken} to Report the error, followed by +// {@link Parser//consume} to actually "delete" the extraneous token. Then, +// before returning {@link //ReportMatch} is called to signal a successful +// Match.

+// +// @param recognizer the parser instance +// @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) + if expecting.contains(NextTokenType) { + d.ReportUnwantedToken(recognizer) + // print("recoverFromMisMatchedToken deleting " \ + // + str(recognizer.GetTokenStream().LT(1)) \ + // + " since " + str(recognizer.GetTokenStream().LT(2)) \ + // + " is what we want", file=sys.stderr) + recognizer.Consume() // simply delete extra token + // we want to return the token we're actually Matching + MatchedSymbol := recognizer.GetCurrentToken() + d.ReportMatch(recognizer) // we know current token is correct + return MatchedSymbol + } + + return nil +} + +// Conjure up a missing token during error recovery. +// +// The recognizer attempts to recover from single missing +// symbols. But, actions might refer to that missing symbol. +// For example, x=ID {f($x)}. The action clearly assumes +// that there has been an identifier Matched previously and that +// $x points at that token. If that token is missing, but +// the next token in the stream is what we want we assume that +// d token is missing and we keep going. Because we +// have to return some token to replace the missing token, +// we have to conjure one up. This method gives the user control +// over the tokens returned for missing tokens. Mostly, +// you will want to create something special for identifier +// tokens. For literals such as '{' and ',', the default +// action in the parser or tree parser works. It simply creates +// 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) + expectedTokenType := expecting.first() + var tokenText string + + if expectedTokenType == TokenEOF { + tokenText = "" + } else { + ln := recognizer.GetLiteralNames() + if expectedTokenType > 0 && expectedTokenType < len(ln) { + tokenText = "" + } else { + tokenText = "" // TODO matches the JS impl + } + } + current := currentSymbol + lookback := recognizer.GetTokenStream().LT(-1) + if current.GetTokenType() == TokenEOF && lookback != nil { + current = lookback + } + + tf := recognizer.GetTokenFactory() + + return tf.Create(current.GetSource(), expectedTokenType, tokenText, TokenDefaultChannel, -1, -1, current.GetLine(), current.GetColumn()) +} + +func (d *DefaultErrorStrategy) GetExpectedTokens(recognizer Parser) *IntervalSet { + return recognizer.GetExpectedTokens() +} + +// 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. +// +func (d *DefaultErrorStrategy) GetTokenErrorDisplay(t Token) string { + if t == nil { + return "" + } + s := t.GetText() + if s == "" { + if t.GetTokenType() == TokenEOF { + s = "" + } else { + s = "<" + strconv.Itoa(t.GetTokenType()) + ">" + } + } + return d.escapeWSAndQuote(s) +} + +func (d *DefaultErrorStrategy) escapeWSAndQuote(s string) string { + s = strings.Replace(s, "\t", "\\t", -1) + s = strings.Replace(s, "\n", "\\n", -1) + s = strings.Replace(s, "\r", "\\r", -1) + return "'" + s + "'" +} + +// Compute the error recovery set for the current rule. During +// rule invocation, the parser pushes the set of tokens that can +// follow that rule reference on the stack d amounts to +// computing FIRST of what follows the rule reference in the +// enclosing rule. See LinearApproximator.FIRST(). +// This local follow set only includes tokens +// from within the rule i.e., the FIRST computation done by +// ANTLR stops at the end of a rule. +// +// EXAMPLE +// +// When you find a "no viable alt exception", the input is not +// consistent with any of the alternatives for rule r. The best +// thing to do is to consume tokens until you see something that +// can legally follow a call to r//or* any rule that called r. +// You don't want the exact set of viable next tokens because the +// input might just be missing a token--you might consume the +// rest of the input looking for one of the missing tokens. +// +// Consider grammar: +// +// a : '[' b ']' +// | '(' b ')' +// +// b : c '^' INT +// 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: +// +// FOLLOW(b1_in_a) = FIRST(']') = ']' +// FOLLOW(b2_in_a) = FIRST(')') = ')' +// FOLLOW(c_in_b) = FIRST('^') = '^' +// +// Upon erroneous input "[]", the call chain is +// +// a -> b -> c +// +// and, hence, the follow context stack is: +// +// depth follow set start of rule execution +// 0 a (from main()) +// 1 ']' b +// 2 '^' c +// +// Notice that ')' is not included, because b would have to have +// been called from a different context in rule a for ')' to be +// included. +// +// For error recovery, we cannot consider FOLLOW(c) +// (context-sensitive or otherwise). We need the combined set of +// all context-sensitive FOLLOW sets--the set of all tokens that +// could follow any reference in the call chain. We need to +// reSync to one of those tokens. Note that FOLLOW(c)='^' and if +// we reSync'd to that token, we'd consume until EOF. We need to +// Sync to context-sensitive FOLLOWs for a, b, and c: {']','^'}. +// In this case, for input "[]", LA(1) is ']' and in the set, so we would +// not consume anything. After printing an error, rule c would +// return normally. Rule b would not find the required '^' though. +// At this point, it gets a mismatched token error and panics an +// exception (since LA(1) is not in the viable following token +// set). The rule exception handler tries to recover, but finds +// the same recovery set and doesn't consume anything. Rule b +// exits normally returning to rule a. Now it finds the ']' (and +// with the successful Match exits errorRecovery mode). +// +// So, you can see that the parser walks up the call chain looking +// for the token that was a member of the recovery set. +// +// Errors are not generated in errorRecovery mode. +// +// ANTLR's error recovery mechanism is based upon original ideas: +// +// "Algorithms + Data Structures = Programs" by Niklaus Wirth +// +// and +// +// "A note on error recovery in recursive descent parsers": +// http://portal.acm.org/citation.cfm?id=947902.947905 +// +// Later, Josef Grosch had some good ideas: +// +// "Efficient and Comfortable Error Recovery in Recursive Descent +// Parsers": +// ftp://www.cocolab.com/products/cocktail/doca4.ps/ell.ps.zip +// +// 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() + recoverSet := NewIntervalSet() + for ctx != nil && ctx.GetInvokingState() >= 0 { + // compute what follows who invoked us + invokingState := atn.states[ctx.GetInvokingState()] + rt := invokingState.GetTransitions()[0] + follow := atn.NextTokens(rt.(*RuleTransition).followState, nil) + recoverSet.addSet(follow) + ctx = ctx.GetParent().(ParserRuleContext) + } + recoverSet.removeOne(TokenEpsilon) + return recoverSet +} + +// Consume tokens until one Matches the given token set.// +func (d *DefaultErrorStrategy) consumeUntil(recognizer Parser, set *IntervalSet) { + ttype := recognizer.GetTokenStream().LA(1) + for ttype != TokenEOF && !set.contains(ttype) { + recognizer.Consume() + ttype = recognizer.GetTokenStream().LA(1) + } +} + +// +// This implementation of {@link ANTLRErrorStrategy} responds to syntax errors +// by immediately canceling the parse operation with a +// {@link ParseCancellationException}. The implementation ensures that the +// {@link ParserRuleContext//exception} field is set for all parse tree nodes +// that were not completed prior to encountering the error. +// +//

+// This error strategy is useful in the following scenarios.

+// +//
    +//
  • Two-stage parsing: This error strategy allows the first +// stage of two-stage parsing to immediately terminate if an error is +// encountered, and immediately fall back to the second stage. In addition to +// avoiding wasted work by attempting to recover from errors here, the empty +// implementation of {@link BailErrorStrategy//Sync} improves the performance of +// the first stage.
  • +//
  • Silent validation: When syntax errors are not being +// Reported or logged, and the parse result is simply ignored if errors occur, +// the {@link BailErrorStrategy} avoids wasting work on recovering from errors +// when the result will be ignored either way.
  • +//
+// +//

+// {@code myparser.setErrorHandler(NewBailErrorStrategy())}

+// +// @see Parser//setErrorHandler(ANTLRErrorStrategy) + +type BailErrorStrategy struct { + *DefaultErrorStrategy +} + +var _ ErrorStrategy = &BailErrorStrategy{} + +func NewBailErrorStrategy() *BailErrorStrategy { + + b := new(BailErrorStrategy) + + b.DefaultErrorStrategy = NewDefaultErrorStrategy() + + return b +} + +// Instead of recovering from exception {@code e}, re-panic it wrapped +// 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 { + context.SetException(e) + context = context.GetParent().(ParserRuleContext) + } + panic(NewParseCancellationException()) // TODO we don't emit e properly +} + +// 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)) + + return nil +} + +// Make sure we don't attempt to recover from problems in subrules.// +func (b *BailErrorStrategy) Sync(recognizer Parser) { + // pass +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/errors.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/errors.go new file mode 100644 index 000000000..2ef74926e --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/errors.go @@ -0,0 +1,241 @@ +// Copyright (c) 2012-2017 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 + +// The root of the ANTLR exception hierarchy. In general, ANTLR tracks just +// 3 kinds of errors: prediction errors, failed predicate errors, and +// mismatched input errors. In each case, the parser knows where it is +// in the input, where it is in the ATN, the rule invocation stack, +// and what kind of problem occurred. + +type RecognitionException interface { + GetOffendingToken() Token + GetMessage() string + GetInputStream() IntStream +} + +type BaseRecognitionException struct { + message string + recognizer Recognizer + offendingToken Token + offendingState int + ctx RuleContext + input IntStream +} + +func NewBaseRecognitionException(message string, recognizer Recognizer, input IntStream, ctx RuleContext) *BaseRecognitionException { + + // todo + // Error.call(this) + // + // if (!!Error.captureStackTrace) { + // Error.captureStackTrace(this, RecognitionException) + // } else { + // stack := NewError().stack + // } + // TODO may be able to use - "runtime" func Stack(buf []byte, all bool) int + + t := new(BaseRecognitionException) + + t.message = message + t.recognizer = recognizer + t.input = input + t.ctx = ctx + // The current {@link Token} when an error occurred. Since not all streams + // support accessing symbols by index, we have to track the {@link Token} + // instance itself. + t.offendingToken = nil + // Get the ATN state number the parser was in at the time the error + // occurred. For {@link NoViableAltException} and + // {@link LexerNoViableAltException} exceptions, this is the + // {@link DecisionState} number. For others, it is the state whose outgoing + // edge we couldn't Match. + t.offendingState = -1 + if t.recognizer != nil { + t.offendingState = t.recognizer.GetState() + } + + return t +} + +func (b *BaseRecognitionException) GetMessage() string { + return b.message +} + +func (b *BaseRecognitionException) GetOffendingToken() Token { + return b.offendingToken +} + +func (b *BaseRecognitionException) GetInputStream() IntStream { + return b.input +} + +//

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. +// +//

If the set of expected tokens is not known and could not be computed, +// b method returns {@code nil}.

+// +// @return The set of token types that could potentially follow the current +// state in the ATN, or {@code nil} if the information is not available. +// / +func (b *BaseRecognitionException) getExpectedTokens() *IntervalSet { + if b.recognizer != nil { + return b.recognizer.GetATN().getExpectedTokens(b.offendingState, b.ctx) + } + + return nil +} + +func (b *BaseRecognitionException) String() string { + return b.message +} + +type LexerNoViableAltException struct { + *BaseRecognitionException + + startIndex int + deadEndConfigs ATNConfigSet +} + +func NewLexerNoViableAltException(lexer Lexer, input CharStream, startIndex int, deadEndConfigs ATNConfigSet) *LexerNoViableAltException { + + l := new(LexerNoViableAltException) + + l.BaseRecognitionException = NewBaseRecognitionException("", lexer, input, nil) + + l.startIndex = startIndex + l.deadEndConfigs = deadEndConfigs + + return l +} + +func (l *LexerNoViableAltException) String() string { + symbol := "" + if l.startIndex >= 0 && l.startIndex < l.input.Size() { + symbol = l.input.(CharStream).GetTextFromInterval(NewInterval(l.startIndex, l.startIndex)) + } + return "LexerNoViableAltException" + symbol +} + +type NoViableAltException struct { + *BaseRecognitionException + + startToken Token + offendingToken Token + ctx ParserRuleContext + deadEndConfigs ATNConfigSet +} + +// Indicates that the parser could not decide which of two or more paths +// 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 { + ctx = recognizer.GetParserRuleContext() + } + + if offendingToken == nil { + offendingToken = recognizer.GetCurrentToken() + } + + if startToken == nil { + startToken = recognizer.GetCurrentToken() + } + + if input == nil { + input = recognizer.GetInputStream().(TokenStream) + } + + n := new(NoViableAltException) + n.BaseRecognitionException = NewBaseRecognitionException("", recognizer, input, ctx) + + // Which configurations did we try at input.Index() that couldn't Match + // input.LT(1)?// + n.deadEndConfigs = deadEndConfigs + // The token object at the start index the input stream might + // not be buffering tokens so get a reference to it. (At the + // time the error occurred, of course the stream needs to keep a + // buffer all of the tokens but later we might not have access to those.) + n.startToken = startToken + n.offendingToken = offendingToken + + return n +} + +type InputMisMatchException struct { + *BaseRecognitionException +} + +// 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) + i.BaseRecognitionException = NewBaseRecognitionException("", recognizer, recognizer.GetInputStream(), recognizer.GetParserRuleContext()) + + i.offendingToken = recognizer.GetCurrentToken() + + return i + +} + +// A semantic predicate failed during validation. Validation of predicates +// occurs when normally parsing the alternative just like Matching a token. +// Disambiguating predicate evaluation occurs when we test a predicate during +// prediction. + +type FailedPredicateException struct { + *BaseRecognitionException + + ruleIndex int + predicateIndex int + predicate string +} + +func NewFailedPredicateException(recognizer Parser, predicate string, message string) *FailedPredicateException { + + f := new(FailedPredicateException) + + f.BaseRecognitionException = NewBaseRecognitionException(f.formatMessage(predicate, message), recognizer, recognizer.GetInputStream(), recognizer.GetParserRuleContext()) + + s := recognizer.GetInterpreter().atn.states[recognizer.GetState()] + trans := s.GetTransitions()[0] + if trans2, ok := trans.(*PredicateTransition); ok { + f.ruleIndex = trans2.ruleIndex + f.predicateIndex = trans2.predIndex + } else { + f.ruleIndex = 0 + f.predicateIndex = 0 + } + f.predicate = predicate + f.offendingToken = recognizer.GetCurrentToken() + + return f +} + +func (f *FailedPredicateException) formatMessage(predicate, message string) string { + if message != "" { + return message + } + + return "failed predicate: {" + predicate + "}?" +} + +type ParseCancellationException struct { +} + +func NewParseCancellationException() *ParseCancellationException { + // Error.call(this) + // Error.captureStackTrace(this, ParseCancellationException) + return new(ParseCancellationException) +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/file_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/file_stream.go new file mode 100644 index 000000000..842170c08 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/file_stream.go @@ -0,0 +1,49 @@ +// Copyright (c) 2012-2017 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" + "io" + "os" +) + +// This is an InputStream that is loaded from a file all at once +// when you construct the object. + +type FileStream struct { + *InputStream + + filename string +} + +func NewFileStream(fileName string) (*FileStream, error) { + + buf := bytes.NewBuffer(nil) + + f, err := os.Open(fileName) + if err != nil { + return nil, err + } + defer f.Close() + _, err = io.Copy(buf, f) + if err != nil { + return nil, err + } + + fs := new(FileStream) + + fs.filename = fileName + s := string(buf.Bytes()) + + fs.InputStream = NewInputStream(s) + + return fs, nil + +} + +func (f *FileStream) GetSourceName() string { + return f.filename +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/input_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/input_stream.go new file mode 100644 index 000000000..5ff270f53 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/input_stream.go @@ -0,0 +1,113 @@ +// Copyright (c) 2012-2017 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 + +type InputStream struct { + name string + index int + data []rune + size int +} + +func NewInputStream(data string) *InputStream { + + is := new(InputStream) + + is.name = "" + is.index = 0 + is.data = []rune(data) + is.size = len(is.data) // number of runes + + return is +} + +func (is *InputStream) reset() { + is.index = 0 +} + +func (is *InputStream) Consume() { + if is.index >= is.size { + // assert is.LA(1) == TokenEOF + panic("cannot consume EOF") + } + is.index++ +} + +func (is *InputStream) LA(offset int) int { + + if offset == 0 { + return 0 // nil + } + if offset < 0 { + offset++ // e.g., translate LA(-1) to use offset=0 + } + pos := is.index + offset - 1 + + if pos < 0 || pos >= is.size { // invalid + return TokenEOF + } + + return int(is.data[pos]) +} + +func (is *InputStream) LT(offset int) int { + return is.LA(offset) +} + +func (is *InputStream) Index() int { + return is.index +} + +func (is *InputStream) Size() int { + return is.size +} + +// mark/release do nothing we have entire buffer +func (is *InputStream) Mark() int { + return -1 +} + +func (is *InputStream) Release(marker int) { +} + +func (is *InputStream) Seek(index int) { + if index <= is.index { + is.index = index // just jump don't update stream state (line,...) + return + } + // seek forward + is.index = intMin(index, is.size) +} + +func (is *InputStream) GetText(start int, stop int) string { + if stop >= is.size { + stop = is.size - 1 + } + if start >= is.size { + return "" + } + + return string(is.data[start : stop+1]) +} + +func (is *InputStream) GetTextFromTokens(start, stop Token) string { + if start != nil && stop != nil { + return is.GetTextFromInterval(NewInterval(start.GetTokenIndex(), stop.GetTokenIndex())) + } + + return "" +} + +func (is *InputStream) GetTextFromInterval(i *Interval) string { + return is.GetText(i.Start, i.Stop) +} + +func (*InputStream) GetSourceName() string { + return "Obtained from string" +} + +func (is *InputStream) String() string { + return string(is.data) +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/int_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/int_stream.go new file mode 100644 index 000000000..438e0ea6e --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/int_stream.go @@ -0,0 +1,16 @@ +// Copyright (c) 2012-2017 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 + +type IntStream interface { + Consume() + LA(int) int + Mark() int + Release(marker int) + Index() int + Seek(index int) + Size() int + GetSourceName() string +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/interval_set.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/interval_set.go new file mode 100644 index 000000000..510d90911 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/interval_set.go @@ -0,0 +1,296 @@ +// Copyright (c) 2012-2017 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 ( + "strconv" + "strings" +) + +type Interval struct { + Start int + Stop int +} + +/* stop is not included! */ +func NewInterval(start, stop int) *Interval { + i := new(Interval) + + i.Start = start + i.Stop = stop + return i +} + +func (i *Interval) Contains(item int) bool { + return item >= i.Start && item < i.Stop +} + +func (i *Interval) String() string { + if i.Start == i.Stop-1 { + return strconv.Itoa(i.Start) + } + + return strconv.Itoa(i.Start) + ".." + strconv.Itoa(i.Stop-1) +} + +func (i *Interval) length() int { + return i.Stop - i.Start +} + +type IntervalSet struct { + intervals []*Interval + readOnly bool +} + +func NewIntervalSet() *IntervalSet { + + i := new(IntervalSet) + + i.intervals = nil + i.readOnly = false + + return i +} + +func (i *IntervalSet) first() int { + if len(i.intervals) == 0 { + return TokenInvalidType + } + + return i.intervals[0].Start +} + +func (i *IntervalSet) addOne(v int) { + i.addInterval(NewInterval(v, v+1)) +} + +func (i *IntervalSet) addRange(l, h int) { + i.addInterval(NewInterval(l, h+1)) +} + +func (i *IntervalSet) addInterval(v *Interval) { + if i.intervals == nil { + i.intervals = make([]*Interval, 0) + i.intervals = append(i.intervals, v) + } else { + // find insert pos + for k, interval := range i.intervals { + // distinct range -> insert + if v.Stop < interval.Start { + i.intervals = append(i.intervals[0:k], append([]*Interval{v}, i.intervals[k:]...)...) + return + } else if v.Stop == interval.Start { + i.intervals[k].Start = v.Start + return + } else if v.Start <= interval.Stop { + i.intervals[k] = NewInterval(intMin(interval.Start, v.Start), intMax(interval.Stop, v.Stop)) + + // if not applying to end, merge potential overlaps + if k < len(i.intervals)-1 { + l := i.intervals[k] + r := i.intervals[k+1] + // if r contained in l + if l.Stop >= r.Stop { + i.intervals = append(i.intervals[0:k+1], i.intervals[k+2:]...) + } else if l.Stop >= r.Start { // partial overlap + i.intervals[k] = NewInterval(l.Start, r.Stop) + i.intervals = append(i.intervals[0:k+1], i.intervals[k+2:]...) + } + } + return + } + } + // greater than any exiting + i.intervals = append(i.intervals, v) + } +} + +func (i *IntervalSet) addSet(other *IntervalSet) *IntervalSet { + if other.intervals != nil { + for k := 0; k < len(other.intervals); k++ { + i2 := other.intervals[k] + i.addInterval(NewInterval(i2.Start, i2.Stop)) + } + } + return i +} + +func (i *IntervalSet) complement(start int, stop int) *IntervalSet { + result := NewIntervalSet() + result.addInterval(NewInterval(start, stop+1)) + for j := 0; j < len(i.intervals); j++ { + result.removeRange(i.intervals[j]) + } + return result +} + +func (i *IntervalSet) contains(item int) bool { + if i.intervals == nil { + return false + } + for k := 0; k < len(i.intervals); k++ { + if i.intervals[k].Contains(item) { + return true + } + } + return false +} + +func (i *IntervalSet) length() int { + len := 0 + + for _, v := range i.intervals { + len += v.length() + } + + return len +} + +func (i *IntervalSet) removeRange(v *Interval) { + if v.Start == v.Stop-1 { + i.removeOne(v.Start) + } else if i.intervals != nil { + k := 0 + for n := 0; n < len(i.intervals); n++ { + ni := i.intervals[k] + // intervals are ordered + if v.Stop <= ni.Start { + return + } else if v.Start > ni.Start && v.Stop < ni.Stop { + i.intervals[k] = NewInterval(ni.Start, v.Start) + x := NewInterval(v.Stop, ni.Stop) + // i.intervals.splice(k, 0, x) + i.intervals = append(i.intervals[0:k], append([]*Interval{x}, i.intervals[k:]...)...) + return + } else if v.Start <= ni.Start && v.Stop >= ni.Stop { + // i.intervals.splice(k, 1) + i.intervals = append(i.intervals[0:k], i.intervals[k+1:]...) + k = k - 1 // need another pass + } else if v.Start < ni.Stop { + i.intervals[k] = NewInterval(ni.Start, v.Start) + } else if v.Stop < ni.Stop { + i.intervals[k] = NewInterval(v.Stop, ni.Stop) + } + k++ + } + } +} + +func (i *IntervalSet) removeOne(v int) { + if i.intervals != nil { + for k := 0; k < len(i.intervals); k++ { + ki := i.intervals[k] + // intervals i ordered + if v < ki.Start { + return + } else if v == ki.Start && v == ki.Stop-1 { + // i.intervals.splice(k, 1) + i.intervals = append(i.intervals[0:k], i.intervals[k+1:]...) + return + } else if v == ki.Start { + i.intervals[k] = NewInterval(ki.Start+1, ki.Stop) + return + } else if v == ki.Stop-1 { + i.intervals[k] = NewInterval(ki.Start, ki.Stop-1) + return + } else if v < ki.Stop-1 { + x := NewInterval(ki.Start, v) + ki.Start = v + 1 + // i.intervals.splice(k, 0, x) + i.intervals = append(i.intervals[0:k], append([]*Interval{x}, i.intervals[k:]...)...) + return + } + } + } +} + +func (i *IntervalSet) String() string { + return i.StringVerbose(nil, nil, false) +} + +func (i *IntervalSet) StringVerbose(literalNames []string, symbolicNames []string, elemsAreChar bool) string { + + if i.intervals == nil { + return "{}" + } else if literalNames != nil || symbolicNames != nil { + return i.toTokenString(literalNames, symbolicNames) + } else if elemsAreChar { + return i.toCharString() + } + + return i.toIndexString() +} + +func (i *IntervalSet) toCharString() string { + names := make([]string, len(i.intervals)) + + for j := 0; j < len(i.intervals); j++ { + v := i.intervals[j] + if v.Stop == v.Start+1 { + if v.Start == TokenEOF { + names = append(names, "") + } else { + names = append(names, ("'" + string(v.Start) + "'")) + } + } else { + names = append(names, "'"+string(v.Start)+"'..'"+string(v.Stop-1)+"'") + } + } + if len(names) > 1 { + return "{" + strings.Join(names, ", ") + "}" + } + + return names[0] +} + +func (i *IntervalSet) toIndexString() string { + + names := make([]string, 0) + for j := 0; j < len(i.intervals); j++ { + v := i.intervals[j] + if v.Stop == v.Start+1 { + if v.Start == TokenEOF { + names = append(names, "") + } else { + names = append(names, strconv.Itoa(v.Start)) + } + } else { + names = append(names, strconv.Itoa(v.Start)+".."+strconv.Itoa(v.Stop-1)) + } + } + if len(names) > 1 { + return "{" + strings.Join(names, ", ") + "}" + } + + return names[0] +} + +func (i *IntervalSet) toTokenString(literalNames []string, symbolicNames []string) string { + names := make([]string, 0) + for _, v := range i.intervals { + for j := v.Start; j < v.Stop; j++ { + names = append(names, i.elementName(literalNames, symbolicNames, j)) + } + } + if len(names) > 1 { + return "{" + strings.Join(names, ", ") + "}" + } + + return names[0] +} + +func (i *IntervalSet) elementName(literalNames []string, symbolicNames []string, a int) string { + if a == TokenEOF { + return "" + } else if a == TokenEpsilon { + return "" + } else { + if a < len(literalNames) && literalNames[a] != "" { + return literalNames[a] + } + + return symbolicNames[a] + } +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer.go new file mode 100644 index 000000000..02deaf99c --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer.go @@ -0,0 +1,417 @@ +// Copyright (c) 2012-2017 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" + "strconv" +) + +// A lexer is recognizer that draws input symbols from a character stream. +// lexer grammars result in a subclass of this object. A Lexer object +// uses simplified Match() and error recovery mechanisms in the interest +// of speed. +/// + +type Lexer interface { + TokenSource + Recognizer + + Emit() Token + + SetChannel(int) + PushMode(int) + PopMode() int + SetType(int) + SetMode(int) +} + +type BaseLexer struct { + *BaseRecognizer + + Interpreter ILexerATNSimulator + TokenStartCharIndex int + TokenStartLine int + TokenStartColumn int + ActionType int + Virt Lexer // The most derived lexer implementation. Allows virtual method calls. + + input CharStream + factory TokenFactory + tokenFactorySourcePair *TokenSourceCharStreamPair + token Token + hitEOF bool + channel int + thetype int + modeStack IntStack + mode int + text string +} + +func NewBaseLexer(input CharStream) *BaseLexer { + + lexer := new(BaseLexer) + + lexer.BaseRecognizer = NewBaseRecognizer() + + lexer.input = input + lexer.factory = CommonTokenFactoryDEFAULT + lexer.tokenFactorySourcePair = &TokenSourceCharStreamPair{lexer, input} + + lexer.Virt = lexer + + lexer.Interpreter = nil // child classes must populate it + + // The goal of all lexer rules/methods is to create a token object. + // l is an instance variable as multiple rules may collaborate to + // create a single token. NextToken will return l object after + // Matching lexer rule(s). If you subclass to allow multiple token + // emissions, then set l to the last token to be Matched or + // something nonnil so that the auto token emit mechanism will not + // emit another token. + lexer.token = nil + + // What character index in the stream did the current token start at? + // Needed, for example, to get the text for current token. Set at + // the start of NextToken. + lexer.TokenStartCharIndex = -1 + + // The line on which the first character of the token resides/// + lexer.TokenStartLine = -1 + + // The character position of first character within the line/// + lexer.TokenStartColumn = -1 + + // Once we see EOF on char stream, next token will be EOF. + // If you have DONE : EOF then you see DONE EOF. + lexer.hitEOF = false + + // The channel number for the current token/// + lexer.channel = TokenDefaultChannel + + // The token type for the current token/// + lexer.thetype = TokenInvalidType + + lexer.modeStack = make([]int, 0) + lexer.mode = LexerDefaultMode + + // You can set the text for the current token to override what is in + // the input char buffer. Use setText() or can set l instance var. + // / + lexer.text = "" + + return lexer +} + +const ( + LexerDefaultMode = 0 + LexerMore = -2 + LexerSkip = -3 +) + +const ( + LexerDefaultTokenChannel = TokenDefaultChannel + LexerHidden = TokenHiddenChannel + LexerMinCharValue = 0x0000 + LexerMaxCharValue = 0x10FFFF +) + +func (b *BaseLexer) reset() { + // wack Lexer state variables + if b.input != nil { + b.input.Seek(0) // rewind the input + } + b.token = nil + b.thetype = TokenInvalidType + b.channel = TokenDefaultChannel + b.TokenStartCharIndex = -1 + b.TokenStartColumn = -1 + b.TokenStartLine = -1 + b.text = "" + + b.hitEOF = false + b.mode = LexerDefaultMode + b.modeStack = make([]int, 0) + + b.Interpreter.reset() +} + +func (b *BaseLexer) GetInterpreter() ILexerATNSimulator { + return b.Interpreter +} + +func (b *BaseLexer) GetInputStream() CharStream { + return b.input +} + +func (b *BaseLexer) GetSourceName() string { + return b.GrammarFileName +} + +func (b *BaseLexer) SetChannel(v int) { + b.channel = v +} + +func (b *BaseLexer) GetTokenFactory() TokenFactory { + return b.factory +} + +func (b *BaseLexer) setTokenFactory(f TokenFactory) { + b.factory = f +} + +func (b *BaseLexer) safeMatch() (ret int) { + defer func() { + if e := recover(); e != nil { + if re, ok := e.(RecognitionException); ok { + b.notifyListeners(re) // Report error + b.Recover(re) + ret = LexerSkip // default + } + } + }() + + return b.Interpreter.Match(b.input, b.mode) +} + +// Return a token from l source i.e., Match a token on the char stream. +func (b *BaseLexer) NextToken() Token { + if b.input == nil { + panic("NextToken requires a non-nil input stream.") + } + + tokenStartMarker := b.input.Mark() + + // previously in finally block + defer func() { + // make sure we release marker after Match or + // unbuffered char stream will keep buffering + b.input.Release(tokenStartMarker) + }() + + for { + if b.hitEOF { + b.EmitEOF() + return b.token + } + b.token = nil + b.channel = TokenDefaultChannel + b.TokenStartCharIndex = b.input.Index() + b.TokenStartColumn = b.Interpreter.GetCharPositionInLine() + b.TokenStartLine = b.Interpreter.GetLine() + b.text = "" + continueOuter := false + for { + b.thetype = TokenInvalidType + ttype := LexerSkip + + ttype = b.safeMatch() + + if b.input.LA(1) == TokenEOF { + b.hitEOF = true + } + if b.thetype == TokenInvalidType { + b.thetype = ttype + } + if b.thetype == LexerSkip { + continueOuter = true + break + } + if b.thetype != LexerMore { + break + } + } + + if continueOuter { + continue + } + if b.token == nil { + b.Virt.Emit() + } + return b.token + } + + return nil +} + +// Instruct the lexer to Skip creating a token for current lexer rule +// and look for another token. NextToken() knows to keep looking when +// a lexer rule finishes with token set to SKIPTOKEN. Recall that +// if token==nil at end of any token rule, it creates one for you +// and emits it. +// / +func (b *BaseLexer) Skip() { + b.thetype = LexerSkip +} + +func (b *BaseLexer) More() { + b.thetype = LexerMore +} + +func (b *BaseLexer) SetMode(m int) { + b.mode = m +} + +func (b *BaseLexer) PushMode(m int) { + if LexerATNSimulatorDebug { + fmt.Println("pushMode " + strconv.Itoa(m)) + } + b.modeStack.Push(b.mode) + b.mode = m +} + +func (b *BaseLexer) PopMode() int { + if len(b.modeStack) == 0 { + panic("Empty Stack") + } + if LexerATNSimulatorDebug { + fmt.Println("popMode back to " + fmt.Sprint(b.modeStack[0:len(b.modeStack)-1])) + } + i, _ := b.modeStack.Pop() + b.mode = i + return b.mode +} + +func (b *BaseLexer) inputStream() CharStream { + return b.input +} + +func (b *BaseLexer) setInputStream(input CharStream) { + b.input = nil + b.tokenFactorySourcePair = &TokenSourceCharStreamPair{b, b.input} + b.reset() + b.input = input + b.tokenFactorySourcePair = &TokenSourceCharStreamPair{b, b.input} +} + +func (b *BaseLexer) GetTokenSourceCharStreamPair() *TokenSourceCharStreamPair { + return b.tokenFactorySourcePair +} + +// By default does not support multiple emits per NextToken invocation +// for efficiency reasons. Subclass and override l method, NextToken, +// and GetToken (to push tokens into a list and pull from that list +// rather than a single variable as l implementation does). +// / +func (b *BaseLexer) EmitToken(token Token) { + b.token = token +} + +// The standard method called to automatically emit a token at the +// outermost lexical rule. The token object should point into the +// char buffer start..stop. If there is a text override in 'text', +// use that to set the token's text. Override l method to emit +// custom Token objects or provide a Newfactory. +// / +func (b *BaseLexer) Emit() Token { + t := b.factory.Create(b.tokenFactorySourcePair, b.thetype, b.text, b.channel, b.TokenStartCharIndex, b.GetCharIndex()-1, b.TokenStartLine, b.TokenStartColumn) + b.EmitToken(t) + return t +} + +func (b *BaseLexer) EmitEOF() Token { + cpos := b.GetCharPositionInLine() + lpos := b.GetLine() + eof := b.factory.Create(b.tokenFactorySourcePair, TokenEOF, "", TokenDefaultChannel, b.input.Index(), b.input.Index()-1, lpos, cpos) + b.EmitToken(eof) + return eof +} + +func (b *BaseLexer) GetCharPositionInLine() int { + return b.Interpreter.GetCharPositionInLine() +} + +func (b *BaseLexer) GetLine() int { + return b.Interpreter.GetLine() +} + +func (b *BaseLexer) GetType() int { + return b.thetype +} + +func (b *BaseLexer) SetType(t int) { + b.thetype = t +} + +// What is the index of the current character of lookahead?/// +func (b *BaseLexer) GetCharIndex() int { + return b.input.Index() +} + +// 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. +func (b *BaseLexer) GetText() string { + if b.text != "" { + return b.text + } + + return b.Interpreter.GetText(b.input) +} + +func (b *BaseLexer) SetText(text string) { + b.text = text +} + +func (b *BaseLexer) GetATN() *ATN { + return b.Interpreter.ATN() +} + +// Return a list of all Token objects in input char stream. +// Forces load of all tokens. Does not include EOF token. +// / +func (b *BaseLexer) GetAllTokens() []Token { + vl := b.Virt + tokens := make([]Token, 0) + t := vl.NextToken() + for t.GetTokenType() != TokenEOF { + tokens = append(tokens, t) + t = vl.NextToken() + } + return tokens +} + +func (b *BaseLexer) notifyListeners(e RecognitionException) { + start := b.TokenStartCharIndex + stop := b.input.Index() + text := b.input.GetTextFromInterval(NewInterval(start, stop)) + msg := "token recognition error at: '" + text + "'" + listener := b.GetErrorListenerDispatch() + listener.SyntaxError(b, nil, b.TokenStartLine, b.TokenStartColumn, msg, e) +} + +func (b *BaseLexer) getErrorDisplayForChar(c rune) string { + if c == TokenEOF { + return "" + } else if c == '\n' { + return "\\n" + } else if c == '\t' { + return "\\t" + } else if c == '\r' { + return "\\r" + } else { + return string(c) + } +} + +func (b *BaseLexer) getCharErrorDisplay(c rune) string { + return "'" + b.getErrorDisplayForChar(c) + "'" +} + +// Lexers can normally Match any char in it's vocabulary after Matching +// a token, so do the easy thing and just kill a character and hope +// it all works out. You can instead use the rule invocation stack +// to do sophisticated error recovery if you are in a fragment rule. +// / +func (b *BaseLexer) Recover(re RecognitionException) { + if b.input.LA(1) != TokenEOF { + if _, ok := re.(*LexerNoViableAltException); ok { + // Skip a char and try again + b.Interpreter.Consume(b.input) + } else { + // TODO: Do we lose character or line position information? + b.input.Consume() + } + } +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action.go new file mode 100644 index 000000000..20df84f94 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action.go @@ -0,0 +1,431 @@ +// Copyright (c) 2012-2017 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 "strconv" + +const ( + LexerActionTypeChannel = 0 //The type of a {@link LexerChannelAction} action. + LexerActionTypeCustom = 1 //The type of a {@link LexerCustomAction} action. + LexerActionTypeMode = 2 //The type of a {@link LexerModeAction} action. + LexerActionTypeMore = 3 //The type of a {@link LexerMoreAction} action. + LexerActionTypePopMode = 4 //The type of a {@link LexerPopModeAction} action. + LexerActionTypePushMode = 5 //The type of a {@link LexerPushModeAction} action. + LexerActionTypeSkip = 6 //The type of a {@link LexerSkipAction} action. + LexerActionTypeType = 7 //The type of a {@link LexerTypeAction} action. +) + +type LexerAction interface { + getActionType() int + getIsPositionDependent() bool + execute(lexer Lexer) + hash() int + equals(other LexerAction) bool +} + +type BaseLexerAction struct { + actionType int + isPositionDependent bool +} + +func NewBaseLexerAction(action int) *BaseLexerAction { + la := new(BaseLexerAction) + + la.actionType = action + la.isPositionDependent = false + + return la +} + +func (b *BaseLexerAction) execute(lexer Lexer) { + panic("Not implemented") +} + +func (b *BaseLexerAction) getActionType() int { + return b.actionType +} + +func (b *BaseLexerAction) getIsPositionDependent() bool { + return b.isPositionDependent +} + +func (b *BaseLexerAction) hash() int { + return b.actionType +} + +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 +// implemented as a singleton instance exposed by {@link //INSTANCE}.

+type LexerSkipAction struct { + *BaseLexerAction +} + +func NewLexerSkipAction() *LexerSkipAction { + la := new(LexerSkipAction) + la.BaseLexerAction = NewBaseLexerAction(LexerActionTypeSkip) + return la +} + +// Provides a singleton instance of l parameterless lexer action. +var LexerSkipActionINSTANCE = NewLexerSkipAction() + +func (l *LexerSkipAction) execute(lexer Lexer) { + lexer.Skip() +} + +func (l *LexerSkipAction) String() string { + return "skip" +} + +// Implements the {@code type} lexer action by calling {@link Lexer//setType} +// with the assigned type. +type LexerTypeAction struct { + *BaseLexerAction + + thetype int +} + +func NewLexerTypeAction(thetype int) *LexerTypeAction { + l := new(LexerTypeAction) + l.BaseLexerAction = NewBaseLexerAction(LexerActionTypeType) + l.thetype = thetype + return l +} + +func (l *LexerTypeAction) execute(lexer Lexer) { + lexer.SetType(l.thetype) +} + +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 { + if l == other { + return true + } else if _, ok := other.(*LexerTypeAction); !ok { + return false + } else { + return l.thetype == other.(*LexerTypeAction).thetype + } +} + +func (l *LexerTypeAction) String() string { + return "actionType(" + strconv.Itoa(l.thetype) + ")" +} + +// Implements the {@code pushMode} lexer action by calling +// {@link Lexer//pushMode} with the assigned mode. +type LexerPushModeAction struct { + *BaseLexerAction + + mode int +} + +func NewLexerPushModeAction(mode int) *LexerPushModeAction { + + l := new(LexerPushModeAction) + l.BaseLexerAction = NewBaseLexerAction(LexerActionTypePushMode) + + l.mode = mode + return l +} + +//

This action is implemented by calling {@link Lexer//pushMode} with the +// value provided by {@link //getMode}.

+func (l *LexerPushModeAction) execute(lexer Lexer) { + lexer.PushMode(l.mode) +} + +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 { + if l == other { + return true + } else if _, ok := other.(*LexerPushModeAction); !ok { + return false + } else { + return l.mode == other.(*LexerPushModeAction).mode + } +} + +func (l *LexerPushModeAction) String() string { + return "pushMode(" + strconv.Itoa(l.mode) + ")" +} + +// Implements the {@code popMode} lexer action by calling {@link Lexer//popMode}. +// +//

The {@code popMode} command does not have any parameters, so l action is +// implemented as a singleton instance exposed by {@link //INSTANCE}.

+type LexerPopModeAction struct { + *BaseLexerAction +} + +func NewLexerPopModeAction() *LexerPopModeAction { + + l := new(LexerPopModeAction) + + l.BaseLexerAction = NewBaseLexerAction(LexerActionTypePopMode) + + return l +} + +var LexerPopModeActionINSTANCE = NewLexerPopModeAction() + +//

This action is implemented by calling {@link Lexer//popMode}.

+func (l *LexerPopModeAction) execute(lexer Lexer) { + lexer.PopMode() +} + +func (l *LexerPopModeAction) String() string { + return "popMode" +} + +// Implements the {@code more} lexer action by calling {@link Lexer//more}. +// +//

The {@code more} command does not have any parameters, so l action is +// implemented as a singleton instance exposed by {@link //INSTANCE}.

+ +type LexerMoreAction struct { + *BaseLexerAction +} + +func NewLexerMoreAction() *LexerMoreAction { + l := new(LexerMoreAction) + l.BaseLexerAction = NewBaseLexerAction(LexerActionTypeMore) + + return l +} + +var LexerMoreActionINSTANCE = NewLexerMoreAction() + +//

This action is implemented by calling {@link Lexer//popMode}.

+func (l *LexerMoreAction) execute(lexer Lexer) { + lexer.More() +} + +func (l *LexerMoreAction) String() string { + return "more" +} + +// Implements the {@code mode} lexer action by calling {@link Lexer//mode} with +// the assigned mode. +type LexerModeAction struct { + *BaseLexerAction + + mode int +} + +func NewLexerModeAction(mode int) *LexerModeAction { + l := new(LexerModeAction) + l.BaseLexerAction = NewBaseLexerAction(LexerActionTypeMode) + l.mode = mode + return l +} + +//

This action is implemented by calling {@link Lexer//mode} with the +// value provided by {@link //getMode}.

+func (l *LexerModeAction) execute(lexer Lexer) { + lexer.SetMode(l.mode) +} + +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 { + if l == other { + return true + } else if _, ok := other.(*LexerModeAction); !ok { + return false + } else { + return l.mode == other.(*LexerModeAction).mode + } +} + +func (l *LexerModeAction) String() string { + return "mode(" + strconv.Itoa(l.mode) + ")" +} + +// Executes a custom lexer action by calling {@link Recognizer//action} with the +// rule and action indexes assigned to the custom action. The implementation of +// a custom action is added to the generated code for the lexer in an override +// of {@link Recognizer//action} when the grammar is compiled. +// +//

This class may represent embedded actions created with the {...} +// syntax in ANTLR 4, as well as actions created for lexer commands where the +// command argument could not be evaluated when the grammar was compiled.

+ +// Constructs a custom lexer action with the specified rule and action +// indexes. +// +// @param ruleIndex The rule index to use for calls to +// {@link Recognizer//action}. +// @param actionIndex The action index to use for calls to +// {@link Recognizer//action}. + +type LexerCustomAction struct { + *BaseLexerAction + ruleIndex, actionIndex int +} + +func NewLexerCustomAction(ruleIndex, actionIndex int) *LexerCustomAction { + l := new(LexerCustomAction) + l.BaseLexerAction = NewBaseLexerAction(LexerActionTypeCustom) + l.ruleIndex = ruleIndex + l.actionIndex = actionIndex + l.isPositionDependent = true + return l +} + +//

Custom actions are implemented by calling {@link Lexer//action} with the +// appropriate rule and action indexes.

+func (l *LexerCustomAction) execute(lexer Lexer) { + lexer.Action(nil, l.ruleIndex, l.actionIndex) +} + +func (l *LexerCustomAction) hash() int { + h := murmurInit(0) + h = murmurUpdate(h, l.actionType) + h = murmurUpdate(h, l.ruleIndex) + h = murmurUpdate(h, l.actionIndex) + return murmurFinish(h, 3) +} + +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 + } +} + +// Implements the {@code channel} lexer action by calling +// {@link Lexer//setChannel} with the assigned channel. +// Constructs a New{@code channel} action with the specified channel value. +// @param channel The channel value to pass to {@link Lexer//setChannel}. +type LexerChannelAction struct { + *BaseLexerAction + + channel int +} + +func NewLexerChannelAction(channel int) *LexerChannelAction { + l := new(LexerChannelAction) + l.BaseLexerAction = NewBaseLexerAction(LexerActionTypeChannel) + l.channel = channel + return l +} + +//

This action is implemented by calling {@link Lexer//setChannel} with the +// value provided by {@link //getChannel}.

+func (l *LexerChannelAction) execute(lexer Lexer) { + lexer.SetChannel(l.channel) +} + +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 { + if l == other { + return true + } else if _, ok := other.(*LexerChannelAction); !ok { + return false + } else { + return l.channel == other.(*LexerChannelAction).channel + } +} + +func (l *LexerChannelAction) String() string { + return "channel(" + strconv.Itoa(l.channel) + ")" +} + +// This implementation of {@link LexerAction} is used for tracking input offsets +// for position-dependent actions within a {@link LexerActionExecutor}. +// +//

This action is not serialized as part of the ATN, and is only required for +// position-dependent lexer actions which appear at a location other than the +// end of a rule. For more information about DFA optimizations employed for +// lexer actions, see {@link LexerActionExecutor//append} and +// {@link LexerActionExecutor//fixOffsetBeforeMatch}.

+ +// Constructs a Newindexed custom action by associating a character offset +// with a {@link LexerAction}. +// +//

Note: This class is only required for lexer actions for which +// {@link LexerAction//isPositionDependent} returns {@code true}.

+// +// @param offset The offset into the input {@link CharStream}, relative to +// the token start index, at which the specified lexer action should be +// executed. +// @param action The lexer action to execute at a particular offset in the +// input {@link CharStream}. +type LexerIndexedCustomAction struct { + *BaseLexerAction + + offset int + lexerAction LexerAction + isPositionDependent bool +} + +func NewLexerIndexedCustomAction(offset int, lexerAction LexerAction) *LexerIndexedCustomAction { + + l := new(LexerIndexedCustomAction) + l.BaseLexerAction = NewBaseLexerAction(lexerAction.getActionType()) + + l.offset = offset + l.lexerAction = lexerAction + l.isPositionDependent = true + + return l +} + +//

This method calls {@link //execute} on the result of {@link //getAction} +// using the provided {@code lexer}.

+func (l *LexerIndexedCustomAction) execute(lexer Lexer) { + // assume the input stream position was properly set by the calling code + l.lexerAction.execute(lexer) +} + +func (l *LexerIndexedCustomAction) hash() int { + h := murmurInit(0) + h = murmurUpdate(h, l.actionType) + h = murmurUpdate(h, l.offset) + h = murmurUpdate(h, l.lexerAction.hash()) + return murmurFinish(h, 3) +} + +func (l *LexerIndexedCustomAction) equals(other LexerAction) bool { + if l == other { + return true + } else if _, ok := other.(*LexerIndexedCustomAction); !ok { + return false + } else { + return l.offset == other.(*LexerIndexedCustomAction).offset && l.lexerAction == 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/lexer_action_executor.go new file mode 100644 index 000000000..80b949a1a --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action_executor.go @@ -0,0 +1,170 @@ +// Copyright (c) 2012-2017 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 + +// Represents an executor for a sequence of lexer actions which traversed during +// the Matching operation of a lexer rule (token). +// +//

The executor tracks position information for position-dependent lexer actions +// efficiently, ensuring that actions appearing only at the end of the rule do +// not cause bloating of the {@link DFA} created for the lexer.

+ +type LexerActionExecutor struct { + lexerActions []LexerAction + cachedHash int +} + +func NewLexerActionExecutor(lexerActions []LexerAction) *LexerActionExecutor { + + if lexerActions == nil { + lexerActions = make([]LexerAction, 0) + } + + l := new(LexerActionExecutor) + + l.lexerActions = lexerActions + + // Caches the result of {@link //hashCode} since the hash code is an element + // of the performance-critical {@link LexerATNConfig//hashCode} operation. + l.cachedHash = murmurInit(57) + for _, a := range lexerActions { + l.cachedHash = murmurUpdate(l.cachedHash, a.hash()) + } + + return l +} + +// Creates a {@link LexerActionExecutor} which executes the actions for +// the input {@code lexerActionExecutor} followed by a specified +// {@code lexerAction}. +// +// @param lexerActionExecutor The executor for actions already traversed by +// the lexer while Matching a token within a particular +// {@link LexerATNConfig}. If this is {@code nil}, the method behaves as +// though it were an empty executor. +// @param lexerAction The lexer action to execute after the actions +// specified in {@code lexerActionExecutor}. +// +// @return A {@link LexerActionExecutor} for executing the combine actions +// of {@code lexerActionExecutor} and {@code lexerAction}. +func LexerActionExecutorappend(lexerActionExecutor *LexerActionExecutor, lexerAction LexerAction) *LexerActionExecutor { + if lexerActionExecutor == nil { + return NewLexerActionExecutor([]LexerAction{lexerAction}) + } + + return NewLexerActionExecutor(append(lexerActionExecutor.lexerActions, lexerAction)) +} + +// Creates a {@link LexerActionExecutor} which encodes the current offset +// for position-dependent lexer actions. +// +//

Normally, when the executor encounters lexer actions where +// {@link LexerAction//isPositionDependent} returns {@code true}, it calls +// {@link IntStream//seek} on the input {@link CharStream} to set the input +// position to the end of the current token. This behavior provides +// for efficient DFA representation of lexer actions which appear at the end +// of a lexer rule, even when the lexer rule Matches a variable number of +// characters.

+// +//

Prior to traversing a Match transition in the ATN, the current offset +// from the token start index is assigned to all position-dependent lexer +// actions which have not already been assigned a fixed offset. By storing +// the offsets relative to the token start index, the DFA representation of +// lexer actions which appear in the middle of tokens remains efficient due +// to sharing among tokens of the same length, regardless of their absolute +// position in the input stream.

+// +//

If the current executor already has offsets assigned to all +// position-dependent lexer actions, the method returns {@code this}.

+// +// @param offset The current offset to assign to all position-dependent +// lexer actions which do not already have offsets assigned. +// +// @return A {@link LexerActionExecutor} which stores input stream offsets +// for all position-dependent lexer actions. +// / +func (l *LexerActionExecutor) fixOffsetBeforeMatch(offset int) *LexerActionExecutor { + var updatedLexerActions []LexerAction + for i := 0; i < len(l.lexerActions); i++ { + _, ok := l.lexerActions[i].(*LexerIndexedCustomAction) + if l.lexerActions[i].getIsPositionDependent() && !ok { + if updatedLexerActions == nil { + updatedLexerActions = make([]LexerAction, 0) + + for _, a := range l.lexerActions { + updatedLexerActions = append(updatedLexerActions, a) + } + } + + updatedLexerActions[i] = NewLexerIndexedCustomAction(offset, l.lexerActions[i]) + } + } + if updatedLexerActions == nil { + return l + } + + return NewLexerActionExecutor(updatedLexerActions) +} + +// Execute the actions encapsulated by l executor within the context of a +// particular {@link Lexer}. +// +//

This method calls {@link IntStream//seek} to set the position of the +// {@code input} {@link CharStream} prior to calling +// {@link LexerAction//execute} on a position-dependent action. Before the +// method returns, the input position will be restored to the same position +// it was in when the method was invoked.

+// +// @param lexer The lexer instance. +// @param input The input stream which is the source for the current token. +// When l method is called, the current {@link IntStream//index} for +// {@code input} should be the start of the following token, i.e. 1 +// character past the end of the current token. +// @param startIndex The token start index. This value may be passed to +// {@link IntStream//seek} to set the {@code input} position to the beginning +// of the token. +// / +func (l *LexerActionExecutor) execute(lexer Lexer, input CharStream, startIndex int) { + requiresSeek := false + stopIndex := input.Index() + + defer func() { + if requiresSeek { + input.Seek(stopIndex) + } + }() + + for i := 0; i < len(l.lexerActions); i++ { + lexerAction := l.lexerActions[i] + if la, ok := lexerAction.(*LexerIndexedCustomAction); ok { + offset := la.offset + input.Seek(startIndex + offset) + lexerAction = la.lexerAction + requiresSeek = (startIndex + offset) != stopIndex + } else if lexerAction.getIsPositionDependent() { + input.Seek(stopIndex) + requiresSeek = false + } + lexerAction.execute(lexer) + } +} + +func (l *LexerActionExecutor) hash() int { + if l == nil { + return 61 + } + return l.cachedHash +} + +func (l *LexerActionExecutor) equals(other interface{}) bool { + if l == other { + return true + } else if _, ok := other.(*LexerActionExecutor); !ok { + return false + } else { + return l.cachedHash == other.(*LexerActionExecutor).cachedHash && + &l.lexerActions == &other.(*LexerActionExecutor).lexerActions + } +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_atn_simulator.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_atn_simulator.go new file mode 100644 index 000000000..131364f75 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_atn_simulator.go @@ -0,0 +1,658 @@ +// Copyright (c) 2012-2017 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" + "strconv" +) + +var ( + LexerATNSimulatorDebug = false + LexerATNSimulatorDFADebug = false + + LexerATNSimulatorMinDFAEdge = 0 + LexerATNSimulatorMaxDFAEdge = 127 // forces unicode to stay in ATN + + LexerATNSimulatorMatchCalls = 0 +) + +type ILexerATNSimulator interface { + IATNSimulator + + reset() + Match(input CharStream, mode int) int + GetCharPositionInLine() int + GetLine() int + GetText(input CharStream) string + Consume(input CharStream) +} + +type LexerATNSimulator struct { + *BaseATNSimulator + + recog Lexer + predictionMode int + mergeCache DoubleDict + startIndex int + Line int + CharPositionInLine int + mode int + prevAccept *SimState + MatchCalls int +} + +func NewLexerATNSimulator(recog Lexer, atn *ATN, decisionToDFA []*DFA, sharedContextCache *PredictionContextCache) *LexerATNSimulator { + l := new(LexerATNSimulator) + + l.BaseATNSimulator = NewBaseATNSimulator(atn, sharedContextCache) + + l.decisionToDFA = decisionToDFA + l.recog = recog + // The current token's starting index into the character stream. + // Shared across DFA to ATN simulation in case the ATN fails and the + // DFA did not have a previous accept state. In l case, we use the + // ATN-generated exception object. + l.startIndex = -1 + // line number 1..n within the input/// + l.Line = 1 + // The index of the character relative to the beginning of the line + // 0..n-1/// + l.CharPositionInLine = 0 + l.mode = LexerDefaultMode + // Used during DFA/ATN exec to record the most recent accept configuration + // info + l.prevAccept = NewSimState() + // done + return l +} + +func (l *LexerATNSimulator) copyState(simulator *LexerATNSimulator) { + l.CharPositionInLine = simulator.CharPositionInLine + l.Line = simulator.Line + l.mode = simulator.mode + l.startIndex = simulator.startIndex +} + +func (l *LexerATNSimulator) Match(input CharStream, mode int) int { + l.MatchCalls++ + l.mode = mode + mark := input.Mark() + + defer func() { + input.Release(mark) + }() + + l.startIndex = input.Index() + l.prevAccept.reset() + + dfa := l.decisionToDFA[mode] + + if dfa.s0 == nil { + return l.MatchATN(input) + } + + return l.execATN(input, dfa.s0) +} + +func (l *LexerATNSimulator) reset() { + l.prevAccept.reset() + l.startIndex = -1 + l.Line = 1 + l.CharPositionInLine = 0 + l.mode = LexerDefaultMode +} + +func (l *LexerATNSimulator) MatchATN(input CharStream) int { + startState := l.atn.modeToStartState[l.mode] + + if LexerATNSimulatorDebug { + fmt.Println("MatchATN mode " + strconv.Itoa(l.mode) + " start: " + startState.String()) + } + oldMode := l.mode + s0Closure := l.computeStartState(input, startState) + suppressEdge := s0Closure.hasSemanticContext + s0Closure.hasSemanticContext = false + + next := l.addDFAState(s0Closure) + + if !suppressEdge { + l.decisionToDFA[l.mode].setS0(next) + } + + predict := l.execATN(input, next) + + if LexerATNSimulatorDebug { + fmt.Println("DFA after MatchATN: " + l.decisionToDFA[oldMode].ToLexerString()) + } + return predict +} + +func (l *LexerATNSimulator) execATN(input CharStream, ds0 *DFAState) int { + + if LexerATNSimulatorDebug { + fmt.Println("start state closure=" + ds0.configs.String()) + } + if ds0.isAcceptState { + // allow zero-length tokens + l.captureSimState(l.prevAccept, input, ds0) + } + t := input.LA(1) + s := ds0 // s is current/from DFA state + + for { // while more work + if LexerATNSimulatorDebug { + fmt.Println("execATN loop starting closure: " + s.configs.String()) + } + + // As we move src->trg, src->trg, we keep track of the previous trg to + // avoid looking up the DFA state again, which is expensive. + // If the previous target was already part of the DFA, we might + // be able to avoid doing a reach operation upon t. If s!=nil, + // it means that semantic predicates didn't prevent us from + // creating a DFA state. Once we know s!=nil, we check to see if + // the DFA state has an edge already for t. If so, we can just reuse + // it's configuration set there's no point in re-computing it. + // This is kind of like doing DFA simulation within the ATN + // simulation because DFA simulation is really just a way to avoid + // computing reach/closure sets. Technically, once we know that + // we have a previously added DFA state, we could jump over to + // the DFA simulator. But, that would mean popping back and forth + // a lot and making things more complicated algorithmically. + // This optimization makes a lot of sense for loops within DFA. + // A character will take us back to an existing DFA state + // that already has lots of edges out of it. e.g., .* in comments. + target := l.getExistingTargetState(s, t) + if target == nil { + target = l.computeTargetState(input, s, t) + // print("Computed:" + str(target)) + } + if target == ATNSimulatorError { + break + } + // If l is a consumable input element, make sure to consume before + // capturing the accept state so the input index, line, and char + // position accurately reflect the state of the interpreter at the + // end of the token. + if t != TokenEOF { + l.Consume(input) + } + if target.isAcceptState { + l.captureSimState(l.prevAccept, input, target) + if t == TokenEOF { + break + } + } + t = input.LA(1) + s = target // flip current DFA target becomes Newsrc/from state + } + + return l.failOrAccept(l.prevAccept, input, s.configs, t) +} + +// Get an existing target state for an edge in the DFA. If the target state +// for the edge has not yet been computed or is otherwise not available, +// l method returns {@code nil}. +// +// @param s The current DFA state +// @param t The next input symbol +// @return The existing target DFA state for the given input symbol +// {@code t}, or {@code nil} if the target state for l edge is not +// already cached +func (l *LexerATNSimulator) getExistingTargetState(s *DFAState, t int) *DFAState { + if s.edges == nil || t < LexerATNSimulatorMinDFAEdge || t > LexerATNSimulatorMaxDFAEdge { + return nil + } + + target := s.edges[t-LexerATNSimulatorMinDFAEdge] + if LexerATNSimulatorDebug && target != nil { + fmt.Println("reuse state " + strconv.Itoa(s.stateNumber) + " edge to " + strconv.Itoa(target.stateNumber)) + } + return target +} + +// Compute a target state for an edge in the DFA, and attempt to add the +// computed state and corresponding edge to the DFA. +// +// @param input The input stream +// @param s The current DFA state +// @param t The next input symbol +// +// @return The computed target DFA state for the given input symbol +// {@code t}. If {@code t} does not lead to a valid DFA state, l method +// returns {@link //ERROR}. +func (l *LexerATNSimulator) computeTargetState(input CharStream, s *DFAState, t int) *DFAState { + reach := NewOrderedATNConfigSet() + + // if we don't find an existing DFA state + // Fill reach starting from closure, following t transitions + l.getReachableConfigSet(input, s.configs, reach.BaseATNConfigSet, t) + + if len(reach.configs) == 0 { // we got nowhere on t from s + if !reach.hasSemanticContext { + // we got nowhere on t, don't panic out l knowledge it'd + // cause a failover from DFA later. + l.addDFAEdge(s, t, ATNSimulatorError, nil) + } + // stop when we can't Match any more char + return ATNSimulatorError + } + // Add an edge from s to target DFA found/created for reach + return l.addDFAEdge(s, t, nil, reach.BaseATNConfigSet) +} + +func (l *LexerATNSimulator) failOrAccept(prevAccept *SimState, input CharStream, reach ATNConfigSet, t int) int { + if l.prevAccept.dfaState != nil { + lexerActionExecutor := prevAccept.dfaState.lexerActionExecutor + l.accept(input, lexerActionExecutor, l.startIndex, prevAccept.index, prevAccept.line, prevAccept.column) + return prevAccept.dfaState.prediction + } + + // if no accept and EOF is first char, return EOF + if t == TokenEOF && input.Index() == l.startIndex { + return TokenEOF + } + + panic(NewLexerNoViableAltException(l.recog, input, l.startIndex, reach)) +} + +// Given a starting configuration set, figure out all ATN configurations +// we can reach upon input {@code t}. Parameter {@code reach} is a return +// parameter. +func (l *LexerATNSimulator) getReachableConfigSet(input CharStream, closure ATNConfigSet, reach ATNConfigSet, t int) { + // l is used to Skip processing for configs which have a lower priority + // than a config that already reached an accept state for the same rule + SkipAlt := ATNInvalidAltNumber + + for _, cfg := range closure.GetItems() { + currentAltReachedAcceptState := (cfg.GetAlt() == SkipAlt) + if currentAltReachedAcceptState && cfg.(*LexerATNConfig).passedThroughNonGreedyDecision { + continue + } + + if LexerATNSimulatorDebug { + + fmt.Printf("testing %s at %s\n", l.GetTokenName(t), cfg.String()) // l.recog, true)) + } + + for _, trans := range cfg.GetState().GetTransitions() { + target := l.getReachableTarget(trans, t) + if target != nil { + lexerActionExecutor := cfg.(*LexerATNConfig).lexerActionExecutor + if lexerActionExecutor != nil { + lexerActionExecutor = lexerActionExecutor.fixOffsetBeforeMatch(input.Index() - l.startIndex) + } + treatEOFAsEpsilon := (t == TokenEOF) + config := NewLexerATNConfig3(cfg.(*LexerATNConfig), target, lexerActionExecutor) + if l.closure(input, config, reach, + currentAltReachedAcceptState, true, treatEOFAsEpsilon) { + // any remaining configs for l alt have a lower priority + // than the one that just reached an accept state. + SkipAlt = cfg.GetAlt() + } + } + } + } +} + +func (l *LexerATNSimulator) accept(input CharStream, lexerActionExecutor *LexerActionExecutor, startIndex, index, line, charPos int) { + if LexerATNSimulatorDebug { + fmt.Printf("ACTION %s\n", lexerActionExecutor) + } + // seek to after last char in token + input.Seek(index) + l.Line = line + l.CharPositionInLine = charPos + if lexerActionExecutor != nil && l.recog != nil { + lexerActionExecutor.execute(l.recog, input, startIndex) + } +} + +func (l *LexerATNSimulator) getReachableTarget(trans Transition, t int) ATNState { + if trans.Matches(t, 0, LexerMaxCharValue) { + return trans.getTarget() + } + + return nil +} + +func (l *LexerATNSimulator) computeStartState(input CharStream, p ATNState) *OrderedATNConfigSet { + configs := NewOrderedATNConfigSet() + for i := 0; i < len(p.GetTransitions()); i++ { + target := p.GetTransitions()[i].getTarget() + cfg := NewLexerATNConfig6(target, i+1, BasePredictionContextEMPTY) + l.closure(input, cfg, configs, false, false, false) + } + + return configs +} + +// Since the alternatives within any lexer decision are ordered by +// preference, l method stops pursuing the closure as soon as an accept +// state is reached. After the first accept state is reached by depth-first +// search from {@code config}, all other (potentially reachable) states for +// l rule would have a lower priority. +// +// @return {@code true} if an accept state is reached, otherwise +// {@code false}. +func (l *LexerATNSimulator) closure(input CharStream, config *LexerATNConfig, configs ATNConfigSet, + currentAltReachedAcceptState, speculative, treatEOFAsEpsilon bool) bool { + + if LexerATNSimulatorDebug { + fmt.Println("closure(" + config.String() + ")") // config.String(l.recog, true) + ")") + } + + _, ok := config.state.(*RuleStopState) + if ok { + + if LexerATNSimulatorDebug { + if l.recog != nil { + fmt.Printf("closure at %s rule stop %s\n", l.recog.GetRuleNames()[config.state.GetRuleIndex()], config) + } else { + fmt.Printf("closure at rule stop %s\n", config) + } + } + + if config.context == nil || config.context.hasEmptyPath() { + if config.context == nil || config.context.isEmpty() { + configs.Add(config, nil) + return true + } + + configs.Add(NewLexerATNConfig2(config, config.state, BasePredictionContextEMPTY), nil) + currentAltReachedAcceptState = true + } + if config.context != nil && !config.context.isEmpty() { + for i := 0; i < config.context.length(); i++ { + if config.context.getReturnState(i) != BasePredictionContextEmptyReturnState { + newContext := config.context.GetParent(i) // "pop" return state + returnState := l.atn.states[config.context.getReturnState(i)] + cfg := NewLexerATNConfig2(config, returnState, newContext) + currentAltReachedAcceptState = l.closure(input, cfg, configs, currentAltReachedAcceptState, speculative, treatEOFAsEpsilon) + } + } + } + return currentAltReachedAcceptState + } + // optimization + if !config.state.GetEpsilonOnlyTransitions() { + if !currentAltReachedAcceptState || !config.passedThroughNonGreedyDecision { + configs.Add(config, nil) + } + } + for j := 0; j < len(config.state.GetTransitions()); j++ { + trans := config.state.GetTransitions()[j] + cfg := l.getEpsilonTarget(input, config, trans, configs, speculative, treatEOFAsEpsilon) + if cfg != nil { + currentAltReachedAcceptState = l.closure(input, cfg, configs, + currentAltReachedAcceptState, speculative, treatEOFAsEpsilon) + } + } + return currentAltReachedAcceptState +} + +// side-effect: can alter configs.hasSemanticContext +func (l *LexerATNSimulator) getEpsilonTarget(input CharStream, config *LexerATNConfig, trans Transition, + configs ATNConfigSet, speculative, treatEOFAsEpsilon bool) *LexerATNConfig { + + var cfg *LexerATNConfig + + if trans.getSerializationType() == TransitionRULE { + + rt := trans.(*RuleTransition) + newContext := SingletonBasePredictionContextCreate(config.context, rt.followState.GetStateNumber()) + cfg = NewLexerATNConfig2(config, trans.getTarget(), newContext) + + } else if trans.getSerializationType() == TransitionPRECEDENCE { + panic("Precedence predicates are not supported in lexers.") + } else if trans.getSerializationType() == TransitionPREDICATE { + // Track traversing semantic predicates. If we traverse, + // we cannot add a DFA state for l "reach" computation + // because the DFA would not test the predicate again in the + // future. Rather than creating collections of semantic predicates + // like v3 and testing them on prediction, v4 will test them on the + // fly all the time using the ATN not the DFA. This is slower but + // semantically it's not used that often. One of the key elements to + // l predicate mechanism is not adding DFA states that see + // predicates immediately afterwards in the ATN. For example, + + // a : ID {p1}? | ID {p2}? + + // should create the start state for rule 'a' (to save start state + // competition), but should not create target of ID state. The + // collection of ATN states the following ID references includes + // states reached by traversing predicates. Since l is when we + // test them, we cannot cash the DFA state target of ID. + + pt := trans.(*PredicateTransition) + + if LexerATNSimulatorDebug { + fmt.Println("EVAL rule " + strconv.Itoa(trans.(*PredicateTransition).ruleIndex) + ":" + strconv.Itoa(pt.predIndex)) + } + configs.SetHasSemanticContext(true) + if l.evaluatePredicate(input, pt.ruleIndex, pt.predIndex, speculative) { + cfg = NewLexerATNConfig4(config, trans.getTarget()) + } + } else if trans.getSerializationType() == TransitionACTION { + if config.context == nil || config.context.hasEmptyPath() { + // execute actions anywhere in the start rule for a token. + // + // TODO: if the entry rule is invoked recursively, some + // actions may be executed during the recursive call. The + // problem can appear when hasEmptyPath() is true but + // isEmpty() is false. In l case, the config needs to be + // split into two contexts - one with just the empty path + // and another with everything but the empty path. + // Unfortunately, the current algorithm does not allow + // getEpsilonTarget to return two configurations, so + // additional modifications are needed before we can support + // the split operation. + lexerActionExecutor := LexerActionExecutorappend(config.lexerActionExecutor, l.atn.lexerActions[trans.(*ActionTransition).actionIndex]) + cfg = NewLexerATNConfig3(config, trans.getTarget(), lexerActionExecutor) + } else { + // ignore actions in referenced rules + cfg = NewLexerATNConfig4(config, trans.getTarget()) + } + } else if trans.getSerializationType() == TransitionEPSILON { + cfg = NewLexerATNConfig4(config, trans.getTarget()) + } else if trans.getSerializationType() == TransitionATOM || + trans.getSerializationType() == TransitionRANGE || + trans.getSerializationType() == TransitionSET { + if treatEOFAsEpsilon { + if trans.Matches(TokenEOF, 0, LexerMaxCharValue) { + cfg = NewLexerATNConfig4(config, trans.getTarget()) + } + } + } + return cfg +} + +// Evaluate a predicate specified in the lexer. +// +//

If {@code speculative} is {@code true}, l method was called before +// {@link //consume} for the Matched character. This method should call +// {@link //consume} before evaluating the predicate to ensure position +// sensitive values, including {@link Lexer//GetText}, {@link Lexer//GetLine}, +// and {@link Lexer//getcolumn}, properly reflect the current +// lexer state. This method should restore {@code input} and the simulator +// to the original state before returning (i.e. undo the actions made by the +// call to {@link //consume}.

+// +// @param input The input stream. +// @param ruleIndex The rule containing the predicate. +// @param predIndex The index of the predicate within the rule. +// @param speculative {@code true} if the current index in {@code input} is +// one character before the predicate's location. +// +// @return {@code true} if the specified predicate evaluates to +// {@code true}. +// / +func (l *LexerATNSimulator) evaluatePredicate(input CharStream, ruleIndex, predIndex int, speculative bool) bool { + // assume true if no recognizer was provided + if l.recog == nil { + return true + } + if !speculative { + return l.recog.Sempred(nil, ruleIndex, predIndex) + } + savedcolumn := l.CharPositionInLine + savedLine := l.Line + index := input.Index() + marker := input.Mark() + + defer func() { + l.CharPositionInLine = savedcolumn + l.Line = savedLine + input.Seek(index) + input.Release(marker) + }() + + l.Consume(input) + return l.recog.Sempred(nil, ruleIndex, predIndex) +} + +func (l *LexerATNSimulator) captureSimState(settings *SimState, input CharStream, dfaState *DFAState) { + settings.index = input.Index() + settings.line = l.Line + settings.column = l.CharPositionInLine + settings.dfaState = dfaState +} + +func (l *LexerATNSimulator) addDFAEdge(from *DFAState, tk int, to *DFAState, cfgs ATNConfigSet) *DFAState { + if to == nil && cfgs != nil { + // leading to l call, ATNConfigSet.hasSemanticContext is used as a + // marker indicating dynamic predicate evaluation makes l edge + // dependent on the specific input sequence, so the static edge in the + // DFA should be omitted. The target DFAState is still created since + // execATN has the ability to reSynchronize with the DFA state cache + // following the predicate evaluation step. + // + // TJP notes: next time through the DFA, we see a pred again and eval. + // If that gets us to a previously created (but dangling) DFA + // state, we can continue in pure DFA mode from there. + // / + suppressEdge := cfgs.HasSemanticContext() + cfgs.SetHasSemanticContext(false) + + to = l.addDFAState(cfgs) + + if suppressEdge { + return to + } + } + // add the edge + if tk < LexerATNSimulatorMinDFAEdge || tk > LexerATNSimulatorMaxDFAEdge { + // Only track edges within the DFA bounds + return to + } + if LexerATNSimulatorDebug { + fmt.Println("EDGE " + from.String() + " -> " + to.String() + " upon " + strconv.Itoa(tk)) + } + if from.edges == nil { + // make room for tokens 1..n and -1 masquerading as index 0 + from.edges = make([]*DFAState, LexerATNSimulatorMaxDFAEdge-LexerATNSimulatorMinDFAEdge+1) + } + from.edges[tk-LexerATNSimulatorMinDFAEdge] = to // connect + + return to +} + +// Add a NewDFA state if there isn't one with l set of +// configurations already. This method also detects the first +// configuration containing an ATN rule stop state. Later, when +// traversing the DFA, we will know which rule to accept. +func (l *LexerATNSimulator) addDFAState(configs ATNConfigSet) *DFAState { + + proposed := NewDFAState(-1, configs) + var firstConfigWithRuleStopState ATNConfig + + for _, cfg := range configs.GetItems() { + + _, ok := cfg.GetState().(*RuleStopState) + + if ok { + firstConfigWithRuleStopState = cfg + break + } + } + if firstConfigWithRuleStopState != nil { + proposed.isAcceptState = true + proposed.lexerActionExecutor = firstConfigWithRuleStopState.(*LexerATNConfig).lexerActionExecutor + proposed.setPrediction(l.atn.ruleToTokenType[firstConfigWithRuleStopState.GetState().GetRuleIndex()]) + } + hash := proposed.hash() + dfa := l.decisionToDFA[l.mode] + existing, ok := dfa.getState(hash) + if ok { + return existing + } + newState := proposed + newState.stateNumber = dfa.numStates() + configs.SetReadOnly(true) + newState.configs = configs + dfa.setState(hash, newState) + return newState +} + +func (l *LexerATNSimulator) getDFA(mode int) *DFA { + return l.decisionToDFA[mode] +} + +// Get the text Matched so far for the current token. +func (l *LexerATNSimulator) GetText(input CharStream) string { + // index is first lookahead char, don't include. + return input.GetTextFromInterval(NewInterval(l.startIndex, input.Index()-1)) +} + +func (l *LexerATNSimulator) Consume(input CharStream) { + curChar := input.LA(1) + if curChar == int('\n') { + l.Line++ + l.CharPositionInLine = 0 + } else { + l.CharPositionInLine++ + } + input.Consume() +} + +func (l *LexerATNSimulator) GetCharPositionInLine() int { + return l.CharPositionInLine +} + +func (l *LexerATNSimulator) GetLine() int { + return l.Line +} + +func (l *LexerATNSimulator) GetTokenName(tt int) string { + if tt == -1 { + return "EOF" + } + + return "'" + string(tt) + "'" +} + +func resetSimState(sim *SimState) { + sim.index = -1 + sim.line = 0 + sim.column = -1 + sim.dfaState = nil +} + +type SimState struct { + index int + line int + column int + dfaState *DFAState +} + +func NewSimState() *SimState { + s := new(SimState) + resetSimState(s) + return s +} + +func (s *SimState) reset() { + resetSimState(s) +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/ll1_analyzer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/ll1_analyzer.go new file mode 100644 index 000000000..f5afd09b3 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/ll1_analyzer.go @@ -0,0 +1,215 @@ +// Copyright (c) 2012-2017 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 + +type LL1Analyzer struct { + atn *ATN +} + +func NewLL1Analyzer(atn *ATN) *LL1Analyzer { + la := new(LL1Analyzer) + la.atn = atn + return la +} + +//* 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 +// i leads to a semantic predicate before Matching a symbol, the +// element at index i of the result will be {@code nil}. +// +// @param s the ATN state +// @return the expected symbols for each outgoing transition of {@code s}. +func (la *LL1Analyzer) getDecisionLookahead(s ATNState) []*IntervalSet { + if s == nil { + return nil + } + count := len(s.GetTransitions()) + look := make([]*IntervalSet, count) + for alt := 0; alt < count; alt++ { + look[alt] = NewIntervalSet() + lookBusy := NewSet(nil, nil) + 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 + // or we had a predicate when we !seeThruPreds + if look[alt].length() == 0 || look[alt].contains(LL1AnalyzerHitPred) { + look[alt] = nil + } + } + return look +} + +//* +// Compute set of tokens that can follow {@code s} in the ATN in the +// specified {@code ctx}. +// +//

If {@code ctx} is {@code nil} and the end of the rule containing +// {@code s} is reached, {@link Token//EPSILON} is added to the result set. +// If {@code ctx} is not {@code nil} and the end of the outermost rule is +// reached, {@link Token//EOF} is added to the result set.

+// +// @param s the ATN state +// @param stopState the ATN state to stop at. This can be a +// {@link BlockEndState} to detect epsilon paths through a closure. +// @param ctx the complete parser context, or {@code nil} if the context +// should be ignored +// +// @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 + var lookContext PredictionContext + if ctx != nil { + lookContext = predictionContextFromRuleContext(s.GetATN(), ctx) + } + la.look1(s, stopState, lookContext, r, NewSet(nil, nil), NewBitSet(), seeThruPreds, true) + return r +} + +//* +// Compute set of tokens that can follow {@code s} in the ATN in the +// specified {@code ctx}. +// +//

If {@code ctx} is {@code nil} and {@code stopState} or the end of the +// rule containing {@code s} is reached, {@link Token//EPSILON} is added to +// the result set. If {@code ctx} is not {@code nil} and {@code addEOF} is +// {@code true} and {@code stopState} or the end of the outermost rule is +// reached, {@link Token//EOF} is added to the result set.

+// +// @param s the ATN state. +// @param stopState the ATN state to stop at. This can be a +// {@link BlockEndState} to detect epsilon paths through a closure. +// @param ctx The outer context, or {@code nil} if the outer context should +// not be used. +// @param look The result lookahead set. +// @param lookBusy A set used for preventing epsilon closures in the ATN +// from causing a stack overflow. Outside code should pass +// {@code NewSet} for la argument. +// @param calledRuleStack A set used for preventing left recursion in the +// ATN from causing a stack overflow. Outside code should pass +// {@code NewBitSet()} for la argument. +// @param seeThruPreds {@code true} to true semantic predicates as +// implicitly {@code true} and "see through them", otherwise {@code false} +// to treat semantic predicates as opaque and add {@link //HitPred} to the +// result if one is encountered. +// @param addEOF Add {@link Token//EOF} to the result if the end of the +// 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) { + + returnState := la.atn.states[ctx.getReturnState(i)] + + removed := calledRuleStack.contains(returnState.GetRuleIndex()) + + defer func() { + if removed { + calledRuleStack.add(returnState.GetRuleIndex()) + } + }() + + calledRuleStack.remove(returnState.GetRuleIndex()) + 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) { + + c := NewBaseATNConfig6(s, 0, ctx) + + if lookBusy.contains(c) { + return + } + + lookBusy.add(c) + + if s == stopState { + if ctx == nil { + look.addOne(TokenEpsilon) + return + } else if ctx.isEmpty() && addEOF { + look.addOne(TokenEOF) + return + } + } + + _, ok := s.(*RuleStopState) + + if ok { + if ctx == nil { + look.addOne(TokenEpsilon) + return + } else if ctx.isEmpty() && addEOF { + look.addOne(TokenEOF) + return + } + + if ctx != BasePredictionContextEMPTY { + // run thru all possible stack tops in ctx + for i := 0; i < ctx.length(); i++ { + returnState := la.atn.states[ctx.getReturnState(i)] + la.look2(returnState, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF, i) + } + return + } + } + + n := len(s.GetTransitions()) + + for i := 0; i < n; i++ { + t := s.GetTransitions()[i] + + if t1, ok := t.(*RuleTransition); ok { + if calledRuleStack.contains(t1.getTarget().GetRuleIndex()) { + continue + } + + newContext := SingletonBasePredictionContextCreate(ctx, t1.followState.GetStateNumber()) + la.look3(stopState, newContext, look, lookBusy, calledRuleStack, seeThruPreds, addEOF, t1) + } else if t2, ok := t.(AbstractPredicateTransition); ok { + if seeThruPreds { + la.look1(t2.getTarget(), stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF) + } else { + look.addOne(LL1AnalyzerHitPred) + } + } else if t.getIsEpsilon() { + la.look1(t.getTarget(), stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF) + } else if _, ok := t.(*WildcardTransition); ok { + look.addRange(TokenMinUserTokenType, la.atn.maxTokenType) + } else { + set := t.getLabel() + if set != nil { + if _, ok := t.(*NotSetTransition); ok { + set = set.complement(TokenMinUserTokenType, la.atn.maxTokenType) + } + look.addSet(set) + } + } + } +} + +func (la *LL1Analyzer) look3(stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy *Set, calledRuleStack *BitSet, seeThruPreds, addEOF bool, t1 *RuleTransition) { + + newContext := SingletonBasePredictionContextCreate(ctx, t1.followState.GetStateNumber()) + + defer func() { + calledRuleStack.remove(t1.getTarget().GetRuleIndex()) + }() + + calledRuleStack.add(t1.getTarget().GetRuleIndex()) + la.look1(t1.getTarget(), stopState, newContext, look, lookBusy, calledRuleStack, seeThruPreds, addEOF) + +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser.go new file mode 100644 index 000000000..fb60258e3 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser.go @@ -0,0 +1,718 @@ +// Copyright (c) 2012-2017 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" + "strconv" +) + +type Parser interface { + Recognizer + + GetInterpreter() *ParserATNSimulator + + GetTokenStream() TokenStream + GetTokenFactory() TokenFactory + GetParserRuleContext() ParserRuleContext + SetParserRuleContext(ParserRuleContext) + Consume() Token + GetParseListeners() []ParseTreeListener + + GetErrorHandler() ErrorStrategy + SetErrorHandler(ErrorStrategy) + GetInputStream() IntStream + GetCurrentToken() Token + GetExpectedTokens() *IntervalSet + NotifyErrorListeners(string, Token, RecognitionException) + IsExpectedToken(int) bool + GetPrecedence() int + GetRuleInvocationStack(ParserRuleContext) []string +} + +type BaseParser struct { + *BaseRecognizer + + Interpreter *ParserATNSimulator + BuildParseTrees bool + + input TokenStream + errHandler ErrorStrategy + precedenceStack IntStack + ctx ParserRuleContext + + tracer *TraceListener + parseListeners []ParseTreeListener + _SyntaxErrors int +} + +// p.is all the parsing support code essentially most of it is error +// recovery stuff.// +func NewBaseParser(input TokenStream) *BaseParser { + + p := new(BaseParser) + + p.BaseRecognizer = NewBaseRecognizer() + + // The input stream. + p.input = nil + // The error handling strategy for the parser. The default value is a new + // instance of {@link DefaultErrorStrategy}. + p.errHandler = NewDefaultErrorStrategy() + p.precedenceStack = make([]int, 0) + p.precedenceStack.Push(0) + // The {@link ParserRuleContext} object for the currently executing rule. + // p.is always non-nil during the parsing process. + p.ctx = nil + // Specifies whether or not the parser should construct a parse tree during + // the parsing process. The default value is {@code true}. + p.BuildParseTrees = true + // When {@link //setTrace}{@code (true)} is called, a reference to the + // {@link TraceListener} is stored here so it can be easily removed in a + // later call to {@link //setTrace}{@code (false)}. The listener itself is + // implemented as a parser listener so p.field is not directly used by + // other parser methods. + p.tracer = nil + // The list of {@link ParseTreeListener} listeners registered to receive + // events during the parse. + p.parseListeners = nil + // The number of syntax errors Reported during parsing. p.value is + // incremented each time {@link //NotifyErrorListeners} is called. + p._SyntaxErrors = 0 + p.SetInputStream(input) + + return p +} + +// p.field maps from the serialized ATN string to the deserialized {@link +// ATN} with +// bypass alternatives. +// +// @see ATNDeserializationOptions//isGenerateRuleBypassTransitions() +// +var bypassAltsAtnCache = make(map[string]int) + +// reset the parser's state// +func (p *BaseParser) reset() { + if p.input != nil { + p.input.Seek(0) + } + p.errHandler.reset(p) + p.ctx = nil + p._SyntaxErrors = 0 + p.SetTrace(nil) + p.precedenceStack = make([]int, 0) + p.precedenceStack.Push(0) + if p.Interpreter != nil { + p.Interpreter.reset() + } +} + +func (p *BaseParser) GetErrorHandler() ErrorStrategy { + return p.errHandler +} + +func (p *BaseParser) SetErrorHandler(e ErrorStrategy) { + p.errHandler = e +} + +// Match current input symbol against {@code ttype}. If the symbol type +// Matches, {@link ANTLRErrorStrategy//ReportMatch} and {@link //consume} are +// called to complete the Match process. +// +//

If the symbol type does not Match, +// {@link ANTLRErrorStrategy//recoverInline} is called on the current error +// strategy to attempt recovery. If {@link //getBuildParseTree} is +// {@code true} and the token index of the symbol returned by +// {@link ANTLRErrorStrategy//recoverInline} is -1, the symbol is added to +// the parse tree by calling {@link ParserRuleContext//addErrorNode}.

+// +// @param ttype the token type to Match +// @return the Matched symbol +// @panics RecognitionException if the current input symbol did not Match +// {@code ttype} and the error strategy could not recover from the +// mismatched symbol + +func (p *BaseParser) Match(ttype int) Token { + + t := p.GetCurrentToken() + + if t.GetTokenType() == ttype { + p.errHandler.ReportMatch(p) + p.Consume() + } else { + t = p.errHandler.RecoverInline(p) + if p.BuildParseTrees && t.GetTokenIndex() == -1 { + // we must have conjured up a Newtoken during single token + // insertion + // if it's not the current symbol + p.ctx.AddErrorNode(t) + } + } + + return t +} + +// Match current input symbol as a wildcard. If the symbol type Matches +// (i.e. has a value greater than 0), {@link ANTLRErrorStrategy//ReportMatch} +// and {@link //consume} are called to complete the Match process. +// +//

If the symbol type does not Match, +// {@link ANTLRErrorStrategy//recoverInline} is called on the current error +// strategy to attempt recovery. If {@link //getBuildParseTree} is +// {@code true} and the token index of the symbol returned by +// {@link ANTLRErrorStrategy//recoverInline} is -1, the symbol is added to +// the parse tree by calling {@link ParserRuleContext//addErrorNode}.

+// +// @return the Matched symbol +// @panics RecognitionException if the current input symbol did not Match +// a wildcard and the error strategy could not recover from the mismatched +// symbol + +func (p *BaseParser) MatchWildcard() Token { + t := p.GetCurrentToken() + if t.GetTokenType() > 0 { + p.errHandler.ReportMatch(p) + p.Consume() + } else { + t = p.errHandler.RecoverInline(p) + if p.BuildParseTrees && t.GetTokenIndex() == -1 { + // we must have conjured up a Newtoken during single token + // insertion + // if it's not the current symbol + p.ctx.AddErrorNode(t) + } + } + return t +} + +func (p *BaseParser) GetParserRuleContext() ParserRuleContext { + return p.ctx +} + +func (p *BaseParser) SetParserRuleContext(v ParserRuleContext) { + p.ctx = v +} + +func (p *BaseParser) GetParseListeners() []ParseTreeListener { + if p.parseListeners == nil { + return make([]ParseTreeListener, 0) + } + return p.parseListeners +} + +// Registers {@code listener} to receive events during the parsing process. +// +//

To support output-preserving grammar transformations (including but not +// limited to left-recursion removal, automated left-factoring, and +// optimized code generation), calls to listener methods during the parse +// may differ substantially from calls made by +// {@link ParseTreeWalker//DEFAULT} used after the parse is complete. In +// particular, rule entry and exit events may occur in a different order +// during the parse than after the parser. In addition, calls to certain +// rule entry methods may be omitted.

+// +//

With the following specific exceptions, calls to listener events are +// deterministic, i.e. for identical input the calls to listener +// methods will be the same.

+// +//
    +//
  • Alterations to the grammar used to generate code may change the +// behavior of the listener calls.
  • +//
  • Alterations to the command line options passed to ANTLR 4 when +// generating the parser may change the behavior of the listener calls.
  • +//
  • Changing the version of the ANTLR Tool used to generate the parser +// may change the behavior of the listener calls.
  • +//
+// +// @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") + } + if p.parseListeners == nil { + p.parseListeners = make([]ParseTreeListener, 0) + } + 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 { + + idx := -1 + for i, v := range p.parseListeners { + if v == listener { + idx = i + break + } + } + + if idx == -1 { + return + } + + // remove the listener from the slice + p.parseListeners = append(p.parseListeners[0:idx], p.parseListeners[idx+1:]...) + + if len(p.parseListeners) == 0 { + p.parseListeners = nil + } + } +} + +// Remove all parse listeners. +func (p *BaseParser) removeParseListeners() { + p.parseListeners = nil +} + +// Notify any parse listeners of an enter rule event. +func (p *BaseParser) TriggerEnterRuleEvent() { + if p.parseListeners != nil { + ctx := p.ctx + for _, listener := range p.parseListeners { + listener.EnterEveryRule(ctx) + ctx.EnterRule(listener) + } + } +} + +// +// Notify any parse listeners of an exit rule event. +// +// @see //addParseListener +// +func (p *BaseParser) TriggerExitRuleEvent() { + if p.parseListeners != nil { + // reverse order walk of listeners + ctx := p.ctx + l := len(p.parseListeners) - 1 + + for i := range p.parseListeners { + listener := p.parseListeners[l-i] + ctx.ExitRule(listener) + listener.ExitEveryRule(ctx) + } + } +} + +func (p *BaseParser) GetInterpreter() *ParserATNSimulator { + return p.Interpreter +} + +func (p *BaseParser) GetATN() *ATN { + return p.Interpreter.atn +} + +func (p *BaseParser) GetTokenFactory() TokenFactory { + return p.input.GetTokenSource().GetTokenFactory() +} + +// Tell our token source and error strategy about a Newway to create tokens.// +func (p *BaseParser) setTokenFactory(factory TokenFactory) { + p.input.GetTokenSource().setTokenFactory(factory) +} + +// The ATN with bypass alternatives is expensive to create so we create it +// lazily. +// +// @panics UnsupportedOperationException if the current parser does not +// implement the {@link //getSerializedATN()} method. +// +func (p *BaseParser) GetATNWithBypassAlts() { + + // TODO + panic("Not implemented!") + + // serializedAtn := p.getSerializedATN() + // if (serializedAtn == nil) { + // panic("The current parser does not support an ATN with bypass alternatives.") + // } + // result := p.bypassAltsAtnCache[serializedAtn] + // if (result == nil) { + // deserializationOptions := NewATNDeserializationOptions(nil) + // deserializationOptions.generateRuleBypassTransitions = true + // result = NewATNDeserializer(deserializationOptions).deserialize(serializedAtn) + // p.bypassAltsAtnCache[serializedAtn] = result + // } + // return result +} + +// The preferred method of getting a tree pattern. For example, here's a +// sample use: +// +//
+// ParseTree t = parser.expr()
+// ParseTreePattern p = parser.compileParseTreePattern("<ID>+0",
+// MyParser.RULE_expr)
+// ParseTreeMatch m = p.Match(t)
+// String id = m.Get("ID")
+// 
+ +func (p *BaseParser) compileParseTreePattern(pattern, patternRuleIndex, lexer Lexer) { + + panic("NewParseTreePatternMatcher not implemented!") + // + // if (lexer == nil) { + // if (p.GetTokenStream() != nil) { + // tokenSource := p.GetTokenStream().GetTokenSource() + // if _, ok := tokenSource.(ILexer); ok { + // lexer = tokenSource + // } + // } + // } + // if (lexer == nil) { + // panic("Parser can't discover a lexer to use") + // } + + // m := NewParseTreePatternMatcher(lexer, p) + // return m.compile(pattern, patternRuleIndex) +} + +func (p *BaseParser) GetInputStream() IntStream { + return p.GetTokenStream() +} + +func (p *BaseParser) SetInputStream(input TokenStream) { + p.SetTokenStream(input) +} + +func (p *BaseParser) GetTokenStream() TokenStream { + return p.input +} + +// Set the token stream and reset the parser.// +func (p *BaseParser) SetTokenStream(input TokenStream) { + p.input = nil + p.reset() + p.input = input +} + +// 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) +} + +func (p *BaseParser) NotifyErrorListeners(msg string, offendingToken Token, err RecognitionException) { + if offendingToken == nil { + offendingToken = p.GetCurrentToken() + } + p._SyntaxErrors++ + line := offendingToken.GetLine() + column := offendingToken.GetColumn() + listener := p.GetErrorListenerDispatch() + listener.SyntaxError(p, offendingToken, line, column, msg, err) +} + +func (p *BaseParser) Consume() Token { + o := p.GetCurrentToken() + if o.GetTokenType() != TokenEOF { + p.GetInputStream().Consume() + } + hasListener := p.parseListeners != nil && len(p.parseListeners) > 0 + if p.BuildParseTrees || hasListener { + if p.errHandler.inErrorRecoveryMode(p) { + node := p.ctx.AddErrorNode(o) + if p.parseListeners != nil { + for _, l := range p.parseListeners { + l.VisitErrorNode(node) + } + } + + } else { + node := p.ctx.AddTokenNode(o) + if p.parseListeners != nil { + for _, l := range p.parseListeners { + l.VisitTerminal(node) + } + } + } + // node.invokingState = p.state + } + + return o +} + +func (p *BaseParser) addContextToParseTree() { + // add current context to parent if we have a parent + if p.ctx.GetParent() != nil { + p.ctx.GetParent().(ParserRuleContext).AddChild(p.ctx) + } +} + +func (p *BaseParser) EnterRule(localctx ParserRuleContext, state, ruleIndex int) { + p.SetState(state) + p.ctx = localctx + p.ctx.SetStart(p.input.LT(1)) + if p.BuildParseTrees { + p.addContextToParseTree() + } + if p.parseListeners != nil { + p.TriggerEnterRuleEvent() + } +} + +func (p *BaseParser) ExitRule() { + p.ctx.SetStop(p.input.LT(-1)) + // trigger event on ctx, before it reverts to parent + if p.parseListeners != nil { + p.TriggerExitRuleEvent() + } + p.SetState(p.ctx.GetInvokingState()) + if p.ctx.GetParent() != nil { + p.ctx = p.ctx.GetParent().(ParserRuleContext) + } else { + p.ctx = nil + } +} + +func (p *BaseParser) EnterOuterAlt(localctx ParserRuleContext, altNum int) { + localctx.SetAltNumber(altNum) + // if we have Newlocalctx, make sure we replace existing ctx + // that is previous child of parse tree + if p.BuildParseTrees && p.ctx != localctx { + if p.ctx.GetParent() != nil { + p.ctx.GetParent().(ParserRuleContext).RemoveLastChild() + p.ctx.GetParent().(ParserRuleContext).AddChild(localctx) + } + } + p.ctx = localctx +} + +// Get the precedence level for the top-most precedence rule. +// +// @return The precedence level for the top-most precedence rule, or -1 if +// the parser context is not nested within a precedence rule. + +func (p *BaseParser) GetPrecedence() int { + if len(p.precedenceStack) == 0 { + return -1 + } + + return p.precedenceStack[len(p.precedenceStack)-1] +} + +func (p *BaseParser) EnterRecursionRule(localctx ParserRuleContext, state, ruleIndex, precedence int) { + p.SetState(state) + p.precedenceStack.Push(precedence) + p.ctx = localctx + p.ctx.SetStart(p.input.LT(1)) + if p.parseListeners != nil { + p.TriggerEnterRuleEvent() // simulates rule entry for + // left-recursive rules + } +} + +// +// Like {@link //EnterRule} but for recursive rules. + +func (p *BaseParser) PushNewRecursionContext(localctx ParserRuleContext, state, ruleIndex int) { + previous := p.ctx + previous.SetParent(localctx) + previous.SetInvokingState(state) + previous.SetStop(p.input.LT(-1)) + + p.ctx = localctx + p.ctx.SetStart(previous.GetStart()) + if p.BuildParseTrees { + p.ctx.AddChild(previous) + } + if p.parseListeners != nil { + p.TriggerEnterRuleEvent() // simulates rule entry for + // left-recursive rules + } +} + +func (p *BaseParser) UnrollRecursionContexts(parentCtx ParserRuleContext) { + p.precedenceStack.Pop() + p.ctx.SetStop(p.input.LT(-1)) + retCtx := p.ctx // save current ctx (return value) + // unroll so ctx is as it was before call to recursive method + if p.parseListeners != nil { + for p.ctx != parentCtx { + p.TriggerExitRuleEvent() + p.ctx = p.ctx.GetParent().(ParserRuleContext) + } + } else { + p.ctx = parentCtx + } + // hook into tree + retCtx.SetParent(parentCtx) + if p.BuildParseTrees && parentCtx != nil { + // add return ctx into invoking rule's tree + parentCtx.AddChild(retCtx) + } +} + +func (p *BaseParser) GetInvokingContext(ruleIndex int) ParserRuleContext { + ctx := p.ctx + for ctx != nil { + if ctx.GetRuleIndex() == ruleIndex { + return ctx + } + ctx = ctx.GetParent().(ParserRuleContext) + } + return nil +} + +func (p *BaseParser) Precpred(localctx RuleContext, precedence int) bool { + return precedence >= p.precedenceStack[len(p.precedenceStack)-1] +} + +func (p *BaseParser) inContext(context ParserRuleContext) bool { + // TODO: useful in parser? + return false +} + +// +// Checks whether or not {@code symbol} can follow the current state in the +// ATN. The behavior of p.method is equivalent to the following, but is +// implemented such that the complete context-sensitive follow set does not +// need to be explicitly constructed. +// +//
+// return getExpectedTokens().contains(symbol)
+// 
+// +// @param symbol the symbol type to check +// @return {@code true} if {@code symbol} can follow the current state in +// the ATN, otherwise {@code false}. + +func (p *BaseParser) IsExpectedToken(symbol int) bool { + atn := p.Interpreter.atn + ctx := p.ctx + s := atn.states[p.state] + following := atn.NextTokens(s, nil) + if following.contains(symbol) { + return true + } + if !following.contains(TokenEpsilon) { + return false + } + for ctx != nil && ctx.GetInvokingState() >= 0 && following.contains(TokenEpsilon) { + invokingState := atn.states[ctx.GetInvokingState()] + rt := invokingState.GetTransitions()[0] + following = atn.NextTokens(rt.(*RuleTransition).followState, nil) + if following.contains(symbol) { + return true + } + ctx = ctx.GetParent().(ParserRuleContext) + } + if following.contains(TokenEpsilon) && symbol == TokenEOF { + return true + } + + return false +} + +// Computes the set of input symbols which could follow the current parser +// state and context, as given by {@link //GetState} and {@link //GetContext}, +// respectively. +// +// @see ATN//getExpectedTokens(int, RuleContext) +// +func (p *BaseParser) GetExpectedTokens() *IntervalSet { + return p.Interpreter.atn.getExpectedTokens(p.state, p.ctx) +} + +func (p *BaseParser) GetExpectedTokensWithinCurrentRule() *IntervalSet { + atn := p.Interpreter.atn + s := atn.states[p.state] + return atn.NextTokens(s, nil) +} + +// Get a rule's index (i.e., {@code RULE_ruleName} field) or -1 if not found.// +func (p *BaseParser) GetRuleIndex(ruleName string) int { + var ruleIndex, ok = p.GetRuleIndexMap()[ruleName] + if ok { + return ruleIndex + } + + return -1 +} + +// Return List<String> of the rule names in your parser instance +// leading up to a call to the current rule. You could override if +// you want more details such as the file/line info of where +// in the ATN a rule is invoked. +// +// this very useful for error messages. + +func (p *BaseParser) GetRuleInvocationStack(c ParserRuleContext) []string { + if c == nil { + c = p.ctx + } + stack := make([]string, 0) + for c != nil { + // compute what follows who invoked us + ruleIndex := c.GetRuleIndex() + if ruleIndex < 0 { + stack = append(stack, "n/a") + } else { + stack = append(stack, p.GetRuleNames()[ruleIndex]) + } + + vp := c.GetParent() + + if vp == nil { + break + } + + c = vp.(ParserRuleContext) + } + return stack +} + +// For debugging and other purposes.// +func (p *BaseParser) GetDFAStrings() string { + return fmt.Sprint(p.Interpreter.decisionToDFA) +} + +// For debugging and other purposes.// +func (p *BaseParser) DumpDFA() { + seenOne := false + for _, dfa := range p.Interpreter.decisionToDFA { + if dfa.numStates() > 0 { + if seenOne { + fmt.Println() + } + fmt.Println("Decision " + strconv.Itoa(dfa.decision) + ":") + fmt.Print(dfa.String(p.LiteralNames, p.SymbolicNames)) + seenOne = true + } + } +} + +func (p *BaseParser) GetSourceName() string { + return p.GrammarFileName +} + +// 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) + p.tracer = nil + } else { + if p.tracer != nil { + p.RemoveParseListener(p.tracer) + } + p.tracer = NewTraceListener(p) + p.AddParseListener(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/parser_atn_simulator.go new file mode 100644 index 000000000..128b9a96d --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_atn_simulator.go @@ -0,0 +1,1473 @@ +// Copyright (c) 2012-2017 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" + "strconv" + "strings" +) + +var ( + ParserATNSimulatorDebug = false + ParserATNSimulatorListATNDecisions = false + ParserATNSimulatorDFADebug = false + ParserATNSimulatorRetryDebug = false +) + +type ParserATNSimulator struct { + *BaseATNSimulator + + parser Parser + predictionMode int + input TokenStream + startIndex int + dfa *DFA + mergeCache *DoubleDict + outerContext ParserRuleContext +} + +func NewParserATNSimulator(parser Parser, atn *ATN, decisionToDFA []*DFA, sharedContextCache *PredictionContextCache) *ParserATNSimulator { + + p := new(ParserATNSimulator) + + p.BaseATNSimulator = NewBaseATNSimulator(atn, sharedContextCache) + + p.parser = parser + p.decisionToDFA = decisionToDFA + // SLL, LL, or LL + exact ambig detection?// + p.predictionMode = PredictionModeLL + // LAME globals to avoid parameters!!!!! I need these down deep in predTransition + p.input = nil + p.startIndex = 0 + p.outerContext = nil + p.dfa = nil + // Each prediction operation uses a cache for merge of prediction contexts. + // Don't keep around as it wastes huge amounts of memory. DoubleKeyMap + // isn't Synchronized but we're ok since two threads shouldn't reuse same + // parser/atnsim object because it can only handle one input at a time. + // This maps graphs a and b to merged result c. (a,b)&rarrc. We can avoid + // the merge if we ever see a and b again. Note that (b,a)&rarrc should + // also be examined during cache lookup. + // + p.mergeCache = nil + + return p +} + +func (p *ParserATNSimulator) GetPredictionMode() int { + return p.predictionMode +} + +func (p *ParserATNSimulator) SetPredictionMode(v int) { + p.predictionMode = v +} + +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) + + " exec LA(1)==" + p.getLookaheadName(input) + + " line " + strconv.Itoa(input.LT(1).GetLine()) + ":" + + strconv.Itoa(input.LT(1).GetColumn())) + } + + p.input = input + p.startIndex = input.Index() + p.outerContext = outerContext + + dfa := p.decisionToDFA[decision] + p.dfa = dfa + m := input.Mark() + index := input.Index() + + defer func() { + p.dfa = nil + p.mergeCache = nil // wack cache after each prediction + input.Seek(index) + input.Release(m) + }() + + // Now we are certain to have a specific decision's DFA + // But, do we still need an initial state? + var s0 *DFAState + if dfa.precedenceDfa { + // the start state for a precedence DFA depends on the current + // parser precedence, and is provided by a DFA method. + s0 = dfa.getPrecedenceStartState(p.parser.GetPrecedence()) + } else { + // the start state for a "regular" DFA is just s0 + s0 = dfa.s0 + } + + if s0 == nil { + if outerContext == nil { + outerContext = RuleContextEmpty + } + if ParserATNSimulatorDebug || ParserATNSimulatorListATNDecisions { + fmt.Println("predictATN decision " + strconv.Itoa(dfa.decision) + + " exec LA(1)==" + p.getLookaheadName(input) + + ", outerContext=" + outerContext.String(p.parser.GetRuleNames(), nil)) + } + // If p is not a precedence DFA, we check the ATN start state + // to determine if p ATN start state is the decision for the + // closure block that determines whether a precedence rule + // should continue or complete. + + t2 := dfa.atnStartState + t, ok := t2.(*StarLoopEntryState) + if !dfa.precedenceDfa && ok { + if t.precedenceRuleDecision { + dfa.setPrecedenceDfa(true) + } + } + fullCtx := false + s0Closure := p.computeStartState(dfa.atnStartState, RuleContextEmpty, fullCtx) + + if dfa.precedenceDfa { + // If p is a precedence DFA, we use applyPrecedenceFilter + // to convert the computed start state to a precedence start + // state. We then use DFA.setPrecedenceStartState to set the + // appropriate start state for the precedence level rather + // than simply setting DFA.s0. + // + s0Closure = p.applyPrecedenceFilter(s0Closure) + s0 = p.addDFAState(dfa, NewDFAState(-1, s0Closure)) + dfa.setPrecedenceStartState(p.parser.GetPrecedence(), s0) + } else { + s0 = p.addDFAState(dfa, NewDFAState(-1, s0Closure)) + dfa.s0 = s0 + } + } + alt := p.execATN(dfa, s0, input, index, outerContext) + if ParserATNSimulatorDebug { + fmt.Println("DFA after predictATN: " + dfa.String(p.parser.GetLiteralNames(), nil)) + } + return alt + +} + +// Performs ATN simulation to compute a predicted alternative based +// upon the remaining input, but also updates the DFA cache to avoid +// having to traverse the ATN again for the same input sequence. + +// There are some key conditions we're looking for after computing a new +// set of ATN configs (proposed DFA state): +// if the set is empty, there is no viable alternative for current symbol +// does the state uniquely predict an alternative? +// does the state have a conflict that would prevent us from +// putting it on the work list? + +// We also have some key operations to do: +// add an edge from previous DFA state to potentially NewDFA state, D, +// upon current symbol but only if adding to work list, which means in all +// cases except no viable alternative (and possibly non-greedy decisions?) +// collecting predicates and adding semantic context to DFA accept states +// adding rule context to context-sensitive DFA accept states +// consuming an input symbol +// Reporting a conflict +// Reporting an ambiguity +// Reporting a context sensitivity +// Reporting insufficient predicates + +// cover these cases: +// 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 { + fmt.Println("execATN decision " + strconv.Itoa(dfa.decision) + + " exec LA(1)==" + p.getLookaheadName(input) + + " line " + strconv.Itoa(input.LT(1).GetLine()) + ":" + strconv.Itoa(input.LT(1).GetColumn())) + } + + previousD := s0 + + if ParserATNSimulatorDebug { + fmt.Println("s0 = " + s0.String()) + } + t := input.LA(1) + for { // for more work + D := p.getExistingTargetState(previousD, t) + if D == nil { + D = p.computeTargetState(dfa, previousD, t) + } + if D == ATNSimulatorError { + // if any configs in previous dipped into outer context, that + // means that input up to t actually finished entry rule + // at least for SLL decision. Full LL doesn't dip into outer + // so don't need special case. + // We will get an error no matter what so delay until after + // decision better error message. Also, no reachable target + // ATN states in SLL implies LL will also get nowhere. + // If conflict in states that dip out, choose min since we + // will get error no matter what. + e := p.noViableAlt(input, outerContext, previousD.configs, startIndex) + input.Seek(startIndex) + alt := p.getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(previousD.configs, outerContext) + if alt != ATNInvalidAltNumber { + return alt + } + + panic(e) + } + if D.requiresFullContext && p.predictionMode != PredictionModeSLL { + // IF PREDS, MIGHT RESOLVE TO SINGLE ALT => SLL (or syntax error) + conflictingAlts := D.configs.GetConflictingAlts() + if D.predicates != nil { + if ParserATNSimulatorDebug { + fmt.Println("DFA state has preds in DFA sim LL failover") + } + conflictIndex := input.Index() + if conflictIndex != startIndex { + input.Seek(startIndex) + } + conflictingAlts = p.evalSemanticContext(D.predicates, outerContext, true) + if conflictingAlts.length() == 1 { + if ParserATNSimulatorDebug { + fmt.Println("Full LL avoided") + } + return conflictingAlts.minValue() + } + if conflictIndex != startIndex { + // restore the index so Reporting the fallback to full + // context occurs with the index at the correct spot + input.Seek(conflictIndex) + } + } + if ParserATNSimulatorDFADebug { + fmt.Println("ctx sensitive state " + outerContext.String(nil, nil) + " in " + D.String()) + } + fullCtx := true + s0Closure := p.computeStartState(dfa.atnStartState, outerContext, fullCtx) + p.ReportAttemptingFullContext(dfa, conflictingAlts, D.configs, startIndex, input.Index()) + alt := p.execATNWithFullContext(dfa, D, s0Closure, input, startIndex, outerContext) + return alt + } + if D.isAcceptState { + if D.predicates == nil { + return D.prediction + } + stopIndex := input.Index() + input.Seek(startIndex) + alts := p.evalSemanticContext(D.predicates, outerContext, true) + if alts.length() == 0 { + panic(p.noViableAlt(input, outerContext, D.configs, startIndex)) + } else if alts.length() == 1 { + return alts.minValue() + } else { + // Report ambiguity after predicate evaluation to make sure the correct set of ambig alts is Reported. + p.ReportAmbiguity(dfa, D, startIndex, stopIndex, false, alts, D.configs) + return alts.minValue() + } + } + previousD = D + + if t != TokenEOF { + input.Consume() + 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 +// for the edge has not yet been computed or is otherwise not available, +// p method returns {@code nil}. +// +// @param previousD The current DFA state +// @param t The next input symbol +// @return The existing target DFA state for the given input symbol +// {@code t}, or {@code nil} if the target state for p edge is not +// already cached + +func (p *ParserATNSimulator) getExistingTargetState(previousD *DFAState, t int) *DFAState { + edges := previousD.edges + if edges == nil { + return nil + } + + return edges[t+1] +} + +// Compute a target state for an edge in the DFA, and attempt to add the +// computed state and corresponding edge to the DFA. +// +// @param dfa The DFA +// @param previousD The current DFA state +// @param t The next input symbol +// +// @return The computed target DFA state for the given input symbol +// {@code t}. If {@code t} does not lead to a valid DFA state, p method +// returns {@link //ERROR}. + +func (p *ParserATNSimulator) computeTargetState(dfa *DFA, previousD *DFAState, t int) *DFAState { + reach := p.computeReachSet(previousD.configs, t, false) + + if reach == nil { + p.addDFAEdge(dfa, previousD, t, ATNSimulatorError) + return ATNSimulatorError + } + // create Newtarget state we'll add to DFA after it's complete + D := NewDFAState(-1, reach) + + predictedAlt := p.getUniqueAlt(reach) + + if ParserATNSimulatorDebug { + altSubSets := PredictionModegetConflictingAltSubsets(reach) + fmt.Println("SLL altSubSets=" + fmt.Sprint(altSubSets) + + ", previous=" + previousD.configs.String() + + ", configs=" + reach.String() + + ", predict=" + strconv.Itoa(predictedAlt) + + ", allSubsetsConflict=" + + fmt.Sprint(PredictionModeallSubsetsConflict(altSubSets)) + + ", conflictingAlts=" + p.getConflictingAlts(reach).String()) + } + if predictedAlt != ATNInvalidAltNumber { + // NO CONFLICT, UNIQUELY PREDICTED ALT + D.isAcceptState = true + D.configs.SetUniqueAlt(predictedAlt) + D.setPrediction(predictedAlt) + } else if PredictionModehasSLLConflictTerminatingPrediction(p.predictionMode, reach) { + // MORE THAN ONE VIABLE ALTERNATIVE + D.configs.SetConflictingAlts(p.getConflictingAlts(reach)) + D.requiresFullContext = true + // in SLL-only mode, we will stop at p state and return the minimum alt + D.isAcceptState = true + D.setPrediction(D.configs.GetConflictingAlts().minValue()) + } + if D.isAcceptState && D.configs.HasSemanticContext() { + p.predicateDFAState(D, p.atn.getDecisionState(dfa.decision)) + if D.predicates != nil { + D.setPrediction(ATNInvalidAltNumber) + } + } + // all adds to dfa are done after we've created full D state + D = p.addDFAEdge(dfa, previousD, t, D) + return D +} + +func (p *ParserATNSimulator) predicateDFAState(dfaState *DFAState, decisionState DecisionState) { + // We need to test all predicates, even in DFA states that + // uniquely predict alternative. + nalts := len(decisionState.GetTransitions()) + // Update DFA so reach becomes accept state with (predicate,alt) + // pairs if preds found for conflicting alts + altsToCollectPredsFrom := p.getConflictingAltsOrUniqueAlt(dfaState.configs) + altToPred := p.getPredsForAmbigAlts(altsToCollectPredsFrom, dfaState.configs, nalts) + if altToPred != nil { + dfaState.predicates = p.getPredicatePredictions(altsToCollectPredsFrom, altToPred) + dfaState.setPrediction(ATNInvalidAltNumber) // make sure we use preds + } else { + // There are preds in configs but they might go away + // when OR'd together like {p}? || NONE == NONE. If neither + // alt has preds, resolve to min alt + dfaState.setPrediction(altsToCollectPredsFrom.minValue()) + } +} + +// 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 { + fmt.Println("execATNWithFullContext " + s0.String()) + } + + fullCtx := true + foundExactAmbig := false + var reach ATNConfigSet + previous := s0 + input.Seek(startIndex) + t := input.LA(1) + predictedAlt := -1 + + for { // for more work + reach = p.computeReachSet(previous, t, fullCtx) + if reach == nil { + // if any configs in previous dipped into outer context, that + // means that input up to t actually finished entry rule + // at least for LL decision. Full LL doesn't dip into outer + // so don't need special case. + // We will get an error no matter what so delay until after + // decision better error message. Also, no reachable target + // ATN states in SLL implies LL will also get nowhere. + // If conflict in states that dip out, choose min since we + // will get error no matter what. + e := p.noViableAlt(input, outerContext, previous, startIndex) + input.Seek(startIndex) + alt := p.getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(previous, outerContext) + if alt != ATNInvalidAltNumber { + return alt + } + + panic(e) + } + altSubSets := PredictionModegetConflictingAltSubsets(reach) + if ParserATNSimulatorDebug { + fmt.Println("LL altSubSets=" + fmt.Sprint(altSubSets) + ", predict=" + + strconv.Itoa(PredictionModegetUniqueAlt(altSubSets)) + ", resolvesToJustOneViableAlt=" + + fmt.Sprint(PredictionModeresolvesToJustOneViableAlt(altSubSets))) + } + reach.SetUniqueAlt(p.getUniqueAlt(reach)) + // unique prediction? + if reach.GetUniqueAlt() != ATNInvalidAltNumber { + predictedAlt = reach.GetUniqueAlt() + break + } else if p.predictionMode != PredictionModeLLExactAmbigDetection { + predictedAlt = PredictionModeresolvesToJustOneViableAlt(altSubSets) + if predictedAlt != ATNInvalidAltNumber { + break + } + } else { + // In exact ambiguity mode, we never try to terminate early. + // Just keeps scarfing until we know what the conflict is + if PredictionModeallSubsetsConflict(altSubSets) && PredictionModeallSubsetsEqual(altSubSets) { + foundExactAmbig = true + predictedAlt = PredictionModegetSingleViableAlt(altSubSets) + break + } + // else there are multiple non-conflicting subsets or + // we're not sure what the ambiguity is yet. + // So, keep going. + } + previous = reach + if t != TokenEOF { + input.Consume() + t = input.LA(1) + } + } + // If the configuration set uniquely predicts an alternative, + // without conflict, then we know that it's a full LL decision + // not SLL. + if reach.GetUniqueAlt() != ATNInvalidAltNumber { + p.ReportContextSensitivity(dfa, predictedAlt, reach, startIndex, input.Index()) + return predictedAlt + } + // We do not check predicates here because we have checked them + // on-the-fly when doing full context prediction. + + // + // In non-exact ambiguity detection mode, we might actually be able to + // detect an exact ambiguity, but I'm not going to spend the cycles + // needed to check. We only emit ambiguity warnings in exact ambiguity + // mode. + // + // For example, we might know that we have conflicting configurations. + // But, that does not mean that there is no way forward without a + // conflict. It's possible to have nonconflicting alt subsets as in: + + // altSubSets=[{1, 2}, {1, 2}, {1}, {1, 2}] + + // from + // + // [(17,1,[5 $]), (13,1,[5 10 $]), (21,1,[5 10 $]), (11,1,[$]), + // (13,2,[5 10 $]), (21,2,[5 10 $]), (11,2,[$])] + // + // In p case, (17,1,[5 $]) indicates there is some next sequence that + // would resolve p without conflict to alternative 1. Any other viable + // next sequence, however, is associated with a conflict. We stop + // looking for input because no amount of further lookahead will alter + // the fact that we should predict alternative 1. We just can't say for + // sure that there is an ambiguity without looking further. + + p.ReportAmbiguity(dfa, D, startIndex, input.Index(), foundExactAmbig, nil, reach) + + return predictedAlt +} + +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() + } + intermediate := NewBaseATNConfigSet(fullCtx) + + // Configurations already in a rule stop state indicate reaching the end + // of the decision rule (local context) or end of the start rule (full + // context). Once reached, these configurations are never updated by a + // closure operation, so they are handled separately for the performance + // advantage of having a smaller intermediate set when calling closure. + // + // For full-context reach operations, separate handling is required to + // ensure that the alternative Matching the longest overall sequence is + // chosen when multiple such configurations can Match the input. + + var SkippedStopStates []*BaseATNConfig + + // First figure out where we can reach on input t + for _, c := range closure.GetItems() { + if ParserATNSimulatorDebug { + fmt.Println("testing " + p.GetTokenName(t) + " at " + c.String()) + } + + _, ok := c.GetState().(*RuleStopState) + + if ok { + if fullCtx || t == TokenEOF { + if SkippedStopStates == nil { + SkippedStopStates = make([]*BaseATNConfig, 0) + } + SkippedStopStates = append(SkippedStopStates, c.(*BaseATNConfig)) + if ParserATNSimulatorDebug { + fmt.Println("added " + c.String() + " to SkippedStopStates") + } + } + continue + } + + for j := 0; j < len(c.GetState().GetTransitions()); j++ { + trans := c.GetState().GetTransitions()[j] + target := p.getReachableTarget(trans, t) + if target != nil { + cfg := NewBaseATNConfig4(c, target) + intermediate.Add(cfg, p.mergeCache) + if ParserATNSimulatorDebug { + fmt.Println("added " + cfg.String() + " to intermediate") + } + } + } + } + // Now figure out where the reach operation can take us... + var reach ATNConfigSet + + // This block optimizes the reach operation for intermediate sets which + // trivially indicate a termination state for the overall + // AdaptivePredict operation. + // + // The conditions assume that intermediate + // contains all configurations relevant to the reach set, but p + // condition is not true when one or more configurations have been + // withheld in SkippedStopStates, or when the current symbol is EOF. + // + if SkippedStopStates == nil && t != TokenEOF { + if len(intermediate.configs) == 1 { + // Don't pursue the closure if there is just one state. + // It can only have one alternative just add to result + // Also don't pursue the closure if there is unique alternative + // among the configurations. + reach = intermediate + } else if p.getUniqueAlt(intermediate) != ATNInvalidAltNumber { + // Also don't pursue the closure if there is unique alternative + // among the configurations. + reach = intermediate + } + } + // If the reach set could not be trivially determined, perform a closure + // operation on the intermediate set to compute its initial value. + // + if reach == nil { + reach = NewBaseATNConfigSet(fullCtx) + closureBusy := NewSet(nil, nil) + treatEOFAsEpsilon := t == TokenEOF + for k := 0; k < len(intermediate.configs); k++ { + p.closure(intermediate.configs[k], reach, closureBusy, false, fullCtx, treatEOFAsEpsilon) + } + } + if t == TokenEOF { + // After consuming EOF no additional input is possible, so we are + // only interested in configurations which reached the end of the + // decision rule (local context) or end of the start rule (full + // context). Update reach to contain only these configurations. This + // handles both explicit EOF transitions in the grammar and implicit + // EOF transitions following the end of the decision or start rule. + // + // When reach==intermediate, no closure operation was performed. In + // p case, removeAllConfigsNotInRuleStopState needs to check for + // reachable rule stop states as well as configurations already in + // a rule stop state. + // + // This is handled before the configurations in SkippedStopStates, + // because any configurations potentially added from that list are + // already guaranteed to meet p condition whether or not it's + // required. + // + reach = p.removeAllConfigsNotInRuleStopState(reach, reach == intermediate) + } + // If SkippedStopStates!=nil, then it contains at least one + // configuration. For full-context reach operations, these + // configurations reached the end of the start rule, in which case we + // only add them back to reach if no configuration during the current + // closure operation reached such a state. This ensures AdaptivePredict + // chooses an alternative Matching the longest overall sequence when + // multiple alternatives are viable. + // + if SkippedStopStates != nil && ((!fullCtx) || (!PredictionModehasConfigInRuleStopState(reach))) { + for l := 0; l < len(SkippedStopStates); l++ { + reach.Add(SkippedStopStates[l], p.mergeCache) + } + } + if len(reach.GetItems()) == 0 { + return nil + } + + 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 +// method simply returns {@code configs}. +// +//

When {@code lookToEndOfRule} is true, p method uses +// {@link ATN//NextTokens} for each configuration in {@code configs} which is +// not already in a rule stop state to see if a rule stop state is reachable +// from the configuration via epsilon-only transitions.

+// +// @param configs the configuration set to update +// @param lookToEndOfRule when true, p method checks for rule stop states +// reachable by epsilon-only transitions from each configuration in +// {@code configs}. +// +// @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 + } + result := NewBaseATNConfigSet(configs.FullContext()) + for _, config := range configs.GetItems() { + + _, ok := config.GetState().(*RuleStopState) + + if ok { + result.Add(config, p.mergeCache) + continue + } + if lookToEndOfRule && config.GetState().GetEpsilonOnlyTransitions() { + NextTokens := p.atn.NextTokens(config.GetState(), nil) + if NextTokens.contains(TokenEpsilon) { + endOfRuleState := p.atn.ruleToStopState[config.GetState().GetRuleIndex()] + result.Add(NewBaseATNConfig4(config, endOfRuleState), p.mergeCache) + } + } + } + return result +} + +func (p *ParserATNSimulator) computeStartState(a ATNState, ctx RuleContext, fullCtx bool) ATNConfigSet { + // always at least the implicit call to start rule + initialContext := predictionContextFromRuleContext(p.atn, ctx) + configs := NewBaseATNConfigSet(fullCtx) + for i := 0; i < len(a.GetTransitions()); i++ { + target := a.GetTransitions()[i].getTarget() + c := NewBaseATNConfig6(target, i+1, initialContext) + closureBusy := NewSet(nil, nil) + 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 +// process applies the following changes to the start state's configuration +// set. +// +//
    +//
  1. Evaluate the precedence predicates for each configuration using +// {@link SemanticContext//evalPrecedence}.
  2. +//
  3. Remove all configurations which predict an alternative greater than +// 1, for which another configuration that predicts alternative 1 is in the +// same ATN state with the same prediction context. This transformation is +// valid for the following reasons: +//
      +//
    • The closure block cannot contain any epsilon transitions which bypass +// the body of the closure, so all states reachable via alternative 1 are +// part of the precedence alternatives of the transformed left-recursive +// rule.
    • +//
    • The "primary" portion of a left recursive rule cannot contain an +// epsilon transition, so the only way an alternative other than 1 can exist +// in a state that is also reachable via alternative 1 is by nesting calls +// to the left-recursive rule, with the outer calls not being at the +// preferred precedence level.
    • +//
    +//
  4. +//
+// +//

+// The prediction context must be considered by p filter to address +// situations like the following. +//

+// +//
+// grammar TA
+// prog: statement* EOF
+// statement: letterA | statement letterA 'b'
+// letterA: 'a'
+// 
+//
+//

+// If the above grammar, the ATN state immediately before the token +// reference {@code 'a'} in {@code letterA} is reachable from the left edge +// of both the primary and closure blocks of the left-recursive rule +// {@code statement}. The prediction context associated with each of these +// configurations distinguishes between them, and prevents the alternative +// which stepped out to {@code prog} (and then back in to {@code statement} +// from being eliminated by the filter. +//

+// +// @param configs The configuration set computed by +// {@link //computeStartState} as the start state for the DFA. +// @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) + configSet := NewBaseATNConfigSet(configs.FullContext()) + + for _, config := range configs.GetItems() { + // handle alt 1 first + if config.GetAlt() != 1 { + continue + } + updatedContext := config.GetSemanticContext().evalPrecedence(p.parser, p.outerContext) + if updatedContext == nil { + // the configuration was eliminated + continue + } + statesFromAlt1[config.GetState().GetStateNumber()] = config.GetContext() + if updatedContext != config.GetSemanticContext() { + configSet.Add(NewBaseATNConfig2(config, updatedContext), p.mergeCache) + } else { + configSet.Add(config, p.mergeCache) + } + } + for _, config := range configs.GetItems() { + + if config.GetAlt() == 1 { + // already handled + continue + } + // In the future, p elimination step could be updated to also + // filter the prediction context for alternatives predicting alt>1 + // (basically a graph subtraction algorithm). + if !config.getPrecedenceFilterSuppressed() { + context := statesFromAlt1[config.GetState().GetStateNumber()] + if context != nil && context.equals(config.GetContext()) { + // eliminated + continue + } + } + configSet.Add(config, p.mergeCache) + } + return configSet +} + +func (p *ParserATNSimulator) getReachableTarget(trans Transition, ttype int) ATNState { + if trans.Matches(ttype, 0, p.atn.maxTokenType) { + return trans.getTarget() + } + + return nil +} + +func (p *ParserATNSimulator) getPredsForAmbigAlts(ambigAlts *BitSet, configs ATNConfigSet, nalts int) []SemanticContext { + + altToPred := make([]SemanticContext, nalts+1) + for _, c := range configs.GetItems() { + if ambigAlts.contains(c.GetAlt()) { + altToPred[c.GetAlt()] = SemanticContextorContext(altToPred[c.GetAlt()], c.GetSemanticContext()) + } + } + nPredAlts := 0 + for i := 1; i < nalts+1; i++ { + pred := altToPred[i] + if pred == nil { + altToPred[i] = SemanticContextNone + } else if pred != SemanticContextNone { + nPredAlts++ + } + } + // nonambig alts are nil in altToPred + if nPredAlts == 0 { + altToPred = nil + } + if ParserATNSimulatorDebug { + fmt.Println("getPredsForAmbigAlts result " + fmt.Sprint(altToPred)) + } + return altToPred +} + +func (p *ParserATNSimulator) getPredicatePredictions(ambigAlts *BitSet, altToPred []SemanticContext) []*PredPrediction { + pairs := make([]*PredPrediction, 0) + containsPredicate := false + for i := 1; i < len(altToPred); i++ { + pred := altToPred[i] + // unpredicated is indicated by SemanticContextNONE + if ambigAlts != nil && ambigAlts.contains(i) { + pairs = append(pairs, NewPredPrediction(pred, i)) + } + if pred != SemanticContextNone { + containsPredicate = true + } + } + if !containsPredicate { + return nil + } + 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 +// {@link //ERROR} state was reached during ATN simulation. +// +//

+// The default implementation of p method uses the following +// algorithm to identify an ATN configuration which successfully parsed the +// decision entry rule. Choosing such an alternative ensures that the +// {@link ParserRuleContext} returned by the calling rule will be complete +// and valid, and the syntax error will be Reported later at a more +// localized location.

+// +//
    +//
  • If a syntactically valid path or paths reach the end of the decision rule and +// they are semantically valid if predicated, return the min associated alt.
  • +//
  • Else, if a semantically invalid but syntactically valid path exist +// or paths exist, return the minimum associated alt. +//
  • +//
  • Otherwise, return {@link ATN//INVALID_ALT_NUMBER}.
  • +//
+// +//

+// In some scenarios, the algorithm described above could predict an +// alternative which will result in a {@link FailedPredicateException} in +// the parser. Specifically, p could occur if the only configuration +// capable of successfully parsing to the end of the decision rule is +// blocked by a semantic predicate. By choosing p alternative within +// {@link //AdaptivePredict} instead of panicing a +// {@link NoViableAltException}, the resulting +// {@link FailedPredicateException} in the parser will identify the specific +// predicate which is preventing the parser from successfully parsing the +// decision rule, which helps developers identify and correct logic errors +// in semantic predicates. +//

+// +// @param configs The ATN configurations which were valid immediately before +// the {@link //ERROR} state was reached +// @param outerContext The is the \gamma_0 initial parser context from the paper +// or the parser stack at the instant before prediction commences. +// +// @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] + semInvalidConfigs := cfgs[1] + alt := p.GetAltThatFinishedDecisionEntryRule(semValidConfigs) + if alt != ATNInvalidAltNumber { // semantically/syntactically viable path exists + return alt + } + // Is there a syntactically valid path with a failed pred? + if len(semInvalidConfigs.GetItems()) > 0 { + alt = p.GetAltThatFinishedDecisionEntryRule(semInvalidConfigs) + if alt != ATNInvalidAltNumber { // syntactically viable path exists + return alt + } + } + return ATNInvalidAltNumber +} + +func (p *ParserATNSimulator) GetAltThatFinishedDecisionEntryRule(configs ATNConfigSet) int { + alts := NewIntervalSet() + + for _, c := range configs.GetItems() { + _, ok := c.GetState().(*RuleStopState) + + if c.GetReachesIntoOuterContext() > 0 || (ok && c.GetContext().hasEmptyPath()) { + alts.addOne(c.GetAlt()) + } + } + if alts.length() == 0 { + return ATNInvalidAltNumber + } + + return alts.first() +} + +// Walk the list of configurations and split them according to +// those that have preds evaluating to true/false. If no pred, assume +// true pred and include in succeeded set. Returns Pair of sets. +// +// Create a NewSet so as not to alter the incoming parameter. +// +// Assumption: the input stream has been restored to the starting point +// prediction, which is where predicates need to evaluate. + +type ATNConfigSetPair struct { + item0, item1 ATNConfigSet +} + +func (p *ParserATNSimulator) splitAccordingToSemanticValidity(configs ATNConfigSet, outerContext ParserRuleContext) []ATNConfigSet { + succeeded := NewBaseATNConfigSet(configs.FullContext()) + failed := NewBaseATNConfigSet(configs.FullContext()) + + for _, c := range configs.GetItems() { + if c.GetSemanticContext() != SemanticContextNone { + predicateEvaluationResult := c.GetSemanticContext().evaluate(p.parser, outerContext) + if predicateEvaluationResult { + succeeded.Add(c, nil) + } else { + failed.Add(c, nil) + } + } else { + succeeded.Add(c, nil) + } + } + return []ATNConfigSet{succeeded, failed} +} + +// 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. +// +func (p *ParserATNSimulator) evalSemanticContext(predPredictions []*PredPrediction, outerContext ParserRuleContext, complete bool) *BitSet { + predictions := NewBitSet() + for i := 0; i < len(predPredictions); i++ { + pair := predPredictions[i] + if pair.pred == SemanticContextNone { + predictions.add(pair.alt) + if !complete { + break + } + continue + } + + predicateEvaluationResult := pair.pred.evaluate(p.parser, outerContext) + if ParserATNSimulatorDebug || ParserATNSimulatorDFADebug { + fmt.Println("eval pred " + pair.String() + "=" + fmt.Sprint(predicateEvaluationResult)) + } + if predicateEvaluationResult { + if ParserATNSimulatorDebug || ParserATNSimulatorDFADebug { + fmt.Println("PREDICT " + fmt.Sprint(pair.alt)) + } + predictions.add(pair.alt) + if !complete { + break + } + } + } + return predictions +} + +func (p *ParserATNSimulator) closure(config ATNConfig, configs ATNConfigSet, closureBusy *Set, 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 { + fmt.Println("closure(" + config.String() + ")") + fmt.Println("configs(" + configs.String() + ")") + if config.GetReachesIntoOuterContext() > 50 { + panic("problem") + } + } + + _, ok := config.GetState().(*RuleStopState) + if ok { + // We hit rule end. If we have context info, use it + // run thru all possible stack tops in ctx + if !config.GetContext().isEmpty() { + for i := 0; i < config.GetContext().length(); i++ { + if config.GetContext().getReturnState(i) == BasePredictionContextEmptyReturnState { + if fullCtx { + configs.Add(NewBaseATNConfig1(config, config.GetState(), BasePredictionContextEMPTY), p.mergeCache) + continue + } else { + // we have no context info, just chase follow links (if greedy) + if ParserATNSimulatorDebug { + fmt.Println("FALLING off rule " + p.getRuleName(config.GetState().GetRuleIndex())) + } + p.closureWork(config, configs, closureBusy, collectPredicates, fullCtx, depth, treatEOFAsEpsilon) + } + continue + } + returnState := p.atn.states[config.GetContext().getReturnState(i)] + newContext := config.GetContext().GetParent(i) // "pop" return state + + c := NewBaseATNConfig5(returnState, config.GetAlt(), newContext, config.GetSemanticContext()) + // While we have context to pop back from, we may have + // gotten that context AFTER having falling off a rule. + // Make sure we track that we are now out of context. + c.SetReachesIntoOuterContext(config.GetReachesIntoOuterContext()) + p.closureCheckingStopState(c, configs, closureBusy, collectPredicates, fullCtx, depth-1, treatEOFAsEpsilon) + } + return + } else if fullCtx { + // reached end of start rule + configs.Add(config, p.mergeCache) + return + } else { + // else if we have no context info, just chase follow links (if greedy) + if ParserATNSimulatorDebug { + fmt.Println("FALLING off rule " + p.getRuleName(config.GetState().GetRuleIndex())) + } + } + } + p.closureWork(config, configs, closureBusy, collectPredicates, fullCtx, depth, treatEOFAsEpsilon) +} + +// 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) { + state := config.GetState() + // optimization + if !state.GetEpsilonOnlyTransitions() { + configs.Add(config, p.mergeCache) + // make sure to not return here, because EOF transitions can act as + // both epsilon transitions and non-epsilon transitions. + } + for i := 0; i < len(state.GetTransitions()); i++ { + t := state.GetTransitions()[i] + _, ok := t.(*ActionTransition) + continueCollecting := collectPredicates && !ok + c := p.getEpsilonTarget(config, t, continueCollecting, depth == 0, fullCtx, treatEOFAsEpsilon) + if ci, ok := c.(*BaseATNConfig); ok && ci != nil { + if !t.getIsEpsilon() && closureBusy.add(c) != c { + // avoid infinite recursion for EOF* and EOF+ + continue + } + newDepth := depth + + if _, ok := config.GetState().(*RuleStopState); ok { + + // target fell off end of rule mark resulting c as having dipped into outer context + // We can't get here if incoming config was rule stop and we had context + // track how far we dip into outer context. Might + // come in handy and we avoid evaluating context dependent + // preds if p is > 0. + + if closureBusy.add(c) != c { + // avoid infinite recursion for right-recursive rules + continue + } + + if p.dfa != nil && p.dfa.precedenceDfa { + if t.(*EpsilonTransition).outermostPrecedenceReturn == p.dfa.atnStartState.GetRuleIndex() { + c.setPrecedenceFilterSuppressed(true) + } + } + + c.SetReachesIntoOuterContext(c.GetReachesIntoOuterContext() + 1) + configs.SetDipsIntoOuterContext(true) // TODO: can remove? only care when we add to set per middle of p method + newDepth-- + if ParserATNSimulatorDebug { + fmt.Println("dips into outer ctx: " + c.String()) + } + } else if _, ok := t.(*RuleTransition); ok { + // latch when newDepth goes negative - once we step out of the entry context we can't return + if newDepth >= 0 { + newDepth++ + } + } + p.closureCheckingStopState(c, configs, closureBusy, continueCollecting, fullCtx, newDepth, treatEOFAsEpsilon) + } + } +} + +func (p *ParserATNSimulator) getRuleName(index int) string { + if p.parser != nil && index >= 0 { + return p.parser.GetRuleNames()[index] + } + + return "" +} + +func (p *ParserATNSimulator) getEpsilonTarget(config ATNConfig, t Transition, collectPredicates, inContext, fullCtx, treatEOFAsEpsilon bool) ATNConfig { + + switch t.getSerializationType() { + case TransitionRULE: + return p.ruleTransition(config, t.(*RuleTransition)) + case TransitionPRECEDENCE: + return p.precedenceTransition(config, t.(*PrecedencePredicateTransition), collectPredicates, inContext, fullCtx) + case TransitionPREDICATE: + return p.predTransition(config, t.(*PredicateTransition), collectPredicates, inContext, fullCtx) + case TransitionACTION: + return p.actionTransition(config, t.(*ActionTransition)) + case TransitionEPSILON: + return NewBaseATNConfig4(config, t.getTarget()) + case TransitionATOM: + // EOF transitions act like epsilon transitions after the first EOF + // transition is traversed + if treatEOFAsEpsilon { + if t.Matches(TokenEOF, 0, 1) { + return NewBaseATNConfig4(config, t.getTarget()) + } + } + return nil + case TransitionRANGE: + // EOF transitions act like epsilon transitions after the first EOF + // transition is traversed + if treatEOFAsEpsilon { + if t.Matches(TokenEOF, 0, 1) { + return NewBaseATNConfig4(config, t.getTarget()) + } + } + return nil + case TransitionSET: + // EOF transitions act like epsilon transitions after the first EOF + // transition is traversed + if treatEOFAsEpsilon { + if t.Matches(TokenEOF, 0, 1) { + return NewBaseATNConfig4(config, t.getTarget()) + } + } + return nil + default: + return nil + } +} + +func (p *ParserATNSimulator) actionTransition(config ATNConfig, t *ActionTransition) *BaseATNConfig { + if ParserATNSimulatorDebug { + fmt.Println("ACTION edge " + strconv.Itoa(t.ruleIndex) + ":" + strconv.Itoa(t.actionIndex)) + } + return NewBaseATNConfig4(config, t.getTarget()) +} + +func (p *ParserATNSimulator) precedenceTransition(config ATNConfig, + pt *PrecedencePredicateTransition, collectPredicates, inContext, fullCtx bool) *BaseATNConfig { + + if ParserATNSimulatorDebug { + fmt.Println("PRED (collectPredicates=" + fmt.Sprint(collectPredicates) + ") " + + strconv.Itoa(pt.precedence) + ">=_p, ctx dependent=true") + if p.parser != nil { + fmt.Println("context surrounding pred is " + fmt.Sprint(p.parser.GetRuleInvocationStack(nil))) + } + } + var c *BaseATNConfig + if collectPredicates && inContext { + if fullCtx { + // In full context mode, we can evaluate predicates on-the-fly + // during closure, which dramatically reduces the size of + // the config sets. It also obviates the need to test predicates + // later during conflict resolution. + currentPosition := p.input.Index() + p.input.Seek(p.startIndex) + predSucceeds := pt.getPredicate().evaluate(p.parser, p.outerContext) + p.input.Seek(currentPosition) + if predSucceeds { + c = NewBaseATNConfig4(config, pt.getTarget()) // no pred context + } + } else { + newSemCtx := SemanticContextandContext(config.GetSemanticContext(), pt.getPredicate()) + c = NewBaseATNConfig3(config, pt.getTarget(), newSemCtx) + } + } else { + c = NewBaseATNConfig4(config, pt.getTarget()) + } + if ParserATNSimulatorDebug { + fmt.Println("config from pred transition=" + c.String()) + } + return c +} + +func (p *ParserATNSimulator) predTransition(config ATNConfig, pt *PredicateTransition, collectPredicates, inContext, fullCtx bool) *BaseATNConfig { + + if ParserATNSimulatorDebug { + fmt.Println("PRED (collectPredicates=" + fmt.Sprint(collectPredicates) + ") " + strconv.Itoa(pt.ruleIndex) + + ":" + strconv.Itoa(pt.predIndex) + ", ctx dependent=" + fmt.Sprint(pt.isCtxDependent)) + if p.parser != nil { + fmt.Println("context surrounding pred is " + fmt.Sprint(p.parser.GetRuleInvocationStack(nil))) + } + } + var c *BaseATNConfig + if collectPredicates && ((pt.isCtxDependent && inContext) || !pt.isCtxDependent) { + if fullCtx { + // In full context mode, we can evaluate predicates on-the-fly + // during closure, which dramatically reduces the size of + // the config sets. It also obviates the need to test predicates + // later during conflict resolution. + currentPosition := p.input.Index() + p.input.Seek(p.startIndex) + predSucceeds := pt.getPredicate().evaluate(p.parser, p.outerContext) + p.input.Seek(currentPosition) + if predSucceeds { + c = NewBaseATNConfig4(config, pt.getTarget()) // no pred context + } + } else { + newSemCtx := SemanticContextandContext(config.GetSemanticContext(), pt.getPredicate()) + c = NewBaseATNConfig3(config, pt.getTarget(), newSemCtx) + } + } else { + c = NewBaseATNConfig4(config, pt.getTarget()) + } + if ParserATNSimulatorDebug { + fmt.Println("config from pred transition=" + c.String()) + } + return c +} + +func (p *ParserATNSimulator) ruleTransition(config ATNConfig, t *RuleTransition) *BaseATNConfig { + if ParserATNSimulatorDebug { + fmt.Println("CALL rule " + p.getRuleName(t.getTarget().GetRuleIndex()) + ", ctx=" + config.GetContext().String()) + } + returnState := t.followState + newContext := SingletonBasePredictionContextCreate(config.GetContext(), returnState.GetStateNumber()) + return NewBaseATNConfig1(config, t.getTarget(), newContext) +} + +func (p *ParserATNSimulator) getConflictingAlts(configs ATNConfigSet) *BitSet { + altsets := PredictionModegetConflictingAltSubsets(configs) + return PredictionModeGetAlts(altsets) +} + +// Sam pointed out a problem with the previous definition, v3, of +// ambiguous states. If we have another state associated with conflicting +// alternatives, we should keep going. For example, the following grammar +// +// s : (ID | ID ID?) '' +// +// When the ATN simulation reaches the state before '', it has a DFA +// state that looks like: [12|1|[], 6|2|[], 12|2|[]]. Naturally +// 12|1|[] and 12|2|[] conflict, but we cannot stop processing p node +// because alternative to has another way to continue, via [6|2|[]]. +// The key is that we have a single state that has config's only associated +// with a single alternative, 2, and crucially the state transitions +// among the configurations are all non-epsilon transitions. That means +// we don't consider any conflicts that include alternative 2. So, we +// ignore the conflict between alts 1 and 2. We ignore a set of +// conflicting alts when there is an intersection with an alternative +// associated with a single alt state in the state&rarrconfig-list map. +// +// It's also the case that we might have two conflicting configurations but +// also a 3rd nonconflicting configuration for a different alternative: +// [1|1|[], 1|2|[], 8|3|[]]. This can come about from grammar: +// +// a : A | A | A B +// +// After Matching input A, we reach the stop state for rule A, state 1. +// State 8 is the state right before B. Clearly alternatives 1 and 2 +// conflict and no amount of further lookahead will separate the two. +// However, alternative 3 will be able to continue and so we do not +// stop working on p state. In the previous example, we're concerned +// with states associated with the conflicting alternatives. Here alt +// 3 is not associated with the conflicting configs, but since we can continue +// looking for input reasonably, I don't declare the state done. We +// ignore a set of conflicting alts when we have an alternative +// that we still need to pursue. +// + +func (p *ParserATNSimulator) getConflictingAltsOrUniqueAlt(configs ATNConfigSet) *BitSet { + var conflictingAlts *BitSet + if configs.GetUniqueAlt() != ATNInvalidAltNumber { + conflictingAlts = NewBitSet() + conflictingAlts.add(configs.GetUniqueAlt()) + } else { + conflictingAlts = configs.GetConflictingAlts() + } + return conflictingAlts +} + +func (p *ParserATNSimulator) GetTokenName(t int) string { + if t == TokenEOF { + 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) + ">" + } + } + + return strconv.Itoa(t) +} + +func (p *ParserATNSimulator) getLookaheadName(input TokenStream) string { + return p.GetTokenName(input.LA(1)) +} + +// 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. +// +func (p *ParserATNSimulator) dumpDeadEndConfigs(nvae *NoViableAltException) { + + panic("Not implemented") + + // fmt.Println("dead end configs: ") + // var decs = nvae.deadEndConfigs + // + // for i:=0; i0) { + // var t = c.state.GetTransitions()[0] + // if t2, ok := t.(*AtomTransition); ok { + // trans = "Atom "+ p.GetTokenName(t2.label) + // } else if t3, ok := t.(SetTransition); ok { + // _, ok := t.(*NotSetTransition) + // + // var s string + // if (ok){ + // s = "~" + // } + // + // trans = s + "Set " + t3.set + // } + // } + // fmt.Errorf(c.String(p.parser, true) + ":" + trans) + // } +} + +func (p *ParserATNSimulator) noViableAlt(input TokenStream, outerContext ParserRuleContext, configs ATNConfigSet, startIndex int) *NoViableAltException { + return NewNoViableAltException(p.parser, input, input.Get(startIndex), input.LT(1), configs, outerContext) +} + +func (p *ParserATNSimulator) getUniqueAlt(configs ATNConfigSet) int { + alt := ATNInvalidAltNumber + for _, c := range configs.GetItems() { + if alt == ATNInvalidAltNumber { + alt = c.GetAlt() // found first alt + } else if c.GetAlt() != alt { + return ATNInvalidAltNumber + } + } + 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 +// range of edges that can be represented in the DFA tables, p method +// returns without adding the edge to the DFA. +// +//

If {@code to} is {@code nil}, p method returns {@code nil}. +// Otherwise, p method returns the {@link DFAState} returned by calling +// {@link //addDFAState} for the {@code to} state.

+// +// @param dfa The DFA +// @param from The source state for the edge +// @param t The input symbol +// @param to The target state for the edge +// +// @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)) + } + if to == nil { + return nil + } + to = p.addDFAState(dfa, to) // used existing if possible not incoming + if from == nil || t < -1 || t > p.atn.maxTokenType { + return to + } + if from.edges == nil { + from.edges = make([]*DFAState, p.atn.maxTokenType+1+1) + } + from.edges[t+1] = to // connect + + if ParserATNSimulatorDebug { + var names []string + if p.parser != nil { + names = p.parser.GetLiteralNames() + } + + fmt.Println("DFA=\n" + dfa.String(names, nil)) + } + 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 +// method returns {@code D} after adding it to the DFA. +// +//

If {@code D} is {@link //ERROR}, p method returns {@link //ERROR} and +// does not change the DFA.

+// +// @param dfa The dfa +// @param D The DFA state to add +// @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 { + return existing + } + d.stateNumber = dfa.numStates() + 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()) + } + return d +} + +func (p *ParserATNSimulator) ReportAttemptingFullContext(dfa *DFA, conflictingAlts *BitSet, configs ATNConfigSet, startIndex, stopIndex int) { + if ParserATNSimulatorDebug || ParserATNSimulatorRetryDebug { + interval := NewInterval(startIndex, stopIndex+1) + fmt.Println("ReportAttemptingFullContext decision=" + strconv.Itoa(dfa.decision) + ":" + configs.String() + + ", input=" + p.parser.GetTokenStream().GetTextFromInterval(interval)) + } + if p.parser != nil { + p.parser.GetErrorListenerDispatch().ReportAttemptingFullContext(p.parser, dfa, startIndex, stopIndex, conflictingAlts, configs) + } +} + +func (p *ParserATNSimulator) ReportContextSensitivity(dfa *DFA, prediction int, configs ATNConfigSet, startIndex, stopIndex int) { + if ParserATNSimulatorDebug || ParserATNSimulatorRetryDebug { + interval := NewInterval(startIndex, stopIndex+1) + fmt.Println("ReportContextSensitivity decision=" + strconv.Itoa(dfa.decision) + ":" + configs.String() + + ", input=" + p.parser.GetTokenStream().GetTextFromInterval(interval)) + } + if p.parser != nil { + p.parser.GetErrorListenerDispatch().ReportContextSensitivity(p.parser, dfa, startIndex, stopIndex, prediction, configs) + } +} + +// If context sensitive parsing, we know it's ambiguity not conflict// +func (p *ParserATNSimulator) ReportAmbiguity(dfa *DFA, D *DFAState, startIndex, stopIndex int, + exact bool, ambigAlts *BitSet, configs ATNConfigSet) { + if ParserATNSimulatorDebug || ParserATNSimulatorRetryDebug { + interval := NewInterval(startIndex, stopIndex+1) + fmt.Println("ReportAmbiguity " + ambigAlts.String() + ":" + configs.String() + + ", input=" + p.parser.GetTokenStream().GetTextFromInterval(interval)) + } + if p.parser != nil { + p.parser.GetErrorListenerDispatch().ReportAmbiguity(p.parser, dfa, startIndex, stopIndex, exact, ambigAlts, configs) + } +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_rule_context.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_rule_context.go new file mode 100644 index 000000000..49cd10c5f --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_rule_context.go @@ -0,0 +1,362 @@ +// Copyright (c) 2012-2017 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 ( + "reflect" + "strconv" +) + +type ParserRuleContext interface { + RuleContext + + SetException(RecognitionException) + + AddTokenNode(token Token) *TerminalNodeImpl + AddErrorNode(badToken Token) *ErrorNodeImpl + + EnterRule(listener ParseTreeListener) + ExitRule(listener ParseTreeListener) + + SetStart(Token) + GetStart() Token + + SetStop(Token) + GetStop() Token + + AddChild(child RuleContext) RuleContext + RemoveLastChild() +} + +type BaseParserRuleContext struct { + *BaseRuleContext + + start, stop Token + exception RecognitionException + children []Tree +} + +func NewBaseParserRuleContext(parent ParserRuleContext, invokingStateNumber int) *BaseParserRuleContext { + prc := new(BaseParserRuleContext) + + prc.BaseRuleContext = NewBaseRuleContext(parent, invokingStateNumber) + + prc.RuleIndex = -1 + // * If we are debugging or building a parse tree for a Visitor, + // we need to track all of the tokens and rule invocations associated + // with prc rule's context. This is empty for parsing w/o tree constr. + // operation because we don't the need to track the details about + // how we parse prc rule. + // / + prc.children = nil + prc.start = nil + prc.stop = nil + // The exception that forced prc rule to return. If the rule successfully + // completed, prc is {@code nil}. + prc.exception = nil + + return prc +} + +func (prc *BaseParserRuleContext) SetException(e RecognitionException) { + prc.exception = e +} + +func (prc *BaseParserRuleContext) GetChildren() []Tree { + return prc.children +} + +func (prc *BaseParserRuleContext) CopyFrom(ctx *BaseParserRuleContext) { + // from RuleContext + prc.parentCtx = ctx.parentCtx + prc.invokingState = ctx.invokingState + prc.children = nil + prc.start = ctx.start + prc.stop = ctx.stop +} + +func (prc *BaseParserRuleContext) GetText() string { + if prc.GetChildCount() == 0 { + return "" + } + + var s string + for _, child := range prc.children { + s += child.(ParseTree).GetText() + } + + return s +} + +// Double dispatch methods for listeners +func (prc *BaseParserRuleContext) EnterRule(listener ParseTreeListener) { +} + +func (prc *BaseParserRuleContext) ExitRule(listener ParseTreeListener) { +} + +// * Does not set parent link other add methods do that/// +func (prc *BaseParserRuleContext) addTerminalNodeChild(child TerminalNode) TerminalNode { + if prc.children == nil { + prc.children = make([]Tree, 0) + } + if child == nil { + panic("Child may not be null") + } + prc.children = append(prc.children, child) + return child +} + +func (prc *BaseParserRuleContext) AddChild(child RuleContext) RuleContext { + if prc.children == nil { + prc.children = make([]Tree, 0) + } + if child == nil { + panic("Child may not be null") + } + prc.children = append(prc.children, child) + return child +} + +// * Used by EnterOuterAlt to toss out a RuleContext previously added as +// we entered a rule. If we have // label, we will need to remove +// generic ruleContext object. +// / +func (prc *BaseParserRuleContext) RemoveLastChild() { + if prc.children != nil && len(prc.children) > 0 { + prc.children = prc.children[0 : len(prc.children)-1] + } +} + +func (prc *BaseParserRuleContext) AddTokenNode(token Token) *TerminalNodeImpl { + + node := NewTerminalNodeImpl(token) + prc.addTerminalNodeChild(node) + node.parentCtx = prc + return node + +} + +func (prc *BaseParserRuleContext) AddErrorNode(badToken Token) *ErrorNodeImpl { + node := NewErrorNodeImpl(badToken) + prc.addTerminalNodeChild(node) + node.parentCtx = prc + return node +} + +func (prc *BaseParserRuleContext) GetChild(i int) Tree { + if prc.children != nil && len(prc.children) >= i { + return prc.children[i] + } + + return nil +} + +func (prc *BaseParserRuleContext) GetChildOfType(i int, childType reflect.Type) RuleContext { + if childType == nil { + return prc.GetChild(i).(RuleContext) + } + + for j := 0; j < len(prc.children); j++ { + child := prc.children[j] + if reflect.TypeOf(child) == childType { + if i == 0 { + return child.(RuleContext) + } + + i-- + } + } + + return nil +} + +func (prc *BaseParserRuleContext) ToStringTree(ruleNames []string, recog Recognizer) string { + return TreesStringTree(prc, ruleNames, recog) +} + +func (prc *BaseParserRuleContext) GetRuleContext() RuleContext { + return prc +} + +func (prc *BaseParserRuleContext) Accept(visitor ParseTreeVisitor) interface{} { + return visitor.VisitChildren(prc) +} + +func (prc *BaseParserRuleContext) SetStart(t Token) { + prc.start = t +} + +func (prc *BaseParserRuleContext) GetStart() Token { + return prc.start +} + +func (prc *BaseParserRuleContext) SetStop(t Token) { + prc.stop = t +} + +func (prc *BaseParserRuleContext) GetStop() Token { + return prc.stop +} + +func (prc *BaseParserRuleContext) GetToken(ttype int, i int) TerminalNode { + + for j := 0; j < len(prc.children); j++ { + child := prc.children[j] + if c2, ok := child.(TerminalNode); ok { + if c2.GetSymbol().GetTokenType() == ttype { + if i == 0 { + return c2 + } + + i-- + } + } + } + return nil +} + +func (prc *BaseParserRuleContext) GetTokens(ttype int) []TerminalNode { + if prc.children == nil { + return make([]TerminalNode, 0) + } + + tokens := make([]TerminalNode, 0) + + for j := 0; j < len(prc.children); j++ { + child := prc.children[j] + if tchild, ok := child.(TerminalNode); ok { + if tchild.GetSymbol().GetTokenType() == ttype { + tokens = append(tokens, tchild) + } + } + } + + return tokens +} + +func (prc *BaseParserRuleContext) GetPayload() interface{} { + return prc +} + +func (prc *BaseParserRuleContext) getChild(ctxType reflect.Type, i int) RuleContext { + if prc.children == nil || i < 0 || i >= len(prc.children) { + return nil + } + + j := -1 // what element have we found with ctxType? + for _, o := range prc.children { + + childType := reflect.TypeOf(o) + + if childType.Implements(ctxType) { + j++ + if j == i { + return o.(RuleContext) + } + } + } + return nil +} + +// Go lacks generics, so it's not possible for us to return the child with the correct type, but we do +// check for convertibility + +func (prc *BaseParserRuleContext) GetTypedRuleContext(ctxType reflect.Type, i int) RuleContext { + return prc.getChild(ctxType, i) +} + +func (prc *BaseParserRuleContext) GetTypedRuleContexts(ctxType reflect.Type) []RuleContext { + if prc.children == nil { + return make([]RuleContext, 0) + } + + contexts := make([]RuleContext, 0) + + for _, child := range prc.children { + childType := reflect.TypeOf(child) + + if childType.ConvertibleTo(ctxType) { + contexts = append(contexts, child.(RuleContext)) + } + } + return contexts +} + +func (prc *BaseParserRuleContext) GetChildCount() int { + if prc.children == nil { + return 0 + } + + return len(prc.children) +} + +func (prc *BaseParserRuleContext) GetSourceInterval() *Interval { + if prc.start == nil || prc.stop == nil { + return TreeInvalidInterval + } + + return NewInterval(prc.start.GetTokenIndex(), prc.stop.GetTokenIndex()) +} + +//need to manage circular dependencies, so export now + +// Print out a whole tree, not just a node, in LISP format +// (root child1 .. childN). Print just a node if b is a leaf. +// + +func (prc *BaseParserRuleContext) String(ruleNames []string, stop RuleContext) string { + + var p ParserRuleContext = prc + s := "[" + for p != nil && p != stop { + if ruleNames == nil { + if !p.IsEmpty() { + s += strconv.Itoa(p.GetInvokingState()) + } + } else { + ri := p.GetRuleIndex() + var ruleName string + if ri >= 0 && ri < len(ruleNames) { + ruleName = ruleNames[ri] + } else { + ruleName = strconv.Itoa(ri) + } + s += ruleName + } + if p.GetParent() != nil && (ruleNames != nil || !p.GetParent().(ParserRuleContext).IsEmpty()) { + s += " " + } + pi := p.GetParent() + if pi != nil { + p = pi.(ParserRuleContext) + } else { + p = nil + } + } + s += "]" + return s +} + +var RuleContextEmpty = NewBaseParserRuleContext(nil, -1) + +type InterpreterRuleContext interface { + ParserRuleContext +} + +type BaseInterpreterRuleContext struct { + *BaseParserRuleContext +} + +func NewBaseInterpreterRuleContext(parent BaseInterpreterRuleContext, invokingStateNumber, ruleIndex int) *BaseInterpreterRuleContext { + + prc := new(BaseInterpreterRuleContext) + + prc.BaseParserRuleContext = NewBaseParserRuleContext(parent, invokingStateNumber) + + prc.RuleIndex = ruleIndex + + return prc +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_context.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_context.go new file mode 100644 index 000000000..99acb333f --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_context.go @@ -0,0 +1,756 @@ +// Copyright (c) 2012-2017 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 ( + "strconv" +) + +// Represents {@code $} in local context prediction, which means wildcard. +// {@code//+x =//}. +// / +const ( + BasePredictionContextEmptyReturnState = 0x7FFFFFFF +) + +// Represents {@code $} in an array in full context mode, when {@code $} +// doesn't mean wildcard: {@code $ + x = [$,x]}. Here, +// {@code $} = {@link //EmptyReturnState}. +// / + +var ( + BasePredictionContextglobalNodeCount = 1 + BasePredictionContextid = BasePredictionContextglobalNodeCount +) + +type PredictionContext interface { + hash() int + GetParent(int) PredictionContext + getReturnState(int) int + equals(PredictionContext) bool + length() int + isEmpty() bool + hasEmptyPath() bool + String() string +} + +type BasePredictionContext struct { + cachedHash int +} + +func NewBasePredictionContext(cachedHash int) *BasePredictionContext { + pc := new(BasePredictionContext) + pc.cachedHash = cachedHash + + return pc +} + +func (b *BasePredictionContext) isEmpty() bool { + return false +} + +func calculateHash(parent PredictionContext, returnState int) int { + h := murmurInit(1) + h = murmurUpdate(h, parent.hash()) + h = murmurUpdate(h, returnState) + return murmurFinish(h, 2) +} + +func calculateEmptyHash() int { + h := murmurInit(1) + return murmurFinish(h, 0) +} + +// Used to cache {@link BasePredictionContext} objects. Its used for the shared +// context cash associated with contexts in DFA states. This cache +// can be used for both lexers and parsers. + +type PredictionContextCache struct { + cache map[PredictionContext]PredictionContext +} + +func NewPredictionContextCache() *PredictionContextCache { + t := new(PredictionContextCache) + t.cache = make(map[PredictionContext]PredictionContext) + return t +} + +// 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 + } + existing := p.cache[ctx] + if existing != nil { + return existing + } + p.cache[ctx] = ctx + return ctx +} + +func (p *PredictionContextCache) Get(ctx PredictionContext) PredictionContext { + return p.cache[ctx] +} + +func (p *PredictionContextCache) length() int { + return len(p.cache) +} + +type SingletonPredictionContext interface { + PredictionContext +} + +type BaseSingletonPredictionContext struct { + *BasePredictionContext + + parentCtx PredictionContext + returnState int +} + +func NewBaseSingletonPredictionContext(parent PredictionContext, returnState int) *BaseSingletonPredictionContext { + + s := new(BaseSingletonPredictionContext) + s.BasePredictionContext = NewBasePredictionContext(37) + + if parent != nil { + s.cachedHash = calculateHash(parent, returnState) + } else { + s.cachedHash = calculateEmptyHash() + } + + s.parentCtx = parent + s.returnState = returnState + + return s +} + +func SingletonBasePredictionContextCreate(parent PredictionContext, returnState int) PredictionContext { + if returnState == BasePredictionContextEmptyReturnState && parent == nil { + // someone can pass in the bits of an array ctx that mean $ + return BasePredictionContextEMPTY + } + + return NewBaseSingletonPredictionContext(parent, returnState) +} + +func (b *BaseSingletonPredictionContext) length() int { + return 1 +} + +func (b *BaseSingletonPredictionContext) GetParent(index int) PredictionContext { + return b.parentCtx +} + +func (b *BaseSingletonPredictionContext) getReturnState(index int) int { + return b.returnState +} + +func (b *BaseSingletonPredictionContext) hasEmptyPath() bool { + return b.returnState == BasePredictionContextEmptyReturnState +} + +func (b *BaseSingletonPredictionContext) equals(other PredictionContext) bool { + if b == other { + return true + } else 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) { + return false + } else if b.parentCtx == nil { + return otherP.parentCtx == nil + } + + return b.parentCtx.equals(otherP.parentCtx) +} + +func (b *BaseSingletonPredictionContext) hash() int { + h := murmurInit(1) + + if b.parentCtx == nil { + return murmurFinish(h, 0) + } + + h = murmurUpdate(h, b.parentCtx.hash()) + h = murmurUpdate(h, b.returnState) + return murmurFinish(h, 2) +} + +func (b *BaseSingletonPredictionContext) String() string { + var up string + + if b.parentCtx == nil { + up = "" + } else { + up = b.parentCtx.String() + } + + if len(up) == 0 { + if b.returnState == BasePredictionContextEmptyReturnState { + return "$" + } + + return strconv.Itoa(b.returnState) + } + + return strconv.Itoa(b.returnState) + " " + up +} + +var BasePredictionContextEMPTY = NewEmptyPredictionContext() + +type EmptyPredictionContext struct { + *BaseSingletonPredictionContext +} + +func NewEmptyPredictionContext() *EmptyPredictionContext { + + p := new(EmptyPredictionContext) + + p.BaseSingletonPredictionContext = NewBaseSingletonPredictionContext(nil, BasePredictionContextEmptyReturnState) + + return p +} + +func (e *EmptyPredictionContext) isEmpty() bool { + return true +} + +func (e *EmptyPredictionContext) GetParent(index int) PredictionContext { + return nil +} + +func (e *EmptyPredictionContext) getReturnState(index int) int { + return e.returnState +} + +func (e *EmptyPredictionContext) equals(other PredictionContext) bool { + return e == other +} + +func (e *EmptyPredictionContext) String() string { + return "$" +} + +type ArrayPredictionContext struct { + *BasePredictionContext + + parents []PredictionContext + returnStates []int +} + +func NewArrayPredictionContext(parents []PredictionContext, returnStates []int) *ArrayPredictionContext { + // Parent can be nil only if full ctx mode and we make an array + // from {@link //EMPTY} and non-empty. We merge {@link //EMPTY} by using + // nil parent and + // returnState == {@link //EmptyReturnState}. + + c := new(ArrayPredictionContext) + c.BasePredictionContext = NewBasePredictionContext(37) + + for i := range parents { + c.cachedHash += calculateHash(parents[i], returnStates[i]) + } + + c.parents = parents + c.returnStates = returnStates + + return c +} + +func (a *ArrayPredictionContext) GetReturnStates() []int { + return a.returnStates +} + +func (a *ArrayPredictionContext) hasEmptyPath() bool { + return a.getReturnState(a.length()-1) == BasePredictionContextEmptyReturnState +} + +func (a *ArrayPredictionContext) isEmpty() bool { + // since EmptyReturnState can only appear in the last position, we + // don't need to verify that size==1 + return a.returnStates[0] == BasePredictionContextEmptyReturnState +} + +func (a *ArrayPredictionContext) length() int { + return len(a.returnStates) +} + +func (a *ArrayPredictionContext) GetParent(index int) PredictionContext { + return a.parents[index] +} + +func (a *ArrayPredictionContext) getReturnState(index int) int { + return a.returnStates[index] +} + +func (a *ArrayPredictionContext) equals(other PredictionContext) bool { + if _, ok := other.(*ArrayPredictionContext); !ok { + return false + } else 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 + } +} + +func (a *ArrayPredictionContext) hash() int { + h := murmurInit(1) + + for _, p := range a.parents { + h = murmurUpdate(h, p.hash()) + } + + for _, r := range a.returnStates { + h = murmurUpdate(h, r) + } + + return murmurFinish(h, 2 * len(a.parents)) +} + +func (a *ArrayPredictionContext) String() string { + if a.isEmpty() { + return "[]" + } + + s := "[" + for i := 0; i < len(a.returnStates); i++ { + if i > 0 { + s = s + ", " + } + if a.returnStates[i] == BasePredictionContextEmptyReturnState { + s = s + "$" + continue + } + s = s + strconv.Itoa(a.returnStates[i]) + if a.parents[i] != nil { + s = s + " " + a.parents[i].String() + } else { + s = s + "nil" + } + } + + return s + "]" +} + +// Convert a {@link RuleContext} tree to a {@link BasePredictionContext} graph. +// Return {@link //EMPTY} if {@code outerContext} is empty or nil. +// / +func predictionContextFromRuleContext(a *ATN, outerContext RuleContext) PredictionContext { + if outerContext == nil { + outerContext = RuleContextEmpty + } + // 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 { + return BasePredictionContextEMPTY + } + // If we have a parent, convert it to a BasePredictionContext graph + parent := predictionContextFromRuleContext(a, outerContext.GetParent().(RuleContext)) + state := a.states[outerContext.GetInvokingState()] + transition := state.GetTransitions()[0] + + return SingletonBasePredictionContextCreate(parent, transition.(*RuleTransition).followState.GetStateNumber()) +} + +func merge(a, b PredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) PredictionContext { + // share same graph if both same + if a == b { + return a + } + + ac, ok1 := a.(*BaseSingletonPredictionContext) + bc, ok2 := b.(*BaseSingletonPredictionContext) + + if ok1 && ok2 { + return mergeSingletons(ac, bc, rootIsWildcard, mergeCache) + } + // At least one of a or b is array + // If one is $ and rootIsWildcard, return $ as// wildcard + if rootIsWildcard { + if _, ok := a.(*EmptyPredictionContext); ok { + return a + } + if _, ok := b.(*EmptyPredictionContext); ok { + 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)}) + } + if _, ok := b.(*BaseSingletonPredictionContext); ok { + b = NewArrayPredictionContext([]PredictionContext{b.GetParent(0)}, []int{b.getReturnState(0)}) + } + return mergeArrays(a.(*ArrayPredictionContext), b.(*ArrayPredictionContext), rootIsWildcard, mergeCache) +} + +// +// Merge two {@link SingletonBasePredictionContext} instances. +// +//

Stack tops equal, parents merge is same return left graph.
+//

+// +//

Same stack top, parents differ merge parents giving array node, then +// remainders of those graphs. A Newroot node is created to point to the +// merged parents.
+//

+// +//

Different stack tops pointing to same parent. Make array node for the +// root where both element in the root point to the same (original) +// parent.
+//

+// +//

Different stack tops pointing to different parents. Make array node for +// the root where each element points to the corresponding original +// parent.
+//

+// +// @param a the first {@link SingletonBasePredictionContext} +// @param b the second {@link SingletonBasePredictionContext} +// @param rootIsWildcard {@code true} if this is a local-context merge, +// otherwise false to indicate a full-context merge +// @param mergeCache +// / +func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) PredictionContext { + if mergeCache != nil { + previous := mergeCache.Get(a.hash(), b.hash()) + if previous != nil { + return previous.(PredictionContext) + } + previous = mergeCache.Get(b.hash(), a.hash()) + if previous != nil { + return previous.(PredictionContext) + } + } + + rootMerge := mergeRoot(a, b, rootIsWildcard) + if rootMerge != nil { + if mergeCache != nil { + mergeCache.set(a.hash(), b.hash(), rootMerge) + } + return rootMerge + } + if a.returnState == b.returnState { + parent := merge(a.parentCtx, b.parentCtx, rootIsWildcard, mergeCache) + // if parent is same as existing a or b parent or reduced to a parent, + // return it + if parent == a.parentCtx { + return a // ax + bx = ax, if a=b + } + if parent == b.parentCtx { + return b // ax + bx = bx, if a=b + } + // else: ax + ay = a'[x,y] + // merge parents x and y, giving array node with x,y then remainders + // of those graphs. dup a, a' points at merged array + // Newjoined parent so create Newsingleton pointing to it, a' + spc := SingletonBasePredictionContextCreate(parent, a.returnState) + if mergeCache != nil { + mergeCache.set(a.hash(), b.hash(), spc) + } + return spc + } + // a != b payloads differ + // see if we can collapse parents due to $+x parents if local ctx + var singleParent PredictionContext + if a == b || (a.parentCtx != nil && a.parentCtx == b.parentCtx) { // ax + + // bx = + // [a,b]x + singleParent = a.parentCtx + } + if singleParent != nil { // parents are same + // sort payloads and use same parent + payloads := []int{a.returnState, b.returnState} + if a.returnState > b.returnState { + payloads[0] = b.returnState + payloads[1] = a.returnState + } + parents := []PredictionContext{singleParent, singleParent} + apc := NewArrayPredictionContext(parents, payloads) + if mergeCache != nil { + mergeCache.set(a.hash(), b.hash(), apc) + } + return apc + } + // parents differ and can't merge them. Just pack together + // into array can't merge. + // ax + by = [ax,by] + payloads := []int{a.returnState, b.returnState} + parents := []PredictionContext{a.parentCtx, b.parentCtx} + if a.returnState > b.returnState { // sort by payload + payloads[0] = b.returnState + payloads[1] = a.returnState + parents = []PredictionContext{b.parentCtx, a.parentCtx} + } + apc := NewArrayPredictionContext(parents, payloads) + if mergeCache != nil { + 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}. +// +//

Local-Context Merges

+// +//

These local-context merge operations are used when {@code rootIsWildcard} +// is true.

+// +//

{@link //EMPTY} is superset of any graph return {@link //EMPTY}.
+//

+// +//

{@link //EMPTY} and anything is {@code //EMPTY}, so merged parent is +// {@code //EMPTY} return left graph.
+//

+// +//

Special case of last merge if local context.
+//

+// +//

Full-Context Merges

+// +//

These full-context merge operations are used when {@code rootIsWildcard} +// is false.

+// +//

+// +//

Must keep all contexts {@link //EMPTY} in array is a special value (and +// nil parent).
+//

+// +//

+// +// @param a the first {@link SingletonBasePredictionContext} +// @param b the second {@link SingletonBasePredictionContext} +// @param rootIsWildcard {@code true} if this is a local-context merge, +// otherwise false to indicate a full-context merge +// / +func mergeRoot(a, b SingletonPredictionContext, rootIsWildcard bool) PredictionContext { + if rootIsWildcard { + if a == BasePredictionContextEMPTY { + return BasePredictionContextEMPTY // // + b =// + } + if b == BasePredictionContextEMPTY { + return BasePredictionContextEMPTY // a +// =// + } + } else { + if a == BasePredictionContextEMPTY && b == BasePredictionContextEMPTY { + return BasePredictionContextEMPTY // $ + $ = $ + } else if a == BasePredictionContextEMPTY { // $ + x = [$,x] + payloads := []int{b.getReturnState(-1), BasePredictionContextEmptyReturnState} + parents := []PredictionContext{b.GetParent(-1), nil} + return NewArrayPredictionContext(parents, payloads) + } else if b == BasePredictionContextEMPTY { // x + $ = [$,x] ($ is always first if present) + payloads := []int{a.getReturnState(-1), BasePredictionContextEmptyReturnState} + parents := []PredictionContext{a.GetParent(-1), nil} + return NewArrayPredictionContext(parents, payloads) + } + } + return nil +} + +// +// Merge two {@link ArrayBasePredictionContext} instances. +// +//

Different tops, different parents.
+//

+// +//

Shared top, same parents.
+//

+// +//

Shared top, different parents.
+//

+// +//

Shared top, all shared parents.
+//

+// +//

Equal tops, merge parents and reduce top to +// {@link SingletonBasePredictionContext}.
+//

+// / +func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) PredictionContext { + if mergeCache != nil { + previous := mergeCache.Get(a.hash(), b.hash()) + if previous != nil { + return previous.(PredictionContext) + } + previous = mergeCache.Get(b.hash(), a.hash()) + if previous != nil { + return previous.(PredictionContext) + } + } + // merge sorted payloads a + b => M + i := 0 // walks a + j := 0 // walks b + k := 0 // walks target M array + + mergedReturnStates := make([]int, len(a.returnStates)+len(b.returnStates)) + mergedParents := make([]PredictionContext, len(a.returnStates)+len(b.returnStates)) + // walk and merge to yield mergedParents, mergedReturnStates + for i < len(a.returnStates) && j < len(b.returnStates) { + aParent := a.parents[i] + bParent := b.parents[j] + if a.returnStates[i] == b.returnStates[j] { + // same payload (stack tops are equal), must yield merged singleton + payload := a.returnStates[i] + // $+$ = $ + bothDollars := payload == BasePredictionContextEmptyReturnState && aParent == nil && bParent == nil + axAX := (aParent != nil && bParent != nil && aParent == bParent) // ax+ax + // -> + // ax + if bothDollars || axAX { + mergedParents[k] = aParent // choose left + mergedReturnStates[k] = payload + } else { // ax+ay -> a'[x,y] + mergedParent := merge(aParent, bParent, rootIsWildcard, mergeCache) + mergedParents[k] = mergedParent + mergedReturnStates[k] = payload + } + i++ // hop over left one as usual + j++ // but also Skip one in right side since we merge + } else if a.returnStates[i] < b.returnStates[j] { // copy a[i] to M + mergedParents[k] = aParent + mergedReturnStates[k] = a.returnStates[i] + i++ + } else { // b > a, copy b[j] to M + mergedParents[k] = bParent + mergedReturnStates[k] = b.returnStates[j] + j++ + } + k++ + } + // copy over any payloads remaining in either array + if i < len(a.returnStates) { + for p := i; p < len(a.returnStates); p++ { + mergedParents[k] = a.parents[p] + mergedReturnStates[k] = a.returnStates[p] + k++ + } + } else { + for p := j; p < len(b.returnStates); p++ { + mergedParents[k] = b.parents[p] + mergedReturnStates[k] = b.returnStates[p] + k++ + } + } + // trim merged if we combined a few that had same stack tops + if k < len(mergedParents) { // write index < last position trim + 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) + } + return pc + } + mergedParents = mergedParents[0:k] + mergedReturnStates = mergedReturnStates[0:k] + } + + M := NewArrayPredictionContext(mergedParents, mergedReturnStates) + + // if we created same array as a or b, return that instead + // TODO: track whether this is possible above during merge sort for speed + if M == a { + if mergeCache != nil { + mergeCache.set(a.hash(), b.hash(), a) + } + return a + } + if M == b { + if mergeCache != nil { + mergeCache.set(a.hash(), b.hash(), b) + } + return b + } + combineCommonParents(mergedParents) + + if mergeCache != nil { + mergeCache.set(a.hash(), b.hash(), M) + } + return M +} + +// +// Make pass over all M {@code parents} merge any {@code equals()} +// ones. +// / +func combineCommonParents(parents []PredictionContext) { + uniqueParents := make(map[PredictionContext]PredictionContext) + + for p := 0; p < len(parents); p++ { + parent := parents[p] + if uniqueParents[parent] == nil { + uniqueParents[parent] = parent + } + } + for q := 0; q < len(parents); q++ { + parents[q] = uniqueParents[parents[q]] + } +} + +func getCachedBasePredictionContext(context PredictionContext, contextCache *PredictionContextCache, visited map[PredictionContext]PredictionContext) PredictionContext { + + if context.isEmpty() { + return context + } + existing := visited[context] + if existing != nil { + return existing + } + existing = contextCache.Get(context) + if existing != nil { + visited[context] = existing + return existing + } + changed := false + parents := make([]PredictionContext, context.length()) + for i := 0; i < len(parents); i++ { + parent := getCachedBasePredictionContext(context.GetParent(i), contextCache, visited) + if changed || parent != context.GetParent(i) { + if !changed { + parents = make([]PredictionContext, context.length()) + for j := 0; j < context.length(); j++ { + parents[j] = context.GetParent(j) + } + changed = true + } + parents[i] = parent + } + } + if !changed { + contextCache.add(context) + visited[context] = context + return context + } + var updated PredictionContext + if len(parents) == 0 { + updated = BasePredictionContextEMPTY + } else if len(parents) == 1 { + updated = SingletonBasePredictionContextCreate(parents[0], context.getReturnState(0)) + } else { + updated = NewArrayPredictionContext(parents, context.(*ArrayPredictionContext).GetReturnStates()) + } + contextCache.add(updated) + visited[updated] = updated + visited[context] = updated + + return updated +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_mode.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_mode.go new file mode 100644 index 000000000..15718f912 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_mode.go @@ -0,0 +1,553 @@ +// Copyright (c) 2012-2017 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 + +// This enumeration defines the prediction modes available in ANTLR 4 along with +// utility methods for analyzing configuration sets for conflicts and/or +// ambiguities. + +const ( + // + // The SLL(*) prediction mode. This prediction mode ignores the current + // parser context when making predictions. This is the fastest prediction + // mode, and provides correct results for many grammars. This prediction + // mode is more powerful than the prediction mode provided by ANTLR 3, but + // may result in syntax errors for grammar and input combinations which are + // not SLL. + // + //

+ // When using this prediction mode, the parser will either return a correct + // parse tree (i.e. the same parse tree that would be returned with the + // {@link //LL} prediction mode), or it will Report a syntax error. If a + // syntax error is encountered when using the {@link //SLL} prediction mode, + // it may be due to either an actual syntax error in the input or indicate + // that the particular combination of grammar and input requires the more + // powerful {@link //LL} prediction abilities to complete successfully.

+ // + //

+ // This prediction mode does not provide any guarantees for prediction + // behavior for syntactically-incorrect inputs.

+ // + PredictionModeSLL = 0 + // + // The LL(*) prediction mode. This prediction mode allows the current parser + // context to be used for resolving SLL conflicts that occur during + // prediction. This is the fastest prediction mode that guarantees correct + // parse results for all combinations of grammars with syntactically correct + // inputs. + // + //

+ // When using this prediction mode, the parser will make correct decisions + // for all syntactically-correct grammar and input combinations. However, in + // cases where the grammar is truly ambiguous this prediction mode might not + // Report a precise answer for exactly which alternatives are + // ambiguous.

+ // + //

+ // This prediction mode does not provide any guarantees for prediction + // behavior for syntactically-incorrect inputs.

+ // + PredictionModeLL = 1 + // + // The LL(*) prediction mode with exact ambiguity detection. In addition to + // the correctness guarantees provided by the {@link //LL} prediction mode, + // this prediction mode instructs the prediction algorithm to determine the + // complete and exact set of ambiguous alternatives for every ambiguous + // decision encountered while parsing. + // + //

+ // This prediction mode may be used for diagnosing ambiguities during + // grammar development. Due to the performance overhead of calculating sets + // of ambiguous alternatives, this prediction mode should be avoided when + // the exact results are not necessary.

+ // + //

+ // This prediction mode does not provide any guarantees for prediction + // behavior for syntactically-incorrect inputs.

+ // + PredictionModeLLExactAmbigDetection = 2 +) + +// +// Computes the SLL prediction termination condition. +// +//

+// This method computes the SLL prediction termination condition for both of +// the following cases.

+// +//
    +//
  • The usual SLL+LL fallback upon SLL conflict
  • +//
  • Pure SLL without LL fallback
  • +//
+// +//

COMBINED SLL+LL PARSING

+// +//

When LL-fallback is enabled upon SLL conflict, correct predictions are +// ensured regardless of how the termination condition is computed by this +// method. Due to the substantially higher cost of LL prediction, the +// prediction should only fall back to LL when the additional lookahead +// cannot lead to a unique SLL prediction.

+// +//

Assuming combined SLL+LL parsing, an SLL configuration set with only +// conflicting subsets should fall back to full LL, even if the +// configuration sets don't resolve to the same alternative (e.g. +// {@code {1,2}} and {@code {3,4}}. If there is at least one non-conflicting +// configuration, SLL could continue with the hopes that more lookahead will +// resolve via one of those non-conflicting configurations.

+// +//

Here's the prediction termination rule them: SLL (for SLL+LL parsing) +// stops when it sees only conflicting configuration subsets. In contrast, +// full LL keeps going when there is uncertainty.

+// +//

HEURISTIC

+// +//

As a heuristic, we stop prediction when we see any conflicting subset +// unless we see a state that only has one alternative associated with it. +// 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?) '' }

+// +//

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, +// via {@code [6|2|[]]}.

+// +//

It also let's us continue for this rule:

+// +//

{@code [1|1|[], 1|2|[], 8|3|[]] a : A | A | A B }

+// +//

After Matching input A, we reach the stop state for rule A, state 1. +// State 8 is the state right before B. Clearly alternatives 1 and 2 +// conflict and no amount of further lookahead will separate the two. +// However, alternative 3 will be able to continue and so we do not stop +// working on this state. In the previous example, we're concerned with +// states associated with the conflicting alternatives. Here alt 3 is not +// associated with the conflicting configs, but since we can continue +// looking for input reasonably, don't declare the state done.

+// +//

PURE SLL PARSING

+// +//

To handle pure SLL parsing, all we have to do is make sure that we +// combine stack contexts for configurations that differ only by semantic +// predicate. From there, we can do the usual SLL termination heuristic.

+// +//

PREDICATES IN SLL+LL PARSING

+// +//

SLL decisions don't evaluate predicates until after they reach DFA stop +// states because they need to create the DFA cache that works in all +// semantic situations. In contrast, full LL evaluates predicates collected +// during start state computation so it can ignore predicates thereafter. +// This means that SLL termination detection can totally ignore semantic +// predicates.

+// +//

Implementation-wise, {@link ATNConfigSet} combines stack contexts but not +// semantic predicate contexts so we might see two configurations like the +// following.

+// +//

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

+// +//

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 +// the following configurations.

+// +//

{@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 + // configs meet this condition, then none of the configurations is able + // to Match additional input so we terminate prediction. + // + if PredictionModeallConfigsInRuleStopStates(configs) { + return true + } + // pure SLL mode parsing + if mode == PredictionModeSLL { + // Don't bother with combining configs from different semantic + // contexts if we can fail over to full LL costs more time + // since we'll often fail over anyway. + if configs.HasSemanticContext() { + // dup configs, tossing out semantic predicates + dup := NewBaseATNConfigSet(false) + for _, c := range configs.GetItems() { + + // NewBaseATNConfig({semanticContext:}, c) + c = NewBaseATNConfig2(c, SemanticContextNone) + dup.Add(c, nil) + } + configs = dup + } + // now we have combined contexts for configs with dissimilar preds + } + // pure SLL or combined SLL+LL mode parsing + altsets := PredictionModegetConflictingAltSubsets(configs) + return PredictionModehasConflictingAltSet(altsets) && !PredictionModehasStateAssociatedWithOneAlt(configs) +} + +// Checks if any configuration in {@code configs} is in a +// {@link RuleStopState}. Configurations meeting this condition have reached +// the end of the decision rule (local context) or end of start rule (full +// context). +// +// @param configs the configuration set to test +// @return {@code true} if any configuration in {@code configs} is in a +// {@link RuleStopState}, otherwise {@code false} +func PredictionModehasConfigInRuleStopState(configs ATNConfigSet) bool { + for _, c := range configs.GetItems() { + if _, ok := c.GetState().(*RuleStopState); ok { + return true + } + } + return false +} + +// Checks if all configurations in {@code configs} are in a +// {@link RuleStopState}. Configurations meeting this condition have reached +// the end of the decision rule (local context) or end of start rule (full +// context). +// +// @param configs the configuration set to test +// @return {@code true} if all configurations in {@code configs} are in a +// {@link RuleStopState}, otherwise {@code false} +func PredictionModeallConfigsInRuleStopStates(configs ATNConfigSet) bool { + + for _, c := range configs.GetItems() { + if _, ok := c.GetState().(*RuleStopState); !ok { + return false + } + } + return true +} + +// +// Full LL prediction termination. +// +//

Can we stop looking ahead during ATN simulation or is there some +// uncertainty as to which alternative we will ultimately pick, after +// consuming more input? Even if there are partial conflicts, we might know +// that everything is going to resolve to the same minimum alternative. That +// means we can stop since no more lookahead will change that fact. On the +// other hand, there might be multiple conflicts that resolve to different +// minimums. That means we need more look ahead to decide which of those +// alternatives we should predict.

+// +//

The basic idea is to split the set of configurations {@code C}, into +// conflicting subsets {@code (s, _, ctx, _)} and singleton subsets with +// non-conflicting configurations. Two configurations conflict if they have +// identical {@link ATNConfig//state} and {@link ATNConfig//context} values +// but different {@link ATNConfig//alt} value, e.g. {@code (s, i, ctx, _)} +// and {@code (s, j, ctx, _)} for {@code i!=j}.

+// +//

Reduce these configuration subsets to the set of possible alternatives. +// You can compute the alternative subsets in one pass as follows:

+// +//

{@code A_s,ctx = {i | (s, i, ctx, _)}} for each configuration in +// {@code C} holding {@code s} and {@code ctx} fixed.

+// +//

Or in pseudo-code, for each configuration {@code c} in {@code C}:

+// +//
+// map[c] U= c.{@link ATNConfig//alt alt} // map hash/equals uses s and x, not
+// alt and not pred
+// 
+// +//

The values in {@code map} are the set of {@code A_s,ctx} sets.

+// +//

If {@code |A_s,ctx|=1} then there is no conflict associated with +// {@code s} and {@code ctx}.

+// +//

Reduce the subsets to singletons by choosing a minimum of each subset. If +// the union of these alternative subsets is a singleton, then no amount of +// more lookahead will help us. We will always pick that alternative. If, +// however, there is more than one alternative, then we are uncertain which +// alternative to predict and must continue looking for resolution. We may +// or may not discover an ambiguity in the future, even if there are no +// conflicting subsets this round.

+// +//

The biggest sin is to terminate early because it means we've made a +// decision but were uncertain as to the eventual outcome. We haven't used +// enough lookahead. On the other hand, announcing a conflict too late is no +// big deal you will still have the conflict. It's just inefficient. It +// might even look until the end of file.

+// +//

No special consideration for semantic predicates is required because +// predicates are evaluated on-the-fly for full LL prediction, ensuring that +// no configuration contains a semantic context during the termination +// check.

+// +//

CONFLICTING CONFIGS

+// +//

Two configurations {@code (s, i, x)} and {@code (s, j, x')}, conflict +// when {@code i!=j} but {@code x=x'}. Because we merge all +// {@code (s, i, _)} configurations together, that means that there are at +// most {@code n} configurations associated with state {@code s} for +// {@code n} possible alternatives in the decision. The merged stacks +// complicate the comparison of configuration contexts {@code x} and +// {@code x'}. Sam checks to see if one is a subset of the other by calling +// merge and checking to see if the merged result is either {@code x} or +// {@code x'}. If the {@code x} associated with lowest alternative {@code i} +// is the superset, then {@code i} is the only possible prediction since the +// others resolve to {@code min(i)} as well. However, if {@code x} is +// associated with {@code j>i} then at least one stack configuration for +// {@code j} is not in conflict with alternative {@code i}. The algorithm +// should keep going, looking for more lookahead due to the uncertainty.

+// +//

For simplicity, I'm doing a equality check between {@code x} and +// {@code x'} that lets the algorithm continue to consume lookahead longer +// than necessary. The reason I like the equality is of course the +// simplicity but also because that is the test you need to detect the +// alternatives that are actually in conflict.

+// +//

CONTINUE/STOP RULE

+// +//

Continue if union of resolved alternative sets from non-conflicting and +// conflicting alternative subsets has more than one alternative. We are +// uncertain about which alternative to predict.

+// +//

The complete set of alternatives, {@code [i for (_,i,_)]}, tells us which +// alternatives are still in the running for the amount of input we've +// consumed at this point. The conflicting sets let us to strip away +// configurations that won't lead to more states because we resolve +// conflicts to the configuration with a minimum alternate for the +// conflicting set.

+// +//

CASES

+// +//
    +// +//
  • no conflicts and more than 1 alternative in set => continue
  • +// +//
  • {@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s, 3, z)}, +// {@code (s', 1, y)}, {@code (s', 2, y)} yields non-conflicting set +// {@code {3}} U conflicting sets {@code min({1,2})} U {@code min({1,2})} = +// {@code {1,3}} => continue +//
  • +// +//
  • {@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 {1}} U conflicting sets {@code min({1,2})} U {@code min({1,2})} = +// {@code {1}} => stop and predict 1
  • +// +//
  • {@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 1, y)}, +// {@code (s', 2, y)} yields conflicting, reduced sets {@code {1}} U +// {@code {1}} = {@code {1}} => stop and predict 1, can announce +// ambiguity {@code {1,2}}
  • +// +//
  • {@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 2, y)}, +// {@code (s', 3, y)} yields conflicting, reduced sets {@code {1}} U +// {@code {2}} = {@code {1,2}} => continue
  • +// +//
  • {@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 3, y)}, +// {@code (s', 4, y)} yields conflicting, reduced sets {@code {1}} U +// {@code {3}} = {@code {1,3}} => continue
  • +// +//
+// +//

EXACT AMBIGUITY DETECTION

+// +//

If all states Report the same conflicting set of alternatives, then we +// know we have the exact ambiguity set.

+// +//

|A_i|>1 and +// A_i = A_j for all i, j.

+// +//

In other words, we continue examining lookahead until all {@code A_i} +// have more than one alternative and all {@code A_i} are the same. If +// {@code A={{1,2}, {1,3}}}, then regular LL prediction would terminate +// because the resolved set is {@code {1}}. To determine what the real +// ambiguity is, we have to know whether the ambiguity is between one and +// 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] + if alts.length() == 1 { + return true + } + } + 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] + if alts.length() > 1 { + return true + } + } + 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 + + for i := 0; i < len(altsets); i++ { + alts := altsets[i] + if first == nil { + first = alts + } else if alts != first { + return false + } + } + + 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 { + return all.minValue() + } + + return ATNInvalidAltNumber +} + +// Gets the complete set of represented alternatives for a collection of +// alternative subsets. This method returns the union of each {@link BitSet} +// in {@code altsets}. +// +// @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 { + all.or(alts) + } + return all +} + +// +// This func 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) + + for _, c := range configs.GetItems() { + key := 31 * c.GetState().GetStateNumber() + c.GetContext().hash() + + alts, ok := configToAlts[key] + if !ok { + alts = NewBitSet() + configToAlts[key] = alts + } + alts.add(c.GetAlt()) + } + + values := make([]*BitSet, 0, 10) + for _, v := range configToAlts { + values = append(values, v) + } + return values +} + +// +// Get 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() + + for _, c := range configs.GetItems() { + alts := m.Get(c.GetState().String()) + if alts == nil { + alts = NewBitSet() + m.put(c.GetState().String(), alts) + } + alts.(*BitSet).add(c.GetAlt()) + } + return m +} + +func PredictionModehasStateAssociatedWithOneAlt(configs ATNConfigSet) bool { + values := PredictionModeGetStateToAltMap(configs).values() + for i := 0; i < len(values); i++ { + if values[i].(*BitSet).length() == 1 { + return true + } + } + return false +} + +func PredictionModegetSingleViableAlt(altsets []*BitSet) int { + result := ATNInvalidAltNumber + + for i := 0; i < len(altsets); i++ { + alts := altsets[i] + minAlt := alts.minValue() + if result == ATNInvalidAltNumber { + result = minAlt + } else if result != minAlt { // more than 1 viable alt + return ATNInvalidAltNumber + } + } + return result +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/recognizer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/recognizer.go new file mode 100644 index 000000000..9ea9f6f59 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/recognizer.go @@ -0,0 +1,217 @@ +// Copyright (c) 2012-2017 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" + "strings" + + "strconv" +) + +type Recognizer interface { + GetLiteralNames() []string + GetSymbolicNames() []string + GetRuleNames() []string + + Sempred(RuleContext, int, int) bool + Precpred(RuleContext, int) bool + + GetState() int + SetState(int) + Action(RuleContext, int, int) + AddErrorListener(ErrorListener) + RemoveErrorListeners() + GetATN() *ATN + GetErrorListenerDispatch() ErrorListener +} + +type BaseRecognizer struct { + listeners []ErrorListener + state int + + RuleNames []string + LiteralNames []string + SymbolicNames []string + GrammarFileName string +} + +func NewBaseRecognizer() *BaseRecognizer { + rec := new(BaseRecognizer) + rec.listeners = []ErrorListener{ConsoleErrorListenerINSTANCE} + rec.state = -1 + return rec +} + +var tokenTypeMapCache = make(map[string]int) +var ruleIndexMapCache = make(map[string]int) + +func (b *BaseRecognizer) checkVersion(toolVersion string) { + runtimeVersion := "4.7.2" + if runtimeVersion != toolVersion { + fmt.Println("ANTLR runtime and generated code versions disagree: " + runtimeVersion + "!=" + toolVersion) + } +} + +func (b *BaseRecognizer) Action(context RuleContext, ruleIndex, actionIndex int) { + panic("action not implemented on Recognizer!") +} + +func (b *BaseRecognizer) AddErrorListener(listener ErrorListener) { + b.listeners = append(b.listeners, listener) +} + +func (b *BaseRecognizer) RemoveErrorListeners() { + b.listeners = make([]ErrorListener, 0) +} + +func (b *BaseRecognizer) GetRuleNames() []string { + return b.RuleNames +} + +func (b *BaseRecognizer) GetTokenNames() []string { + return b.LiteralNames +} + +func (b *BaseRecognizer) GetSymbolicNames() []string { + return b.SymbolicNames +} + +func (b *BaseRecognizer) GetLiteralNames() []string { + return b.LiteralNames +} + +func (b *BaseRecognizer) GetState() int { + return b.state +} + +func (b *BaseRecognizer) SetState(v int) { + b.state = v +} + +//func (b *Recognizer) GetTokenTypeMap() { +// var tokenNames = b.GetTokenNames() +// if (tokenNames==nil) { +// panic("The current recognizer does not provide a list of token names.") +// } +// var result = tokenTypeMapCache[tokenNames] +// if(result==nil) { +// result = tokenNames.reduce(function(o, k, i) { o[k] = i }) +// result.EOF = TokenEOF +// tokenTypeMapCache[tokenNames] = result +// } +// return result +//} + +// 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!") + // var ruleNames = b.GetRuleNames() + // if (ruleNames==nil) { + // panic("The current recognizer does not provide a list of rule names.") + // } + // + // var result = ruleIndexMapCache[ruleNames] + // if(result==nil) { + // result = ruleNames.reduce(function(o, k, i) { o[k] = i }) + // ruleIndexMapCache[ruleNames] = result + // } + // return result +} + +func (b *BaseRecognizer) GetTokenType(tokenName string) int { + panic("Method not defined!") + // var ttype = b.GetTokenTypeMap()[tokenName] + // if (ttype !=nil) { + // return ttype + // } else { + // return TokenInvalidType + // } +} + +//func (b *Recognizer) GetTokenTypeMap() map[string]int { +// Vocabulary vocabulary = getVocabulary() +// +// Synchronized (tokenTypeMapCache) { +// Map result = tokenTypeMapCache.Get(vocabulary) +// if (result == null) { +// result = new HashMap() +// for (int i = 0; i < GetATN().maxTokenType; i++) { +// String literalName = vocabulary.getLiteralName(i) +// if (literalName != null) { +// result.put(literalName, i) +// } +// +// String symbolicName = vocabulary.GetSymbolicName(i) +// if (symbolicName != null) { +// result.put(symbolicName, i) +// } +// } +// +// result.put("EOF", Token.EOF) +// result = Collections.unmodifiableMap(result) +// tokenTypeMapCache.put(vocabulary, result) +// } +// +// return result +// } +//} + +// What is the error header, normally line/character position information?// +func (b *BaseRecognizer) GetErrorHeader(e RecognitionException) string { + line := e.GetOffendingToken().GetLine() + column := e.GetOffendingToken().GetColumn() + return "line " + strconv.Itoa(line) + ":" + strconv.Itoa(column) +} + +// 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. +// +// @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 "" + } + s := t.GetText() + if s == "" { + if t.GetTokenType() == TokenEOF { + s = "" + } else { + s = "<" + strconv.Itoa(t.GetTokenType()) + ">" + } + } + s = strings.Replace(s, "\t", "\\t", -1) + s = strings.Replace(s, "\n", "\\n", -1) + s = strings.Replace(s, "\r", "\\r", -1) + + return "'" + s + "'" +} + +func (b *BaseRecognizer) GetErrorListenerDispatch() ErrorListener { + return NewProxyErrorListener(b.listeners) +} + +// subclass needs to override these if there are sempreds or actions +// that the ATN interp needs to execute +func (b *BaseRecognizer) Sempred(localctx RuleContext, ruleIndex int, actionIndex int) bool { + return true +} + +func (b *BaseRecognizer) Precpred(localctx RuleContext, precedence int) bool { + return true +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/rule_context.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/rule_context.go new file mode 100644 index 000000000..600cf8c06 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/rule_context.go @@ -0,0 +1,114 @@ +// Copyright (c) 2012-2017 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 + +// A rule context is a record of a single rule invocation. It knows +// which context invoked it, if any. If there is no parent context, then +// naturally the invoking state is not valid. The parent link +// provides a chain upwards from the current rule invocation to the root +// of the invocation tree, forming a stack. We actually carry no +// information about the rule associated with b context (except +// when parsing). We keep only the state number of the invoking state from +// the ATN submachine that invoked b. Contrast b with the s +// pointer inside ParserRuleContext that tracks the current state +// being "executed" for the current rule. +// +// The parent contexts are useful for computing lookahead sets and +// getting error information. +// +// These objects are used during parsing and prediction. +// For the special case of parsers, we use the subclass +// ParserRuleContext. +// +// @see ParserRuleContext +// + +type RuleContext interface { + RuleNode + + GetInvokingState() int + SetInvokingState(int) + + GetRuleIndex() int + IsEmpty() bool + + GetAltNumber() int + SetAltNumber(altNumber int) + + String([]string, RuleContext) string +} + +type BaseRuleContext struct { + parentCtx RuleContext + invokingState int + RuleIndex int +} + +func NewBaseRuleContext(parent RuleContext, invokingState int) *BaseRuleContext { + + rn := new(BaseRuleContext) + + // What context invoked b rule? + rn.parentCtx = parent + + // What state invoked the rule associated with b context? + // The "return address" is the followState of invokingState + // If parent is nil, b should be -1. + if parent == nil { + rn.invokingState = -1 + } else { + rn.invokingState = invokingState + } + + return rn +} + +func (b *BaseRuleContext) GetBaseRuleContext() *BaseRuleContext { + return b +} + +func (b *BaseRuleContext) SetParent(v Tree) { + if v == nil { + b.parentCtx = nil + } else { + b.parentCtx = v.(RuleContext) + } +} + +func (b *BaseRuleContext) GetInvokingState() int { + return b.invokingState +} + +func (b *BaseRuleContext) SetInvokingState(t int) { + b.invokingState = t +} + +func (b *BaseRuleContext) GetRuleIndex() int { + return b.RuleIndex +} + +func (b *BaseRuleContext) GetAltNumber() int { + return ATNInvalidAltNumber +} + +func (b *BaseRuleContext) SetAltNumber(altNumber int) {} + +// A context is empty if there is no invoking state meaning nobody call +// current context. +func (b *BaseRuleContext) IsEmpty() bool { + return b.invokingState == -1 +} + +// Return the combined text of all child nodes. This method only considers +// tokens which have been added to the parse tree. +//

+// Since tokens on hidden channels (e.g. whitespace or comments) are not +// added to the parse trees, they will not appear in the output of b +// method. +// + +func (b *BaseRuleContext) GetParent() Tree { + return b.parentCtx +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/semantic_context.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/semantic_context.go new file mode 100644 index 000000000..49205a162 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/semantic_context.go @@ -0,0 +1,455 @@ +// Copyright (c) 2012-2017 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" + "strconv" +) + +// A tree structure used to record the semantic context in which +// an ATN configuration is valid. It's either a single predicate, +// a conjunction {@code p1&&p2}, or a sum of products {@code p1||p2}. +// +//

I have scoped the {@link AND}, {@link OR}, and {@link Predicate} subclasses of +// {@link SemanticContext} within the scope of this outer class.

+// + +type SemanticContext interface { + comparable + + evaluate(parser Recognizer, outerContext RuleContext) bool + evalPrecedence(parser Recognizer, outerContext RuleContext) SemanticContext + + hash() int + String() string +} + +func SemanticContextandContext(a, b SemanticContext) SemanticContext { + if a == nil || a == SemanticContextNone { + return b + } + if b == nil || b == SemanticContextNone { + return a + } + result := NewAND(a, b) + if len(result.opnds) == 1 { + return result.opnds[0] + } + + return result +} + +func SemanticContextorContext(a, b SemanticContext) SemanticContext { + if a == nil { + return b + } + if b == nil { + return a + } + if a == SemanticContextNone || b == SemanticContextNone { + return SemanticContextNone + } + result := NewOR(a, b) + if len(result.opnds) == 1 { + return result.opnds[0] + } + + return result +} + +type Predicate struct { + ruleIndex int + predIndex int + isCtxDependent bool +} + +func NewPredicate(ruleIndex, predIndex int, isCtxDependent bool) *Predicate { + p := new(Predicate) + + p.ruleIndex = ruleIndex + p.predIndex = predIndex + p.isCtxDependent = isCtxDependent // e.g., $i ref in pred + return p +} + +//The default {@link SemanticContext}, which is semantically equivalent to +//a predicate of the form {@code {true}?}. + +var SemanticContextNone SemanticContext = NewPredicate(-1, -1, false) + +func (p *Predicate) evalPrecedence(parser Recognizer, outerContext RuleContext) SemanticContext { + return p +} + +func (p *Predicate) evaluate(parser Recognizer, outerContext RuleContext) bool { + + var localctx RuleContext + + if p.isCtxDependent { + localctx = outerContext + } + + return parser.Sempred(localctx, p.ruleIndex, p.predIndex) +} + +func (p *Predicate) equals(other interface{}) bool { + if p == other { + return true + } else if _, ok := other.(*Predicate); !ok { + return false + } else { + return p.ruleIndex == other.(*Predicate).ruleIndex && + p.predIndex == other.(*Predicate).predIndex && + p.isCtxDependent == other.(*Predicate).isCtxDependent + } +} + +func (p *Predicate) hash() int { + return p.ruleIndex*43 + p.predIndex*47 +} + +func (p *Predicate) String() string { + return "{" + strconv.Itoa(p.ruleIndex) + ":" + strconv.Itoa(p.predIndex) + "}?" +} + +type PrecedencePredicate struct { + precedence int +} + +func NewPrecedencePredicate(precedence int) *PrecedencePredicate { + + p := new(PrecedencePredicate) + p.precedence = precedence + + return p +} + +func (p *PrecedencePredicate) evaluate(parser Recognizer, outerContext RuleContext) bool { + return parser.Precpred(outerContext, p.precedence) +} + +func (p *PrecedencePredicate) evalPrecedence(parser Recognizer, outerContext RuleContext) SemanticContext { + if parser.Precpred(outerContext, p.precedence) { + return SemanticContextNone + } + + return nil +} + +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 { + return false + } else { + return p.precedence == other.(*PrecedencePredicate).precedence + } +} + +func (p *PrecedencePredicate) hash() int { + return p.precedence * 51 +} + +func (p *PrecedencePredicate) String() string { + return "{" + strconv.Itoa(p.precedence) + ">=prec}?" +} + +func PrecedencePredicatefilterPrecedencePredicates(set *Set) []*PrecedencePredicate { + result := make([]*PrecedencePredicate, 0) + + for _, v := range set.values() { + if c2, ok := v.(*PrecedencePredicate); ok { + result = append(result, c2) + } + } + + return result +} + +// A semantic context which is true whenever none of the contained contexts +// is false.` + +type AND struct { + opnds []SemanticContext +} + +func NewAND(a, b SemanticContext) *AND { + + operands := NewSet(nil, nil) + if aa, ok := a.(*AND); ok { + for _, o := range aa.opnds { + operands.add(o) + } + } else { + operands.add(a) + } + + if ba, ok := b.(*AND); ok { + for _, o := range ba.opnds { + operands.add(o) + } + } else { + operands.add(b) + } + precedencePredicates := PrecedencePredicatefilterPrecedencePredicates(operands) + if len(precedencePredicates) > 0 { + // interested in the transition with the lowest precedence + var reduced *PrecedencePredicate + + for _, p := range precedencePredicates { + if reduced == nil || p.precedence < reduced.precedence { + reduced = p + } + } + + operands.add(reduced) + } + + vs := operands.values() + opnds := make([]SemanticContext, len(vs)) + for i, v := range vs { + opnds[i] = v.(SemanticContext) + } + + and := new(AND) + and.opnds = opnds + + return and +} + +func (a *AND) equals(other interface{}) bool { + if a == other { + return true + } else if _, ok := other.(*AND); !ok { + return false + } else { + for i, v := range other.(*AND).opnds { + if !a.opnds[i].equals(v) { + return false + } + } + return true + } +} + +// +// {@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) { + return false + } + } + return true +} + +func (a *AND) evalPrecedence(parser Recognizer, outerContext RuleContext) SemanticContext { + differs := false + operands := make([]SemanticContext, 0) + + for i := 0; i < len(a.opnds); i++ { + context := a.opnds[i] + evaluated := context.evalPrecedence(parser, outerContext) + differs = differs || (evaluated != context) + if evaluated == nil { + // The AND context is false if any element is false + return nil + } else if evaluated != SemanticContextNone { + // Reduce the result by Skipping true elements + operands = append(operands, evaluated) + } + } + if !differs { + return a + } + + if len(operands) == 0 { + // all elements were true, so the AND context is true + return SemanticContextNone + } + + var result SemanticContext + + for _, o := range operands { + if result == nil { + result = o + } else { + result = SemanticContextandContext(result, o) + } + } + + return result +} + +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()) + } + return murmurFinish(h, len(a.opnds)) +} + +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()) + } + return murmurFinish(h, len(a.opnds)) +} + +func (a *AND) String() string { + s := "" + + for _, o := range a.opnds { + s += "&& " + fmt.Sprint(o) + } + + if len(s) > 3 { + return s[0:3] + } + + return s +} + +// +// A semantic context which is true whenever at least one of the contained +// contexts is true. +// + +type OR struct { + opnds []SemanticContext +} + +func NewOR(a, b SemanticContext) *OR { + + operands := NewSet(nil, nil) + if aa, ok := a.(*OR); ok { + for _, o := range aa.opnds { + operands.add(o) + } + } else { + operands.add(a) + } + + if ba, ok := b.(*OR); ok { + for _, o := range ba.opnds { + operands.add(o) + } + } else { + operands.add(b) + } + precedencePredicates := PrecedencePredicatefilterPrecedencePredicates(operands) + if len(precedencePredicates) > 0 { + // interested in the transition with the lowest precedence + var reduced *PrecedencePredicate + + for _, p := range precedencePredicates { + if reduced == nil || p.precedence > reduced.precedence { + reduced = p + } + } + + operands.add(reduced) + } + + vs := operands.values() + + opnds := make([]SemanticContext, len(vs)) + for i, v := range vs { + opnds[i] = v.(SemanticContext) + } + + o := new(OR) + o.opnds = opnds + + return o +} + +func (o *OR) equals(other interface{}) 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) { + return false + } + } + return true + } +} + +//

+// 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) { + return true + } + } + return false +} + +func (o *OR) evalPrecedence(parser Recognizer, outerContext RuleContext) SemanticContext { + differs := false + operands := make([]SemanticContext, 0) + for i := 0; i < len(o.opnds); i++ { + context := o.opnds[i] + evaluated := context.evalPrecedence(parser, outerContext) + differs = differs || (evaluated != context) + if evaluated == SemanticContextNone { + // The OR context is true if any element is true + return SemanticContextNone + } else if evaluated != nil { + // Reduce the result by Skipping false elements + operands = append(operands, evaluated) + } + } + if !differs { + return o + } + if len(operands) == 0 { + // all elements were false, so the OR context is false + return nil + } + var result SemanticContext + + for _, o := range operands { + if result == nil { + result = o + } else { + result = SemanticContextorContext(result, o) + } + } + + return result +} + +func (o *OR) String() string { + s := "" + + for _, o := range o.opnds { + s += "|| " + fmt.Sprint(o) + } + + if len(s) > 3 { + return s[0:3] + } + + return s +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token.go new file mode 100644 index 000000000..2d8e99095 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token.go @@ -0,0 +1,210 @@ +// Copyright (c) 2012-2017 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 ( + "strconv" + "strings" +) + +type TokenSourceCharStreamPair struct { + tokenSource TokenSource + charStream CharStream +} + +// A token has properties: text, type, line, character position in the line +// (so we can ignore tabs), token channel, index, and source from which +// we obtained this token. + +type Token interface { + GetSource() *TokenSourceCharStreamPair + GetTokenType() int + GetChannel() int + GetStart() int + GetStop() int + GetLine() int + GetColumn() int + + GetText() string + SetText(s string) + + GetTokenIndex() int + SetTokenIndex(v int) + + GetTokenSource() TokenSource + GetInputStream() CharStream +} + +type BaseToken struct { + source *TokenSourceCharStreamPair + tokenType int // token type of the token + channel int // The parser ignores everything not on DEFAULT_CHANNEL + start int // optional return -1 if not implemented. + stop int // optional return -1 if not implemented. + tokenIndex int // from 0..n-1 of the token object in the input stream + line int // line=1..n of the 1st character + column int // beginning of the line at which it occurs, 0..n-1 + text string // text of the token. + readOnly bool +} + +const ( + TokenInvalidType = 0 + + // During lookahead operations, this "token" signifies we hit rule end ATN state + // and did not follow it despite needing to. + TokenEpsilon = -2 + + TokenMinUserTokenType = 1 + + TokenEOF = -1 + + // All tokens go to the parser (unless Skip() is called in that rule) + // on a particular "channel". The parser tunes to a particular channel + // so that whitespace etc... can go to the parser on a "hidden" channel. + + TokenDefaultChannel = 0 + + // Anything on different channel than DEFAULT_CHANNEL is not parsed + // by parser. + + TokenHiddenChannel = 1 +) + +func (b *BaseToken) GetChannel() int { + return b.channel +} + +func (b *BaseToken) GetStart() int { + return b.start +} + +func (b *BaseToken) GetStop() int { + return b.stop +} + +func (b *BaseToken) GetLine() int { + return b.line +} + +func (b *BaseToken) GetColumn() int { + return b.column +} + +func (b *BaseToken) GetTokenType() int { + return b.tokenType +} + +func (b *BaseToken) GetSource() *TokenSourceCharStreamPair { + return b.source +} + +func (b *BaseToken) GetTokenIndex() int { + return b.tokenIndex +} + +func (b *BaseToken) SetTokenIndex(v int) { + b.tokenIndex = v +} + +func (b *BaseToken) GetTokenSource() TokenSource { + return b.source.tokenSource +} + +func (b *BaseToken) GetInputStream() CharStream { + return b.source.charStream +} + +type CommonToken struct { + *BaseToken +} + +func NewCommonToken(source *TokenSourceCharStreamPair, tokenType, channel, start, stop int) *CommonToken { + + t := new(CommonToken) + + t.BaseToken = new(BaseToken) + + t.source = source + t.tokenType = tokenType + t.channel = channel + t.start = start + t.stop = stop + t.tokenIndex = -1 + if t.source.tokenSource != nil { + t.line = source.tokenSource.GetLine() + t.column = source.tokenSource.GetCharPositionInLine() + } else { + t.column = -1 + } + return t +} + +// An empty {@link Pair} which is used as the default value of +// {@link //source} for tokens that do not have a source. + +//CommonToken.EMPTY_SOURCE = [ nil, nil ] + +// Constructs a New{@link CommonToken} as a copy of another {@link Token}. +// +//

+// If {@code oldToken} is also a {@link CommonToken} instance, the newly +// constructed token will share a reference to the {@link //text} field and +// the {@link Pair} stored in {@link //source}. Otherwise, {@link //text} will +// be assigned the result of calling {@link //GetText}, and {@link //source} +// will be constructed from the result of {@link Token//GetTokenSource} and +// {@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() + t.line = c.GetLine() + t.column = c.GetColumn() + t.text = c.GetText() + return t +} + +func (c *CommonToken) GetText() string { + if c.text != "" { + return c.text + } + input := c.GetInputStream() + if input == nil { + return "" + } + n := input.Size() + if c.start < n && c.stop < n { + return input.GetTextFromInterval(NewInterval(c.start, c.stop)) + } + return "" +} + +func (c *CommonToken) SetText(text string) { + c.text = text +} + +func (c *CommonToken) String() string { + txt := c.GetText() + if txt != "" { + txt = strings.Replace(txt, "\n", "\\n", -1) + txt = strings.Replace(txt, "\r", "\\r", -1) + txt = strings.Replace(txt, "\t", "\\t", -1) + } else { + txt = "" + } + + var ch string + if c.channel > 0 { + ch = ",channel=" + strconv.Itoa(c.channel) + } else { + ch = "" + } + + return "[@" + strconv.Itoa(c.tokenIndex) + "," + strconv.Itoa(c.start) + ":" + strconv.Itoa(c.stop) + "='" + + txt + "',<" + strconv.Itoa(c.tokenType) + ">" + + ch + "," + strconv.Itoa(c.line) + ":" + strconv.Itoa(c.column) + "]" +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_source.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_source.go new file mode 100644 index 000000000..e023978fe --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_source.go @@ -0,0 +1,17 @@ +// Copyright (c) 2012-2017 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 + +type TokenSource interface { + NextToken() Token + Skip() + More() + GetLine() int + GetCharPositionInLine() int + GetInputStream() CharStream + GetSourceName() string + setTokenFactory(factory TokenFactory) + GetTokenFactory() TokenFactory +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_stream.go new file mode 100644 index 000000000..df92c8147 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_stream.go @@ -0,0 +1,20 @@ +// Copyright (c) 2012-2017 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 + +type TokenStream interface { + IntStream + + LT(k int) Token + + Get(index int) Token + GetTokenSource() TokenSource + SetTokenSource(TokenSource) + + GetAllText() string + GetTextFromInterval(*Interval) string + GetTextFromRuleContext(RuleContext) string + GetTextFromTokens(Token, Token) string +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/tokenstream_rewriter.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/tokenstream_rewriter.go new file mode 100644 index 000000000..96a03f02a --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/tokenstream_rewriter.go @@ -0,0 +1,649 @@ +// Copyright (c) 2012-2017 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" +) + + +// +// Useful for rewriting out a buffered input token stream after doing some +// augmentation or other manipulations on it. + +//

+// You can insert stuff, replace, and delete chunks. Note that the operations +// are done lazily--only if you convert the buffer to a {@link String} with +// {@link TokenStream#getText()}. This is very efficient because you are not +// moving data around all the time. As the buffer of tokens is converted to +// strings, the {@link #getText()} method(s) scan the input token stream and +// check to see if there is an operation at the current index. If so, the +// operation is done and then normal {@link String} rendering continues on the +// buffer. This is like having multiple Turing machine instruction streams +// (programs) operating on a single input tape. :)

+//

+ +// This rewriter makes no modifications to the token stream. It does not ask the +// stream to fill itself up nor does it advance the input cursor. The token +// stream {@link TokenStream#index()} will return the same value before and +// after any {@link #getText()} call.

+ +//

+// The rewriter only works on tokens that you have in the buffer and ignores the +// current input cursor. If you are buffering tokens on-demand, calling +// {@link #getText()} halfway through the input will only do rewrites for those +// tokens in the first half of the file.

+ +//

+// Since the operations are done lazily at {@link #getText}-time, operations do +// not screw up the token index values. That is, an insert operation at token +// index {@code i} does not change the index values for tokens +// {@code i}+1..n-1.

+ +//

+// Because operations never actually alter the buffer, you may always get the +// original token stream back without undoing anything. Since the instructions +// are queued up, you can easily simulate transactions and roll back any changes +// if there is an error just by removing instructions. For example,

+ +//
+// CharStream input = new ANTLRFileStream("input");
+// TLexer lex = new TLexer(input);
+// CommonTokenStream tokens = new CommonTokenStream(lex);
+// T parser = new T(tokens);
+// TokenStreamRewriter rewriter = new TokenStreamRewriter(tokens);
+// parser.startRule();
+// 
+ +//

+// Then in the rules, you can execute (assuming rewriter is visible):

+ +//
+// Token t,u;
+// ...
+// rewriter.insertAfter(t, "text to put after t");}
+// rewriter.insertAfter(u, "text after u");}
+// System.out.println(rewriter.getText());
+// 
+ +//

+// You can also have multiple "instruction streams" and get multiple rewrites +// from a single pass over the input. Just name the instruction streams and use +// that name again when printing the buffer. This could be useful for generating +// a C file and also its header file--all from the same buffer:

+ +//
+// rewriter.insertAfter("pass1", t, "text to put after t");}
+// rewriter.insertAfter("pass2", u, "text after u");}
+// System.out.println(rewriter.getText("pass1"));
+// System.out.println(rewriter.getText("pass2"));
+// 
+ +//

+// If you don't use named rewrite streams, a "default" stream is used as the +// first example shows.

+ + + +const( + Default_Program_Name = "default" + Program_Init_Size = 100 + Min_Token_Index = 0 +) + +// Define the rewrite operation hierarchy + +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 + SetInstructionIndex(val int) + SetIndex(int) + SetText(string) + SetOpName(string) + SetTokens(TokenStream) +} + +type BaseRewriteOperation struct { + //Current index of rewrites list + instruction_index int + //Token buffer index + index int + //Substitution text + text string + //Actual operation name + op_name string + //Pointer to token steam + tokens TokenStream +} + +func (op *BaseRewriteOperation)GetInstructionIndex() int{ + return op.instruction_index +} + +func (op *BaseRewriteOperation)GetIndex() int{ + return op.index +} + +func (op *BaseRewriteOperation)GetText() string{ + return op.text +} + +func (op *BaseRewriteOperation)GetOpName() string{ + return op.op_name +} + +func (op *BaseRewriteOperation)GetTokens() TokenStream{ + return op.tokens +} + +func (op *BaseRewriteOperation)SetInstructionIndex(val int){ + op.instruction_index = val +} + +func (op *BaseRewriteOperation)SetIndex(val int) { + op.index = val +} + +func (op *BaseRewriteOperation)SetText(val string){ + op.text = val +} + +func (op *BaseRewriteOperation)SetOpName(val string){ + op.op_name = val +} + +func (op *BaseRewriteOperation)SetTokens(val TokenStream) { + op.tokens = val +} + + +func (op *BaseRewriteOperation) Execute(buffer *bytes.Buffer) int{ + return op.index +} + +func (op *BaseRewriteOperation) String() string { + return fmt.Sprintf("<%s@%d:\"%s\">", + op.op_name, + op.tokens.Get(op.GetIndex()), + op.text, + ) + +} + + +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 (op *InsertBeforeOp) Execute(buffer *bytes.Buffer) int{ + buffer.WriteString(op.text) + if op.tokens.Get(op.index).GetTokenType() != TokenEOF{ + buffer.WriteString(op.tokens.Get(op.index).GetText()) + } + return op.index+1 +} + +func (op *InsertBeforeOp) String() string { + return op.BaseRewriteOperation.String() +} + +// Distinguish between insert after/before to do the "insert afters" +// first and then the "insert befores" at same index. Implementation +// of "insert after" is "insert before index+1". + +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 (op *InsertAfterOp) Execute(buffer *bytes.Buffer) int { + buffer.WriteString(op.text) + if op.tokens.Get(op.index).GetTokenType() != TokenEOF{ + buffer.WriteString(op.tokens.Get(op.index).GetText()) + } + return op.index+1 +} + +func (op *InsertAfterOp) String() string { + return op.BaseRewriteOperation.String() +} + +// I'm going to try replacing range from x..y with (y-x)+1 ReplaceOp +// instructions. +type ReplaceOp struct{ + BaseRewriteOperation + LastIndex int +} + +func NewReplaceOp(from, to int, text string, stream TokenStream)*ReplaceOp { + return &ReplaceOp{ + BaseRewriteOperation:BaseRewriteOperation{ + index:from, + text:text, + op_name:"ReplaceOp", + tokens:stream, + }, + LastIndex:to, + } +} + +func (op *ReplaceOp)Execute(buffer *bytes.Buffer) int{ + if op.text != ""{ + buffer.WriteString(op.text) + } + return op.LastIndex +1 +} + +func (op *ReplaceOp) String() string { + if op.text == "" { + return fmt.Sprintf("", + op.tokens.Get(op.index), op.tokens.Get(op.LastIndex)) + } + return fmt.Sprintf("", + op.tokens.Get(op.index), op.tokens.Get(op.LastIndex), op.text) +} + + +type TokenStreamRewriter struct { + //Our source stream + 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 +} + +func NewTokenStreamRewriter(tokens TokenStream) *TokenStreamRewriter{ + return &TokenStreamRewriter{ + tokens: tokens, + programs: map[string][]RewriteOperation{ + Default_Program_Name:make([]RewriteOperation,0, Program_Init_Size), + }, + last_rewrite_token_indexes: map[string]int{}, + } +} + +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{ + tsr.programs[program_name] = is[Min_Token_Index:instruction_index] + } +} + +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){ + tsr.Rollback(program_name, Min_Token_Index) //TODO: double test on that cause lower bound is not included +} + +func (tsr *TokenStreamRewriter) DeleteProgramDefault(){ + tsr.DeleteProgram(Default_Program_Name) +} + +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) + op.SetInstructionIndex(len(rewrites)) + tsr.AddToProgram(program_name, op) +} + +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){ + tsr.InsertAfter(program_name, token.GetTokenIndex(), text) +} + +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){ + tsr.InsertBefore(Default_Program_Name, index, text) +} + +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(){ + panic(fmt.Sprintf("replace: range invalid: %d..%d(size=%d)", + from, to, tsr.tokens.Size())) + } + var op RewriteOperation = NewReplaceOp(from, to, text, tsr.tokens) + rewrites := tsr.GetProgram(program_name) + op.SetInstructionIndex(len(rewrites)) + tsr.AddToProgram(program_name, op) +} + +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){ + tsr.ReplaceDefault(index, index, text) +} + +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){ + tsr.ReplaceToken(Default_Program_Name, from, to, text) +} + +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)DeleteDefault(from, to int){ + tsr.Delete(Default_Program_Name, from, to) +} + +func (tsr *TokenStreamRewriter)DeleteDefaultPos(index int){ + tsr.DeleteDefault(index,index) +} + +func (tsr *TokenStreamRewriter)DeleteToken(program_name string, from, to Token) { + tsr.ReplaceToken(program_name, from, to, "") +} + +func (tsr *TokenStreamRewriter)DeleteTokenDefault(from,to Token){ + tsr.DeleteToken(Default_Program_Name, from, to) +} + +func (tsr *TokenStreamRewriter)GetLastRewriteTokenIndex(program_name string)int { + i, ok := tsr.last_rewrite_token_indexes[program_name] + if !ok{ + return -1 + } + return i +} + +func (tsr *TokenStreamRewriter)GetLastRewriteTokenIndexDefault()int{ + return tsr.GetLastRewriteTokenIndex(Default_Program_Name) +} + +func (tsr *TokenStreamRewriter)SetLastRewriteTokenIndex(program_name string, i int){ + tsr.last_rewrite_token_indexes[program_name] = i +} + +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){ + is := tsr.GetProgram(name) + is = append(is, op) + tsr.programs[name] = is +} + +func (tsr *TokenStreamRewriter)GetProgram(name string) []RewriteOperation { + is, ok := tsr.programs[name] + 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 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 { + rewrites := tsr.programs[program_name] + start := interval.Start + 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{ + 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())} + } + } + 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: +// +// 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 +// +// 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 = 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: +// +// 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: +// +// 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. +// +// 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{ + // WALK REPLACES + for i:=0; i < len(rewrites); i++{ + op := rewrites[i] + if op == nil{continue} + rop, ok := op.(*ReplaceOp) + if !ok{continue} + // Wipe prior inserts within range + for j:=0; j 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{ + // delete replace as it's a no-op. + rewrites[prevop.instruction_index] = nil + continue + } + // throw exception unless disjoint or identical + 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{ + 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{ + panic("replace op boundaries of " + rop.String() + " overlap with previous " + prevop.String()) + } + } + } + } + // WALK INSERTS + for i:=0; i < len(rewrites); i++ { + op := rewrites[i] + if op == nil{continue} + //hack to replicate inheritance in composition + _, iok := rewrites[i].(*InsertBeforeOp) + _, aok := rewrites[i].(*InsertAfterOp) + 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()) + } + } + } + } + m := map[int]RewriteOperation{} + for i:=0; i < len(rewrites); i++{ + op := rewrites[i] + if op == nil {continue} + if _, ok := m[op.GetIndex()]; ok{ + panic("should only be one op per index") + } + m[op.GetIndex()] = op + } + return m +} + + +/* + Quick fixing Go lack of overloads + */ + +func max(a,b int)int{ + if a>b{ + return a + }else { + return b + } +} +func min(a,b int)int{ + if aThis is a one way link. It emanates from a state (usually via a list of +// transitions) and has a target state.

+// +//

Since we never have to change the ATN transitions once we construct it, +// the states. We'll use the term Edge for the DFA to distinguish them from +// ATN transitions.

+ +type Transition interface { + getTarget() ATNState + setTarget(ATNState) + getIsEpsilon() bool + getLabel() *IntervalSet + getSerializationType() int + Matches(int, int, int) bool +} + +type BaseTransition struct { + target ATNState + isEpsilon bool + label int + intervalSet *IntervalSet + serializationType int +} + +func NewBaseTransition(target ATNState) *BaseTransition { + + if target == nil { + panic("target cannot be nil.") + } + + t := new(BaseTransition) + + t.target = target + // Are we epsilon, action, sempred? + t.isEpsilon = false + t.intervalSet = nil + + return t +} + +func (t *BaseTransition) getTarget() ATNState { + return t.target +} + +func (t *BaseTransition) setTarget(s ATNState) { + t.target = s +} + +func (t *BaseTransition) getIsEpsilon() bool { + return t.isEpsilon +} + +func (t *BaseTransition) getLabel() *IntervalSet { + return t.intervalSet +} + +func (t *BaseTransition) getSerializationType() int { + return t.serializationType +} + +func (t *BaseTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { + panic("Not implemented") +} + +const ( + TransitionEPSILON = 1 + TransitionRANGE = 2 + TransitionRULE = 3 + TransitionPREDICATE = 4 // e.g., {isType(input.LT(1))}? + TransitionATOM = 5 + TransitionACTION = 6 + TransitionSET = 7 // ~(A|B) or ~atom, wildcard, which convert to next 2 + TransitionNOTSET = 8 + TransitionWILDCARD = 9 + TransitionPRECEDENCE = 10 +) + +var TransitionserializationNames = []string{ + "INVALID", + "EPSILON", + "RANGE", + "RULE", + "PREDICATE", + "ATOM", + "ACTION", + "SET", + "NOT_SET", + "WILDCARD", + "PRECEDENCE", +} + +//var TransitionserializationTypes struct { +// EpsilonTransition int +// RangeTransition int +// RuleTransition int +// PredicateTransition int +// AtomTransition int +// ActionTransition int +// SetTransition int +// NotSetTransition int +// WildcardTransition int +// PrecedencePredicateTransition int +//}{ +// TransitionEPSILON, +// TransitionRANGE, +// TransitionRULE, +// TransitionPREDICATE, +// TransitionATOM, +// TransitionACTION, +// TransitionSET, +// TransitionNOTSET, +// TransitionWILDCARD, +// TransitionPRECEDENCE +//} + +// TODO: make all transitions sets? no, should remove set edges +type AtomTransition struct { + *BaseTransition +} + +func NewAtomTransition(target ATNState, intervalSet int) *AtomTransition { + + t := new(AtomTransition) + t.BaseTransition = NewBaseTransition(target) + + t.label = intervalSet // The token type or character value or, signifies special intervalSet. + t.intervalSet = t.makeLabel() + t.serializationType = TransitionATOM + + return t +} + +func (t *AtomTransition) makeLabel() *IntervalSet { + s := NewIntervalSet() + s.addOne(t.label) + return s +} + +func (t *AtomTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { + return t.label == symbol +} + +func (t *AtomTransition) String() string { + return strconv.Itoa(t.label) +} + +type RuleTransition struct { + *BaseTransition + + followState ATNState + ruleIndex, precedence int +} + +func NewRuleTransition(ruleStart ATNState, ruleIndex, precedence int, followState ATNState) *RuleTransition { + + t := new(RuleTransition) + t.BaseTransition = NewBaseTransition(ruleStart) + + t.ruleIndex = ruleIndex + t.precedence = precedence + t.followState = followState + t.serializationType = TransitionRULE + t.isEpsilon = true + + return t +} + +func (t *RuleTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { + return false +} + +type EpsilonTransition struct { + *BaseTransition + + outermostPrecedenceReturn int +} + +func NewEpsilonTransition(target ATNState, outermostPrecedenceReturn int) *EpsilonTransition { + + t := new(EpsilonTransition) + t.BaseTransition = NewBaseTransition(target) + + t.serializationType = TransitionEPSILON + t.isEpsilon = true + t.outermostPrecedenceReturn = outermostPrecedenceReturn + return t +} + +func (t *EpsilonTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { + return false +} + +func (t *EpsilonTransition) String() string { + return "epsilon" +} + +type RangeTransition struct { + *BaseTransition + + start, stop int +} + +func NewRangeTransition(target ATNState, start, stop int) *RangeTransition { + + t := new(RangeTransition) + t.BaseTransition = NewBaseTransition(target) + + t.serializationType = TransitionRANGE + t.start = start + t.stop = stop + t.intervalSet = t.makeLabel() + return t +} + +func (t *RangeTransition) makeLabel() *IntervalSet { + s := NewIntervalSet() + s.addRange(t.start, t.stop) + return s +} + +func (t *RangeTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { + return symbol >= t.start && symbol <= t.stop +} + +func (t *RangeTransition) String() string { + return "'" + string(t.start) + "'..'" + string(t.stop) + "'" +} + +type AbstractPredicateTransition interface { + Transition + IAbstractPredicateTransitionFoo() +} + +type BaseAbstractPredicateTransition struct { + *BaseTransition +} + +func NewBasePredicateTransition(target ATNState) *BaseAbstractPredicateTransition { + + t := new(BaseAbstractPredicateTransition) + t.BaseTransition = NewBaseTransition(target) + + return t +} + +func (a *BaseAbstractPredicateTransition) IAbstractPredicateTransitionFoo() {} + +type PredicateTransition struct { + *BaseAbstractPredicateTransition + + isCtxDependent bool + ruleIndex, predIndex int +} + +func NewPredicateTransition(target ATNState, ruleIndex, predIndex int, isCtxDependent bool) *PredicateTransition { + + t := new(PredicateTransition) + t.BaseAbstractPredicateTransition = NewBasePredicateTransition(target) + + t.serializationType = TransitionPREDICATE + t.ruleIndex = ruleIndex + t.predIndex = predIndex + t.isCtxDependent = isCtxDependent // e.g., $i ref in pred + t.isEpsilon = true + return t +} + +func (t *PredicateTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { + return false +} + +func (t *PredicateTransition) getPredicate() *Predicate { + return NewPredicate(t.ruleIndex, t.predIndex, t.isCtxDependent) +} + +func (t *PredicateTransition) String() string { + return "pred_" + strconv.Itoa(t.ruleIndex) + ":" + strconv.Itoa(t.predIndex) +} + +type ActionTransition struct { + *BaseTransition + + isCtxDependent bool + ruleIndex, actionIndex, predIndex int +} + +func NewActionTransition(target ATNState, ruleIndex, actionIndex int, isCtxDependent bool) *ActionTransition { + + t := new(ActionTransition) + t.BaseTransition = NewBaseTransition(target) + + t.serializationType = TransitionACTION + t.ruleIndex = ruleIndex + t.actionIndex = actionIndex + t.isCtxDependent = isCtxDependent // e.g., $i ref in pred + t.isEpsilon = true + return t +} + +func (t *ActionTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { + return false +} + +func (t *ActionTransition) String() string { + return "action_" + strconv.Itoa(t.ruleIndex) + ":" + strconv.Itoa(t.actionIndex) +} + +type SetTransition struct { + *BaseTransition +} + +func NewSetTransition(target ATNState, set *IntervalSet) *SetTransition { + + t := new(SetTransition) + t.BaseTransition = NewBaseTransition(target) + + t.serializationType = TransitionSET + if set != nil { + t.intervalSet = set + } else { + t.intervalSet = NewIntervalSet() + t.intervalSet.addOne(TokenInvalidType) + } + + return t +} + +func (t *SetTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { + return t.intervalSet.contains(symbol) +} + +func (t *SetTransition) String() string { + return t.intervalSet.String() +} + +type NotSetTransition struct { + *SetTransition +} + +func NewNotSetTransition(target ATNState, set *IntervalSet) *NotSetTransition { + + t := new(NotSetTransition) + + t.SetTransition = NewSetTransition(target, set) + + t.serializationType = TransitionNOTSET + + return t +} + +func (t *NotSetTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { + return symbol >= minVocabSymbol && symbol <= maxVocabSymbol && !t.intervalSet.contains(symbol) +} + +func (t *NotSetTransition) String() string { + return "~" + t.intervalSet.String() +} + +type WildcardTransition struct { + *BaseTransition +} + +func NewWildcardTransition(target ATNState) *WildcardTransition { + + t := new(WildcardTransition) + t.BaseTransition = NewBaseTransition(target) + + t.serializationType = TransitionWILDCARD + return t +} + +func (t *WildcardTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { + return symbol >= minVocabSymbol && symbol <= maxVocabSymbol +} + +func (t *WildcardTransition) String() string { + return "." +} + +type PrecedencePredicateTransition struct { + *BaseAbstractPredicateTransition + + precedence int +} + +func NewPrecedencePredicateTransition(target ATNState, precedence int) *PrecedencePredicateTransition { + + t := new(PrecedencePredicateTransition) + t.BaseAbstractPredicateTransition = NewBasePredicateTransition(target) + + t.serializationType = TransitionPRECEDENCE + t.precedence = precedence + t.isEpsilon = true + + return t +} + +func (t *PrecedencePredicateTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bool { + return false +} + +func (t *PrecedencePredicateTransition) getPredicate() *PrecedencePredicate { + return NewPrecedencePredicate(t.precedence) +} + +func (t *PrecedencePredicateTransition) String() string { + return fmt.Sprint(t.precedence) + " >= _p" +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/tree.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/tree.go new file mode 100644 index 000000000..ad0eabf00 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/tree.go @@ -0,0 +1,251 @@ +// Copyright (c) 2012-2017 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 + +// The basic notion of a tree has a parent, a payload, and a list of children. +// It is the most abstract interface for all the trees used by ANTLR. +/// + +var TreeInvalidInterval = NewInterval(-1, -2) + +type Tree interface { + GetParent() Tree + SetParent(Tree) + GetPayload() interface{} + GetChild(i int) Tree + GetChildCount() int + GetChildren() []Tree +} + +type SyntaxTree interface { + Tree + + GetSourceInterval() *Interval +} + +type ParseTree interface { + SyntaxTree + + Accept(Visitor ParseTreeVisitor) interface{} + GetText() string + + ToStringTree([]string, Recognizer) string +} + +type RuleNode interface { + ParseTree + + GetRuleContext() RuleContext + GetBaseRuleContext() *BaseRuleContext +} + +type TerminalNode interface { + ParseTree + + GetSymbol() Token +} + +type ErrorNode interface { + TerminalNode + + errorNode() +} + +type ParseTreeVisitor interface { + Visit(tree ParseTree) interface{} + VisitChildren(node RuleNode) interface{} + VisitTerminal(node TerminalNode) interface{} + VisitErrorNode(node ErrorNode) interface{} +} + +type BaseParseTreeVisitor struct{} + +var _ ParseTreeVisitor = &BaseParseTreeVisitor{} + +func (v *BaseParseTreeVisitor) Visit(tree ParseTree) interface{} { return nil } +func (v *BaseParseTreeVisitor) VisitChildren(node RuleNode) interface{} { return nil } +func (v *BaseParseTreeVisitor) VisitTerminal(node TerminalNode) interface{} { return nil } +func (v *BaseParseTreeVisitor) VisitErrorNode(node ErrorNode) interface{} { return nil } + +// TODO +//func (this ParseTreeVisitor) Visit(ctx) { +// if (Utils.isArray(ctx)) { +// self := this +// return ctx.map(function(child) { return VisitAtom(self, child)}) +// } else { +// return VisitAtom(this, ctx) +// } +//} +// +//func VisitAtom(Visitor, ctx) { +// if (ctx.parser == nil) { //is terminal +// return +// } +// +// name := ctx.parser.ruleNames[ctx.ruleIndex] +// funcName := "Visit" + Utils.titleCase(name) +// +// return Visitor[funcName](ctx) +//} + +type ParseTreeListener interface { + VisitTerminal(node TerminalNode) + VisitErrorNode(node ErrorNode) + EnterEveryRule(ctx ParserRuleContext) + ExitEveryRule(ctx ParserRuleContext) +} + +type BaseParseTreeListener struct{} + +var _ ParseTreeListener = &BaseParseTreeListener{} + +func (l *BaseParseTreeListener) VisitTerminal(node TerminalNode) {} +func (l *BaseParseTreeListener) VisitErrorNode(node ErrorNode) {} +func (l *BaseParseTreeListener) EnterEveryRule(ctx ParserRuleContext) {} +func (l *BaseParseTreeListener) ExitEveryRule(ctx ParserRuleContext) {} + +type TerminalNodeImpl struct { + parentCtx RuleContext + + symbol Token +} + +var _ TerminalNode = &TerminalNodeImpl{} + +func NewTerminalNodeImpl(symbol Token) *TerminalNodeImpl { + tn := new(TerminalNodeImpl) + + tn.parentCtx = nil + tn.symbol = symbol + + return tn +} + +func (t *TerminalNodeImpl) GetChild(i int) Tree { + return nil +} + +func (t *TerminalNodeImpl) GetChildren() []Tree { + return nil +} + +func (t *TerminalNodeImpl) SetChildren(tree []Tree) { + panic("Cannot set children on terminal node") +} + +func (t *TerminalNodeImpl) GetSymbol() Token { + return t.symbol +} + +func (t *TerminalNodeImpl) GetParent() Tree { + return t.parentCtx +} + +func (t *TerminalNodeImpl) SetParent(tree Tree) { + t.parentCtx = tree.(RuleContext) +} + +func (t *TerminalNodeImpl) GetPayload() interface{} { + return t.symbol +} + +func (t *TerminalNodeImpl) GetSourceInterval() *Interval { + if t.symbol == nil { + return TreeInvalidInterval + } + tokenIndex := t.symbol.GetTokenIndex() + return NewInterval(tokenIndex, tokenIndex) +} + +func (t *TerminalNodeImpl) GetChildCount() int { + return 0 +} + +func (t *TerminalNodeImpl) Accept(v ParseTreeVisitor) interface{} { + return v.VisitTerminal(t) +} + +func (t *TerminalNodeImpl) GetText() string { + return t.symbol.GetText() +} + +func (t *TerminalNodeImpl) String() string { + if t.symbol.GetTokenType() == TokenEOF { + return "" + } + + return t.symbol.GetText() +} + +func (t *TerminalNodeImpl) ToStringTree(s []string, r Recognizer) string { + return t.String() +} + +// Represents a token that was consumed during reSynchronization +// rather than during a valid Match operation. For example, +// we will create this kind of a node during single token insertion +// and deletion as well as during "consume until error recovery set" +// upon no viable alternative exceptions. + +type ErrorNodeImpl struct { + *TerminalNodeImpl +} + +var _ ErrorNode = &ErrorNodeImpl{} + +func NewErrorNodeImpl(token Token) *ErrorNodeImpl { + en := new(ErrorNodeImpl) + en.TerminalNodeImpl = NewTerminalNodeImpl(token) + return en +} + +func (e *ErrorNodeImpl) errorNode() {} + +func (e *ErrorNodeImpl) Accept(v ParseTreeVisitor) interface{} { + return v.VisitErrorNode(e) +} + +type ParseTreeWalker struct { +} + +func NewParseTreeWalker() *ParseTreeWalker { + return new(ParseTreeWalker) +} + +func (p *ParseTreeWalker) Walk(listener ParseTreeListener, t Tree) { + switch tt := t.(type) { + case ErrorNode: + listener.VisitErrorNode(tt) + case TerminalNode: + listener.VisitTerminal(tt) + default: + p.EnterRule(listener, t.(RuleNode)) + for i := 0; i < t.GetChildCount(); i++ { + child := t.GetChild(i) + p.Walk(listener, child) + } + p.ExitRule(listener, t.(RuleNode)) + } +} + +// +// The discovery of a rule node, involves sending two events: the generic +// {@link ParseTreeListener//EnterEveryRule} and a +// {@link RuleContext}-specific event. First we trigger the generic and then +// the rule specific. We to them in reverse order upon finishing the node. +// +func (p *ParseTreeWalker) EnterRule(listener ParseTreeListener, r RuleNode) { + ctx := r.GetRuleContext().(ParserRuleContext) + listener.EnterEveryRule(ctx) + ctx.EnterRule(listener) +} + +func (p *ParseTreeWalker) ExitRule(listener ParseTreeListener, r RuleNode) { + ctx := r.GetRuleContext().(ParserRuleContext) + ctx.ExitRule(listener) + listener.ExitEveryRule(ctx) +} + +var ParseTreeWalkerDefault = NewParseTreeWalker() diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/trees.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/trees.go new file mode 100644 index 000000000..80144ecad --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/trees.go @@ -0,0 +1,137 @@ +// Copyright (c) 2012-2017 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" + +/** A set of utility routines useful for all kinds of ANTLR trees. */ + +// Print out a whole tree in LISP form. {@link //getNodeText} is used on the +// node payloads to get the text for the nodes. Detect +// parse trees and extract data appropriately. +func TreesStringTree(tree Tree, ruleNames []string, recog Recognizer) string { + + if recog != nil { + ruleNames = recog.GetRuleNames() + } + + s := TreesGetNodeText(tree, ruleNames, nil) + + s = EscapeWhitespace(s, false) + c := tree.GetChildCount() + if c == 0 { + return s + } + res := "(" + s + " " + if c > 0 { + s = TreesStringTree(tree.GetChild(0), ruleNames, nil) + res += s + } + for i := 1; i < c; i++ { + s = TreesStringTree(tree.GetChild(i), ruleNames, nil) + res += (" " + s) + } + res += ")" + return res +} + +func TreesGetNodeText(t Tree, ruleNames []string, recog Parser) string { + if recog != nil { + ruleNames = recog.GetRuleNames() + } + + if ruleNames != nil { + switch t2 := t.(type) { + case RuleNode: + t3 := t2.GetRuleContext() + altNumber := t3.GetAltNumber() + + if altNumber != ATNInvalidAltNumber { + return fmt.Sprintf("%s:%d", ruleNames[t3.GetRuleIndex()], altNumber) + } + return ruleNames[t3.GetRuleIndex()] + case ErrorNode: + return fmt.Sprint(t2) + case TerminalNode: + if t2.GetSymbol() != nil { + return t2.GetSymbol().GetText() + } + } + } + + // no recog for rule names + payload := t.GetPayload() + if p2, ok := payload.(Token); ok { + return p2.GetText() + } + + return fmt.Sprint(t.GetPayload()) +} + +// Return ordered list of all children of this node +func TreesGetChildren(t Tree) []Tree { + list := make([]Tree, 0) + for i := 0; i < t.GetChildCount(); i++ { + list = append(list, t.GetChild(i)) + } + return list +} + +// Return a list of all ancestors of this node. The first node of +// list is the root and the last is the parent of this node. +// +func TreesgetAncestors(t Tree) []Tree { + ancestors := make([]Tree, 0) + t = t.GetParent() + for t != nil { + f := []Tree{t} + ancestors = append(f, ancestors...) + t = t.GetParent() + } + return ancestors +} + +func TreesFindAllTokenNodes(t ParseTree, ttype int) []ParseTree { + return TreesfindAllNodes(t, ttype, true) +} + +func TreesfindAllRuleNodes(t ParseTree, ruleIndex int) []ParseTree { + return TreesfindAllNodes(t, ruleIndex, false) +} + +func TreesfindAllNodes(t ParseTree, index int, findTokens bool) []ParseTree { + nodes := make([]ParseTree, 0) + treesFindAllNodes(t, index, findTokens, &nodes) + return nodes +} + +func treesFindAllNodes(t ParseTree, index int, findTokens bool, nodes *[]ParseTree) { + // check this node (the root) first + + t2, ok := t.(TerminalNode) + t3, ok2 := t.(ParserRuleContext) + + if findTokens && ok { + if t2.GetSymbol().GetTokenType() == index { + *nodes = append(*nodes, t2) + } + } else if !findTokens && ok2 { + if t3.GetRuleIndex() == index { + *nodes = append(*nodes, t3) + } + } + // check children + for i := 0; i < t.GetChildCount(); i++ { + treesFindAllNodes(t.GetChild(i).(ParseTree), index, findTokens, nodes) + } +} + +func TreesDescendants(t ParseTree) []ParseTree { + nodes := []ParseTree{t} + for i := 0; i < t.GetChildCount(); i++ { + nodes = append(nodes, TreesDescendants(t.GetChild(i).(ParseTree))...) + } + return nodes +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/utils.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/utils.go new file mode 100644 index 000000000..bba2ffae7 --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/utils.go @@ -0,0 +1,417 @@ +// Copyright (c) 2012-2017 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" + "errors" + "fmt" + "sort" + "strconv" + "strings" +) + +func intMin(a, b int) int { + if a < b { + return a + } + return b +} + +func intMax(a, b int) int { + if a > b { + return a + } + return b +} + +// A simple integer stack + +type IntStack []int + +var ErrEmptyStack = errors.New("Stack is empty") + +func (s *IntStack) Pop() (int, error) { + l := len(*s) - 1 + if l < 0 { + return 0, ErrEmptyStack + } + v := (*s)[l] + *s = (*s)[0:l] + return v, nil +} + +func (s *IntStack) Push(e int) { + *s = append(*s, e) +} + +type Set struct { + data map[int][]interface{} + hashcodeFunction func(interface{}) int + equalsFunction func(interface{}, interface{}) bool +} + +func NewSet( + hashcodeFunction func(interface{}) int, + equalsFunction func(interface{}, interface{}) bool) *Set { + + s := new(Set) + + s.data = make(map[int][]interface{}) + + if hashcodeFunction != nil { + s.hashcodeFunction = hashcodeFunction + } else { + s.hashcodeFunction = standardHashFunction + } + + if equalsFunction == nil { + s.equalsFunction = standardEqualsFunction + } else { + s.equalsFunction = equalsFunction + } + + return s +} + +func standardEqualsFunction(a interface{}, b interface{}) bool { + + ac, oka := a.(comparable) + bc, okb := b.(comparable) + + if !oka || !okb { + panic("Not Comparable") + } + + return ac.equals(bc) +} + +func standardHashFunction(a interface{}) int { + if h, ok := a.(hasher); ok { + return h.hash() + } + + panic("Not Hasher") +} + +type hasher interface { + hash() int +} + +func (s *Set) length() int { + return len(s.data) +} + +func (s *Set) add(value interface{}) interface{} { + + key := s.hashcodeFunction(value) + + values := s.data[key] + + if s.data[key] != nil { + for i := 0; i < len(values); i++ { + if s.equalsFunction(value, values[i]) { + return values[i] + } + } + + s.data[key] = append(s.data[key], value) + return value + } + + v := make([]interface{}, 1, 10) + v[0] = value + s.data[key] = v + + return value +} + +func (s *Set) contains(value interface{}) bool { + + key := s.hashcodeFunction(value) + + values := s.data[key] + + if s.data[key] != nil { + for i := 0; i < len(values); i++ { + if s.equalsFunction(value, values[i]) { + return true + } + } + } + return false +} + +func (s *Set) values() []interface{} { + var l []interface{} + + for _, v := range s.data { + l = append(l, v...) + } + + return l +} + +func (s *Set) String() string { + r := "" + + for _, av := range s.data { + for _, v := range av { + r += fmt.Sprint(v) + } + } + + return r +} + +type BitSet struct { + data map[int]bool +} + +func NewBitSet() *BitSet { + b := new(BitSet) + b.data = make(map[int]bool) + return b +} + +func (b *BitSet) add(value int) { + b.data[value] = true +} + +func (b *BitSet) clear(index int) { + delete(b.data, index) +} + +func (b *BitSet) or(set *BitSet) { + for k := range set.data { + b.add(k) + } +} + +func (b *BitSet) remove(value int) { + delete(b.data, value) +} + +func (b *BitSet) contains(value int) bool { + return b.data[value] +} + +func (b *BitSet) values() []int { + ks := make([]int, len(b.data)) + i := 0 + for k := range b.data { + ks[i] = k + i++ + } + sort.Ints(ks) + return ks +} + +func (b *BitSet) minValue() int { + min := 2147483647 + + for k := range b.data { + if k < min { + min = k + } + } + + return min +} + +func (b *BitSet) equals(other interface{}) bool { + otherBitSet, ok := other.(*BitSet) + if !ok { + return false + } + + if len(b.data) != len(otherBitSet.data) { + return false + } + + for k, v := range b.data { + if otherBitSet.data[k] != v { + return false + } + } + + return true +} + +func (b *BitSet) length() int { + return len(b.data) +} + +func (b *BitSet) String() string { + vals := b.values() + valsS := make([]string, len(vals)) + + for i, val := range vals { + valsS[i] = strconv.Itoa(val) + } + return "{" + strings.Join(valsS, ", ") + "}" +} + +type AltDict struct { + data map[string]interface{} +} + +func NewAltDict() *AltDict { + d := new(AltDict) + d.data = make(map[string]interface{}) + return d +} + +func (a *AltDict) Get(key string) interface{} { + key = "k-" + key + return a.data[key] +} + +func (a *AltDict) put(key string, value interface{}) { + key = "k-" + key + a.data[key] = value +} + +func (a *AltDict) values() []interface{} { + vs := make([]interface{}, len(a.data)) + i := 0 + for _, v := range a.data { + vs[i] = v + i++ + } + return vs +} + +type DoubleDict struct { + data map[int]map[int]interface{} +} + +func NewDoubleDict() *DoubleDict { + dd := new(DoubleDict) + dd.data = make(map[int]map[int]interface{}) + return dd +} + +func (d *DoubleDict) Get(a, b int) interface{} { + data := d.data[a] + + if data == nil { + return nil + } + + return data[b] +} + +func (d *DoubleDict) set(a, b int, o interface{}) { + data := d.data[a] + + if data == nil { + data = make(map[int]interface{}) + d.data[a] = data + } + + data[b] = o +} + +func EscapeWhitespace(s string, escapeSpaces bool) string { + + s = strings.Replace(s, "\t", "\\t", -1) + s = strings.Replace(s, "\n", "\\n", -1) + s = strings.Replace(s, "\r", "\\r", -1) + if escapeSpaces { + s = strings.Replace(s, " ", "\u00B7", -1) + } + return s +} + +func TerminalNodeToStringArray(sa []TerminalNode) []string { + st := make([]string, len(sa)) + + for i, s := range sa { + st[i] = fmt.Sprintf("%v", s) + } + + return st +} + +func PrintArrayJavaStyle(sa []string) string { + var buffer bytes.Buffer + + buffer.WriteString("[") + + for i, s := range sa { + buffer.WriteString(s) + if i != len(sa)-1 { + buffer.WriteString(", ") + } + } + + buffer.WriteString("]") + + return buffer.String() +} + +// The following routines were lifted from bits.rotate* available in Go 1.9. + +const uintSize = 32 << (^uint(0) >> 32 & 1) // 32 or 64 + +// rotateLeft returns the value of x rotated left by (k mod UintSize) bits. +// To rotate x right by k bits, call RotateLeft(x, -k). +func rotateLeft(x uint, k int) uint { + if uintSize == 32 { + return uint(rotateLeft32(uint32(x), k)) + } + return uint(rotateLeft64(uint64(x), k)) +} + +// rotateLeft32 returns the value of x rotated left by (k mod 32) bits. +func rotateLeft32(x uint32, k int) uint32 { + const n = 32 + s := uint(k) & (n - 1) + return x<>(n-s) +} + +// rotateLeft64 returns the value of x rotated left by (k mod 64) bits. +func rotateLeft64(x uint64, k int) uint64 { + const n = 64 + s := uint(k) & (n - 1) + return x<>(n-s) +} + + +// murmur hash +const ( + c1_32 uint = 0xCC9E2D51 + c2_32 uint = 0x1B873593 + n1_32 uint = 0xE6546B64 +) + +func murmurInit(seed int) int { + return seed +} + +func murmurUpdate(h1 int, k1 int) int { + var k1u uint + k1u = uint(k1) * c1_32 + k1u = rotateLeft(k1u, 15) + k1u *= c2_32 + + var h1u = uint(h1) ^ k1u + k1u = rotateLeft(k1u, 13) + h1u = h1u*5 + 0xe6546b64 + return int(h1u) +} + +func murmurFinish(h1 int, numberOfWords int) int { + var h1u uint = uint(h1) + h1u ^= uint(numberOfWords * 4) + h1u ^= h1u >> 16 + h1u *= uint(0x85ebca6b) + h1u ^= h1u >> 13 + h1u *= 0xc2b2ae35 + h1u ^= h1u >> 16 + + return int(h1u) +} diff --git a/vendor/github.com/golang/protobuf/descriptor/descriptor.go b/vendor/github.com/golang/protobuf/descriptor/descriptor.go new file mode 100644 index 000000000..ac7e51bfb --- /dev/null +++ b/vendor/github.com/golang/protobuf/descriptor/descriptor.go @@ -0,0 +1,93 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2016 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +// Package descriptor provides functions for obtaining protocol buffer +// descriptors for generated Go types. +// +// These functions cannot go in package proto because they depend on the +// generated protobuf descriptor messages, which themselves depend on proto. +package descriptor + +import ( + "bytes" + "compress/gzip" + "fmt" + "io/ioutil" + + "github.com/golang/protobuf/proto" + protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor" +) + +// extractFile extracts a FileDescriptorProto from a gzip'd buffer. +func extractFile(gz []byte) (*protobuf.FileDescriptorProto, error) { + r, err := gzip.NewReader(bytes.NewReader(gz)) + if err != nil { + return nil, fmt.Errorf("failed to open gzip reader: %v", err) + } + defer r.Close() + + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, fmt.Errorf("failed to uncompress descriptor: %v", err) + } + + fd := new(protobuf.FileDescriptorProto) + if err := proto.Unmarshal(b, fd); err != nil { + return nil, fmt.Errorf("malformed FileDescriptorProto: %v", err) + } + + return fd, nil +} + +// Message is a proto.Message with a method to return its descriptor. +// +// Message types generated by the protocol compiler always satisfy +// the Message interface. +type Message interface { + proto.Message + Descriptor() ([]byte, []int) +} + +// ForMessage returns a FileDescriptorProto and a DescriptorProto from within it +// describing the given message. +func ForMessage(msg Message) (fd *protobuf.FileDescriptorProto, md *protobuf.DescriptorProto) { + gz, path := msg.Descriptor() + fd, err := extractFile(gz) + if err != nil { + panic(fmt.Sprintf("invalid FileDescriptorProto for %T: %v", msg, err)) + } + + md = fd.MessageType[path[0]] + for _, i := range path[1:] { + md = md.NestedType[i] + } + return fd, md +} diff --git a/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go b/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go new file mode 100644 index 000000000..e9cc20258 --- /dev/null +++ b/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go @@ -0,0 +1,1284 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2015 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +/* +Package jsonpb provides marshaling and unmarshaling between protocol buffers and JSON. +It follows the specification at https://developers.google.com/protocol-buffers/docs/proto3#json. + +This package produces a different output than the standard "encoding/json" package, +which does not operate correctly on protocol buffers. +*/ +package jsonpb + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "math" + "reflect" + "sort" + "strconv" + "strings" + "time" + + "github.com/golang/protobuf/proto" + + stpb "github.com/golang/protobuf/ptypes/struct" +) + +const secondInNanos = int64(time.Second / time.Nanosecond) +const maxSecondsInDuration = 315576000000 + +// Marshaler is a configurable object for converting between +// protocol buffer objects and a JSON representation for them. +type Marshaler struct { + // Whether to render enum values as integers, as opposed to string values. + EnumsAsInts bool + + // Whether to render fields with zero values. + EmitDefaults bool + + // A string to indent each level by. The presence of this field will + // also cause a space to appear between the field separator and + // value, and for newlines to be appear between fields and array + // elements. + Indent string + + // Whether to use the original (.proto) name for fields. + OrigName bool + + // A custom URL resolver to use when marshaling Any messages to JSON. + // If unset, the default resolution strategy is to extract the + // fully-qualified type name from the type URL and pass that to + // proto.MessageType(string). + AnyResolver AnyResolver +} + +// AnyResolver takes a type URL, present in an Any message, and resolves it into +// an instance of the associated message. +type AnyResolver interface { + Resolve(typeUrl string) (proto.Message, error) +} + +func defaultResolveAny(typeUrl string) (proto.Message, error) { + // Only the part of typeUrl after the last slash is relevant. + mname := typeUrl + if slash := strings.LastIndex(mname, "/"); slash >= 0 { + mname = mname[slash+1:] + } + mt := proto.MessageType(mname) + if mt == nil { + return nil, fmt.Errorf("unknown message type %q", mname) + } + return reflect.New(mt.Elem()).Interface().(proto.Message), nil +} + +// JSONPBMarshaler is implemented by protobuf messages that customize the +// way they are marshaled to JSON. Messages that implement this should +// also implement JSONPBUnmarshaler so that the custom format can be +// parsed. +// +// The JSON marshaling must follow the proto to JSON specification: +// https://developers.google.com/protocol-buffers/docs/proto3#json +type JSONPBMarshaler interface { + MarshalJSONPB(*Marshaler) ([]byte, error) +} + +// JSONPBUnmarshaler is implemented by protobuf messages that customize +// the way they are unmarshaled from JSON. Messages that implement this +// should also implement JSONPBMarshaler so that the custom format can be +// produced. +// +// The JSON unmarshaling must follow the JSON to proto specification: +// https://developers.google.com/protocol-buffers/docs/proto3#json +type JSONPBUnmarshaler interface { + UnmarshalJSONPB(*Unmarshaler, []byte) error +} + +// Marshal marshals a protocol buffer into JSON. +func (m *Marshaler) Marshal(out io.Writer, pb proto.Message) error { + v := reflect.ValueOf(pb) + if pb == nil || (v.Kind() == reflect.Ptr && v.IsNil()) { + return errors.New("Marshal called with nil") + } + // Check for unset required fields first. + if err := checkRequiredFields(pb); err != nil { + return err + } + writer := &errWriter{writer: out} + return m.marshalObject(writer, pb, "", "") +} + +// MarshalToString converts a protocol buffer object to JSON string. +func (m *Marshaler) MarshalToString(pb proto.Message) (string, error) { + var buf bytes.Buffer + if err := m.Marshal(&buf, pb); err != nil { + return "", err + } + return buf.String(), nil +} + +type int32Slice []int32 + +var nonFinite = map[string]float64{ + `"NaN"`: math.NaN(), + `"Infinity"`: math.Inf(1), + `"-Infinity"`: math.Inf(-1), +} + +// For sorting extensions ids to ensure stable output. +func (s int32Slice) Len() int { return len(s) } +func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } +func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +type wkt interface { + XXX_WellKnownType() string +} + +// marshalObject writes a struct to the Writer. +func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent, typeURL string) error { + if jsm, ok := v.(JSONPBMarshaler); ok { + b, err := jsm.MarshalJSONPB(m) + if err != nil { + return err + } + if typeURL != "" { + // we are marshaling this object to an Any type + var js map[string]*json.RawMessage + if err = json.Unmarshal(b, &js); err != nil { + return fmt.Errorf("type %T produced invalid JSON: %v", v, err) + } + turl, err := json.Marshal(typeURL) + if err != nil { + return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err) + } + js["@type"] = (*json.RawMessage)(&turl) + if m.Indent != "" { + b, err = json.MarshalIndent(js, indent, m.Indent) + } else { + b, err = json.Marshal(js) + } + if err != nil { + return err + } + } + + out.write(string(b)) + return out.err + } + + s := reflect.ValueOf(v).Elem() + + // Handle well-known types. + if wkt, ok := v.(wkt); ok { + switch wkt.XXX_WellKnownType() { + case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value", + "Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue": + // "Wrappers use the same representation in JSON + // as the wrapped primitive type, ..." + sprop := proto.GetProperties(s.Type()) + return m.marshalValue(out, sprop.Prop[0], s.Field(0), indent) + case "Any": + // Any is a bit more involved. + return m.marshalAny(out, v, indent) + case "Duration": + s, ns := s.Field(0).Int(), s.Field(1).Int() + if s < -maxSecondsInDuration || s > maxSecondsInDuration { + return fmt.Errorf("seconds out of range %v", s) + } + if ns <= -secondInNanos || ns >= secondInNanos { + return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos) + } + if (s > 0 && ns < 0) || (s < 0 && ns > 0) { + return errors.New("signs of seconds and nanos do not match") + } + // Generated output always contains 0, 3, 6, or 9 fractional digits, + // depending on required precision, followed by the suffix "s". + f := "%d.%09d" + if ns < 0 { + ns = -ns + if s == 0 { + f = "-%d.%09d" + } + } + x := fmt.Sprintf(f, s, ns) + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, ".000") + out.write(`"`) + out.write(x) + out.write(`s"`) + return out.err + case "Struct", "ListValue": + // Let marshalValue handle the `Struct.fields` map or the `ListValue.values` slice. + // TODO: pass the correct Properties if needed. + return m.marshalValue(out, &proto.Properties{}, s.Field(0), indent) + case "Timestamp": + // "RFC 3339, where generated output will always be Z-normalized + // and uses 0, 3, 6 or 9 fractional digits." + s, ns := s.Field(0).Int(), s.Field(1).Int() + if ns < 0 || ns >= secondInNanos { + return fmt.Errorf("ns out of range [0, %v)", secondInNanos) + } + t := time.Unix(s, ns).UTC() + // time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits). + x := t.Format("2006-01-02T15:04:05.000000000") + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, ".000") + out.write(`"`) + out.write(x) + out.write(`Z"`) + return out.err + case "Value": + // Value has a single oneof. + kind := s.Field(0) + if kind.IsNil() { + // "absence of any variant indicates an error" + return errors.New("nil Value") + } + // oneof -> *T -> T -> T.F + x := kind.Elem().Elem().Field(0) + // TODO: pass the correct Properties if needed. + return m.marshalValue(out, &proto.Properties{}, x, indent) + } + } + + out.write("{") + if m.Indent != "" { + out.write("\n") + } + + firstField := true + + if typeURL != "" { + if err := m.marshalTypeURL(out, indent, typeURL); err != nil { + return err + } + firstField = false + } + + for i := 0; i < s.NumField(); i++ { + value := s.Field(i) + valueField := s.Type().Field(i) + if strings.HasPrefix(valueField.Name, "XXX_") { + continue + } + + // IsNil will panic on most value kinds. + switch value.Kind() { + case reflect.Chan, reflect.Func, reflect.Interface: + if value.IsNil() { + continue + } + } + + if !m.EmitDefaults { + switch value.Kind() { + case reflect.Bool: + if !value.Bool() { + continue + } + case reflect.Int32, reflect.Int64: + if value.Int() == 0 { + continue + } + case reflect.Uint32, reflect.Uint64: + if value.Uint() == 0 { + continue + } + case reflect.Float32, reflect.Float64: + if value.Float() == 0 { + continue + } + case reflect.String: + if value.Len() == 0 { + continue + } + case reflect.Map, reflect.Ptr, reflect.Slice: + if value.IsNil() { + continue + } + } + } + + // Oneof fields need special handling. + if valueField.Tag.Get("protobuf_oneof") != "" { + // value is an interface containing &T{real_value}. + sv := value.Elem().Elem() // interface -> *T -> T + value = sv.Field(0) + valueField = sv.Type().Field(0) + } + prop := jsonProperties(valueField, m.OrigName) + if !firstField { + m.writeSep(out) + } + if err := m.marshalField(out, prop, value, indent); err != nil { + return err + } + firstField = false + } + + // Handle proto2 extensions. + if ep, ok := v.(proto.Message); ok { + extensions := proto.RegisteredExtensions(v) + // Sort extensions for stable output. + ids := make([]int32, 0, len(extensions)) + for id, desc := range extensions { + if !proto.HasExtension(ep, desc) { + continue + } + ids = append(ids, id) + } + sort.Sort(int32Slice(ids)) + for _, id := range ids { + desc := extensions[id] + if desc == nil { + // unknown extension + continue + } + ext, extErr := proto.GetExtension(ep, desc) + if extErr != nil { + return extErr + } + value := reflect.ValueOf(ext) + var prop proto.Properties + prop.Parse(desc.Tag) + prop.JSONName = fmt.Sprintf("[%s]", desc.Name) + if !firstField { + m.writeSep(out) + } + if err := m.marshalField(out, &prop, value, indent); err != nil { + return err + } + firstField = false + } + + } + + if m.Indent != "" { + out.write("\n") + out.write(indent) + } + out.write("}") + return out.err +} + +func (m *Marshaler) writeSep(out *errWriter) { + if m.Indent != "" { + out.write(",\n") + } else { + out.write(",") + } +} + +func (m *Marshaler) marshalAny(out *errWriter, any proto.Message, indent string) error { + // "If the Any contains a value that has a special JSON mapping, + // it will be converted as follows: {"@type": xxx, "value": yyy}. + // Otherwise, the value will be converted into a JSON object, + // and the "@type" field will be inserted to indicate the actual data type." + v := reflect.ValueOf(any).Elem() + turl := v.Field(0).String() + val := v.Field(1).Bytes() + + var msg proto.Message + var err error + if m.AnyResolver != nil { + msg, err = m.AnyResolver.Resolve(turl) + } else { + msg, err = defaultResolveAny(turl) + } + if err != nil { + return err + } + + if err := proto.Unmarshal(val, msg); err != nil { + return err + } + + if _, ok := msg.(wkt); ok { + out.write("{") + if m.Indent != "" { + out.write("\n") + } + if err := m.marshalTypeURL(out, indent, turl); err != nil { + return err + } + m.writeSep(out) + if m.Indent != "" { + out.write(indent) + out.write(m.Indent) + out.write(`"value": `) + } else { + out.write(`"value":`) + } + if err := m.marshalObject(out, msg, indent+m.Indent, ""); err != nil { + return err + } + if m.Indent != "" { + out.write("\n") + out.write(indent) + } + out.write("}") + return out.err + } + + return m.marshalObject(out, msg, indent, turl) +} + +func (m *Marshaler) marshalTypeURL(out *errWriter, indent, typeURL string) error { + if m.Indent != "" { + out.write(indent) + out.write(m.Indent) + } + out.write(`"@type":`) + if m.Indent != "" { + out.write(" ") + } + b, err := json.Marshal(typeURL) + if err != nil { + return err + } + out.write(string(b)) + return out.err +} + +// marshalField writes field description and value to the Writer. +func (m *Marshaler) marshalField(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error { + if m.Indent != "" { + out.write(indent) + out.write(m.Indent) + } + out.write(`"`) + out.write(prop.JSONName) + out.write(`":`) + if m.Indent != "" { + out.write(" ") + } + if err := m.marshalValue(out, prop, v, indent); err != nil { + return err + } + return nil +} + +// marshalValue writes the value to the Writer. +func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error { + var err error + v = reflect.Indirect(v) + + // Handle nil pointer + if v.Kind() == reflect.Invalid { + out.write("null") + return out.err + } + + // Handle repeated elements. + if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 { + out.write("[") + comma := "" + for i := 0; i < v.Len(); i++ { + sliceVal := v.Index(i) + out.write(comma) + if m.Indent != "" { + out.write("\n") + out.write(indent) + out.write(m.Indent) + out.write(m.Indent) + } + if err := m.marshalValue(out, prop, sliceVal, indent+m.Indent); err != nil { + return err + } + comma = "," + } + if m.Indent != "" { + out.write("\n") + out.write(indent) + out.write(m.Indent) + } + out.write("]") + return out.err + } + + // Handle well-known types. + // Most are handled up in marshalObject (because 99% are messages). + if wkt, ok := v.Interface().(wkt); ok { + switch wkt.XXX_WellKnownType() { + case "NullValue": + out.write("null") + return out.err + } + } + + // Handle enumerations. + if !m.EnumsAsInts && prop.Enum != "" { + // Unknown enum values will are stringified by the proto library as their + // value. Such values should _not_ be quoted or they will be interpreted + // as an enum string instead of their value. + enumStr := v.Interface().(fmt.Stringer).String() + var valStr string + if v.Kind() == reflect.Ptr { + valStr = strconv.Itoa(int(v.Elem().Int())) + } else { + valStr = strconv.Itoa(int(v.Int())) + } + isKnownEnum := enumStr != valStr + if isKnownEnum { + out.write(`"`) + } + out.write(enumStr) + if isKnownEnum { + out.write(`"`) + } + return out.err + } + + // Handle nested messages. + if v.Kind() == reflect.Struct { + return m.marshalObject(out, v.Addr().Interface().(proto.Message), indent+m.Indent, "") + } + + // Handle maps. + // Since Go randomizes map iteration, we sort keys for stable output. + if v.Kind() == reflect.Map { + out.write(`{`) + keys := v.MapKeys() + sort.Sort(mapKeys(keys)) + for i, k := range keys { + if i > 0 { + out.write(`,`) + } + if m.Indent != "" { + out.write("\n") + out.write(indent) + out.write(m.Indent) + out.write(m.Indent) + } + + // TODO handle map key prop properly + b, err := json.Marshal(k.Interface()) + if err != nil { + return err + } + s := string(b) + + // If the JSON is not a string value, encode it again to make it one. + if !strings.HasPrefix(s, `"`) { + b, err := json.Marshal(s) + if err != nil { + return err + } + s = string(b) + } + + out.write(s) + out.write(`:`) + if m.Indent != "" { + out.write(` `) + } + + vprop := prop + if prop != nil && prop.MapValProp != nil { + vprop = prop.MapValProp + } + if err := m.marshalValue(out, vprop, v.MapIndex(k), indent+m.Indent); err != nil { + return err + } + } + if m.Indent != "" { + out.write("\n") + out.write(indent) + out.write(m.Indent) + } + out.write(`}`) + return out.err + } + + // Handle non-finite floats, e.g. NaN, Infinity and -Infinity. + if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 { + f := v.Float() + var sval string + switch { + case math.IsInf(f, 1): + sval = `"Infinity"` + case math.IsInf(f, -1): + sval = `"-Infinity"` + case math.IsNaN(f): + sval = `"NaN"` + } + if sval != "" { + out.write(sval) + return out.err + } + } + + // Default handling defers to the encoding/json library. + b, err := json.Marshal(v.Interface()) + if err != nil { + return err + } + needToQuote := string(b[0]) != `"` && (v.Kind() == reflect.Int64 || v.Kind() == reflect.Uint64) + if needToQuote { + out.write(`"`) + } + out.write(string(b)) + if needToQuote { + out.write(`"`) + } + return out.err +} + +// Unmarshaler is a configurable object for converting from a JSON +// representation to a protocol buffer object. +type Unmarshaler struct { + // Whether to allow messages to contain unknown fields, as opposed to + // failing to unmarshal. + AllowUnknownFields bool + + // A custom URL resolver to use when unmarshaling Any messages from JSON. + // If unset, the default resolution strategy is to extract the + // fully-qualified type name from the type URL and pass that to + // proto.MessageType(string). + AnyResolver AnyResolver +} + +// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream. +// This function is lenient and will decode any options permutations of the +// related Marshaler. +func (u *Unmarshaler) UnmarshalNext(dec *json.Decoder, pb proto.Message) error { + inputValue := json.RawMessage{} + if err := dec.Decode(&inputValue); err != nil { + return err + } + if err := u.unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue, nil); err != nil { + return err + } + return checkRequiredFields(pb) +} + +// Unmarshal unmarshals a JSON object stream into a protocol +// buffer. This function is lenient and will decode any options +// permutations of the related Marshaler. +func (u *Unmarshaler) Unmarshal(r io.Reader, pb proto.Message) error { + dec := json.NewDecoder(r) + return u.UnmarshalNext(dec, pb) +} + +// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream. +// This function is lenient and will decode any options permutations of the +// related Marshaler. +func UnmarshalNext(dec *json.Decoder, pb proto.Message) error { + return new(Unmarshaler).UnmarshalNext(dec, pb) +} + +// Unmarshal unmarshals a JSON object stream into a protocol +// buffer. This function is lenient and will decode any options +// permutations of the related Marshaler. +func Unmarshal(r io.Reader, pb proto.Message) error { + return new(Unmarshaler).Unmarshal(r, pb) +} + +// UnmarshalString will populate the fields of a protocol buffer based +// on a JSON string. This function is lenient and will decode any options +// permutations of the related Marshaler. +func UnmarshalString(str string, pb proto.Message) error { + return new(Unmarshaler).Unmarshal(strings.NewReader(str), pb) +} + +// unmarshalValue converts/copies a value into the target. +// prop may be nil. +func (u *Unmarshaler) unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *proto.Properties) error { + targetType := target.Type() + + // Allocate memory for pointer fields. + if targetType.Kind() == reflect.Ptr { + // If input value is "null" and target is a pointer type, then the field should be treated as not set + // UNLESS the target is structpb.Value, in which case it should be set to structpb.NullValue. + _, isJSONPBUnmarshaler := target.Interface().(JSONPBUnmarshaler) + if string(inputValue) == "null" && targetType != reflect.TypeOf(&stpb.Value{}) && !isJSONPBUnmarshaler { + return nil + } + target.Set(reflect.New(targetType.Elem())) + + return u.unmarshalValue(target.Elem(), inputValue, prop) + } + + if jsu, ok := target.Addr().Interface().(JSONPBUnmarshaler); ok { + return jsu.UnmarshalJSONPB(u, []byte(inputValue)) + } + + // Handle well-known types that are not pointers. + if w, ok := target.Addr().Interface().(wkt); ok { + switch w.XXX_WellKnownType() { + case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value", + "Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue": + return u.unmarshalValue(target.Field(0), inputValue, prop) + case "Any": + // Use json.RawMessage pointer type instead of value to support pre-1.8 version. + // 1.8 changed RawMessage.MarshalJSON from pointer type to value type, see + // https://github.com/golang/go/issues/14493 + var jsonFields map[string]*json.RawMessage + if err := json.Unmarshal(inputValue, &jsonFields); err != nil { + return err + } + + val, ok := jsonFields["@type"] + if !ok || val == nil { + return errors.New("Any JSON doesn't have '@type'") + } + + var turl string + if err := json.Unmarshal([]byte(*val), &turl); err != nil { + return fmt.Errorf("can't unmarshal Any's '@type': %q", *val) + } + target.Field(0).SetString(turl) + + var m proto.Message + var err error + if u.AnyResolver != nil { + m, err = u.AnyResolver.Resolve(turl) + } else { + m, err = defaultResolveAny(turl) + } + if err != nil { + return err + } + + if _, ok := m.(wkt); ok { + val, ok := jsonFields["value"] + if !ok { + return errors.New("Any JSON doesn't have 'value'") + } + + if err := u.unmarshalValue(reflect.ValueOf(m).Elem(), *val, nil); err != nil { + return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err) + } + } else { + delete(jsonFields, "@type") + nestedProto, err := json.Marshal(jsonFields) + if err != nil { + return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err) + } + + if err = u.unmarshalValue(reflect.ValueOf(m).Elem(), nestedProto, nil); err != nil { + return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err) + } + } + + b, err := proto.Marshal(m) + if err != nil { + return fmt.Errorf("can't marshal proto %T into Any.Value: %v", m, err) + } + target.Field(1).SetBytes(b) + + return nil + case "Duration": + unq, err := unquote(string(inputValue)) + if err != nil { + return err + } + + d, err := time.ParseDuration(unq) + if err != nil { + return fmt.Errorf("bad Duration: %v", err) + } + + ns := d.Nanoseconds() + s := ns / 1e9 + ns %= 1e9 + target.Field(0).SetInt(s) + target.Field(1).SetInt(ns) + return nil + case "Timestamp": + unq, err := unquote(string(inputValue)) + if err != nil { + return err + } + + t, err := time.Parse(time.RFC3339Nano, unq) + if err != nil { + return fmt.Errorf("bad Timestamp: %v", err) + } + + target.Field(0).SetInt(t.Unix()) + target.Field(1).SetInt(int64(t.Nanosecond())) + return nil + case "Struct": + var m map[string]json.RawMessage + if err := json.Unmarshal(inputValue, &m); err != nil { + return fmt.Errorf("bad StructValue: %v", err) + } + + target.Field(0).Set(reflect.ValueOf(map[string]*stpb.Value{})) + for k, jv := range m { + pv := &stpb.Value{} + if err := u.unmarshalValue(reflect.ValueOf(pv).Elem(), jv, prop); err != nil { + return fmt.Errorf("bad value in StructValue for key %q: %v", k, err) + } + target.Field(0).SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(pv)) + } + return nil + case "ListValue": + var s []json.RawMessage + if err := json.Unmarshal(inputValue, &s); err != nil { + return fmt.Errorf("bad ListValue: %v", err) + } + + target.Field(0).Set(reflect.ValueOf(make([]*stpb.Value, len(s)))) + for i, sv := range s { + if err := u.unmarshalValue(target.Field(0).Index(i), sv, prop); err != nil { + return err + } + } + return nil + case "Value": + ivStr := string(inputValue) + if ivStr == "null" { + target.Field(0).Set(reflect.ValueOf(&stpb.Value_NullValue{})) + } else if v, err := strconv.ParseFloat(ivStr, 0); err == nil { + target.Field(0).Set(reflect.ValueOf(&stpb.Value_NumberValue{v})) + } else if v, err := unquote(ivStr); err == nil { + target.Field(0).Set(reflect.ValueOf(&stpb.Value_StringValue{v})) + } else if v, err := strconv.ParseBool(ivStr); err == nil { + target.Field(0).Set(reflect.ValueOf(&stpb.Value_BoolValue{v})) + } else if err := json.Unmarshal(inputValue, &[]json.RawMessage{}); err == nil { + lv := &stpb.ListValue{} + target.Field(0).Set(reflect.ValueOf(&stpb.Value_ListValue{lv})) + return u.unmarshalValue(reflect.ValueOf(lv).Elem(), inputValue, prop) + } else if err := json.Unmarshal(inputValue, &map[string]json.RawMessage{}); err == nil { + sv := &stpb.Struct{} + target.Field(0).Set(reflect.ValueOf(&stpb.Value_StructValue{sv})) + return u.unmarshalValue(reflect.ValueOf(sv).Elem(), inputValue, prop) + } else { + return fmt.Errorf("unrecognized type for Value %q", ivStr) + } + return nil + } + } + + // Handle enums, which have an underlying type of int32, + // and may appear as strings. + // The case of an enum appearing as a number is handled + // at the bottom of this function. + if inputValue[0] == '"' && prop != nil && prop.Enum != "" { + vmap := proto.EnumValueMap(prop.Enum) + // Don't need to do unquoting; valid enum names + // are from a limited character set. + s := inputValue[1 : len(inputValue)-1] + n, ok := vmap[string(s)] + if !ok { + return fmt.Errorf("unknown value %q for enum %s", s, prop.Enum) + } + if target.Kind() == reflect.Ptr { // proto2 + target.Set(reflect.New(targetType.Elem())) + target = target.Elem() + } + if targetType.Kind() != reflect.Int32 { + return fmt.Errorf("invalid target %q for enum %s", targetType.Kind(), prop.Enum) + } + target.SetInt(int64(n)) + return nil + } + + // Handle nested messages. + if targetType.Kind() == reflect.Struct { + var jsonFields map[string]json.RawMessage + if err := json.Unmarshal(inputValue, &jsonFields); err != nil { + return err + } + + consumeField := func(prop *proto.Properties) (json.RawMessage, bool) { + // Be liberal in what names we accept; both orig_name and camelName are okay. + fieldNames := acceptedJSONFieldNames(prop) + + vOrig, okOrig := jsonFields[fieldNames.orig] + vCamel, okCamel := jsonFields[fieldNames.camel] + if !okOrig && !okCamel { + return nil, false + } + // If, for some reason, both are present in the data, favour the camelName. + var raw json.RawMessage + if okOrig { + raw = vOrig + delete(jsonFields, fieldNames.orig) + } + if okCamel { + raw = vCamel + delete(jsonFields, fieldNames.camel) + } + return raw, true + } + + sprops := proto.GetProperties(targetType) + for i := 0; i < target.NumField(); i++ { + ft := target.Type().Field(i) + if strings.HasPrefix(ft.Name, "XXX_") { + continue + } + + valueForField, ok := consumeField(sprops.Prop[i]) + if !ok { + continue + } + + if err := u.unmarshalValue(target.Field(i), valueForField, sprops.Prop[i]); err != nil { + return err + } + } + // Check for any oneof fields. + if len(jsonFields) > 0 { + for _, oop := range sprops.OneofTypes { + raw, ok := consumeField(oop.Prop) + if !ok { + continue + } + nv := reflect.New(oop.Type.Elem()) + target.Field(oop.Field).Set(nv) + if err := u.unmarshalValue(nv.Elem().Field(0), raw, oop.Prop); err != nil { + return err + } + } + } + // Handle proto2 extensions. + if len(jsonFields) > 0 { + if ep, ok := target.Addr().Interface().(proto.Message); ok { + for _, ext := range proto.RegisteredExtensions(ep) { + name := fmt.Sprintf("[%s]", ext.Name) + raw, ok := jsonFields[name] + if !ok { + continue + } + delete(jsonFields, name) + nv := reflect.New(reflect.TypeOf(ext.ExtensionType).Elem()) + if err := u.unmarshalValue(nv.Elem(), raw, nil); err != nil { + return err + } + if err := proto.SetExtension(ep, ext, nv.Interface()); err != nil { + return err + } + } + } + } + if !u.AllowUnknownFields && len(jsonFields) > 0 { + // Pick any field to be the scapegoat. + var f string + for fname := range jsonFields { + f = fname + break + } + return fmt.Errorf("unknown field %q in %v", f, targetType) + } + return nil + } + + // Handle arrays (which aren't encoded bytes) + if targetType.Kind() == reflect.Slice && targetType.Elem().Kind() != reflect.Uint8 { + var slc []json.RawMessage + if err := json.Unmarshal(inputValue, &slc); err != nil { + return err + } + if slc != nil { + l := len(slc) + target.Set(reflect.MakeSlice(targetType, l, l)) + for i := 0; i < l; i++ { + if err := u.unmarshalValue(target.Index(i), slc[i], prop); err != nil { + return err + } + } + } + return nil + } + + // Handle maps (whose keys are always strings) + if targetType.Kind() == reflect.Map { + var mp map[string]json.RawMessage + if err := json.Unmarshal(inputValue, &mp); err != nil { + return err + } + if mp != nil { + target.Set(reflect.MakeMap(targetType)) + for ks, raw := range mp { + // Unmarshal map key. The core json library already decoded the key into a + // string, so we handle that specially. Other types were quoted post-serialization. + var k reflect.Value + if targetType.Key().Kind() == reflect.String { + k = reflect.ValueOf(ks) + } else { + k = reflect.New(targetType.Key()).Elem() + var kprop *proto.Properties + if prop != nil && prop.MapKeyProp != nil { + kprop = prop.MapKeyProp + } + if err := u.unmarshalValue(k, json.RawMessage(ks), kprop); err != nil { + return err + } + } + + // Unmarshal map value. + v := reflect.New(targetType.Elem()).Elem() + var vprop *proto.Properties + if prop != nil && prop.MapValProp != nil { + vprop = prop.MapValProp + } + if err := u.unmarshalValue(v, raw, vprop); err != nil { + return err + } + target.SetMapIndex(k, v) + } + } + return nil + } + + // Non-finite numbers can be encoded as strings. + isFloat := targetType.Kind() == reflect.Float32 || targetType.Kind() == reflect.Float64 + if isFloat { + if num, ok := nonFinite[string(inputValue)]; ok { + target.SetFloat(num) + return nil + } + } + + // integers & floats can be encoded as strings. In this case we drop + // the quotes and proceed as normal. + isNum := targetType.Kind() == reflect.Int64 || targetType.Kind() == reflect.Uint64 || + targetType.Kind() == reflect.Int32 || targetType.Kind() == reflect.Uint32 || + targetType.Kind() == reflect.Float32 || targetType.Kind() == reflect.Float64 + if isNum && strings.HasPrefix(string(inputValue), `"`) { + inputValue = inputValue[1 : len(inputValue)-1] + } + + // Use the encoding/json for parsing other value types. + return json.Unmarshal(inputValue, target.Addr().Interface()) +} + +func unquote(s string) (string, error) { + var ret string + err := json.Unmarshal([]byte(s), &ret) + return ret, err +} + +// jsonProperties returns parsed proto.Properties for the field and corrects JSONName attribute. +func jsonProperties(f reflect.StructField, origName bool) *proto.Properties { + var prop proto.Properties + prop.Init(f.Type, f.Name, f.Tag.Get("protobuf"), &f) + if origName || prop.JSONName == "" { + prop.JSONName = prop.OrigName + } + return &prop +} + +type fieldNames struct { + orig, camel string +} + +func acceptedJSONFieldNames(prop *proto.Properties) fieldNames { + opts := fieldNames{orig: prop.OrigName, camel: prop.OrigName} + if prop.JSONName != "" { + opts.camel = prop.JSONName + } + return opts +} + +// Writer wrapper inspired by https://blog.golang.org/errors-are-values +type errWriter struct { + writer io.Writer + err error +} + +func (w *errWriter) write(str string) { + if w.err != nil { + return + } + _, w.err = w.writer.Write([]byte(str)) +} + +// Map fields may have key types of non-float scalars, strings and enums. +// The easiest way to sort them in some deterministic order is to use fmt. +// If this turns out to be inefficient we can always consider other options, +// such as doing a Schwartzian transform. +// +// Numeric keys are sorted in numeric order per +// https://developers.google.com/protocol-buffers/docs/proto#maps. +type mapKeys []reflect.Value + +func (s mapKeys) Len() int { return len(s) } +func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s mapKeys) Less(i, j int) bool { + if k := s[i].Kind(); k == s[j].Kind() { + switch k { + case reflect.String: + return s[i].String() < s[j].String() + case reflect.Int32, reflect.Int64: + return s[i].Int() < s[j].Int() + case reflect.Uint32, reflect.Uint64: + return s[i].Uint() < s[j].Uint() + } + } + return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface()) +} + +// checkRequiredFields returns an error if any required field in the given proto message is not set. +// This function is used by both Marshal and Unmarshal. While required fields only exist in a +// proto2 message, a proto3 message can contain proto2 message(s). +func checkRequiredFields(pb proto.Message) error { + // Most well-known type messages do not contain required fields. The "Any" type may contain + // a message that has required fields. + // + // When an Any message is being marshaled, the code will invoked proto.Unmarshal on Any.Value + // field in order to transform that into JSON, and that should have returned an error if a + // required field is not set in the embedded message. + // + // When an Any message is being unmarshaled, the code will have invoked proto.Marshal on the + // embedded message to store the serialized message in Any.Value field, and that should have + // returned an error if a required field is not set. + if _, ok := pb.(wkt); ok { + return nil + } + + v := reflect.ValueOf(pb) + // Skip message if it is not a struct pointer. + if v.Kind() != reflect.Ptr { + return nil + } + v = v.Elem() + if v.Kind() != reflect.Struct { + return nil + } + + for i := 0; i < v.NumField(); i++ { + field := v.Field(i) + sfield := v.Type().Field(i) + + if sfield.PkgPath != "" { + // blank PkgPath means the field is exported; skip if not exported + continue + } + + if strings.HasPrefix(sfield.Name, "XXX_") { + continue + } + + // Oneof field is an interface implemented by wrapper structs containing the actual oneof + // field, i.e. an interface containing &T{real_value}. + if sfield.Tag.Get("protobuf_oneof") != "" { + if field.Kind() != reflect.Interface { + continue + } + v := field.Elem() + if v.Kind() != reflect.Ptr || v.IsNil() { + continue + } + v = v.Elem() + if v.Kind() != reflect.Struct || v.NumField() < 1 { + continue + } + field = v.Field(0) + sfield = v.Type().Field(0) + } + + protoTag := sfield.Tag.Get("protobuf") + if protoTag == "" { + continue + } + var prop proto.Properties + prop.Init(sfield.Type, sfield.Name, protoTag, &sfield) + + switch field.Kind() { + case reflect.Map: + if field.IsNil() { + continue + } + // Check each map value. + keys := field.MapKeys() + for _, k := range keys { + v := field.MapIndex(k) + if err := checkRequiredFieldsInValue(v); err != nil { + return err + } + } + case reflect.Slice: + // Handle non-repeated type, e.g. bytes. + if !prop.Repeated { + if prop.Required && field.IsNil() { + return fmt.Errorf("required field %q is not set", prop.Name) + } + continue + } + + // Handle repeated type. + if field.IsNil() { + continue + } + // Check each slice item. + for i := 0; i < field.Len(); i++ { + v := field.Index(i) + if err := checkRequiredFieldsInValue(v); err != nil { + return err + } + } + case reflect.Ptr: + if field.IsNil() { + if prop.Required { + return fmt.Errorf("required field %q is not set", prop.Name) + } + continue + } + if err := checkRequiredFieldsInValue(field); err != nil { + return err + } + } + } + + // Handle proto2 extensions. + for _, ext := range proto.RegisteredExtensions(pb) { + if !proto.HasExtension(pb, ext) { + continue + } + ep, err := proto.GetExtension(pb, ext) + if err != nil { + return err + } + err = checkRequiredFieldsInValue(reflect.ValueOf(ep)) + if err != nil { + return err + } + } + + return nil +} + +func checkRequiredFieldsInValue(v reflect.Value) error { + if pm, ok := v.Interface().(proto.Message); ok { + return checkRequiredFields(pm) + } + return nil +} diff --git a/vendor/github.com/google/cel-go/LICENSE b/vendor/github.com/google/cel-go/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/vendor/github.com/google/cel-go/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor 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, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/vendor/github.com/google/cel-go/cel/cel.go b/vendor/github.com/google/cel-go/cel/cel.go new file mode 100644 index 000000000..eb5a9f4cc --- /dev/null +++ b/vendor/github.com/google/cel-go/cel/cel.go @@ -0,0 +1,19 @@ +// Copyright 2019 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 defines the top-level interface for the Common Expression Language (CEL). +// +// CEL is a non-Turing complete expression language designed to parse, check, and evaluate +// expressions against user-defined environments. +package cel diff --git a/vendor/github.com/google/cel-go/cel/env.go b/vendor/github.com/google/cel-go/cel/env.go new file mode 100644 index 000000000..fd465a13a --- /dev/null +++ b/vendor/github.com/google/cel-go/cel/env.go @@ -0,0 +1,283 @@ +// Copyright 2019 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 ( + "errors" + "fmt" + + "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/packages" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/interpreter/functions" + "github.com/google/cel-go/parser" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// Source interface representing a user-provided expression. +type Source interface { + common.Source +} + +// Ast interface representing the checked or unchecked expression, its source, and related metadata +// such as source position information. +type Ast interface { + // Expr returns the proto serializable instance of the parsed/checked expression. + Expr() *exprpb.Expr + + // IsChecked returns whether the Ast value has been successfully type-checked. + IsChecked() bool + + // 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. + ResultType() *exprpb.Type + + // Source returns a view of the input used to create the Ast. This source may be complete or + // constructed from the SourceInfo. + Source() Source + + // SourceInfo returns character offset and newling position information about expression + // elements. + SourceInfo() *exprpb.SourceInfo +} + +// Env defines functions for parsing and type-checking expressions against a set of user-defined +// constants, variables, and functions. The Env interface also defines a method for generating +// evaluable programs from parsed and checked Asts. +type Env interface { + // Extend the current environment with additional options to produce a new Env. + Extend(opts ...EnvOption) (Env, error) + + // Check performs type-checking on the input Ast and yields a checked Ast and/or set of Issues. + // + // Checking has failed if the returned Issues value and its Issues.Err() value is 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. + Check(ast Ast) (Ast, Issues) + + // Parse parses the input expression value `txt` to a Ast and/or a set of Issues. + // + // Parsing has failed if the returned Issues value and its Issues.Err() value is 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. + Parse(txt string) (Ast, Issues) + + // Program generates an evaluable instance of the Ast within the environment (Env). + Program(ast Ast, opts ...ProgramOption) (Program, error) + + // TypeAdapter returns the `ref.TypeAdapter` configured for the environment. + TypeAdapter() ref.TypeAdapter + + // TypeProvider returns the `ref.TypeProvider` configured for the environment. + TypeProvider() ref.TypeProvider +} + +// 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 interface. +type Issues interface { + fmt.Stringer + + // Err returns an error value if the issues list contains one or more errors. + Err() error + + // Errors returns the collection of errors encountered in more granular detail. + Errors() []common.Error +} + +// NewEnv creates an Env instance suitable for parsing and checking expressions against a set of +// user-defined constants, variables, and functions. Macros and the standard built-ins are enabled +// by default. +// +// See the EnvOptions for the options that can be used to configure the environment. +func NewEnv(opts ...EnvOption) (Env, error) { + registry := types.NewRegistry() + return (&env{ + declarations: checker.StandardDeclarations(), + macros: parser.AllMacros, + pkg: packages.DefaultPackage, + provider: registry, + adapter: registry, + enableBuiltins: true, + enableDynamicAggregateLiterals: true, + }).configure(opts...) +} + +// Extend the current environment with additional options to produce a new Env. +func (e *env) Extend(opts ...EnvOption) (Env, error) { + ext := &env{} + *ext = *e + return ext.configure(opts...) +} + +// configure applies a series of EnvOptions to the current environment. +func (e *env) configure(opts ...EnvOption) (Env, error) { + // Customized the environment using the provided EnvOption values. If an error is + // generated at any step this, will be returned as a nil Env with a non-nil error. + var err error + for _, opt := range opts { + e, err = opt(e) + if err != nil { + return nil, err + } + } + // Construct the internal checker env, erroring if there is an issue adding the declarations. + ce := checker.NewEnv(e.pkg, e.provider) + ce.EnableDynamicAggregateLiterals(e.enableDynamicAggregateLiterals) + err = ce.Add(e.declarations...) + if err != nil { + return nil, err + } + e.chk = ce + return e, nil +} + +// astValue is the internal implementation of the ast interface. +type astValue struct { + expr *exprpb.Expr + info *exprpb.SourceInfo + source Source + refMap map[int64]*exprpb.Reference + typeMap map[int64]*exprpb.Type +} + +// Expr implements the Ast interface method. +func (ast *astValue) Expr() *exprpb.Expr { + return ast.expr +} + +// IsChecked implements the Ast interface method. +func (ast *astValue) IsChecked() bool { + return ast.refMap != nil && ast.typeMap != nil +} + +// SourceInfo implements the Ast interface method. +func (ast *astValue) SourceInfo() *exprpb.SourceInfo { + return ast.info +} + +// ResultType implements the Ast interface method. +func (ast *astValue) ResultType() *exprpb.Type { + if !ast.IsChecked() { + return decls.Dyn + } + return ast.typeMap[ast.expr.Id] +} + +// Source implements the Ast interface method. +func (ast *astValue) Source() Source { + return ast.source +} + +// env is the internal implementation of the Env interface. +type env struct { + declarations []*exprpb.Decl + macros []parser.Macro + pkg packages.Packager + provider ref.TypeProvider + adapter ref.TypeAdapter + chk *checker.Env + // environment options, true by default. + enableBuiltins bool + enableDynamicAggregateLiterals bool +} + +// Check implements the Env interface method. +func (e *env) Check(ast Ast) (Ast, Issues) { + pe, err := AstToParsedExpr(ast) + if err != nil { + errs := common.NewErrors(ast.Source()) + errs.ReportError(common.NoLocation, err.Error()) + return nil, &issues{errs: errs} + } + res, errs := checker.Check(pe, ast.Source(), e.chk) + if len(errs.GetErrors()) > 0 { + return nil, &issues{errs: errs} + } + // 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 &astValue{ + source: ast.Source(), + expr: res.GetExpr(), + info: res.GetSourceInfo(), + refMap: res.GetReferenceMap(), + typeMap: res.GetTypeMap()}, nil +} + +// Parse implements the Env interface method. +func (e *env) Parse(txt string) (Ast, Issues) { + src := common.NewTextSource(txt) + res, errs := parser.ParseWithMacros(src, e.macros) + if len(errs.GetErrors()) > 0 { + return nil, &issues{errs: errs} + } + // Manually create the Ast to ensure that the text source information is propagated on + // subsequent calls to Check. + return &astValue{ + source: Source(src), + expr: res.GetExpr(), + info: res.GetSourceInfo()}, nil +} + +// Program implements the Env interface method. +func (e *env) Program(ast Ast, opts ...ProgramOption) (Program, error) { + if e.enableBuiltins { + opts = append( + []ProgramOption{Functions(functions.StandardOverloads()...)}, + opts...) + } + return newProgram(e, ast, opts...) +} + +// TypeAdapter implements the Env interface method. +func (e *env) TypeAdapter() ref.TypeAdapter { + return e.adapter +} + +// TypeProvider implements the Env interface method. +func (e *env) TypeProvider() ref.TypeProvider { + return e.provider +} + +// issues is the internal implementation of the Issues interface. +type issues struct { + errs *common.Errors +} + +// Err implements the Issues interface method. +func (i *issues) Err() error { + if len(i.errs.GetErrors()) > 0 { + return errors.New(i.errs.ToDisplayString()) + } + return nil +} + +// Errors implements the Issues interface method. +func (i *issues) Errors() []common.Error { + return i.errs.GetErrors() +} + +// String converts the issues to a suitable display string. +func (i *issues) String() string { + return i.errs.ToDisplayString() +} diff --git a/vendor/github.com/google/cel-go/cel/io.go b/vendor/github.com/google/cel-go/cel/io.go new file mode 100644 index 000000000..01e326c95 --- /dev/null +++ b/vendor/github.com/google/cel-go/cel/io.go @@ -0,0 +1,77 @@ +// Copyright 2019 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" + + "github.com/google/cel-go/common" + "github.com/google/cel-go/parser" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// CheckedExprToAst converts a checked expression proto message to an Ast. +func CheckedExprToAst(checkedExpr *exprpb.CheckedExpr) Ast { + return &astValue{ + expr: checkedExpr.GetExpr(), + info: checkedExpr.GetSourceInfo(), + source: common.NewInfoSource(checkedExpr.GetSourceInfo()), + refMap: checkedExpr.GetReferenceMap(), + typeMap: checkedExpr.GetTypeMap(), + } +} + +// AstToCheckedExpr converts an Ast to an protobuf CheckedExpr value. +// +// If the Ast.IsChecked() returns false, this conversion method will return an error. +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(), + ReferenceMap: a.(*astValue).refMap, + TypeMap: a.(*astValue).typeMap, + }, nil +} + +// ParsedExprToAst converts a parsed expression proto message to an Ast. +func ParsedExprToAst(parsedExpr *exprpb.ParsedExpr) Ast { + return &astValue{ + expr: parsedExpr.GetExpr(), + info: parsedExpr.GetSourceInfo(), + source: common.NewInfoSource(parsedExpr.GetSourceInfo()), + } +} + +// AstToParsedExpr converts an Ast to an protobuf ParsedExpr value. +func AstToParsedExpr(a Ast) (*exprpb.ParsedExpr, error) { + return &exprpb.ParsedExpr{ + Expr: a.Expr(), + SourceInfo: a.SourceInfo(), + }, nil +} + +// AstToString converts an Ast back to a string if possible. +// +// Note, the conversion may not be an exact replica of the original expression, but will produce +// a string that is semantically equivalent. +func AstToString(a Ast) (string, error) { + expr := a.Expr() + info := a.SourceInfo() + return parser.Unparse(expr, info) +} diff --git a/vendor/github.com/google/cel-go/cel/options.go b/vendor/github.com/google/cel-go/cel/options.go new file mode 100644 index 000000000..115deb1cd --- /dev/null +++ b/vendor/github.com/google/cel-go/cel/options.go @@ -0,0 +1,249 @@ +// Copyright 2019 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" + + "github.com/golang/protobuf/proto" + "github.com/google/cel-go/common/packages" + "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" + + descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// EnvOption is a functional interface for configuring the environment. +type EnvOption func(e *env) (*env, error) + +// ClearBuiltIns option removes all standard types, operators, and macros from the environment. +// +// Note: This option must be specified before Declarations and/or Macros if used together. +func ClearBuiltIns() EnvOption { + return func(e *env) (*env, error) { + e.declarations = []*exprpb.Decl{} + e.macros = parser.NoMacros + e.enableBuiltins = false + return e, nil + } +} + +// ClearMacros options clears all parser macros. +// +// Clearing macros will ensure CEL expressions can only contain linear evaluation paths, as +// comprehensions such as `all` and `exists` are enabled only via macros. +// +// Note: This option is a no-op when used with ClearBuiltIns, and must be used before Macros +// if used together. +func ClearMacros() EnvOption { + return func(e *env) (*env, error) { + e.macros = parser.NoMacros + return e, nil + } +} + +// CustomTypeAdapter swaps the default ref.TypeAdapter 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 { + return func(e *env) (*env, error) { + e.adapter = adapter + return e, nil + } +} + +// CustomTypeProvider swaps the default ref.TypeProvider implementation with a custom one. +// +// Note: This option must be specified before the Types and TypeDescs options when used together. +func CustomTypeProvider(provider ref.TypeProvider) EnvOption { + return func(e *env) (*env, error) { + e.provider = provider + return e, nil + } +} + +// Declarations option extends the declaration set configured in the environment. +// +// Note: This option must be specified after ClearBuiltIns if both are used together. +func Declarations(decls ...*exprpb.Decl) EnvOption { + // TODO: provide an alternative means of specifying declarations that doesn't refer + // to the underlying proto implementations. + return func(e *env) (*env, error) { + e.declarations = append(e.declarations, decls...) + return e, nil + } +} + +// HomogeneousAggregateLiterals option ensures that list and map literal entry types must agree +// during type-checking. +// +// 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 func(e *env) (*env, error) { + e.enableDynamicAggregateLiterals = false + return e, nil + } +} + +// Macros option extends the macro set configured in the environment. +// +// Note: This option must be specified after ClearBuiltIns and/or ClearMacros if used together. +func Macros(macros ...parser.Macro) EnvOption { + return func(e *env) (*env, error) { + e.macros = append(e.macros, macros...) + return e, nil + } +} + +// Container sets the container for resolving variable names. Defaults to an empty container. +// +// If all references within an expression are relative to a protocol buffer package, then +// specifying a container of `google.type` would make it possible to write expressions such as +// `Expr{expression: 'a < b'}` instead of having to write `google.type.Expr{...}`. +func Container(pkg string) EnvOption { + return func(e *env) (*env, error) { + e.pkg = packages.NewPackage(pkg) + return e, nil + } +} + +// Types adds one or more type declarations to the environment, allowing for construction of +// type-literals whose definitions are included in the common expression built-in set. +// +// The input types may either be instances of `proto.Message` or `ref.Type`. Any other type +// provided to this option will result in an error. +// +// Well-known protobuf types within the `google.protobuf.*` package are included in the standard +// environment by default. +// +// Note: This option must be specified after the CustomTypeProvider option when used together. +func Types(addTypes ...interface{}) EnvOption { + return func(e *env) (*env, error) { + reg, isReg := e.provider.(ref.TypeRegistry) + if !isReg { + return nil, fmt.Errorf("custom types not supported by provider: %T", e.provider) + } + for _, t := range addTypes { + switch t.(type) { + case proto.Message: + err := reg.RegisterMessage(t.(proto.Message)) + if err != nil { + return nil, err + } + case ref.Type: + err := reg.RegisterType(t.(ref.Type)) + if err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("unsupported type: %T", t) + } + } + return e, nil + } +} + +// TypeDescs adds type declarations for one or more protocol buffer +// FileDescriptorProtos or FileDescriptorSets. Note that types added +// via descriptor will not be able to instantiate messages, and so are +// only useful for Check() operations. +func TypeDescs(descs ...interface{}) EnvOption { + return func(e *env) (*env, error) { + reg, isReg := e.provider.(ref.TypeRegistry) + if !isReg { + return nil, fmt.Errorf("custom types not supported by provider: %T", e.provider) + } + for _, d := range descs { + switch p := d.(type) { + case *descpb.FileDescriptorSet: + for _, fd := range p.File { + err := reg.RegisterDescriptor(fd) + if err != nil { + return nil, err + } + } + case *descpb.FileDescriptorProto: + err := reg.RegisterDescriptor(p) + if err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("unsupported type descriptor: %T", d) + } + } + return e, nil + } +} + +// ProgramOption is a functional interface for configuring evaluation bindings and behaviors. +type ProgramOption func(p *prog) (*prog, error) + +// Functions adds function overloads that extend or override the set of CEL built-ins. +func Functions(funcs ...*functions.Overload) ProgramOption { + return func(p *prog) (*prog, error) { + if err := p.dispatcher.Add(funcs...); err != nil { + return nil, err + } + return p, nil + } +} + +// Globals sets the global variable values for a given program. These values may be shadowed by +// variables with the same name provided to the Eval() call. +// +// The vars value may either be an `interpreter.Activation` instance or a `map[string]interface{}`. +func Globals(vars interface{}) ProgramOption { + return func(p *prog) (*prog, error) { + defaultVars, err := + interpreter.NewAdaptingActivation(p.adapter, vars) + if err != nil { + return nil, err + } + p.defaultVars = defaultVars + return p, nil + } +} + +// EvalOption indicates an evaluation option that may affect the evaluation behavior or information +// in the output result. +type EvalOption int + +const ( + // OptTrackState will cause the runtime to return an immutable EvalState value in the Result. + OptTrackState EvalOption = 1 << iota + + // OptExhaustiveEval causes the runtime to disable short-circuits and track state. + OptExhaustiveEval EvalOption = 1< 0 { + // Instantiate overload's type with fresh type variables. + substitutions := newMapping() + for _, typePar := range overload.TypeParams { + substitutions.add(decls.NewTypeParamType(typePar), c.newTypeVar()) + } + + overloadType = substitute(substitutions, overloadType, false) + } + + candidateArgTypes := overloadType.GetFunction().ArgTypes + if c.isAssignableList(argTypes, candidateArgTypes) { + if checkedRef == nil { + checkedRef = newFunctionReference(overload.OverloadId) + } else { + checkedRef.OverloadId = append(checkedRef.OverloadId, overload.OverloadId) + } + + if resultType == nil { + // First matching overload, determines result type. + resultType = substitute(c.mappings, + overloadType.GetFunction().ResultType, + false) + } else { + // More than one matching overload, narrow result type to DYN. + resultType = decls.Dyn + } + + } + } + + if resultType == nil { + c.errors.noMatchingOverload(loc, fn.Name, argTypes, target != nil) + resultType = decls.Error + return nil + } + + return newResolution(checkedRef, resultType) +} + +func (c *checker) checkCreateList(e *exprpb.Expr) { + create := e.GetListExpr() + var elemType *exprpb.Type + for _, e := range create.Elements { + c.check(e) + elemType = c.joinTypes(c.location(e), elemType, c.getType(e)) + } + if elemType == nil { + // If the list is empty, assign free type var to elem type. + elemType = c.newTypeVar() + } + c.setType(e, decls.NewListType(elemType)) +} + +func (c *checker) checkCreateStruct(e *exprpb.Expr) { + str := e.GetStructExpr() + if str.MessageName != "" { + c.checkCreateMessage(e) + } else { + c.checkCreateMap(e) + } +} + +func (c *checker) checkCreateMap(e *exprpb.Expr) { + mapVal := e.GetStructExpr() + var keyType *exprpb.Type + var valueType *exprpb.Type + for _, ent := range mapVal.GetEntries() { + key := ent.GetMapKey() + c.check(key) + keyType = c.joinTypes(c.location(key), keyType, c.getType(key)) + + c.check(ent.Value) + valueType = c.joinTypes(c.location(ent.Value), valueType, c.getType(ent.Value)) + } + if keyType == nil { + // If the map is empty, assign free type variables to typeKey and value type. + keyType = c.newTypeVar() + valueType = c.newTypeVar() + } + c.setType(e, decls.NewMapType(keyType, valueType)) +} + +func (c *checker) checkCreateMessage(e *exprpb.Expr) { + msgVal := e.GetStructExpr() + // Determine the type of the message. + messageType := decls.Error + decl := c.env.LookupIdent(msgVal.MessageName) + if decl == nil { + c.errors.undeclaredReference( + c.location(e), c.env.packager.Package(), msgVal.MessageName) + return + } + + c.setReference(e, newIdentReference(decl.Name, nil)) + ident := decl.GetIdent() + identKind := kindOf(ident.Type) + if identKind != kindError { + if identKind != kindType { + c.errors.notAType(c.location(e), ident.Type) + } else { + messageType = ident.Type.GetType() + if kindOf(messageType) != kindObject { + c.errors.notAMessageType(c.location(e), messageType) + messageType = decls.Error + } + } + } + if isObjectWellKnownType(messageType) { + c.setType(e, getObjectWellKnownType(messageType)) + } else { + c.setType(e, messageType) + } + + // Check the field initializers. + for _, ent := range msgVal.GetEntries() { + field := ent.GetFieldKey() + value := ent.Value + c.check(value) + + fieldType := decls.Error + if t, found := c.lookupFieldType( + c.locationByID(ent.Id), + messageType.GetMessageType(), + field); found { + fieldType = t.Type + } + if !c.isAssignable(fieldType, c.getType(value)) { + c.errors.fieldTypeMismatch( + c.locationByID(ent.Id), field, fieldType, c.getType(value)) + } + } +} + +func (c *checker) checkComprehension(e *exprpb.Expr) { + comp := e.GetComprehensionExpr() + c.check(comp.IterRange) + c.check(comp.AccuInit) + accuType := c.getType(comp.AccuInit) + rangeType := c.getType(comp.IterRange) + var varType *exprpb.Type + + switch kindOf(rangeType) { + case kindList: + varType = rangeType.GetListType().ElemType + case kindMap: + // Ranges over the keys. + varType = rangeType.GetMapType().KeyType + case kindDyn, kindError: + varType = decls.Dyn + default: + c.errors.notAComprehensionRange(c.location(comp.IterRange), rangeType) + } + + // 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.NewIdent(comp.AccuVar, accuType, nil)) + // Create a block scope for the loop. + c.env = c.env.enterScope() + c.env.Add(decls.NewIdent(comp.IterVar, varType, nil)) + // Check the variable references in the condition and step. + c.check(comp.LoopCondition) + c.assertType(comp.LoopCondition, decls.Bool) + c.check(comp.LoopStep) + c.assertType(comp.LoopStep, accuType) + // Exit the loop's block scope before checking the result. + c.env = c.env.exitScope() + c.check(comp.Result) + // Exit the comprehension scope. + c.env = c.env.exitScope() + c.setType(e, c.getType(comp.Result)) +} + +// 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 { + if previous == nil { + return current + } + if c.isAssignable(previous, current) { + return mostGeneral(previous, current) + } + if c.dynAggregateLiteralElementTypesEnabled() { + return decls.Dyn + } + c.errors.typeMismatch(loc, previous, current) + return decls.Error +} + +func (c *checker) dynAggregateLiteralElementTypesEnabled() bool { + return c.env.aggLitElemType == dynElementType +} + +func (c *checker) newTypeVar() *exprpb.Type { + id := c.freeTypeVarCounter + c.freeTypeVarCounter++ + return decls.NewTypeParamType(fmt.Sprintf("_var%d", id)) +} + +func (c *checker) isAssignable(t1 *exprpb.Type, t2 *exprpb.Type) bool { + subs := isAssignable(c.mappings, t1, t2) + if subs != nil { + c.mappings = subs + return true + } + + return false +} + +func (c *checker) isAssignableList(l1 []*exprpb.Type, l2 []*exprpb.Type) bool { + subs := isAssignableList(c.mappings, l1, l2) + if subs != nil { + c.mappings = subs + return true + } + + 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 + } + + c.errors.undefinedField(l, fieldName) + return nil, false +} + +func (c *checker) setType(e *exprpb.Expr, t *exprpb.Type) { + if old, found := c.types[e.Id]; found && !proto.Equal(old, t) { + panic(fmt.Sprintf("(Incompatible) Type already exists for expression: %v(%d) old:%v, new:%v", e, e.Id, old, t)) + } + c.types[e.Id] = t +} + +func (c *checker) getType(e *exprpb.Expr) *exprpb.Type { + return c.types[e.Id] +} + +func (c *checker) setReference(e *exprpb.Expr, r *exprpb.Reference) { + if old, found := c.references[e.Id]; found && !proto.Equal(old, r) { + panic(fmt.Sprintf("Reference already exists for expression: %v(%d) old:%v, new:%v", e, e.Id, old, r)) + } + c.references[e.Id] = r +} + +func (c *checker) assertType(e *exprpb.Expr, t *exprpb.Type) { + if !c.isAssignable(t, c.getType(e)) { + c.errors.typeMismatch(c.location(e), t, c.getType(e)) + } +} + +type overloadResolution struct { + Reference *exprpb.Reference + Type *exprpb.Type +} + +func newResolution(checkedRef *exprpb.Reference, t *exprpb.Type) *overloadResolution { + return &overloadResolution{ + Reference: checkedRef, + Type: t, + } +} + +func (c *checker) location(e *exprpb.Expr) common.Location { + return c.locationByID(e.Id) +} + +func (c *checker) locationByID(id int64) common.Location { + positions := c.sourceInfo.GetPositions() + var line = 1 + if offset, found := positions[id]; found { + col := int(offset) + for _, lineOffset := range c.sourceInfo.LineOffsets { + if lineOffset < offset { + line++ + col = int(offset - lineOffset) + } else { + break + } + } + return common.NewLocation(line, col) + } + return common.NoLocation +} + +func newIdentReference(name string, value *exprpb.Constant) *exprpb.Reference { + return &exprpb.Reference{Name: name, Value: value} +} + +func newFunctionReference(overloads ...string) *exprpb.Reference { + return &exprpb.Reference{OverloadId: overloads} +} + +// Attempt to interpret an expression as a qualified name. This traverses select and getIdent +// expression and returns the name they constitute, or null if the expression cannot be +// interpreted like this. +func toQualifiedName(e *exprpb.Expr) (string, bool) { + switch e.ExprKind.(type) { + case *exprpb.Expr_IdentExpr: + i := e.GetIdentExpr() + return i.Name, true + case *exprpb.Expr_SelectExpr: + s := e.GetSelectExpr() + if qname, found := toQualifiedName(s.Operand); found { + return qname + "." + s.Field, true + } + } + return "", false +} diff --git a/vendor/github.com/google/cel-go/checker/decls/decls.go b/vendor/github.com/google/cel-go/checker/decls/decls.go new file mode 100644 index 000000000..04ee6d67b --- /dev/null +++ b/vendor/github.com/google/cel-go/checker/decls/decls.go @@ -0,0 +1,215 @@ +// 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 decls provides helpers for creating variable and function declarations. +package decls + +import ( + emptypb "github.com/golang/protobuf/ptypes/empty" + structpb "github.com/golang/protobuf/ptypes/struct" + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +var ( + // Error type used to communicate issues during type-checking. + Error = &exprpb.Type{ + TypeKind: &exprpb.Type_Error{ + Error: &emptypb.Empty{}}} + + // Dyn is a top-type used to represent any value. + Dyn = &exprpb.Type{ + TypeKind: &exprpb.Type_Dyn{ + Dyn: &emptypb.Empty{}}} +) + +// Commonly used types. +var ( + Bool = NewPrimitiveType(exprpb.Type_BOOL) + Bytes = NewPrimitiveType(exprpb.Type_BYTES) + Double = NewPrimitiveType(exprpb.Type_DOUBLE) + Int = NewPrimitiveType(exprpb.Type_INT64) + Null = &exprpb.Type{ + TypeKind: &exprpb.Type_Null{ + Null: structpb.NullValue_NULL_VALUE}} + String = NewPrimitiveType(exprpb.Type_STRING) + Uint = NewPrimitiveType(exprpb.Type_UINT64) +) + +// Well-known types. +// TODO: Replace with an abstract type registry. +var ( + Any = NewWellKnownType(exprpb.Type_ANY) + Duration = NewWellKnownType(exprpb.Type_DURATION) + Timestamp = NewWellKnownType(exprpb.Type_TIMESTAMP) +) + +// NewAbstractType creates an abstract type declaration which references a proto +// message name and may also include type parameters. +func NewAbstractType(name string, paramTypes ...*exprpb.Type) *exprpb.Type { + return &exprpb.Type{ + TypeKind: &exprpb.Type_AbstractType_{ + AbstractType: &exprpb.Type_AbstractType{ + Name: name, + ParameterTypes: paramTypes}}} +} + +// NewFunctionType creates a function invocation contract, typically only used +// by type-checking steps after overload resolution. +func NewFunctionType(resultType *exprpb.Type, + argTypes ...*exprpb.Type) *exprpb.Type { + return &exprpb.Type{ + TypeKind: &exprpb.Type_Function{ + Function: &exprpb.Type_FunctionType{ + ResultType: resultType, + ArgTypes: argTypes}}} +} + +// NewFunction creates a named function declaration with one or more overloads. +func NewFunction(name string, + overloads ...*exprpb.Decl_FunctionDecl_Overload) *exprpb.Decl { + return &exprpb.Decl{ + Name: name, + DeclKind: &exprpb.Decl_Function{ + Function: &exprpb.Decl_FunctionDecl{ + Overloads: overloads}}} +} + +// NewIdent creates a named identifier declaration with an optional literal +// value. +// +// Literal values are typically only associated with enum identifiers. +func NewIdent(name string, t *exprpb.Type, v *exprpb.Constant) *exprpb.Decl { + return &exprpb.Decl{ + Name: name, + DeclKind: &exprpb.Decl_Ident{ + Ident: &exprpb.Decl_IdentDecl{ + Type: t, + Value: v}}} +} + +// NewInstanceOverload creates a instance function overload contract. +// First element of argTypes is instance. +func NewInstanceOverload(id string, argTypes []*exprpb.Type, + resultType *exprpb.Type) *exprpb.Decl_FunctionDecl_Overload { + return &exprpb.Decl_FunctionDecl_Overload{ + OverloadId: id, + ResultType: resultType, + Params: argTypes, + IsInstanceFunction: true} +} + +// NewListType generates a new list with elements of a certain type. +func NewListType(elem *exprpb.Type) *exprpb.Type { + return &exprpb.Type{ + TypeKind: &exprpb.Type_ListType_{ + ListType: &exprpb.Type_ListType{ + ElemType: elem}}} +} + +// NewMapType generates a new map with typed keys and values. +func NewMapType(key *exprpb.Type, value *exprpb.Type) *exprpb.Type { + return &exprpb.Type{ + TypeKind: &exprpb.Type_MapType_{ + MapType: &exprpb.Type_MapType{ + KeyType: key, + ValueType: value}}} +} + +// NewObjectType creates an object type for a qualified type name. +func NewObjectType(typeName string) *exprpb.Type { + return &exprpb.Type{ + TypeKind: &exprpb.Type_MessageType{ + MessageType: typeName}} +} + +// NewOverload creates a function overload declaration which contains a unique +// overload id as well as the expected argument and result types. Overloads +// must be aggregated within a Function declaration. +func NewOverload(id string, argTypes []*exprpb.Type, + resultType *exprpb.Type) *exprpb.Decl_FunctionDecl_Overload { + return &exprpb.Decl_FunctionDecl_Overload{ + OverloadId: id, + ResultType: resultType, + Params: argTypes, + IsInstanceFunction: false} +} + +// NewParameterizedInstanceOverload creates a parametric function instance overload type. +func NewParameterizedInstanceOverload(id string, + argTypes []*exprpb.Type, + resultType *exprpb.Type, + typeParams []string) *exprpb.Decl_FunctionDecl_Overload { + return &exprpb.Decl_FunctionDecl_Overload{ + OverloadId: id, + ResultType: resultType, + Params: argTypes, + TypeParams: typeParams, + IsInstanceFunction: true} +} + +// NewParameterizedOverload creates a parametric function overload type. +func NewParameterizedOverload(id string, + argTypes []*exprpb.Type, + resultType *exprpb.Type, + typeParams []string) *exprpb.Decl_FunctionDecl_Overload { + return &exprpb.Decl_FunctionDecl_Overload{ + OverloadId: id, + ResultType: resultType, + Params: argTypes, + TypeParams: typeParams, + IsInstanceFunction: false} +} + +// NewPrimitiveType creates a type for a primitive value. See the var declarations +// for Int, Uint, etc. +func NewPrimitiveType(primitive exprpb.Type_PrimitiveType) *exprpb.Type { + return &exprpb.Type{ + TypeKind: &exprpb.Type_Primitive{ + Primitive: primitive}} +} + +// NewTypeType creates a new type designating a type. +func NewTypeType(nested *exprpb.Type) *exprpb.Type { + return &exprpb.Type{ + TypeKind: &exprpb.Type_Type{ + Type: nested}} +} + +// NewTypeParamType creates a type corresponding to a named, contextual parameter. +func NewTypeParamType(name string) *exprpb.Type { + return &exprpb.Type{ + TypeKind: &exprpb.Type_TypeParam{ + TypeParam: name}} +} + +// NewWellKnownType creates a type corresponding to a protobuf well-known type +// value. +func NewWellKnownType(wellKnown exprpb.Type_WellKnownType) *exprpb.Type { + return &exprpb.Type{ + TypeKind: &exprpb.Type_WellKnown{ + WellKnown: wellKnown}} +} + +// NewWrapperType creates a wrapped primitive type instance. Wrapped types +// are roughly equivalent to a nullable, or optionally valued type. +func NewWrapperType(wrapped *exprpb.Type) *exprpb.Type { + primitive := wrapped.GetPrimitive() + if primitive == exprpb.Type_PRIMITIVE_TYPE_UNSPECIFIED { + // TODO: return an error + panic("Wrapped type must be a primitive") + } + return &exprpb.Type{ + TypeKind: &exprpb.Type_Wrapper{ + Wrapper: primitive}} +} diff --git a/vendor/github.com/google/cel-go/checker/decls/scopes.go b/vendor/github.com/google/cel-go/checker/decls/scopes.go new file mode 100644 index 000000000..1064c73b1 --- /dev/null +++ b/vendor/github.com/google/cel-go/checker/decls/scopes.go @@ -0,0 +1,115 @@ +// 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 decls + +import exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + +// Scopes represents nested Decl sets where the Scopes value contains a Groups containing all +// identifiers in scope and an optional parent representing outer scopes. +// Each Groups value is a mapping of names to Decls in the ident and function namespaces. +// Lookups are performed such that bindings in inner scopes shadow those in outer scopes. +type Scopes struct { + parent *Scopes + scopes *Group +} + +// NewScopes creates a new, empty Scopes. +// Some operations can't be safely performed until a Group is added with Push. +func NewScopes() *Scopes { + return &Scopes{ + scopes: newGroup(), + } +} + +// Push creates a new Scopes value which references the current Scope as its parent. +func (s *Scopes) Push() *Scopes { + return &Scopes{ + parent: s, + scopes: newGroup(), + } +} + +// Pop returns the parent Scopes value for the current scope, or the current scope if the parent +// is nil. +func (s *Scopes) Pop() *Scopes { + if s.parent != nil { + return s.parent + } + // TODO: Consider whether this should be an error / panic. + return s +} + +// 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 +} + +// 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 { + if ident, found := s.scopes.idents[name]; found { + return ident + } + if s.parent != nil { + return s.parent.FindIdent(name) + } + return nil +} + +// 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 { + if ident, found := s.scopes.idents[name]; found { + return ident + } + return nil +} + +// AddFunction 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) AddFunction(fn *exprpb.Decl) { + 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 { + if fn, found := s.scopes.functions[name]; found { + return fn + } + if s.parent != nil { + return s.parent.FindFunction(name) + } + return nil +} + +// Group is a set of Decls that is pushed on or popped off a Scopes as a unit. +// Contains separate namespaces for idenifier and function Decls. +// (Should be named "Scope" perhaps?) +type Group struct { + idents map[string]*exprpb.Decl + functions map[string]*exprpb.Decl +} + +func newGroup() *Group { + return &Group{ + idents: make(map[string]*exprpb.Decl), + functions: make(map[string]*exprpb.Decl), + } +} diff --git a/vendor/github.com/google/cel-go/checker/env.go b/vendor/github.com/google/cel-go/checker/env.go new file mode 100644 index 000000000..456e127ac --- /dev/null +++ b/vendor/github.com/google/cel-go/checker/env.go @@ -0,0 +1,352 @@ +// 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 checker + +import ( + "fmt" + "strings" + + "github.com/google/cel-go/checker/decls" + "github.com/google/cel-go/common/packages" + "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 + +const ( + dynElementType aggregateLiteralElementType = iota + homogenousElementType aggregateLiteralElementType = 1 << iota +) + +// Env is the environment for type checking. +// It consists of a Packager, a Type Provider, declarations, and collection of errors encountered +// during checking. +type Env struct { + packager packages.Packager + provider ref.TypeProvider + declarations *decls.Scopes + aggLitElemType aggregateLiteralElementType +} + +// NewEnv returns a new *Env with the given parameters. +func NewEnv(packager packages.Packager, provider ref.TypeProvider) *Env { + declarations := decls.NewScopes() + declarations.Push() + + return &Env{ + packager: packager, + provider: provider, + declarations: declarations, + } +} + +// NewStandardEnv returns a new *Env with the given params plus standard declarations. +func NewStandardEnv(packager packages.Packager, provider ref.TypeProvider) *Env { + e := NewEnv(packager, provider) + if err := e.Add(StandardDeclarations()...); err != nil { + // The standard declaration set should never have duplicate declarations. + panic(err) + } + // TODO: isolate standard declarations from the custom set which may be provided layer. + return e +} + +// EnableDynamicAggregateLiterals detmerines whether list and map literals may support mixed +// element types at check-time. This does not preclude the presence of a dynamic list or map +// somewhere in the CEL evaluation process. +func (e *Env) EnableDynamicAggregateLiterals(enabled bool) *Env { + e.aggLitElemType = dynElementType + if !enabled { + e.aggLitElemType = homogenousElementType + } + return e +} + +// Add adds new Decl protos to the Env. +// Returns an error for identifier redeclarations. +func (e *Env) Add(decls ...*exprpb.Decl) 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.addFunction(sanitizeFunction(decl))...) + } + } + 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(typeName string) *exprpb.Decl { + for _, candidate := range e.packager.ResolveCandidateNames(typeName) { + if ident := e.declarations.FindIdent(candidate); ident != nil { + return ident + } + + // 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.NewIdent(candidate, t, nil) + e.declarations.AddIdent(decl) + return 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))}}) + e.declarations.AddIdent(decl) + return decl + } + } + return nil +} + +// 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(typeName string) *exprpb.Decl { + for _, candidate := range e.packager.ResolveCandidateNames(typeName) { + if fn := e.declarations.FindFunction(candidate); fn != nil { + return fn + } + } + 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 +} + +// addFunction 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) addFunction(decl *exprpb.Decl) []errorMsg { + 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) + e.declarations.AddFunction(current) + } + + errorMsgs := make([]errorMsg, 0) + for _, overload := range decl.GetFunction().GetOverloads() { + errorMsgs = append(errorMsgs, e.addOverload(current, overload)...) + } + return errorMsgs +} + +// 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) + if current != nil { + return overlappingIdentifierError(decl.Name) + } + e.declarations.AddIdent(decl) + return "" +} + +// 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, 0, len(fn.GetOverloads())) + for i, o := range fn.GetOverloads() { + var sanitized bool + rt := o.GetResultType() + if isObjectWellKnownType(rt) { + rt = getObjectWellKnownType(rt) + sanitized = true + } + params := make([]*exprpb.Type, 0, len(o.GetParams())) + copy(params, o.GetParams()) + for j, p := range params { + if isObjectWellKnownType(p) { + params[j] = getObjectWellKnownType(p) + sanitized = true + } + } + // If sanitized, replace the overload definition. + if sanitized { + if o.IsInstanceFunction { + overloads[i] = + decls.NewInstanceOverload(o.GetOverloadId(), params, rt) + } else { + overloads[i] = + decls.NewOverload(o.GetOverloadId(), params, rt) + } + } else { + // Otherwise, preserve the original overload. + overloads[i] = o + } + } + 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()] +} + +// enterScope creates a new Env instance with a new innermost declaration scope. +func (e *Env) enterScope() *Env { + childDecls := e.declarations.Push() + return &Env{ + declarations: childDecls, + packager: e.packager, + provider: e.provider, + aggLitElemType: e.aggLitElemType, + } +} + +// exitScope creates a new Env instance with the nearest outer declaration scope. +func (e *Env) exitScope() *Env { + parentDecls := e.declarations.Pop() + return &Env{ + declarations: parentDecls, + packager: e.packager, + provider: e.provider, + aggLitElemType: e.aggLitElemType, + } +} + +// errorMsg is a type alias meant to represent error-based return values which +// may be accumulated into an error at a later point in execution. +type errorMsg string + +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)) +} + +func formatError(errMsgs []errorMsg) error { + errStrs := make([]string, 0) + if len(errMsgs) > 0 { + for i := 0; i < len(errMsgs); i++ { + if errMsgs[i] != "" { + errStrs = append(errStrs, string(errMsgs[i])) + } + } + } + if len(errStrs) > 0 { + return fmt.Errorf("%s", strings.Join(errStrs, "\n")) + } + return nil +} diff --git a/vendor/github.com/google/cel-go/checker/errors.go b/vendor/github.com/google/cel-go/checker/errors.go new file mode 100644 index 000000000..33af57cd2 --- /dev/null +++ b/vendor/github.com/google/cel-go/checker/errors.go @@ -0,0 +1,123 @@ +// 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 checker + +import ( + "github.com/google/cel-go/common" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// typeErrors is a specialization of Errors. +type typeErrors struct { + *common.Errors +} + +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) expressionDoesNotSelectField(l common.Location) { + e.ReportError(l, "expression does not select a field") +} + +func (e *typeErrors) typeDoesNotSupportFieldSelection(l common.Location, t *exprpb.Type) { + e.ReportError(l, "type '%s' does not support field selection", t) +} + +func (e *typeErrors) undefinedField(l common.Location, field string) { + e.ReportError(l, "undefined field '%s'", field) +} + +func (e *typeErrors) fieldDoesNotSupportPresenceCheck(l common.Location, field string) { + e.ReportError(l, "field '%s' does not support presence check", field) +} + +func (e *typeErrors) overlappingOverload(l common.Location, name string, overloadID1 string, f1 *exprpb.Type, + overloadID2 string, f2 *exprpb.Type) { + e.ReportError(l, "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 (e *typeErrors) overlappingMacro(l common.Location, name string, args int) { + e.ReportError(l, "overload for name '%s' with %d argument(s) overlaps with predefined macro", + name, args) +} + +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) aggregateTypeMismatch(l common.Location, aggregate *exprpb.Type, member *exprpb.Type) { + e.ReportError( + l, + "type '%s' does not match previous type '%s' in aggregate. Use 'dyn(x)' to make the aggregate dynamic.", + FormatCheckedType(member), + FormatCheckedType(aggregate)) +} + +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) notAMessageType(l common.Location, t *exprpb.Type) { + e.ReportError(l, "'%s' is not a message type", FormatCheckedType(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) unexpectedFailedResolution(l common.Location, typeName string) { + e.ReportError(l, "[internal] unexpected failed resolution of '%s'", typeName) +} + +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) typeMismatch(l common.Location, expected *exprpb.Type, actual *exprpb.Type) { + e.ReportError(l, "expected type '%s' but found '%s'", + FormatCheckedType(expected), FormatCheckedType(actual)) +} + +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 +} diff --git a/vendor/github.com/google/cel-go/checker/mapping.go b/vendor/github.com/google/cel-go/checker/mapping.go new file mode 100644 index 000000000..bd5e412db --- /dev/null +++ b/vendor/github.com/google/cel-go/checker/mapping.go @@ -0,0 +1,62 @@ +// 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 checker + +import ( + "fmt" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +type mapping struct { + mapping map[string]*exprpb.Type +} + +func newMapping() *mapping { + return &mapping{ + mapping: make(map[string]*exprpb.Type), + } +} + +func (m *mapping) add(from *exprpb.Type, to *exprpb.Type) { + m.mapping[typeKey(from)] = to +} + +func (m *mapping) find(from *exprpb.Type) (*exprpb.Type, bool) { + if r, found := m.mapping[typeKey(from)]; found { + return r, found + } + return nil, false +} + +func (m *mapping) copy() *mapping { + c := newMapping() + + for k, v := range m.mapping { + c.mapping[k] = v + } + return c +} + +func (m *mapping) String() string { + result := "{" + + for k, v := range m.mapping { + result += fmt.Sprintf("%v => %v ", k, v) + } + + result += "}" + return result +} diff --git a/vendor/github.com/google/cel-go/checker/printer.go b/vendor/github.com/google/cel-go/checker/printer.go new file mode 100644 index 000000000..15c25ecc6 --- /dev/null +++ b/vendor/github.com/google/cel-go/checker/printer.go @@ -0,0 +1,71 @@ +// 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 checker + +import ( + "github.com/google/cel-go/common/debug" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +type semanticAdorner struct { + checks *exprpb.CheckedExpr +} + +var _ debug.Adorner = &semanticAdorner{} + +func (a *semanticAdorner) GetMetadata(elem interface{}) string { + result := "" + e, isExpr := elem.(*exprpb.Expr) + if !isExpr { + return result + } + t := a.checks.TypeMap[e.Id] + if t != nil { + result += "~" + result += FormatCheckedType(t) + } + + switch e.ExprKind.(type) { + case *exprpb.Expr_IdentExpr, + *exprpb.Expr_CallExpr, + *exprpb.Expr_StructExpr, + *exprpb.Expr_SelectExpr: + if ref, found := a.checks.ReferenceMap[e.Id]; found { + if len(ref.GetOverloadId()) == 0 { + result += "^" + ref.Name + } else { + for i, overload := range ref.OverloadId { + if i == 0 { + result += "^" + } else { + result += "|" + } + result += overload + } + } + } + } + + return result +} + +// Print returns a string representation of the Expr message, +// annotated with types from the CheckedExpr. The Expr must +// be a sub-expression embedded in the CheckedExpr. +func Print(e *exprpb.Expr, checks *exprpb.CheckedExpr) string { + a := &semanticAdorner{checks: checks} + return debug.ToAdornedDebugString(e, a) +} diff --git a/vendor/github.com/google/cel-go/checker/standard.go b/vendor/github.com/google/cel-go/checker/standard.go new file mode 100644 index 000000000..773ab44a2 --- /dev/null +++ b/vendor/github.com/google/cel-go/checker/standard.go @@ -0,0 +1,440 @@ +// 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 checker + +import ( + "github.com/google/cel-go/checker/decls" + "github.com/google/cel-go/common/operators" + "github.com/google/cel-go/common/overloads" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// StandardDeclarations returns the Decls for all functions and constants in the evaluator. +func StandardDeclarations() []*exprpb.Decl { + // 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.NewIdent(FormatCheckedType(t), decls.NewTypeType(t), nil)) + } + idents = append(idents, + decls.NewIdent("list", decls.NewTypeType(listOfA), nil), + decls.NewIdent("map", decls.NewTypeType(mapOfAB), nil), + decls.NewIdent("null_type", decls.NewTypeType(decls.Null), nil), + decls.NewIdent("type", decls.NewTypeType(decls.NewTypeType(nil)), nil)) + + // Booleans + // TODO: allow the conditional to return a heterogenous type. + return append(idents, []*exprpb.Decl{ + 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)), + + // 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.LessUint64, + []*exprpb.Type{decls.Uint, decls.Uint}, decls.Bool), + decls.NewOverload(overloads.LessDouble, + []*exprpb.Type{decls.Double, decls.Double}, 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.LessEqualsUint64, + []*exprpb.Type{decls.Uint, decls.Uint}, decls.Bool), + decls.NewOverload(overloads.LessEqualsDouble, + []*exprpb.Type{decls.Double, decls.Double}, 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.GreaterUint64, + []*exprpb.Type{decls.Uint, decls.Uint}, decls.Bool), + decls.NewOverload(overloads.GreaterDouble, + []*exprpb.Type{decls.Double, decls.Double}, 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.GreaterEqualsUint64, + []*exprpb.Type{decls.Uint, decls.Uint}, decls.Bool), + decls.NewOverload(overloads.GreaterEqualsDouble, + []*exprpb.Type{decls.Double, decls.Double}, 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)), + + 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)), + //decls.NewOverload(overloads.IndexMessage, + // []*expr.Type{decls.Dyn, decls.String}, decls.Dyn)), + + // 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)), + //decls.NewOverload(overloads.InMessage, + // []*expr.Type{Dyn, decls.String},decls.Bool)), + + // 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.NewInstanceOverload(overloads.MatchString, + []*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))}...) +} diff --git a/vendor/github.com/google/cel-go/checker/types.go b/vendor/github.com/google/cel-go/checker/types.go new file mode 100644 index 000000000..2d716e0bf --- /dev/null +++ b/vendor/github.com/google/cel-go/checker/types.go @@ -0,0 +1,485 @@ +// 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 checker + +import ( + "fmt" + "strings" + + "github.com/golang/protobuf/proto" + "github.com/google/cel-go/checker/decls" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +const ( + kindUnknown = iota + 1 + kindError + kindFunction + kindDyn + kindPrimitive + kindWellKnown + kindWrapper + kindNull + kindAbstract // TODO: Update the checker protos to include abstract + 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().ElemType)) + case kindObject: + return t.GetMessageType() + case kindMap: + return fmt.Sprintf("map(%s, %s)", + FormatCheckedType(t.GetMapType().KeyType), + FormatCheckedType(t.GetMapType().ValueType)) + 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!" + } + 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 { + // 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: + 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 { + switch kindOf(t) { + case kindError: + return true + default: + return isDyn(t) + } +} + +// 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) + // The first type is less specific. + if isDyn(t1) || kind1 == kindTypeParam { + return true + } + // The first type is not less specific. + if isDyn(t2) || kind2 == kindTypeParam { + return false + } + // Types must be of the same kind to be equal. + if kind1 != kind2 { + return false + } + + // 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()) { + return false + } + for i, p1 := range a1.GetParameterTypes() { + if !isEqualOrLessSpecific(p1, a2.GetParameterTypes()[i]) { + return false + } + } + return true + case kindFunction: + fn1 := t1.GetFunction() + fn2 := t2.GetFunction() + if len(fn1.ArgTypes) != len(fn2.ArgTypes) { + return false + } + if !isEqualOrLessSpecific(fn1.ResultType, fn2.ResultType) { + return false + } + for i, a1 := range fn1.ArgTypes { + if !isEqualOrLessSpecific(a1, fn2.ArgTypes[i]) { + return false + } + } + return true + case kindList: + return isEqualOrLessSpecific(t1.GetListType().ElemType, t2.GetListType().ElemType) + case kindMap: + m1 := t1.GetMapType() + m2 := t2.GetMapType() + return isEqualOrLessSpecific(m1.KeyType, m2.KeyType) && + isEqualOrLessSpecific(m1.KeyType, m2.KeyType) + case kindType: + return true + default: + return proto.Equal(t1, t2) + } +} + +/// internalIsAssignable returns true if t1 is assignable to t2. +func internalIsAssignable(m *mapping, t1 *exprpb.Type, t2 *exprpb.Type) bool { + // A type is always assignable to itself. + // Early terminate the call to avoid cases of infinite recursion. + if proto.Equal(t1, t2) { + return true + } + // Process type parameters. + kind1, kind2 := kindOf(t1), kindOf(t2) + if kind2 == kindTypeParam { + if t2Sub, found := m.find(t2); found { + // If the types are compatible, pick the more general type and return true + if internalIsAssignable(m, t1, t2Sub) { + m.add(t2, mostGeneral(t1, t2Sub)) + return true + } + return false + } + if notReferencedIn(t2, t1) { + m.add(t2, t1) + return true + } + } + if kind1 == kindTypeParam { + // For the lower type bound, we currently do not perform adjustment. The restricted + // way we use type parameters in lower type bounds, it is not necessary, but may + // become if we generalize type unification. + if t1Sub, found := m.find(t1); found { + // If the types are compatible, pick the more general type and return true + if internalIsAssignable(m, t1Sub, t2) { + m.add(t1, mostGeneral(t1Sub, t2)) + return true + } + return false + } + if notReferencedIn(t1, t2) { + m.add(t1, t2) + return true + } + } + + // Next check for wildcard types. + 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: + 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 + } + } + + // Test for when the types must agree. + 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() + default: + return 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 { + if a1.GetName() != a2.GetName() { + return false + } + if internalIsAssignableList(m, a1.GetParameterTypes(), a2.GetParameterTypes()) { + return true + } + return false +} + +// 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 { + if internalIsAssignableList(m, + append(f1.GetArgTypes(), f1.GetResultType()), + append(f2.GetArgTypes(), f2.GetResultType())) { + 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 { + if len(l1) != len(l2) { + return false + } + for i, t1 := range l1 { + if !internalIsAssignable(m, t1, l2[i]) { + return false + } + } + 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 + } +} + +// 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 + } +} + +// isAssignable returns an updated type substitution mapping if t1 is assignable to t2. +func isAssignable(m *mapping, t1 *exprpb.Type, t2 *exprpb.Type) *mapping { + mCopy := m.copy() + if internalIsAssignable(mCopy, t1, t2) { + return mCopy + } + return nil +} + +// isAssignableList returns an updated type substitution mapping if l1 is assignable to l2. +func isAssignableList(m *mapping, l1 []*exprpb.Type, l2 []*exprpb.Type) *mapping { + mCopy := m.copy() + if internalIsAssignableList(mCopy, l1, l2) { + return mCopy + } + 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.TypeKind.(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 + } + 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 { + if isEqualOrLessSpecific(t1, t2) { + return t1 + } + return t2 +} + +// 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(t *exprpb.Type, withinType *exprpb.Type) bool { + if proto.Equal(t, withinType) { + return false + } + withinKind := kindOf(withinType) + switch withinKind { + case kindAbstract: + for _, pt := range withinType.GetAbstractType().GetParameterTypes() { + if !notReferencedIn(t, pt) { + return false + } + } + return true + case kindFunction: + fn := withinType.GetFunction() + types := append(fn.ArgTypes, fn.ResultType) + for _, a := range types { + if !notReferencedIn(t, a) { + return false + } + } + return true + case kindList: + return notReferencedIn(t, withinType.GetListType().ElemType) + case kindMap: + m := withinType.GetMapType() + return notReferencedIn(t, m.KeyType) && notReferencedIn(t, m.ValueType) + case kindWrapper: + return notReferencedIn(t, decls.NewPrimitiveType(withinType.GetWrapper())) + default: + return true + } +} + +// 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 { + if tSub, found := m.find(t); found { + return substitute(m, tSub, typeParamToDyn) + } + kind := kindOf(t) + if typeParamToDyn && kind == kindTypeParam { + return decls.Dyn + } + switch kind { + case kindAbstract: + // TODO: implement! + 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.ArgTypes)) + 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().ElemType, typeParamToDyn)) + case kindMap: + mt := t.GetMapType() + return decls.NewMapType(substitute(m, mt.KeyType, typeParamToDyn), + substitute(m, mt.ValueType, typeParamToDyn)) + case kindType: + if t.GetType() != nil { + return decls.NewTypeType(substitute(m, t.GetType(), typeParamToDyn)) + } + return t + default: + return t + } +} + +func typeKey(t *exprpb.Type) string { + return FormatCheckedType(t) +} diff --git a/vendor/github.com/google/cel-go/common/debug/debug.go b/vendor/github.com/google/cel-go/common/debug/debug.go new file mode 100644 index 000000000..5a4894733 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/debug/debug.go @@ -0,0 +1,305 @@ +// 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 debug provides tools to print a parsed expression graph and +// adorn each expression element with additional metadata. +package debug + +import ( + "bytes" + "fmt" + "strconv" + "strings" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// Adorner returns debug metadata that will be tacked on to the string +// representation of an expression. +type Adorner interface { + // GetMetadata for the input context. + GetMetadata(ctx interface{}) string +} + +// Writer manages writing expressions to an internal string. +type Writer interface { + fmt.Stringer + + // Buffer pushes an expression into an internal queue of expressions to + // write to a string. + Buffer(e *exprpb.Expr) +} + +type emptyDebugAdorner struct { +} + +var emptyAdorner Adorner = &emptyDebugAdorner{} + +func (a *emptyDebugAdorner) GetMetadata(e interface{}) string { + return "" +} + +// ToDebugString gives the unadorned string representation of the Expr. +func ToDebugString(e *exprpb.Expr) string { + return ToAdornedDebugString(e, emptyAdorner) +} + +// ToAdornedDebugString gives the adorned string representation of the Expr. +func ToAdornedDebugString(e *exprpb.Expr, adorner Adorner) string { + w := newDebugWriter(adorner) + w.Buffer(e) + return w.String() +} + +// debugWriter is used to print out pretty-printed debug strings. +type debugWriter struct { + adorner Adorner + buffer bytes.Buffer + indent int + lineStart bool +} + +func newDebugWriter(a Adorner) *debugWriter { + return &debugWriter{ + adorner: a, + indent: 0, + lineStart: true, + } +} + +func (w *debugWriter) Buffer(e *exprpb.Expr) { + if e == nil { + return + } + switch e.ExprKind.(type) { + case *exprpb.Expr_ConstExpr: + w.append(formatLiteral(e.GetConstExpr())) + case *exprpb.Expr_IdentExpr: + w.append(e.GetIdentExpr().Name) + case *exprpb.Expr_SelectExpr: + w.appendSelect(e.GetSelectExpr()) + case *exprpb.Expr_CallExpr: + w.appendCall(e.GetCallExpr()) + case *exprpb.Expr_ListExpr: + w.appendList(e.GetListExpr()) + case *exprpb.Expr_StructExpr: + w.appendStruct(e.GetStructExpr()) + case *exprpb.Expr_ComprehensionExpr: + w.appendComprehension(e.GetComprehensionExpr()) + } + w.adorn(e) +} + +func (w *debugWriter) appendSelect(sel *exprpb.Expr_Select) { + w.Buffer(sel.Operand) + w.append(".") + w.append(sel.Field) + if sel.TestOnly { + w.append("~test-only~") + } +} + +func (w *debugWriter) appendCall(call *exprpb.Expr_Call) { + if call.Target != nil { + w.Buffer(call.Target) + w.append(".") + } + w.append(call.Function) + w.append("(") + if len(call.GetArgs()) > 0 { + w.addIndent() + w.appendLine() + for i, arg := range call.Args { + if i > 0 { + w.append(",") + w.appendLine() + } + w.Buffer(arg) + } + w.removeIndent() + w.appendLine() + } + w.append(")") +} + +func (w *debugWriter) appendList(list *exprpb.Expr_CreateList) { + w.append("[") + if len(list.GetElements()) > 0 { + w.appendLine() + w.addIndent() + for i, elem := range list.Elements { + if i > 0 { + w.append(",") + w.appendLine() + } + w.Buffer(elem) + } + w.removeIndent() + w.appendLine() + } + w.append("]") +} + +func (w *debugWriter) appendStruct(obj *exprpb.Expr_CreateStruct) { + if obj.MessageName != "" { + w.appendObject(obj) + } else { + w.appendMap(obj) + } +} + +func (w *debugWriter) appendObject(obj *exprpb.Expr_CreateStruct) { + w.append(obj.MessageName) + w.append("{") + if len(obj.Entries) > 0 { + w.appendLine() + w.addIndent() + for i, entry := range obj.Entries { + if i > 0 { + w.append(",") + w.appendLine() + } + w.append(entry.GetFieldKey()) + w.append(":") + w.Buffer(entry.Value) + w.adorn(entry) + } + w.removeIndent() + w.appendLine() + } + w.append("}") +} + +func (w *debugWriter) appendMap(obj *exprpb.Expr_CreateStruct) { + w.append("{") + if len(obj.Entries) > 0 { + w.appendLine() + w.addIndent() + for i, entry := range obj.Entries { + if i > 0 { + w.append(",") + w.appendLine() + } + w.Buffer(entry.GetMapKey()) + w.append(":") + w.Buffer(entry.Value) + w.adorn(entry) + } + w.removeIndent() + w.appendLine() + } + w.append("}") +} + +func (w *debugWriter) appendComprehension(comprehension *exprpb.Expr_Comprehension) { + w.append("__comprehension__(") + w.addIndent() + w.appendLine() + w.append("// Variable") + w.appendLine() + w.append(comprehension.IterVar) + w.append(",") + w.appendLine() + w.append("// Target") + w.appendLine() + w.Buffer(comprehension.IterRange) + w.append(",") + w.appendLine() + w.append("// Accumulator") + w.appendLine() + w.append(comprehension.AccuVar) + w.append(",") + w.appendLine() + w.append("// Init") + w.appendLine() + w.Buffer(comprehension.AccuInit) + w.append(",") + w.appendLine() + w.append("// LoopCondition") + w.appendLine() + w.Buffer(comprehension.LoopCondition) + w.append(",") + w.appendLine() + w.append("// LoopStep") + w.appendLine() + w.Buffer(comprehension.LoopStep) + w.append(",") + w.appendLine() + w.append("// Result") + w.appendLine() + w.Buffer(comprehension.Result) + w.append(")") + w.removeIndent() +} + +func formatLiteral(c *exprpb.Constant) string { + switch c.ConstantKind.(type) { + case *exprpb.Constant_BoolValue: + return fmt.Sprintf("%t", c.GetBoolValue()) + case *exprpb.Constant_BytesValue: + return fmt.Sprintf("b\"%s\"", string(c.GetBytesValue())) + case *exprpb.Constant_DoubleValue: + return fmt.Sprintf("%v", c.GetDoubleValue()) + case *exprpb.Constant_Int64Value: + return fmt.Sprintf("%d", c.GetInt64Value()) + case *exprpb.Constant_StringValue: + return strconv.Quote(c.GetStringValue()) + case *exprpb.Constant_Uint64Value: + return fmt.Sprintf("%du", c.GetUint64Value()) + case *exprpb.Constant_NullValue: + return "null" + default: + panic("Unknown constant type") + } +} + +func (w *debugWriter) append(s string) { + w.doIndent() + w.buffer.WriteString(s) +} + +func (w *debugWriter) appendFormat(f string, args ...interface{}) { + w.append(fmt.Sprintf(f, args...)) +} + +func (w *debugWriter) doIndent() { + if w.lineStart { + w.lineStart = false + w.buffer.WriteString(strings.Repeat(" ", w.indent)) + } +} + +func (w *debugWriter) adorn(e interface{}) { + w.append(w.adorner.GetMetadata(e)) +} + +func (w *debugWriter) appendLine() { + w.buffer.WriteString("\n") + w.lineStart = true +} + +func (w *debugWriter) addIndent() { + w.indent++ +} + +func (w *debugWriter) removeIndent() { + w.indent-- + if w.indent < 0 { + panic("negative indent") + } +} + +func (w *debugWriter) String() string { + return w.buffer.String() +} diff --git a/vendor/github.com/google/cel-go/common/doc.go b/vendor/github.com/google/cel-go/common/doc.go new file mode 100644 index 000000000..5362fdfe4 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/doc.go @@ -0,0 +1,17 @@ +// 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 common defines types and utilities common to expression parsing, +// checking, and interpretation +package common diff --git a/vendor/github.com/google/cel-go/common/error.go b/vendor/github.com/google/cel-go/common/error.go new file mode 100644 index 000000000..bfe93d973 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/error.go @@ -0,0 +1,70 @@ +// 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 common + +import ( + "fmt" + "strings" + "unicode/utf8" + + "golang.org/x/text/width" +) + +// Error type which references a location within source and a message. +type Error struct { + Location Location + Message string +} + +const ( + dot = "." + ind = "^" +) + +var ( + wideDot = width.Widen.String(dot) + wideInd = width.Widen.String(ind) +) + +// ToDisplayString decorates the error message with the source location. +func (e *Error) ToDisplayString(source Source) string { + var result = fmt.Sprintf("ERROR: %s:%d:%d: %s", + source.Description(), + e.Location.Line(), + e.Location.Column()+1, // add one to the 0-based column for display + e.Message) + if snippet, found := source.Snippet(e.Location.Line()); found { + snippet := strings.Replace(snippet, "\t", " ", -1) + srcLine := "\n | " + snippet + var bytes = []byte(snippet) + var indLine = "\n | " + for i := 0; i < e.Location.Column() && len(bytes) > 0; i++ { + _, sz := utf8.DecodeRune(bytes) + bytes = bytes[sz:] + if sz > 1 { + indLine += wideDot + } else { + indLine += dot + } + } + if _, sz := utf8.DecodeRune(bytes); sz > 1 { + indLine += wideInd + } else { + indLine += ind + } + result += srcLine + indLine + } + return result +} diff --git a/vendor/github.com/google/cel-go/common/errors.go b/vendor/github.com/google/cel-go/common/errors.go new file mode 100644 index 000000000..e7045a5c7 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/errors.go @@ -0,0 +1,58 @@ +// 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 common + +import ( + "fmt" +) + +// Errors type which contains a list of errors observed during parsing. +type Errors struct { + errors []Error + source Source +} + +// NewErrors creates a new instance of the Errors type. +func NewErrors(source Source) *Errors { + return &Errors{ + errors: []Error{}, + source: source} +} + +// ReportError records an error at a source location. +func (e *Errors) ReportError(l Location, format string, args ...interface{}) { + err := Error{ + Location: l, + Message: fmt.Sprintf(format, args...), + } + e.errors = append(e.errors, err) +} + +// GetErrors returns the list of observed errors. +func (e *Errors) GetErrors() []Error { + return e.errors[:] +} + +// ToDisplayString returns the error set to a newline delimited string. +func (e *Errors) ToDisplayString() string { + var result = "" + for i, err := range e.errors { + if i >= 1 { + result += "\n" + } + result += err.ToDisplayString(e.source) + } + return result +} diff --git a/vendor/github.com/google/cel-go/common/location.go b/vendor/github.com/google/cel-go/common/location.go new file mode 100644 index 000000000..31fce6cd3 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/location.go @@ -0,0 +1,51 @@ +// 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 common + +// Location interface to represent a location within Source. +type Location interface { + Line() int // 1-based line number within source. + Column() int // 0-based column number within source. +} + +// SourceLocation helper type to manually construct a location. +type SourceLocation struct { + line int + column int +} + +var ( + // Location implements the SourcceLocation interface. + _ Location = &SourceLocation{} + // NoLocation is a particular illegal location. + NoLocation = &SourceLocation{-1, -1} +) + +// NewLocation creates a new location. +func NewLocation(line, column int) Location { + return &SourceLocation{ + line: line, + column: column} +} + +// Line returns the 1-based line of the location. +func (l *SourceLocation) Line() int { + return l.line +} + +// Column returns the 0-based column number of the location. +func (l *SourceLocation) Column() int { + return l.column +} diff --git a/vendor/github.com/google/cel-go/common/operators/operators.go b/vendor/github.com/google/cel-go/common/operators/operators.go new file mode 100644 index 000000000..8f832c4d4 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/operators/operators.go @@ -0,0 +1,145 @@ +// 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 operators defines the internal function names of operators. +// +// ALl operators in the expression language are modelled as function calls. +package operators + +// String "names" for CEL operators. +const ( + // Symbolic operators. + Conditional = "_?_:_" + LogicalAnd = "_&&_" + LogicalOr = "_||_" + LogicalNot = "!_" + Equals = "_==_" + NotEquals = "_!=_" + Less = "_<_" + LessEquals = "_<=_" + Greater = "_>_" + GreaterEquals = "_>=_" + Add = "_+_" + Subtract = "_-_" + Multiply = "_*_" + Divide = "_/_" + Modulo = "_%_" + Negate = "-_" + Index = "_[_]" + + // Macros, must have a valid identifier. + Has = "has" + All = "all" + Exists = "exists" + ExistsOne = "exists_one" + Map = "map" + Filter = "filter" + + // Named operators, must not have be valid identifiers. + NotStrictlyFalse = "@not_strictly_false" + In = "@in" + + // Deprecated: named operators with valid identifiers. + OldNotStrictlyFalse = "__not_strictly_false__" + OldIn = "_in_" +) + +var ( + operators = map[string]string{ + "+": Add, + "/": Divide, + "==": Equals, + ">": Greater, + ">=": GreaterEquals, + "in": In, + "<": Less, + "<=": LessEquals, + "%": Modulo, + "*": Multiply, + "!=": NotEquals, + "-": Subtract, + } + reverseOperators = map[string]string{ + Add: "+", + Divide: "/", + Equals: "==", + Greater: ">", + GreaterEquals: ">=", + In: "in", + Less: "<", + LessEquals: "<=", + LogicalAnd: "&&", + LogicalNot: "!", + LogicalOr: "||", + Modulo: "%", + Multiply: "*", + Negate: "-", + NotEquals: "!=", + OldIn: "in", + Subtract: "-", + } + // precedence of the operator, where the higher value means higher. + precedence = map[string]int{ + Conditional: 8, + LogicalOr: 7, + LogicalAnd: 6, + Equals: 5, + Greater: 5, + GreaterEquals: 5, + In: 5, + Less: 5, + LessEquals: 5, + NotEquals: 5, + OldIn: 5, + Add: 4, + Subtract: 4, + Divide: 3, + Modulo: 3, + Multiply: 3, + LogicalNot: 2, + Negate: 2, + Index: 1, + } +) + +// Find the internal function name for an operator, if the input text is one. +func Find(text string) (string, bool) { + op, found := operators[text] + return op, found +} + +// FindReverse returns the unmangled, text representation of the operator. +func FindReverse(op string) (string, bool) { + txt, found := reverseOperators[op] + return txt, found +} + +// FindReverseBinaryOperator returns the unmangled, text representation of a binary operator. +func FindReverseBinaryOperator(op string) (string, bool) { + if op == LogicalNot || op == Negate { + return "", false + } + txt, found := reverseOperators[op] + return txt, found +} + +// Precedence returns the operator precedence, where the higher the number indicates +// higher precedence operations. +func Precedence(op string) int { + p, found := precedence[op] + if found { + return p + } + return 0 +} diff --git a/vendor/github.com/google/cel-go/common/overloads/overloads.go b/vendor/github.com/google/cel-go/common/overloads/overloads.go new file mode 100644 index 000000000..5ec4ef9a5 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/overloads/overloads.go @@ -0,0 +1,273 @@ +// 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 overloads defines the internal overload identifiers for function and +// operator overloads. +package overloads + +// Boolean logic overloads +const ( + Conditional = "conditional" + LogicalAnd = "logical_and" + LogicalOr = "logical_or" + LogicalNot = "logical_not" + NotStrictlyFalse = "not_strictly_false" + Equals = "equals" + NotEquals = "not_equals" + LessBool = "less_bool" + LessInt64 = "less_int64" + LessUint64 = "less_uint64" + LessDouble = "less_double" + LessString = "less_string" + LessBytes = "less_bytes" + LessTimestamp = "less_timestamp" + LessDuration = "less_duration" + LessEqualsBool = "less_equals_bool" + LessEqualsInt64 = "less_equals_int64" + LessEqualsUint64 = "less_equals_uint64" + LessEqualsDouble = "less_equals_double" + LessEqualsString = "less_equals_string" + LessEqualsBytes = "less_equals_bytes" + LessEqualsTimestamp = "less_equals_timestamp" + LessEqualsDuration = "less_equals_duration" + GreaterBool = "greater_bool" + GreaterInt64 = "greater_int64" + GreaterUint64 = "greater_uint64" + GreaterDouble = "greater_double" + GreaterString = "greater_string" + GreaterBytes = "greater_bytes" + GreaterTimestamp = "greater_timestamp" + GreaterDuration = "greater_duration" + GreaterEqualsBool = "greater_equals_bool" + GreaterEqualsInt64 = "greater_equals_int64" + GreaterEqualsUint64 = "greater_equals_uint64" + GreaterEqualsDouble = "greater_equals_double" + GreaterEqualsString = "greater_equals_string" + GreaterEqualsBytes = "greater_equals_bytes" + GreaterEqualsTimestamp = "greater_equals_timestamp" + GreaterEqualsDuration = "greater_equals_duration" +) + +// Math overloads +const ( + AddInt64 = "add_int64" + AddUint64 = "add_uint64" + AddDouble = "add_double" + AddString = "add_string" + AddBytes = "add_bytes" + AddList = "add_list" + AddTimestampDuration = "add_timestamp_duration" + AddDurationTimestamp = "add_duration_timestamp" + AddDurationDuration = "add_duration_duration" + SubtractInt64 = "subtract_int64" + SubtractUint64 = "subtract_uint64" + SubtractDouble = "subtract_double" + SubtractTimestampTimestamp = "subtract_timestamp_timestamp" + SubtractTimestampDuration = "subtract_timestamp_duration" + SubtractDurationDuration = "subtract_duration_duration" + MultiplyInt64 = "multiply_int64" + MultiplyUint64 = "multiply_uint64" + MultiplyDouble = "multiply_double" + DivideInt64 = "divide_int64" + DivideUint64 = "divide_uint64" + DivideDouble = "divide_double" + ModuloInt64 = "modulo_int64" + ModuloUint64 = "modulo_uint64" + NegateInt64 = "negate_int64" + NegateDouble = "negate_double" +) + +// Index overloads +const ( + IndexList = "index_list" + IndexMap = "index_map" + IndexMessage = "index_message" // TODO: introduce concept of types.Message +) + +// In operators +const ( + DeprecatedIn = "in" + InList = "in_list" + InMap = "in_map" + InMessage = "in_message" // TODO: introduce concept of types.Message +) + +// Size overloads +const ( + Size = "size" + SizeString = "size_string" + SizeBytes = "size_bytes" + SizeList = "size_list" + SizeMap = "size_map" + SizeStringInst = "string_size" + SizeBytesInst = "bytes_size" + SizeListInst = "list_size" + SizeMapInst = "map_size" +) + +// String function names. +const ( + Contains = "contains" + EndsWith = "endsWith" + Matches = "matches" + StartsWith = "startsWith" +) + +// String function overload names. +const ( + ContainsString = "contains_string" + EndsWithString = "ends_with_string" + MatchString = "matches_string" + StartsWithString = "starts_with_string" +) + +// Time-based functions. +const ( + TimeGetFullYear = "getFullYear" + TimeGetMonth = "getMonth" + TimeGetDayOfYear = "getDayOfYear" + TimeGetDate = "getDate" + TimeGetDayOfMonth = "getDayOfMonth" + TimeGetDayOfWeek = "getDayOfWeek" + TimeGetHours = "getHours" + TimeGetMinutes = "getMinutes" + TimeGetSeconds = "getSeconds" + TimeGetMilliseconds = "getMilliseconds" +) + +// Timestamp overloads for time functions without timezones. +const ( + TimestampToYear = "timestamp_to_year" + TimestampToMonth = "timestamp_to_month" + TimestampToDayOfYear = "timestamp_to_day_of_year" + TimestampToDayOfMonthZeroBased = "timestamp_to_day_of_month" + TimestampToDayOfMonthOneBased = "timestamp_to_day_of_month_1_based" + TimestampToDayOfWeek = "timestamp_to_day_of_week" + TimestampToHours = "timestamp_to_hours" + TimestampToMinutes = "timestamp_to_minutes" + TimestampToSeconds = "timestamp_to_seconds" + TimestampToMilliseconds = "timestamp_to_milliseconds" +) + +// Timestamp overloads for time functions with timezones. +const ( + TimestampToYearWithTz = "timestamp_to_year_with_tz" + TimestampToMonthWithTz = "timestamp_to_month_with_tz" + TimestampToDayOfYearWithTz = "timestamp_to_day_of_year_with_tz" + TimestampToDayOfMonthZeroBasedWithTz = "timestamp_to_day_of_month_with_tz" + TimestampToDayOfMonthOneBasedWithTz = "timestamp_to_day_of_month_1_based_with_tz" + TimestampToDayOfWeekWithTz = "timestamp_to_day_of_week_with_tz" + TimestampToHoursWithTz = "timestamp_to_hours_with_tz" + TimestampToMinutesWithTz = "timestamp_to_minutes_with_tz" + TimestampToSecondsWithTz = "timestamp_to_seconds_tz" + TimestampToMillisecondsWithTz = "timestamp_to_milliseconds_with_tz" +) + +// Duration overloads for time functions. +const ( + DurationToHours = "duration_to_hours" + DurationToMinutes = "duration_to_minutes" + DurationToSeconds = "duration_to_seconds" + DurationToMilliseconds = "duration_to_milliseconds" +) + +// Type conversion methods and overloads +const ( + TypeConvertInt = "int" + TypeConvertUint = "uint" + TypeConvertDouble = "double" + TypeConvertBool = "bool" + TypeConvertString = "string" + TypeConvertBytes = "bytes" + TypeConvertTimestamp = "timestamp" + TypeConvertDuration = "duration" + TypeConvertType = "type" + TypeConvertDyn = "dyn" +) + +// Int conversion functions. +const ( + IntToInt = "int64_to_int64" + UintToInt = "uint64_to_int64" + DoubleToInt = "double_to_int64" + StringToInt = "string_to_int64" + TimestampToInt = "timestamp_to_int64" + DurationToInt = "duration_to_int64" +) + +// Uint conversion functions. +const ( + UintToUint = "uint64_to_uint64" + IntToUint = "int64_to_uint64" + DoubleToUint = "double_to_uint64" + StringToUint = "string_to_uint64" +) + +// Double conversion functions. +const ( + DoubleToDouble = "double_to_double" + IntToDouble = "int64_to_double" + UintToDouble = "uint64_to_double" + StringToDouble = "string_to_double" +) + +// Bool conversion functions. +const ( + BoolToBool = "bool_to_bool" + StringToBool = "string_to_bool" +) + +// Bytes conversion functions. +const ( + BytesToBytes = "bytes_to_bytes" + StringToBytes = "string_to_bytes" +) + +// String conversion functions. +const ( + StringToString = "string_to_string" + BoolToString = "bool_to_string" + IntToString = "int64_to_string" + UintToString = "uint64_to_string" + DoubleToString = "double_to_string" + BytesToString = "bytes_to_string" + TimestampToString = "timestamp_to_string" + DurationToString = "duration_to_string" +) + +// Timestamp conversion functions +const ( + TimestampToTimestamp = "timestamp_to_timestamp" + StringToTimestamp = "string_to_timestamp" + IntToTimestamp = "int64_to_timestamp" +) + +// Convert duration from string +const ( + DurationToDuration = "duration_to_duration" + StringToDuration = "string_to_duration" + IntToDuration = "int64_to_duration" +) + +// Convert to dyn +const ( + ToDyn = "to_dyn" +) + +// Comprehensions helper methods, not directly accessible via a developer. +const ( + Iterator = "@iterator" + HasNext = "@hasNext" + Next = "@next" +) diff --git a/vendor/github.com/google/cel-go/common/packages/packager.go b/vendor/github.com/google/cel-go/common/packages/packager.go new file mode 100644 index 000000000..4a2c37d79 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/packages/packager.go @@ -0,0 +1,82 @@ +// 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 packages defines types for interpreting qualified names. +*/ +package packages + +import ( + "strings" +) + +// Packager helps interpret qualified names. +type Packager interface { + // Package returns the qualified package name of the packager. + // + // The package path may be a namespace, package, or type. + Package() string + + // ResolveCandidateNames returns the list of possible qualified names + // visible within the module in name resolution order. + // + // Name candidates are returned in order of most to least qualified in + // order to ensure that shadowing names are encountered first. + ResolveCandidateNames(name string) []string +} + +var ( + // DefaultPackage has an empty package name. + DefaultPackage = NewPackage("") +) + +// NewPackage creates a new Packager with the given qualified package name. +func NewPackage(pkg string) Packager { + return &defaultPackage{pkg: pkg} +} + +type defaultPackage struct { + pkg string +} + +func (p *defaultPackage) Package() string { + return p.pkg +} + +// ResolveCandidateNames returns the candidates name of namespaced +// identifiers in C++ resolution order. +// +// Names which shadow other names are returned first. If a name includes a +// leading dot ('.'), the name is treated as an absolute identifier which +// cannot be shadowed. +// +// Given a package name a.b.c.M.N and a type name R.s, this will deliver in +// order a.b.c.M.N.R.s, a.b.c.M.R.s, a.b.c.R.s, a.b.R.s, a.R.s, R.s. +func (p *defaultPackage) ResolveCandidateNames(name string) []string { + if strings.HasPrefix(name, ".") { + return []string{name[1:]} + } + + if p.pkg == "" { + return []string{name} + } + + nextPkg := p.pkg + candidates := []string{nextPkg + "." + name} + for i := strings.LastIndex(nextPkg, "."); i >= 0; i = strings.LastIndex(nextPkg, ".") { + nextPkg = nextPkg[:i] + candidates = append(candidates, nextPkg+"."+name) + } + return append(candidates, name) +} diff --git a/vendor/github.com/google/cel-go/common/source.go b/vendor/github.com/google/cel-go/common/source.go new file mode 100644 index 000000000..a2f550bab --- /dev/null +++ b/vendor/github.com/google/cel-go/common/source.go @@ -0,0 +1,189 @@ +// 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 common + +import ( + "strings" + "unicode/utf8" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// Source interface for filter source contents. +type Source interface { + // Content returns the source content represented as a string. + // Examples contents are the single file contents, textbox field, + // or url parameter. + Content() string + + // Description gives a brief description of the source. + // Example descriptions are a file name or ui element. + Description() string + + // LineOffsets gives the character offsets at which lines occur. + // The zero-th entry should refer to the break between the first + // and second line, or EOF if there is only one line of source. + LineOffsets() []int32 + + // LocationOffset translates a Location to an offset. + // Given the line and column of the Location returns the + // Location's character offset in the Source, and a bool + // indicating whether the Location was found. + LocationOffset(location Location) (int32, bool) + + // OffsetLocation translates a character offset to a Location, or + // false if the conversion was not feasible. + OffsetLocation(offset int32) (Location, bool) + + // Snippet returns a line of content and whether the line was found. + Snippet(line int) (string, bool) + + // IDOffset returns the raw character offset of an expression within + // the source, or false if the expression cannot be found. + IDOffset(exprID int64) (int32, bool) + + // IDLocation returns a Location for the given expression id, + // or false if one cannot be found. It behaves as the obvious + // composition of IdOffset() and OffsetLocation(). + IDLocation(exprID int64) (Location, bool) +} + +// The sourceImpl type implementation of the Source interface. +type sourceImpl struct { + contents []rune + description string + lineOffsets []int32 + idOffsets map[int64]int32 +} + +// TODO(jimlarson) "Character offsets" should index the code points +// within the UTF-8 encoded string. It currently indexes bytes. +// Can be accomplished by using rune[] instead of string for contents. + +// NewTextSource creates a new Source from the input text string. +func NewTextSource(text string) Source { + return NewStringSource(text, "") +} + +// NewStringSource creates a new Source from the given contents and description. +func NewStringSource(contents string, description string) Source { + // Compute line offsets up front as they are referred to frequently. + lines := strings.Split(contents, "\n") + offsets := make([]int32, len(lines)) + var offset int32 + for i, line := range lines { + offset = offset + int32(utf8.RuneCountInString(line)) + 1 + offsets[int32(i)] = offset + } + return &sourceImpl{ + contents: []rune(contents), + description: description, + lineOffsets: offsets, + idOffsets: map[int64]int32{}, + } +} + +// NewInfoSource creates a new Source from a SourceInfo. +func NewInfoSource(info *exprpb.SourceInfo) Source { + return &sourceImpl{ + contents: []rune(""), + description: info.Location, + lineOffsets: info.LineOffsets, + idOffsets: info.Positions, + } +} + +func (s *sourceImpl) Content() string { + return string(s.contents) +} + +func (s *sourceImpl) Description() string { + return s.description +} + +func (s *sourceImpl) LineOffsets() []int32 { + return s.lineOffsets +} + +func (s *sourceImpl) LocationOffset(location Location) (int32, bool) { + if lineOffset, found := s.findLineOffset(location.Line()); found { + return lineOffset + int32(location.Column()), true + } + return -1, false +} + +func (s *sourceImpl) OffsetLocation(offset int32) (Location, bool) { + line, lineOffset := s.findLine(offset) + return NewLocation(int(line), int(offset-lineOffset)), true +} + +func (s *sourceImpl) Snippet(line int) (string, bool) { + charStart, found := s.findLineOffset(line) + if !found || len(s.contents) == 0 { + return "", false + } + charEnd, found := s.findLineOffset(line + 1) + if found { + return string(s.contents[charStart : charEnd-1]), true + } + return string(s.contents[charStart:]), true +} + +func (s *sourceImpl) IDOffset(exprID int64) (int32, bool) { + if offset, found := s.idOffsets[exprID]; found { + return offset, true + } + return -1, false +} + +func (s *sourceImpl) IDLocation(exprID int64) (Location, bool) { + if offset, found := s.IDOffset(exprID); found { + if location, found := s.OffsetLocation(offset); found { + return location, true + } + } + return NewLocation(1, 0), false +} + +// findLineOffset returns the offset where the (1-indexed) line begins, +// or false if line doesn't exist. +func (s *sourceImpl) findLineOffset(line int) (int32, bool) { + if line == 1 { + return 0, true + } else if line > 1 && line <= int(len(s.lineOffsets)) { + offset := s.lineOffsets[line-2] + return offset, true + } + return -1, false +} + +// findLine finds the line that contains the given character offset and +// returns the line number and offset of the beginning of that line. +// Note that the last line is treated as if it contains all offsets +// beyond the end of the actual source. +func (s *sourceImpl) findLine(characterOffset int32) (int32, int32) { + var line int32 = 1 + for _, lineOffset := range s.lineOffsets { + if lineOffset > characterOffset { + break + } else { + line++ + } + } + if line == 1 { + return line, 0 + } + return line, s.lineOffsets[line-2] +} diff --git a/vendor/github.com/google/cel-go/common/types/any_value.go b/vendor/github.com/google/cel-go/common/types/any_value.go new file mode 100644 index 000000000..8272ca006 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/any_value.go @@ -0,0 +1,24 @@ +// 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 ( + "reflect" + + anypb "github.com/golang/protobuf/ptypes/any" +) + +// anyValueType constant representing the reflected type of google.protobuf.Any. +var anyValueType = reflect.TypeOf(&anypb.Any{}) diff --git a/vendor/github.com/google/cel-go/common/types/bool.go b/vendor/github.com/google/cel-go/common/types/bool.go new file mode 100644 index 000000000..44649c78d --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/bool.go @@ -0,0 +1,142 @@ +// 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" + "strconv" + + "github.com/golang/protobuf/ptypes" + + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + + structpb "github.com/golang/protobuf/ptypes/struct" + wrapperspb "github.com/golang/protobuf/ptypes/wrappers" +) + +// Bool type that implements ref.Val and supports comparison and negation. +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{}) +) + +// Boolean constants +var ( + False = Bool(false) + True = Bool(true) +) + +// Compare implements the traits.Comparer interface method. +func (b Bool) Compare(other ref.Val) ref.Val { + otherBool, ok := other.(Bool) + if !ok { + return ValOrErr(other, "no such overload") + } + if b == otherBool { + return IntZero + } + if !b && otherBool { + return IntNegOne + } + return IntOne +} + +// ConvertToNative implements the ref.Val interface method. +func (b Bool) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + switch typeDesc.Kind() { + case reflect.Bool: + return bool(b), nil + case reflect.Ptr: + switch typeDesc { + case anyValueType: + // Primitives must be wrapped before being set on an Any field. + return ptypes.MarshalAny(&wrapperspb.BoolValue{Value: bool(b)}) + case boolWrapperType: + // Convert the bool to a protobuf.BoolValue. + return &wrapperspb.BoolValue{Value: bool(b)}, nil + case jsonValueType: + return &structpb.Value{ + Kind: &structpb.Value_BoolValue{BoolValue: bool(b)}, + }, nil + default: + if typeDesc.Elem().Kind() == reflect.Bool { + p := bool(b) + return &p, nil + } + } + case reflect.Interface: + if reflect.TypeOf(b).Implements(typeDesc) { + return b, nil + } + } + return nil, fmt.Errorf("type conversion error from bool to '%v'", typeDesc) +} + +// ConvertToType implements the ref.Val interface method. +func (b Bool) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case StringType: + return String(strconv.FormatBool(bool(b))) + case BoolType: + return b + case TypeType: + return BoolType + } + return NewErr("type conversion error from '%v' to '%v'", BoolType, typeVal) +} + +// Equal implements the ref.Val interface method. +func (b Bool) Equal(other ref.Val) ref.Val { + otherBool, ok := other.(Bool) + if !ok { + return ValOrErr(other, "no such overload") + } + return Bool(b == otherBool) +} + +// Negate implements the traits.Negater interface method. +func (b Bool) Negate() ref.Val { + return !b +} + +// Type implements the ref.Val interface method. +func (b Bool) Type() ref.Type { + return BoolType +} + +// Value implements the ref.Val interface method. +func (b Bool) Value() interface{} { + return bool(b) +} + +// IsBool returns whether the input ref.Val or ref.Type is equal to BoolType. +func IsBool(elem interface{}) bool { + switch elem.(type) { + case ref.Type: + return elem == BoolType + case ref.Val: + return IsBool(elem.(ref.Val).Type()) + } + return false +} diff --git a/vendor/github.com/google/cel-go/common/types/bytes.go b/vendor/github.com/google/cel-go/common/types/bytes.go new file mode 100644 index 000000000..0caf4754e --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/bytes.go @@ -0,0 +1,132 @@ +// 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 ( + "bytes" + "encoding/base64" + "fmt" + "reflect" + + "github.com/golang/protobuf/ptypes" + + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + + structpb "github.com/golang/protobuf/ptypes/struct" + wrapperspb "github.com/golang/protobuf/ptypes/wrappers" +) + +// Bytes type that implements ref.Val and supports add, compare, and size +// operations. +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{}) +) + +// Add implements traits.Adder interface method by concatenating byte sequences. +func (b Bytes) Add(other ref.Val) ref.Val { + otherBytes, ok := other.(Bytes) + if !ok { + return ValOrErr(other, "no such overload") + } + return append(b, otherBytes...) +} + +// Compare implments traits.Comparer interface method by lexicographic ordering. +func (b Bytes) Compare(other ref.Val) ref.Val { + otherBytes, ok := other.(Bytes) + if !ok { + return ValOrErr(other, "no such overload") + } + return Int(bytes.Compare(b, otherBytes)) +} + +// ConvertToNative implements the ref.Val interface method. +func (b Bytes) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + switch typeDesc.Kind() { + case reflect.Array, reflect.Slice: + if typeDesc.Elem().Kind() == reflect.Uint8 { + return b.Value(), nil + } + case reflect.Ptr: + switch typeDesc { + case anyValueType: + // Primitives must be wrapped before being set on an Any field. + return ptypes.MarshalAny(&wrapperspb.BytesValue{Value: []byte(b)}) + case byteWrapperType: + // Convert the bytes to a protobuf.BytesValue. + return &wrapperspb.BytesValue{Value: []byte(b)}, nil + case jsonValueType: + // CEL follows the proto3 to JSON conversion by encoding bytes to a string via base64. + // The encoding below matches the golang 'encoding/json' behavior during marshaling, + // which uses base64.StdEncoding. + str := base64.StdEncoding.EncodeToString([]byte(b)) + return &structpb.Value{ + Kind: &structpb.Value_StringValue{StringValue: str}, + }, nil + } + case reflect.Interface: + if reflect.TypeOf(b).Implements(typeDesc) { + return b, nil + } + } + return nil, fmt.Errorf("type conversion error from Bytes to '%v'", typeDesc) +} + +// ConvertToType implements the ref.Val interface method. +func (b Bytes) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case StringType: + return String(b) + case BytesType: + return b + case TypeType: + return BytesType + } + return NewErr("type conversion error from '%s' to '%s'", BytesType, typeVal) +} + +// Equal implements the ref.Val interface method. +func (b Bytes) Equal(other ref.Val) ref.Val { + otherBytes, ok := other.(Bytes) + if !ok { + return ValOrErr(other, "no such overload") + } + return Bool(bytes.Equal(b, otherBytes)) +} + +// Size implements the traits.Sizer interface method. +func (b Bytes) Size() ref.Val { + return Int(len(b)) +} + +// Type implements the ref.Val interface method. +func (b Bytes) Type() ref.Type { + return BytesType +} + +// Value implements the ref.Val interface method. +func (b Bytes) Value() interface{} { + return []byte(b) +} diff --git a/vendor/github.com/google/cel-go/common/types/doc.go b/vendor/github.com/google/cel-go/common/types/doc.go new file mode 100644 index 000000000..5f641d704 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/doc.go @@ -0,0 +1,17 @@ +// 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 contains the types, traits, and utilities common to all +// components of expression handling. +package types diff --git a/vendor/github.com/google/cel-go/common/types/double.go b/vendor/github.com/google/cel-go/common/types/double.go new file mode 100644 index 000000000..ea2218c33 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/double.go @@ -0,0 +1,185 @@ +// 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" + + "github.com/golang/protobuf/ptypes" + + structpb "github.com/golang/protobuf/ptypes/struct" + wrapperspb "github.com/golang/protobuf/ptypes/wrappers" +) + +// Double type that implements ref.Val, comparison, and mathematical +// operations. +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{}) + + // floatWrapperType reflected type for protobuf float wrapper type. + floatWrapperType = reflect.TypeOf(&wrapperspb.FloatValue{}) +) + +// Add implements traits.Adder.Add. +func (d Double) Add(other ref.Val) ref.Val { + otherDouble, ok := other.(Double) + if !ok { + return ValOrErr(other, "no such overload") + } + return d + otherDouble +} + +// Compare implements traits.Comparer.Compare. +func (d Double) Compare(other ref.Val) ref.Val { + otherDouble, ok := other.(Double) + if !ok { + return ValOrErr(other, "no such overload") + } + if d < otherDouble { + return IntNegOne + } + if d > otherDouble { + return IntOne + } + return IntZero +} + +// ConvertToNative implements ref.Val.ConvertToNative. +func (d Double) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + switch typeDesc.Kind() { + case reflect.Float32: + return float32(d), nil + case reflect.Float64: + return float64(d), nil + case reflect.Ptr: + switch typeDesc { + case anyValueType: + // Primitives must be wrapped before being set on an Any field. + return ptypes.MarshalAny(&wrapperspb.DoubleValue{Value: float64(d)}) + case doubleWrapperType: + // Convert to a protobuf.DoubleValue + return &wrapperspb.DoubleValue{Value: float64(d)}, nil + case floatWrapperType: + // Convert to a protobuf.FloatValue (with truncation). + return &wrapperspb.FloatValue{Value: float32(d)}, nil + case jsonValueType: + // Note, there are special cases for proto3 to json conversion that + // expect the floating point value to be converted to a NaN, + // Infinity, or -Infinity string values, but the jsonpb string + // marshaling of the protobuf.Value will handle this conversion. + return &structpb.Value{ + Kind: &structpb.Value_NumberValue{NumberValue: float64(d)}, + }, nil + } + switch typeDesc.Elem().Kind() { + case reflect.Float32: + p := float32(d) + return &p, nil + case reflect.Float64: + p := float64(d) + return &p, nil + } + case reflect.Interface: + if reflect.TypeOf(d).Implements(typeDesc) { + return d, nil + } + } + return nil, fmt.Errorf("type conversion error from Double to '%v'", typeDesc) +} + +// ConvertToType implements ref.Val.ConvertToType. +func (d Double) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case IntType: + return Int(float64(d)) + case UintType: + return Uint(float64(d)) + case DoubleType: + return d + case StringType: + return String(fmt.Sprintf("%g", float64(d))) + case TypeType: + return DoubleType + } + return NewErr("type conversion error from '%s' to '%s'", DoubleType, typeVal) +} + +// Divide implements traits.Divider.Divide. +func (d Double) Divide(other ref.Val) ref.Val { + otherDouble, ok := other.(Double) + if !ok { + return ValOrErr(other, "no such overload") + } + return d / otherDouble +} + +// Equal implements ref.Val.Equal. +func (d Double) Equal(other ref.Val) ref.Val { + otherDouble, ok := other.(Double) + if !ok { + return ValOrErr(other, "no such overload") + } + // TODO: Handle NaNs properly. + return Bool(d == otherDouble) +} + +// Multiply implements traits.Multiplier.Multiply. +func (d Double) Multiply(other ref.Val) ref.Val { + otherDouble, ok := other.(Double) + if !ok { + return ValOrErr(other, "no such overload") + } + return d * otherDouble +} + +// Negate implements traits.Negater.Negate. +func (d Double) Negate() ref.Val { + return -d +} + +// Subtract implements traits.Subtractor.Subtract. +func (d Double) Subtract(subtrahend ref.Val) ref.Val { + subtraDouble, ok := subtrahend.(Double) + if !ok { + return ValOrErr(subtrahend, "no such overload") + } + return d - subtraDouble +} + +// Type implements ref.Val.Type. +func (d Double) Type() ref.Type { + return DoubleType +} + +// Value implements ref.Val.Value. +func (d Double) Value() interface{} { + return float64(d) +} diff --git a/vendor/github.com/google/cel-go/common/types/duration.go b/vendor/github.com/google/cel-go/common/types/duration.go new file mode 100644 index 000000000..6b0016abd --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/duration.go @@ -0,0 +1,220 @@ +// 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" + "strconv" + "time" + + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes" + + "github.com/google/cel-go/common/overloads" + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + + dpb "github.com/golang/protobuf/ptypes/duration" + structpb "github.com/golang/protobuf/ptypes/struct" +) + +// Duration type that implements ref.Val and supports add, compare, negate, +// and subtract operators. This type is also a receiver which means it can +// participate in dispatch to receiver functions. +type Duration struct { + *dpb.Duration +} + +var ( + // DurationType singleton. + DurationType = NewTypeValue("google.protobuf.Duration", + traits.AdderType, + traits.ComparerType, + traits.NegatorType, + traits.ReceiverType, + traits.SubtractorType) +) + +// Add implements traits.Adder.Add. +func (d Duration) Add(other ref.Val) ref.Val { + switch other.Type() { + case DurationType: + dur1, err := ptypes.Duration(d.Duration) + if err != nil { + return &Err{err} + } + dur2, err := ptypes.Duration(other.(Duration).Duration) + if err != nil { + return &Err{err} + } + return Duration{ptypes.DurationProto(dur1 + dur2)} + case TimestampType: + dur, err := ptypes.Duration(d.Duration) + if err != nil { + return &Err{err} + } + ts, err := ptypes.Timestamp(other.(Timestamp).Timestamp) + if err != nil { + return &Err{err} + } + tstamp, err := ptypes.TimestampProto(ts.Add(dur)) + if err != nil { + return &Err{err} + } + return Timestamp{tstamp} + } + return ValOrErr(other, "no such overload") +} + +// Compare implements traits.Comparer.Compare. +func (d Duration) Compare(other ref.Val) ref.Val { + otherDur, ok := other.(Duration) + if !ok { + return ValOrErr(other, "no such overload") + } + dur1, err := ptypes.Duration(d.Duration) + if err != nil { + return &Err{err} + } + dur2, err := ptypes.Duration(otherDur.Duration) + if err != nil { + return &Err{err} + } + dur := dur1 - dur2 + if dur < 0 { + return IntNegOne + } + if dur > 0 { + return IntOne + } + return IntZero +} + +// ConvertToNative implements ref.Val.ConvertToNative. +func (d Duration) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + switch typeDesc { + case anyValueType: + // Pack the underlying proto value into an Any value. + return ptypes.MarshalAny(d.Value().(*dpb.Duration)) + case durationValueType: + // Unwrap the CEL value to its underlying proto value. + return d.Value(), nil + case jsonValueType: + // CEL follows the proto3 to JSON conversion. + // Note, using jsonpb would wrap the result in extra double quotes. + v := d.ConvertToType(StringType) + if IsError(v) { + return nil, v.(*Err) + } + return &structpb.Value{ + Kind: &structpb.Value_StringValue{StringValue: string(v.(String))}, + }, nil + } + // If the duration is already assignable to the desired type return it. + if reflect.TypeOf(d).AssignableTo(typeDesc) { + return d, nil + } + return nil, fmt.Errorf("type conversion error from "+ + "'google.protobuf.Duration' to '%v'", typeDesc) +} + +// ConvertToType implements ref.Val.ConvertToType. +func (d Duration) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case StringType: + if dur, err := ptypes.Duration(d.Duration); err == nil { + return String(strconv.FormatFloat(dur.Seconds(), 'f', -1, 64) + "s") + } + case IntType: + if dur, err := ptypes.Duration(d.Duration); err == nil { + return Int(dur) + } + case DurationType: + return d + case TypeType: + return DurationType + } + return NewErr("type conversion error from '%s' to '%s'", DurationType, typeVal) +} + +// Equal implements ref.Val.Equal. +func (d Duration) Equal(other ref.Val) ref.Val { + otherDur, ok := other.(Duration) + if !ok { + return ValOrErr(other, "no such overload") + } + return Bool(proto.Equal(d.Duration, otherDur.Value().(proto.Message))) +} + +// Negate implements traits.Negater.Negate. +func (d Duration) Negate() ref.Val { + dur, err := ptypes.Duration(d.Duration) + if err != nil { + return &Err{err} + } + return Duration{ptypes.DurationProto(-dur)} +} + +// Receive implements traits.Receiver.Receive. +func (d Duration) Receive(function string, overload string, args []ref.Val) ref.Val { + dur, err := ptypes.Duration(d.Duration) + if err != nil { + return &Err{err} + } + if len(args) == 0 { + if f, found := durationZeroArgOverloads[function]; found { + return f(dur) + } + } + return NewErr("no such overload") +} + +// Subtract implements traits.Subtractor.Subtract. +func (d Duration) Subtract(subtrahend ref.Val) ref.Val { + subtraDur, ok := subtrahend.(Duration) + if !ok { + return ValOrErr(subtrahend, "no such overload") + } + return d.Add(subtraDur.Negate()) +} + +// Type implements ref.Val.Type. +func (d Duration) Type() ref.Type { + return DurationType +} + +// Value implements ref.Val.Value. +func (d Duration) Value() interface{} { + return d.Duration +} + +var ( + durationValueType = reflect.TypeOf(&dpb.Duration{}) + + 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.Nanoseconds() / 1000000) + }} +) diff --git a/vendor/github.com/google/cel-go/common/types/dyn.go b/vendor/github.com/google/cel-go/common/types/dyn.go new file mode 100644 index 000000000..08530c999 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/dyn.go @@ -0,0 +1,33 @@ +// 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 "github.com/google/cel-go/common/types/ref" + +var ( + // DynType singleton. + DynType = NewTypeValue("dyn") +) + +// IsDyn indicates whether the input ref.Val or ref.Type is equal to DynType. +func IsDyn(elem interface{}) bool { + switch elem.(type) { + case ref.Type: + return elem == DynType + case ref.Val: + return IsDyn(elem.(ref.Val).Type()) + } + return false +} diff --git a/vendor/github.com/google/cel-go/common/types/err.go b/vendor/github.com/google/cel-go/common/types/err.go new file mode 100644 index 000000000..0b7123757 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/err.go @@ -0,0 +1,90 @@ +// 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" +) + +// Err type which extends the built-in go error and implements ref.Val. +type Err struct { + error +} + +var ( + // ErrType singleton. + ErrType = NewTypeValue("error") +) + +// NewErr creates a new Err described by the format string and args. +// TODO: Audit the use of this function and standardize the error messages and codes. +func NewErr(format string, args ...interface{}) ref.Val { + return &Err{fmt.Errorf(format, args...)} +} + +// ValOrErr either returns the existing error or create a new one. +// TODO: Audit the use of this function and standardize the error messages and codes. +func ValOrErr(val ref.Val, format string, args ...interface{}) ref.Val { + if val == nil { + return NewErr(format, args...) + } + switch val.Type() { + case ErrType, UnknownType: + return val + default: + return NewErr(format, args...) + } +} + +// ConvertToNative implements ref.Val.ConvertToNative. +func (e *Err) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + return nil, e.error +} + +// ConvertToType implements ref.Val.ConvertToType. +func (e *Err) ConvertToType(typeVal ref.Type) ref.Val { + // Errors are not convertible to other representations. + return e +} + +// Equal implements ref.Val.Equal. +func (e *Err) Equal(other ref.Val) ref.Val { + // An error cannot be equal to any other value, so it returns itself. + return e +} + +// String implements fmt.Stringer. +func (e *Err) String() string { + return e.error.Error() +} + +// Type implements ref.Val.Type. +func (e *Err) Type() ref.Type { + return ErrType +} + +// Value implements ref.Val.Value. +func (e *Err) Value() interface{} { + 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 { + return val.Type() == ErrType +} diff --git a/vendor/github.com/google/cel-go/common/types/int.go b/vendor/github.com/google/cel-go/common/types/int.go new file mode 100644 index 000000000..f89d04416 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/int.go @@ -0,0 +1,243 @@ +// 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" + "strconv" + + "github.com/golang/protobuf/ptypes" + + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + + structpb "github.com/golang/protobuf/ptypes/struct" + wrapperspb "github.com/golang/protobuf/ptypes/wrappers" +) + +// Int type that implements ref.Val as well as comparison and math operators. +type Int int64 + +// Int constants used for comparison results. +const ( + // IntZero is the zero-value for Int + IntZero = Int(0) + IntOne = Int(1) + IntNegOne = Int(-1) +) + +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{}) + + // int64WrapperType reflected type for protobuf int64 wrapper type. + int64WrapperType = reflect.TypeOf(&wrapperspb.Int64Value{}) +) + +// Add implements traits.Adder.Add. +func (i Int) Add(other ref.Val) ref.Val { + otherInt, ok := other.(Int) + if !ok { + return ValOrErr(other, "no such overload") + } + return i + otherInt +} + +// Compare implements traits.Comparer.Compare. +func (i Int) Compare(other ref.Val) ref.Val { + otherInt, ok := other.(Int) + if !ok { + return ValOrErr(other, "no such overload") + } + if i < otherInt { + return IntNegOne + } + if i > otherInt { + return IntOne + } + return IntZero +} + +// ConvertToNative implements ref.Val.ConvertToNative. +func (i Int) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + switch typeDesc.Kind() { + case reflect.Int32: + // Enums are also mapped as int32 derivations. + // Note, the code doesn't convert to the enum value directly since this is not known, but + // the net effect with respect to proto-assignment is handled correctly by the reflection + // Convert method. + return reflect.ValueOf(i).Convert(typeDesc).Interface(), nil + case reflect.Int64: + return int64(i), nil + case reflect.Ptr: + switch typeDesc { + case anyValueType: + // Primitives must be wrapped before being set on an Any field. + return ptypes.MarshalAny(&wrapperspb.Int64Value{Value: int64(i)}) + case int32WrapperType: + // Convert the value to a protobuf.Int32Value (with truncation). + return &wrapperspb.Int32Value{Value: int32(i)}, nil + case int64WrapperType: + // Convert the value to a protobuf.Int64Value. + return &wrapperspb.Int64Value{Value: int64(i)}, nil + case jsonValueType: + // The proto-to-JSON conversion rules would convert all 64-bit integer values to JSON + // decimal strings. Because CEL ints might come from the automatic widening of 32-bit + // values in protos, the JSON type is chosen dynamically based on the value. + // + // - Integers -2^53-1 < n < 2^53-1 are encoded as JSON numbers. + // - Integers outside this range are encoded as JSON strings. + // + // The integer to float range represents the largest interval where such a conversion + // can round-trip accurately. Thus, conversions from a 32-bit source can expect a JSON + // number as with protobuf. Those consuming JSON from a 64-bit source must be able to + // handle either a JSON number or a JSON decimal string. To handle these cases safely + // the string values must be explicitly converted to int() within a CEL expression; + // however, it is best to simply stay within the JSON number range when building JSON + // objects in CEL. + if i.isJSONSafe() { + return &structpb.Value{ + Kind: &structpb.Value_NumberValue{NumberValue: float64(i)}, + }, nil + } + // Proto3 to JSON conversion requires string-formatted int64 values + // since the conversion to floating point would result in truncation. + return &structpb.Value{ + Kind: &structpb.Value_StringValue{ + StringValue: strconv.FormatInt(int64(i), 10), + }, + }, nil + } + switch typeDesc.Elem().Kind() { + case reflect.Int32: + p := int32(i) + return &p, nil + case reflect.Int64: + p := int64(i) + return &p, nil + } + case reflect.Interface: + if reflect.TypeOf(i).Implements(typeDesc) { + return i, nil + } + } + return nil, fmt.Errorf("unsupported type conversion from 'int' to %v", typeDesc) +} + +// ConvertToType implements ref.Val.ConvertToType. +func (i Int) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case IntType: + return i + case UintType: + return Uint(i) + case DoubleType: + return Double(i) + case StringType: + return String(fmt.Sprintf("%d", int64(i))) + case TypeType: + return IntType + } + return NewErr("type conversion error from '%s' to '%s'", IntType, typeVal) +} + +// Divide implements traits.Divider.Divide. +func (i Int) Divide(other ref.Val) ref.Val { + otherInt, ok := other.(Int) + if !ok { + return ValOrErr(other, "no such overload") + } + if otherInt == IntZero { + return NewErr("divide by zero") + } + return i / otherInt +} + +// Equal implements ref.Val.Equal. +func (i Int) Equal(other ref.Val) ref.Val { + otherInt, ok := other.(Int) + if !ok { + return ValOrErr(other, "no such overload") + } + return Bool(i == otherInt) +} + +// Modulo implements traits.Modder.Modulo. +func (i Int) Modulo(other ref.Val) ref.Val { + otherInt, ok := other.(Int) + if !ok { + return ValOrErr(other, "no such overload") + } + if otherInt == IntZero { + return NewErr("modulus by zero") + } + return i % otherInt +} + +// Multiply implements traits.Multiplier.Multiply. +func (i Int) Multiply(other ref.Val) ref.Val { + otherInt, ok := other.(Int) + if !ok { + return ValOrErr(other, "no such overload") + } + return i * otherInt +} + +// Negate implements traits.Negater.Negate. +func (i Int) Negate() ref.Val { + return -i +} + +// Subtract implements traits.Subtractor.Subtract. +func (i Int) Subtract(subtrahend ref.Val) ref.Val { + subtraInt, ok := subtrahend.(Int) + if !ok { + return ValOrErr(subtrahend, "no such overload") + } + return i - subtraInt +} + +// Type implements ref.Val.Type. +func (i Int) Type() ref.Type { + return IntType +} + +// Value implements ref.Val.Value. +func (i Int) Value() interface{} { + return int64(i) +} + +// isJSONSafe indicates whether the int is safely representable as a floating point value in JSON. +func (i Int) isJSONSafe() bool { + return i >= minIntJSON && i <= maxIntJSON +} + +const ( + // maxIntJSON is defined as the Number.MAX_SAFE_INTEGER value per EcmaScript 6. + maxIntJSON = 1<<53 - 1 + // minIntJSON is defined as the Number.MIN_SAFE_INTEGER value per EcmaScript 6. + minIntJSON = -maxIntJSON +) diff --git a/vendor/github.com/google/cel-go/common/types/iterator.go b/vendor/github.com/google/cel-go/common/types/iterator.go new file mode 100644 index 000000000..023fcaf7a --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/iterator.go @@ -0,0 +1,55 @@ +// 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 ( + // IteratorType singleton. + IteratorType = NewTypeValue("iterator", traits.IteratorType) +) + +// baseIterator is the basis for list, map, and object iterators. +// +// An iterator in and of itself should not be a valid value for comparison, but must implement the +// `ref.Val` methods in order to be well-supported within instruction arguments processed by the +// interpreter. +type baseIterator struct{} + +func (it *baseIterator) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + return nil, fmt.Errorf("type conversion on iterators not supported") +} + +func (it *baseIterator) ConvertToType(typeVal ref.Type) ref.Val { + return NewErr("no such overload") +} + +func (it *baseIterator) Equal(other ref.Val) ref.Val { + return NewErr("no such overload") +} + +func (it *baseIterator) Type() ref.Type { + return IteratorType +} + +func (it *baseIterator) Value() interface{} { + return nil +} diff --git a/vendor/github.com/google/cel-go/common/types/json_list.go b/vendor/github.com/google/cel-go/common/types/json_list.go new file mode 100644 index 000000000..32e1e7782 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/json_list.go @@ -0,0 +1,217 @@ +// 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/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes" + structpb "github.com/golang/protobuf/ptypes/struct" + + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" +) + +var ( + jsonListValueType = reflect.TypeOf(&structpb.ListValue{}) +) + +type jsonListValue struct { + *structpb.ListValue + ref.TypeAdapter +} + +// NewJSONList creates a traits.Lister implementation backed by a JSON list that has been encoded +// in protocol buffer form. +// +// The `adapter` argument provides type adaptation capabilities from proto to CEL. +func NewJSONList(adapter ref.TypeAdapter, l *structpb.ListValue) traits.Lister { + return &jsonListValue{TypeAdapter: adapter, ListValue: l} +} + +// Add implements the traits.Adder interface method. +func (l *jsonListValue) Add(other ref.Val) ref.Val { + if other.Type() != ListType { + return ValOrErr(other, "no such overload") + } + switch other.(type) { + case *jsonListValue: + otherList := other.(*jsonListValue) + concatElems := append(l.GetValues(), otherList.GetValues()...) + return NewJSONList(l.TypeAdapter, &structpb.ListValue{Values: concatElems}) + } + return &concatList{ + TypeAdapter: l.TypeAdapter, + prevList: l, + nextList: other.(traits.Lister)} +} + +// Contains implements the traits.Container interface method. +func (l *jsonListValue) Contains(elem ref.Val) ref.Val { + if IsUnknownOrError(elem) { + return elem + } + var err ref.Val + for i := Int(0); i < l.Size().(Int); i++ { + val := l.Get(i) + cmp := elem.Equal(val) + b, ok := cmp.(Bool) + // When there is an error on the contain check, this is not necessarily terminal. + // The contains call could find the element and return True, just as though the user + // had written a per-element comparison in an exists() macro or logical ||, e.g. + // list.exists(e, e == elem) + if !ok && err == nil { + err = ValOrErr(cmp, "no such overload") + } + if b == True { + return True + } + } + if err != nil { + return err + } + return False +} + +// ConvertToNative implements the ref.Val interface method. +func (l *jsonListValue) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + switch typeDesc.Kind() { + case reflect.Array, reflect.Slice: + elemCount := int(l.Size().(Int)) + nativeList := reflect.MakeSlice(typeDesc, elemCount, elemCount) + for i := 0; i < elemCount; i++ { + elem := l.Get(Int(i)) + nativeElemVal, err := elem.ConvertToNative(typeDesc.Elem()) + if err != nil { + return nil, err + } + nativeList.Index(i).Set(reflect.ValueOf(nativeElemVal)) + } + return nativeList.Interface(), nil + + case reflect.Ptr: + switch typeDesc { + case anyValueType: + return ptypes.MarshalAny(l.Value().(proto.Message)) + case jsonValueType: + return &structpb.Value{ + Kind: &structpb.Value_ListValue{ListValue: l.ListValue}, + }, nil + case jsonListValueType: + return l.ListValue, nil + } + + case reflect.Interface: + // If the list is already assignable to the desired type return it. + if reflect.TypeOf(l).Implements(typeDesc) { + return l, nil + } + } + return nil, fmt.Errorf("no conversion found from list type to native type."+ + " list elem: google.protobuf.Value, native type: %v", typeDesc) +} + +// ConvertToType implements the ref.Val interface method. +func (l *jsonListValue) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case ListType: + return l + case TypeType: + return ListType + } + return NewErr("type conversion error from '%s' to '%s'", ListType, typeVal) +} + +// Equal implements the ref.Val interface method. +func (l *jsonListValue) Equal(other ref.Val) ref.Val { + otherList, ok := other.(traits.Lister) + if !ok { + return ValOrErr(other, "no such overload") + } + if l.Size() != otherList.Size() { + return False + } + for i := IntZero; i < l.Size().(Int); i++ { + thisElem := l.Get(i) + otherElem := otherList.Get(i) + elemEq := thisElem.Equal(otherElem) + if elemEq != True { + return elemEq + } + } + return True +} + +// Get implements the traits.Indexer interface method. +func (l *jsonListValue) Get(index ref.Val) ref.Val { + i, ok := index.(Int) + if !ok { + return ValOrErr(index, "unsupported index type: '%v", index.Type()) + } + if i < 0 || i >= l.Size().(Int) { + return NewErr("index '%d' out of range in list size '%d'", i, l.Size()) + } + elem := l.GetValues()[i] + return l.NativeToValue(elem) +} + +// Iterator implements the traits.Iterable interface method. +func (l *jsonListValue) Iterator() traits.Iterator { + return &jsonValueListIterator{ + baseIterator: &baseIterator{}, + TypeAdapter: l.TypeAdapter, + elems: l.GetValues(), + len: len(l.GetValues())} +} + +// Size implements the traits.Sizer interface method. +func (l *jsonListValue) Size() ref.Val { + return Int(len(l.GetValues())) +} + +// Type implements the ref.Val interface method. +func (l *jsonListValue) Type() ref.Type { + return ListType +} + +// Value implements the ref.Val interface method. +func (l *jsonListValue) Value() interface{} { + return l.ListValue +} + +type jsonValueListIterator struct { + *baseIterator + ref.TypeAdapter + cursor int + elems []*structpb.Value + len int +} + +// HasNext implements the traits.Iterator interface method. +func (it *jsonValueListIterator) HasNext() ref.Val { + return Bool(it.cursor < it.len) +} + +// Next implements the traits.Iterator interface method. +func (it *jsonValueListIterator) Next() ref.Val { + if it.HasNext() == True { + index := it.cursor + it.cursor++ + return it.NativeToValue(it.elems[index]) + } + return nil +} diff --git a/vendor/github.com/google/cel-go/common/types/json_struct.go b/vendor/github.com/google/cel-go/common/types/json_struct.go new file mode 100644 index 000000000..25bea8b6a --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/json_struct.go @@ -0,0 +1,218 @@ +// 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/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes" + + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + + structpb "github.com/golang/protobuf/ptypes/struct" +) + +var ( + jsonStructType = reflect.TypeOf(&structpb.Struct{}) +) + +type jsonStruct struct { + ref.TypeAdapter + *structpb.Struct +} + +// NewJSONStruct creates a traits.Mapper implementation backed by a JSON struct that has been +// encoded in protocol buffer form. +// +// The `adapter` argument provides type adaptation capabilities from proto to CEL. +func NewJSONStruct(adapter ref.TypeAdapter, st *structpb.Struct) traits.Mapper { + return &jsonStruct{TypeAdapter: adapter, Struct: st} +} + +// Contains implements the traits.Container interface method. +func (m *jsonStruct) Contains(index ref.Val) ref.Val { + val, found := m.Find(index) + // When the index is not found and val is non-nil, this is an error or unknown value. + if !found && val != nil && IsUnknownOrError(val) { + return val + } + return Bool(found) +} + +// ConvertToNative implements the ref.Val interface method. +func (m *jsonStruct) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + switch typeDesc.Kind() { + case reflect.Map: + otherKey := typeDesc.Key() + otherElem := typeDesc.Elem() + if typeDesc.Key().Kind() == reflect.String { + nativeMap := reflect.MakeMapWithSize(typeDesc, int(m.Size().(Int))) + it := m.Iterator() + for it.HasNext() == True { + key := it.Next() + refKeyValue, err := key.ConvertToNative(otherKey) + if err != nil { + return nil, err + } + refElemValue, err := m.Get(key).ConvertToNative(otherElem) + if err != nil { + return nil, err + } + nativeMap.SetMapIndex( + reflect.ValueOf(refKeyValue), + reflect.ValueOf(refElemValue)) + } + return nativeMap.Interface(), nil + } + + case reflect.Ptr: + switch typeDesc { + case anyValueType: + return ptypes.MarshalAny(m.Value().(proto.Message)) + case jsonValueType: + return &structpb.Value{ + Kind: &structpb.Value_StructValue{StructValue: m.Struct}, + }, nil + case jsonStructType: + return m.Struct, nil + } + + case reflect.Interface: + // If the struct is already assignable to the desired type return it. + if reflect.TypeOf(m).Implements(typeDesc) { + return m, nil + } + } + return nil, fmt.Errorf( + "no conversion found from map type to native type."+ + " map type: google.protobuf.Struct, native type: %v", typeDesc) +} + +// ConvertToType implements the ref.Val interface method. +func (m *jsonStruct) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case MapType: + return m + case TypeType: + return MapType + } + return NewErr("type conversion error from '%s' to '%s'", MapType, typeVal) +} + +// Equal implements the ref.Val interface method. +func (m *jsonStruct) Equal(other ref.Val) ref.Val { + if MapType != other.Type() { + return ValOrErr(other, "no such overload") + } + otherMap := other.(traits.Mapper) + if m.Size() != otherMap.Size() { + return False + } + it := m.Iterator() + for it.HasNext() == True { + key := it.Next() + thisVal, _ := m.Find(key) + otherVal, found := otherMap.Find(key) + if !found { + if otherVal == nil { + return False + } + return ValOrErr(otherVal, "no such overload") + } + valEq := thisVal.Equal(otherVal) + if valEq != True { + return valEq + } + } + return True +} + +// Find implements the traits.Mapper interface method. +func (m *jsonStruct) Find(key ref.Val) (ref.Val, bool) { + strKey, ok := key.(String) + if !ok { + return ValOrErr(key, "no such overload"), false + } + fields := m.Struct.GetFields() + value, found := fields[string(strKey)] + if !found { + return nil, found + } + return m.NativeToValue(value), found +} + +// Get implements the traits.Indexer interface method. +func (m *jsonStruct) Get(key ref.Val) ref.Val { + v, found := m.Find(key) + if !found { + return ValOrErr(v, "no such key: %v", key) + } + return v +} + +// Iterator implements the traits.Iterable interface method. +func (m *jsonStruct) Iterator() traits.Iterator { + f := m.GetFields() + keys := make([]string, len(m.GetFields())) + i := 0 + for k := range f { + keys[i] = k + i++ + } + return &jsonValueMapIterator{ + baseIterator: &baseIterator{}, + len: len(keys), + mapKeys: keys} +} + +// Size implements the traits.Sizer interface method. +func (m *jsonStruct) Size() ref.Val { + return Int(len(m.GetFields())) +} + +// Type implements the ref.Val interface method. +func (m *jsonStruct) Type() ref.Type { + return MapType +} + +// Value implements the ref.Val interface method. +func (m *jsonStruct) Value() interface{} { + return m.Struct +} + +type jsonValueMapIterator struct { + *baseIterator + cursor int + len int + mapKeys []string +} + +// HasNext implements the traits.Iterator interface method. +func (it *jsonValueMapIterator) HasNext() ref.Val { + return Bool(it.cursor < it.len) +} + +// Next implements the traits.Iterator interface method. +func (it *jsonValueMapIterator) Next() ref.Val { + if it.HasNext() == True { + index := it.cursor + it.cursor++ + return String(it.mapKeys[index]) + } + return nil +} diff --git a/vendor/github.com/google/cel-go/common/types/json_value.go b/vendor/github.com/google/cel-go/common/types/json_value.go new file mode 100644 index 000000000..e082dc6a2 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/json_value.go @@ -0,0 +1,24 @@ +// 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 ( + "reflect" + + "github.com/golang/protobuf/ptypes/struct" +) + +// jsonValueType constant representing the reflected type of a protobuf Value. +var jsonValueType = reflect.TypeOf(&structpb.Value{}) diff --git a/vendor/github.com/google/cel-go/common/types/list.go b/vendor/github.com/google/cel-go/common/types/list.go new file mode 100644 index 000000000..4300e2933 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/list.go @@ -0,0 +1,523 @@ +// 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/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes" + + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + + structpb "github.com/golang/protobuf/ptypes/struct" +) + +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 interface{}) traits.Lister { + return &baseList{ + TypeAdapter: adapter, + value: value, + refValue: reflect.ValueOf(value)} +} + +// NewStringList returns a traits.Lister containing only strings. +func NewStringList(adapter ref.TypeAdapter, elems []string) traits.Lister { + return &stringList{ + baseList: NewDynamicList(adapter, elems).(*baseList), + elems: elems} +} + +// NewValueList returns a traits.Lister with ref.Val elements. +func NewValueList(adapter ref.TypeAdapter, elems []ref.Val) traits.Lister { + return &valueList{ + baseList: NewDynamicList(adapter, elems).(*baseList), + elems: elems} +} + +// 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. +type baseList struct { + ref.TypeAdapter + value interface{} + refValue reflect.Value +} + +// Add implements the traits.Adder interface method. +func (l *baseList) Add(other ref.Val) ref.Val { + otherList, ok := other.(traits.Lister) + if !ok { + return ValOrErr(other, "no such overload") + } + if l.Size() == IntZero { + return other + } + if otherList.Size() == IntZero { + return l + } + return &concatList{ + TypeAdapter: l.TypeAdapter, + prevList: l, + nextList: otherList} +} + +// Contains implements the traits.Container interface method. +func (l *baseList) Contains(elem ref.Val) ref.Val { + if IsUnknownOrError(elem) { + return elem + } + var err ref.Val + sz := l.Size().(Int) + for i := Int(0); i < sz; i++ { + val := l.Get(i) + cmp := elem.Equal(val) + b, ok := cmp.(Bool) + // When there is an error on the contain check, this is not necessarily terminal. + // The contains call could find the element and return True, just as though the user + // had written a per-element comparison in an exists() macro or logical ||, e.g. + // list.exists(e, e == elem) + if !ok && err == nil { + err = ValOrErr(cmp, "no such overload") + } + if b == True { + return True + } + } + if err != nil { + return err + } + return False +} + +// ConvertToNative implements the ref.Val interface method. +func (l *baseList) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + // TODO: Add support for conversion to Any + // JSON conversions are a special case since the 'native' type is a proto message. + switch typeDesc { + case anyValueType: + json, err := l.ConvertToNative(jsonListValueType) + if err != nil { + return nil, err + } + return ptypes.MarshalAny(json.(proto.Message)) + case jsonValueType, jsonListValueType: + jsonValues, err := + l.ConvertToNative(reflect.TypeOf([]*structpb.Value{})) + if err != nil { + return nil, err + } + jsonList := &structpb.ListValue{Values: jsonValues.([]*structpb.Value)} + if typeDesc == jsonListValueType { + return jsonList, nil + } + return &structpb.Value{Kind: &structpb.Value_ListValue{ListValue: jsonList}}, nil + } + + // Non-list conversion. + if typeDesc.Kind() != reflect.Slice && typeDesc.Kind() != reflect.Array { + return nil, fmt.Errorf("type conversion error from list to '%v'", typeDesc) + } + + // If the list is already assignable to the desired type return it. + if reflect.TypeOf(l).AssignableTo(typeDesc) { + return l, nil + } + + // List conversion. + thisType := l.refValue.Type() + thisElem := thisType.Elem() + thisElemKind := thisElem.Kind() + + otherElem := typeDesc.Elem() + otherElemKind := otherElem.Kind() + if otherElemKind == thisElemKind { + return l.value, nil + } + // Allow the element ConvertToNative() function to determine whether conversion is possible. + elemCount := int(l.Size().(Int)) + nativeList := reflect.MakeSlice(typeDesc, elemCount, elemCount) + for i := 0; i < elemCount; i++ { + elem := l.Get(Int(i)) + nativeElemVal, err := elem.ConvertToNative(otherElem) + if err != nil { + return nil, err + } + nativeList.Index(i).Set(reflect.ValueOf(nativeElemVal)) + } + return nativeList.Interface(), nil +} + +// ConvertToType implements the ref.Val interface method. +func (l *baseList) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case ListType: + return l + case TypeType: + return ListType + } + return NewErr("type conversion error from '%s' to '%s'", ListType, typeVal) +} + +// Equal implements the ref.Val interface method. +func (l *baseList) Equal(other ref.Val) ref.Val { + otherList, ok := other.(traits.Lister) + if !ok { + return ValOrErr(other, "no such overload") + } + if l.Size() != otherList.Size() { + return False + } + for i := IntZero; i < l.Size().(Int); i++ { + thisElem := l.Get(i) + otherElem := otherList.Get(i) + elemEq := thisElem.Equal(otherElem) + if elemEq != True { + return elemEq + } + } + return True +} + +// Get implements the traits.Indexer interface method. +func (l *baseList) Get(index ref.Val) ref.Val { + i, ok := index.(Int) + if !ok { + return ValOrErr(index, "unsupported index type '%s' in list", index.Type()) + } + if i < 0 || i >= l.Size().(Int) { + return NewErr("index '%d' out of range in list size '%d'", i, l.Size()) + } + elem := l.refValue.Index(int(i)).Interface() + return l.NativeToValue(elem) +} + +// Iterator implements the traits.Iterable interface method. +func (l *baseList) Iterator() traits.Iterator { + return &listIterator{ + baseIterator: &baseIterator{}, + listValue: l, + cursor: 0, + len: l.Size().(Int)} +} + +// Size implements the traits.Sizer interface method. +func (l *baseList) Size() ref.Val { + return Int(l.refValue.Len()) +} + +// Type implements the ref.Val interface method. +func (l *baseList) Type() ref.Type { + return ListType +} + +// Value implements the ref.Val interface method. +func (l *baseList) Value() interface{} { + return l.value +} + +// concatList combines two list implementations together into a view. +// The `ref.TypeAdapter` enables native type to CEL type conversions. +type concatList struct { + ref.TypeAdapter + value interface{} + prevList traits.Lister + nextList traits.Lister +} + +// Add implements the traits.Adder interface method. +func (l *concatList) Add(other ref.Val) ref.Val { + otherList, ok := other.(traits.Lister) + if !ok { + return ValOrErr(other, "no such overload") + } + if l.Size() == IntZero { + return other + } + if otherList.Size() == IntZero { + return l + } + return &concatList{ + TypeAdapter: l.TypeAdapter, + prevList: l, + nextList: otherList} +} + +// Contains implments the traits.Container interface method. +func (l *concatList) Contains(elem ref.Val) ref.Val { + // The concat list relies on the IsErrorOrUnknown checks against the input element to be + // performed by the `prevList` and/or `nextList`. + prev := l.prevList.Contains(elem) + // Short-circuit the return if the elem was found in the prev list. + if prev == True { + return prev + } + // Return if the elem was found in the next list. + next := l.nextList.Contains(elem) + if next == True { + return next + } + // Handle the case where an error or unknown was encountered before checking next. + if IsUnknownOrError(prev) { + return prev + } + // Otherwise, rely on the next value as the representative result. + return next +} + +// ConvertToNative implements the ref.Val interface method. +func (l *concatList) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + combined := &baseList{ + TypeAdapter: l.TypeAdapter, + value: l.Value(), + refValue: reflect.ValueOf(l.Value())} + return combined.ConvertToNative(typeDesc) +} + +// ConvertToType implements the ref.Val interface method. +func (l *concatList) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case ListType: + return l + case TypeType: + return ListType + } + return NewErr("type conversion error from '%s' to '%s'", ListType, typeVal) +} + +// Equal implements the ref.Val interface method. +func (l *concatList) Equal(other ref.Val) ref.Val { + otherList, ok := other.(traits.Lister) + if !ok { + return ValOrErr(other, "no such overload") + } + if l.Size() != otherList.Size() { + return False + } + for i := IntZero; i < l.Size().(Int); i++ { + thisElem := l.Get(i) + otherElem := otherList.Get(i) + elemEq := thisElem.Equal(otherElem) + if elemEq != True { + return elemEq + } + } + return True +} + +// Get implements the traits.Indexer interface method. +func (l *concatList) Get(index ref.Val) ref.Val { + i, ok := index.(Int) + if !ok { + return ValOrErr(index, "no such overload") + } + if i < l.prevList.Size().(Int) { + return l.prevList.Get(i) + } + offset := i - l.prevList.Size().(Int) + return l.nextList.Get(offset) +} + +// Iterator implements the traits.Iterable interface method. +func (l *concatList) Iterator() traits.Iterator { + return &listIterator{ + baseIterator: &baseIterator{}, + listValue: l, + cursor: 0, + len: l.Size().(Int)} +} + +// Size implements the traits.Sizer interface method. +func (l *concatList) Size() ref.Val { + return l.prevList.Size().(Int).Add(l.nextList.Size()) +} + +// Type implements the ref.Val interface method. +func (l *concatList) Type() ref.Type { + return ListType +} + +// Value implements the ref.Val interface method. +func (l *concatList) Value() interface{} { + if l.value == nil { + merged := make([]interface{}, l.Size().(Int), l.Size().(Int)) + prevLen := l.prevList.Size().(Int) + for i := Int(0); i < prevLen; i++ { + merged[i] = l.prevList.Get(i).Value() + } + nextLen := l.nextList.Size().(Int) + for j := Int(0); j < nextLen; j++ { + merged[prevLen+j] = l.nextList.Get(j).Value() + } + l.value = merged + } + return l.value +} + +// stringList is a specialization of the traits.Lister interface which is +// present to demonstrate the ability to specialize Lister implementations. +type stringList struct { + *baseList + elems []string +} + +// Add implments the traits.Adder interface method. +func (l *stringList) Add(other ref.Val) ref.Val { + if other.Type() != ListType { + return ValOrErr(other, "no such overload") + } + if l.Size() == IntZero { + return other + } + if other.(traits.Sizer).Size() == IntZero { + return l + } + switch other.(type) { + case *stringList: + concatElems := append(l.elems, other.(*stringList).elems...) + return NewStringList(l.TypeAdapter, concatElems) + } + return &concatList{ + TypeAdapter: l.TypeAdapter, + prevList: l.baseList, + nextList: other.(traits.Lister)} +} + +// ConvertToNative implements the ref.Val interface method. +func (l *stringList) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + switch typeDesc.Kind() { + case reflect.Array, reflect.Slice: + if typeDesc.Elem().Kind() == reflect.String { + return l.elems, nil + } + case reflect.Ptr: + switch typeDesc { + case anyValueType: + json, err := l.ConvertToNative(jsonListValueType) + if err != nil { + return nil, err + } + return ptypes.MarshalAny(json.(proto.Message)) + case jsonValueType, jsonListValueType: + elemCount := len(l.elems) + listVals := make([]*structpb.Value, elemCount, elemCount) + for i := 0; i < elemCount; i++ { + listVals[i] = &structpb.Value{ + Kind: &structpb.Value_StringValue{StringValue: l.elems[i]}} + } + jsonList := &structpb.ListValue{Values: listVals} + if typeDesc == jsonListValueType { + return jsonList, nil + } + return &structpb.Value{ + Kind: &structpb.Value_ListValue{ + ListValue: jsonList}}, nil + } + } + // If the list is already assignable to the desired type return it. + if reflect.TypeOf(l).AssignableTo(typeDesc) { + return l, nil + } + return nil, fmt.Errorf("no conversion found from list type to native type."+ + " list elem: string, native type: %v", typeDesc) +} + +// Get implements the traits.Indexer interface method. +func (l *stringList) Get(index ref.Val) ref.Val { + i, ok := index.(Int) + if !ok { + return ValOrErr(index, "no such overload") + } + if i < 0 || i >= l.Size().(Int) { + return NewErr("index '%d' out of range in list size '%d'", i, l.Size()) + } + return String(l.elems[i]) +} + +// Size implements the traits.Sizer interface method. +func (l *stringList) Size() ref.Val { + return Int(len(l.elems)) +} + +// valueList is a specialization of traits.Lister for ref.Val. +type valueList struct { + *baseList + elems []ref.Val +} + +// Add implements the traits.Adder interface method. +func (l *valueList) Add(other ref.Val) ref.Val { + otherList, ok := other.(traits.Lister) + if !ok { + return ValOrErr(other, "no such overload") + } + return &concatList{ + TypeAdapter: l.TypeAdapter, + prevList: l, + nextList: otherList} +} + +// Get implements the traits.Indexer interface method. +func (l *valueList) Get(index ref.Val) ref.Val { + i, ok := index.(Int) + if !ok { + return ValOrErr(index, "no such overload") + } + if i < 0 || i >= l.Size().(Int) { + return NewErr("index '%d' out of range in list size '%d'", i, l.Size()) + } + return l.elems[i] +} + +// Size implements the traits.Sizer interface method. +func (l *valueList) Size() ref.Val { + return Int(len(l.elems)) +} + +type listIterator struct { + *baseIterator + listValue traits.Lister + cursor Int + len Int +} + +// HasNext implements the traits.Iterator interface method. +func (it *listIterator) HasNext() ref.Val { + return Bool(it.cursor < it.len) +} + +// Next implements the traits.Iterator interface method. +func (it *listIterator) Next() ref.Val { + if it.HasNext() == True { + index := it.cursor + it.cursor++ + return it.listValue.Get(index) + } + return nil +} diff --git a/vendor/github.com/google/cel-go/common/types/map.go b/vendor/github.com/google/cel-go/common/types/map.go new file mode 100644 index 000000000..b3506c2ff --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/map.go @@ -0,0 +1,339 @@ +// 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/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes" + + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + + structpb "github.com/golang/protobuf/ptypes/struct" +) + +// baseMap is a reflection based map implementation designed to handle a variety of map-like types. +type baseMap struct { + ref.TypeAdapter + value interface{} + refValue reflect.Value +} + +// stringMap is a specialization to improve the performance of simple key, value pair lookups by +// string as this is the most common usage of maps. +type stringMap struct { + *baseMap + mapStrStr map[string]string +} + +// NewDynamicMap returns a traits.Mapper value with dynamic key, value pairs. +func NewDynamicMap(adapter ref.TypeAdapter, value interface{}) traits.Mapper { + return &baseMap{ + TypeAdapter: adapter, + value: value, + refValue: reflect.ValueOf(value)} +} + +// NewStringStringMap returns a specialized traits.Mapper with string keys and values. +func NewStringStringMap(adapter ref.TypeAdapter, value map[string]string) traits.Mapper { + return &stringMap{ + baseMap: &baseMap{TypeAdapter: adapter, value: value}, + mapStrStr: value, + } +} + +var ( + // MapType singleton. + MapType = NewTypeValue("map", + traits.ContainerType, + traits.IndexerType, + traits.IterableType, + traits.SizerType) +) + +// Contains implements the traits.Container interface method. +func (m *baseMap) Contains(index ref.Val) ref.Val { + val, found := m.Find(index) + // When the index is not found and val is non-nil, this is an error or unknown value. + if !found && val != nil && IsUnknownOrError(val) { + return val + } + return Bool(found) +} + +// Contains implements the traits.Container interface method. +func (m *stringMap) Contains(index ref.Val) ref.Val { + val, found := m.Find(index) + // When the index is not found and val is non-nil, this is an error or unknown value. + if !found && val != nil && IsUnknownOrError(val) { + return val + } + return Bool(found) +} + +// ConvertToNative implements the ref.Val interface method. +func (m *baseMap) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + switch typeDesc { + case anyValueType: + json, err := m.ConvertToNative(jsonStructType) + if err != nil { + return nil, err + } + return ptypes.MarshalAny(json.(proto.Message)) + case jsonValueType, jsonStructType: + jsonEntries, err := + m.ConvertToNative(reflect.TypeOf(map[string]*structpb.Value{})) + if err != nil { + return nil, err + } + jsonMap := &structpb.Struct{ + Fields: jsonEntries.(map[string]*structpb.Value)} + if typeDesc == jsonStructType { + return jsonMap, nil + } + return &structpb.Value{ + Kind: &structpb.Value_StructValue{ + StructValue: jsonMap}}, nil + } + + // Non-map conversion. + if typeDesc.Kind() != reflect.Map { + return nil, fmt.Errorf("type conversion error from map to '%v'", typeDesc) + } + + // If the map is already assignable to the desired type return it. + if reflect.TypeOf(m).AssignableTo(typeDesc) { + return m, nil + } + + // Map conversion. + thisType := m.refValue.Type() + thisKey := thisType.Key() + thisKeyKind := thisKey.Kind() + thisElem := thisType.Elem() + thisElemKind := thisElem.Kind() + + otherKey := typeDesc.Key() + otherKeyKind := otherKey.Kind() + otherElem := typeDesc.Elem() + otherElemKind := otherElem.Kind() + + if otherKeyKind == thisKeyKind && otherElemKind == thisElemKind { + return m.value, nil + } + elemCount := m.Size().(Int) + nativeMap := reflect.MakeMapWithSize(typeDesc, int(elemCount)) + it := m.Iterator() + for it.HasNext() == True { + key := it.Next() + refKeyValue, err := key.ConvertToNative(otherKey) + if err != nil { + return nil, err + } + refElemValue, err := m.Get(key).ConvertToNative(otherElem) + if err != nil { + return nil, err + } + nativeMap.SetMapIndex( + reflect.ValueOf(refKeyValue), + reflect.ValueOf(refElemValue)) + } + return nativeMap.Interface(), nil +} + +// ConvertToNative implements the ref.Val interface method. +func (m *stringMap) ConvertToNative(refType reflect.Type) (interface{}, error) { + if !m.baseMap.refValue.IsValid() { + m.baseMap.refValue = reflect.ValueOf(m.value) + } + return m.baseMap.ConvertToNative(refType) +} + +// ConvertToType implements the ref.Val interface method. +func (m *baseMap) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case MapType: + return m + case TypeType: + return MapType + } + return NewErr("type conversion error from '%s' to '%s'", MapType, typeVal) +} + +// ConvertToType implements the ref.Val interface method. +func (m *stringMap) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case MapType: + return m + default: + return m.baseMap.ConvertToType(typeVal) + } +} + +// Equal implements the ref.Val interface method. +func (m *baseMap) Equal(other ref.Val) ref.Val { + if MapType != other.Type() { + return ValOrErr(other, "no such overload") + } + otherMap := other.(traits.Mapper) + if m.Size() != otherMap.Size() { + return False + } + it := m.Iterator() + for it.HasNext() == True { + key := it.Next() + thisVal, _ := m.Find(key) + otherVal, found := otherMap.Find(key) + if !found { + if otherVal == nil { + return False + } + return ValOrErr(otherVal, "no such overload") + } + valEq := thisVal.Equal(otherVal) + if valEq != True { + return valEq + } + } + return True +} + +// Equal implements the ref.Val interface method. +func (m *stringMap) Equal(other ref.Val) ref.Val { + if !m.baseMap.refValue.IsValid() { + m.baseMap.refValue = reflect.ValueOf(m.value) + } + return m.baseMap.Equal(other) +} + +// Find implements the traits.Mapper interface method. +func (m *baseMap) Find(key ref.Val) (ref.Val, bool) { + // TODO: There are multiple reasons why a Get could fail. Typically, this is because the key + // does not exist in the map; however, it's possible that the value cannot be converted to + // the desired type. Refine this strategy to disambiguate these cases. + if IsUnknownOrError(key) { + return key, false + } + thisKeyType := m.refValue.Type().Key() + nativeKey, err := key.ConvertToNative(thisKeyType) + if err != nil { + return &Err{err}, false + } + nativeKeyVal := reflect.ValueOf(nativeKey) + value := m.refValue.MapIndex(nativeKeyVal) + if !value.IsValid() { + return nil, false + } + return m.NativeToValue(value.Interface()), true +} + +// Find implements the traits.Mapper interface method. +func (m *stringMap) Find(key ref.Val) (ref.Val, bool) { + strKey, ok := key.(String) + if !ok { + return ValOrErr(key, "no such overload"), false + } + val, found := m.mapStrStr[string(strKey)] + if !found { + return nil, false + } + return String(val), true +} + +// Get implements the traits.Indexer interface method. +func (m *baseMap) Get(key ref.Val) ref.Val { + v, found := m.Find(key) + if !found { + return ValOrErr(v, "no such key: %v", key) + } + return v +} + +// Get implements the traits.Indexer interface method. +func (m *stringMap) Get(key ref.Val) ref.Val { + v, found := m.Find(key) + if !found { + return ValOrErr(v, "no such key: %v", key) + } + return v +} + +// Iterator implements the traits.Iterable interface method. +func (m *baseMap) Iterator() traits.Iterator { + mapKeys := m.refValue.MapKeys() + return &mapIterator{ + baseIterator: &baseIterator{}, + TypeAdapter: m.TypeAdapter, + mapValue: m, + mapKeys: mapKeys, + cursor: 0, + len: int(m.Size().(Int))} +} + +// Iterator implements the traits.Iterable interface method. +func (m *stringMap) Iterator() traits.Iterator { + if !m.baseMap.refValue.IsValid() { + m.baseMap.refValue = reflect.ValueOf(m.value) + } + return m.baseMap.Iterator() +} + +// Size implements the traits.Sizer interface method. +func (m *baseMap) Size() ref.Val { + return Int(m.refValue.Len()) +} + +// Size implements the traits.Sizer interface method. +func (m *stringMap) Size() ref.Val { + return Int(len(m.mapStrStr)) +} + +// Type implements the ref.Val interface method. +func (m *baseMap) Type() ref.Type { + return MapType +} + +// Value implements the ref.Val interface method. +func (m *baseMap) Value() interface{} { + return m.value +} + +type mapIterator struct { + *baseIterator + ref.TypeAdapter + mapValue traits.Mapper + mapKeys []reflect.Value + cursor int + len int +} + +// HasNext implements the traits.Iterator interface method. +func (it *mapIterator) HasNext() ref.Val { + return Bool(it.cursor < it.len) +} + +// Next implements the traits.Iterator interface method. +func (it *mapIterator) Next() ref.Val { + if it.HasNext() == True { + index := it.cursor + it.cursor++ + refKey := it.mapKeys[index] + return it.NativeToValue(refKey.Interface()) + } + return nil +} diff --git a/vendor/github.com/google/cel-go/common/types/null.go b/vendor/github.com/google/cel-go/common/types/null.go new file mode 100644 index 000000000..5c4626771 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/null.go @@ -0,0 +1,101 @@ +// 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/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes" + + "github.com/google/cel-go/common/types/ref" + + structpb "github.com/golang/protobuf/ptypes/struct" +) + +// Null type implementation. +type Null structpb.NullValue + +var ( + // NullType singleton. + NullType = NewTypeValue("null_type") + // NullValue singleton. + NullValue = Null(structpb.NullValue_NULL_VALUE) + + jsonNullType = reflect.TypeOf(structpb.NullValue_NULL_VALUE) +) + +// ConvertToNative implements ref.Val.ConvertToNative. +func (n Null) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + switch typeDesc.Kind() { + case reflect.Int32: + if typeDesc == jsonNullType { + return structpb.NullValue_NULL_VALUE, nil + } + case reflect.Ptr: + switch typeDesc { + case anyValueType: + // Convert to a JSON-null before packing to an Any field since the enum value for JSON + // null cannot be packed directly. + pb, err := n.ConvertToNative(jsonValueType) + if err != nil { + return nil, err + } + return ptypes.MarshalAny(pb.(proto.Message)) + case jsonValueType: + return &structpb.Value{ + Kind: &structpb.Value_NullValue{ + NullValue: structpb.NullValue_NULL_VALUE, + }, + }, nil + } + case reflect.Interface: + if reflect.TypeOf(n).Implements(typeDesc) { + return n, nil + } + } + // If the type conversion isn't supported return an error. + return nil, fmt.Errorf("type conversion error from '%v' to '%v'", NullType, typeDesc) +} + +// ConvertToType implements ref.Val.ConvertToType. +func (n Null) ConvertToType(typeVal ref.Type) ref.Val { + if typeVal == StringType { + return String("null") + } + if typeVal == NullType { + return n + } + return NewErr("type conversion error from '%s' to '%s'", NullType, typeVal) +} + +// Equal implements ref.Val.Equal. +func (n Null) Equal(other ref.Val) ref.Val { + if NullType != other.Type() { + return ValOrErr(other, "no such overload") + } + return True +} + +// Type implements ref.Val.Type. +func (n Null) Type() ref.Type { + return NullType +} + +// Value implements ref.Val.Value. +func (n Null) Value() interface{} { + return 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 new file mode 100644 index 000000000..19933827d --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/object.go @@ -0,0 +1,179 @@ +// 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/golang/protobuf/jsonpb" + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes" + + "github.com/google/cel-go/common/types/pb" + "github.com/google/cel-go/common/types/ref" + + structpb "github.com/golang/protobuf/ptypes/struct" +) + +type protoObj struct { + ref.TypeAdapter + value proto.Message + refValue reflect.Value + typeDesc *pb.TypeDescription + typeValue *TypeValue + isAny bool +} + +// NewObject returns an object based on a proto.Message value which handles +// conversion between protobuf type values and expression type values. +// Objects support indexing and iteration. +// Note: only uses default Db. +func NewObject(adapter ref.TypeAdapter, + typeDesc *pb.TypeDescription, + value proto.Message) ref.Val { + return &protoObj{ + TypeAdapter: adapter, + value: value, + refValue: reflect.ValueOf(value), + typeDesc: typeDesc, + typeValue: NewObjectTypeValue(typeDesc.Name())} +} + +func (o *protoObj) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + pb := o.Value().(proto.Message) + switch typeDesc { + case anyValueType: + if o.isAny { + return pb, nil + } + return ptypes.MarshalAny(pb) + case jsonValueType: + // Marshal the proto to JSON first, and then rehydrate as protobuf.Value as there is no + // support for direct conversion from proto.Message to protobuf.Value. + jsonTxt, err := (&jsonpb.Marshaler{}).MarshalToString(pb) + if err != nil { + return nil, err + } + json := &structpb.Value{} + err = jsonpb.UnmarshalString(jsonTxt, json) + if err != nil { + return nil, err + } + return json, nil + } + if o.refValue.Type().AssignableTo(typeDesc) { + return pb, nil + } + return nil, fmt.Errorf("type conversion error from '%v' to '%v'", + o.refValue.Type(), typeDesc) +} + +func (o *protoObj) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + default: + if o.Type().TypeName() == typeVal.TypeName() { + return o + } + case TypeType: + return o.typeValue + } + return NewErr("type conversion error from '%s' to '%s'", + o.typeDesc.Name(), typeVal) +} + +func (o *protoObj) Equal(other ref.Val) ref.Val { + if o.typeDesc.Name() != other.Type().TypeName() { + return ValOrErr(other, "no such overload") + } + return Bool(proto.Equal(o.value, other.Value().(proto.Message))) +} + +// IsSet tests whether a field which is defined is set to a non-default value. +func (o *protoObj) IsSet(field ref.Val) ref.Val { + protoFieldName, ok := field.(String) + if !ok { + return ValOrErr(field, "no such overload") + } + protoFieldStr := string(protoFieldName) + f, found := o.typeDesc.FieldByName(protoFieldStr) + if !found { + return NewErr("no such field '%s'", field) + } + if !f.SupportsPresence() { + return NewErr("field does not support presence testing.") + } + getter := o.refValue.MethodByName(f.GetterName()) + if !getter.IsValid() { + return NewErr("no such field '%s'", field) + } + refField := getter.Call([]reflect.Value{})[0] + if !refField.IsValid() { + return NewErr("no such field '%s'", field) + } + return isFieldSet(refField) +} + +func (o *protoObj) Get(index ref.Val) ref.Val { + protoFieldName, ok := index.(String) + if !ok { + return ValOrErr(index, "no such overload") + } + protoFieldStr := string(protoFieldName) + fd, found := o.typeDesc.FieldByName(protoFieldStr) + if !found { + return NewErr("no such field '%s'", index) + } + getter := o.refValue.MethodByName(fd.GetterName()) + if !getter.IsValid() { + return NewErr("no such field '%s'", index) + } + refField := getter.Call([]reflect.Value{})[0] + if !refField.IsValid() { + return NewErr("no such field '%s'", index) + } + return getOrDefaultInstance(o.TypeAdapter, fd, refField) +} + +func (o *protoObj) Type() ref.Type { + return o.typeValue +} + +func (o *protoObj) Value() interface{} { + return o.value +} + +func isFieldSet(refVal reflect.Value) ref.Val { + if refVal.Kind() == reflect.Ptr && refVal.IsNil() { + return False + } + return True +} + +func getOrDefaultInstance(adapter ref.TypeAdapter, + fd *pb.FieldDescription, + refVal reflect.Value) ref.Val { + if isFieldSet(refVal) == True { + value := refVal.Interface() + return adapter.NativeToValue(value) + } + if fd.IsWrapper() { + return NullValue + } + if fd.IsMessage() { + return adapter.NativeToValue(fd.Type().DefaultValue()) + } + return NewErr("no default value for field: %s", fd.Name()) +} diff --git a/vendor/github.com/google/cel-go/common/types/pb/checked.go b/vendor/github.com/google/cel-go/common/types/pb/checked.go new file mode 100644 index 000000000..10d13176f --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/pb/checked.go @@ -0,0 +1,90 @@ +// 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 pb + +import ( + descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" + emptypb "github.com/golang/protobuf/ptypes/empty" + structpb "github.com/golang/protobuf/ptypes/struct" + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +var ( + // CheckedPrimitives map from proto field descriptor type to expr.Type. + CheckedPrimitives = map[descpb.FieldDescriptorProto_Type]*exprpb.Type{ + descpb.FieldDescriptorProto_TYPE_BOOL: checkedBool, + descpb.FieldDescriptorProto_TYPE_BYTES: checkedBytes, + descpb.FieldDescriptorProto_TYPE_DOUBLE: checkedDouble, + descpb.FieldDescriptorProto_TYPE_FLOAT: checkedDouble, + descpb.FieldDescriptorProto_TYPE_INT32: checkedInt, + descpb.FieldDescriptorProto_TYPE_INT64: checkedInt, + descpb.FieldDescriptorProto_TYPE_SINT32: checkedInt, + descpb.FieldDescriptorProto_TYPE_SINT64: checkedInt, + descpb.FieldDescriptorProto_TYPE_UINT32: checkedUint, + descpb.FieldDescriptorProto_TYPE_UINT64: checkedUint, + descpb.FieldDescriptorProto_TYPE_FIXED32: checkedUint, + descpb.FieldDescriptorProto_TYPE_FIXED64: checkedUint, + descpb.FieldDescriptorProto_TYPE_STRING: checkedString} + + // CheckedWellKnowns map from qualified proto type name to expr.Type for + // well-known proto types. + CheckedWellKnowns = map[string]*exprpb.Type{ + // Wrapper types. + "google.protobuf.BoolValue": checkedWrap(checkedBool), + "google.protobuf.BytesValue": checkedWrap(checkedBytes), + "google.protobuf.DoubleValue": checkedWrap(checkedDouble), + "google.protobuf.FloatValue": checkedWrap(checkedDouble), + "google.protobuf.Int64Value": checkedWrap(checkedInt), + "google.protobuf.Int32Value": checkedWrap(checkedInt), + "google.protobuf.UInt64Value": checkedWrap(checkedUint), + "google.protobuf.UInt32Value": checkedWrap(checkedUint), + "google.protobuf.StringValue": checkedWrap(checkedString), + // Well-known types. + "google.protobuf.Any": checkedAny, + "google.protobuf.Duration": checkedDuration, + "google.protobuf.Timestamp": checkedTimestamp, + // Json types. + "google.protobuf.ListValue": checkedListDyn, + "google.protobuf.NullValue": checkedNull, + "google.protobuf.Struct": checkedMapStringDyn, + "google.protobuf.Value": checkedDyn, + } + + // common types + checkedDyn = &exprpb.Type{TypeKind: &exprpb.Type_Dyn{Dyn: &emptypb.Empty{}}} + // Wrapper and primitive types. + checkedBool = checkedPrimitive(exprpb.Type_BOOL) + checkedBytes = checkedPrimitive(exprpb.Type_BYTES) + checkedDouble = checkedPrimitive(exprpb.Type_DOUBLE) + checkedInt = checkedPrimitive(exprpb.Type_INT64) + checkedString = checkedPrimitive(exprpb.Type_STRING) + checkedUint = checkedPrimitive(exprpb.Type_UINT64) + // Well-known type equivalents. + checkedAny = checkedWellKnown(exprpb.Type_ANY) + checkedDuration = checkedWellKnown(exprpb.Type_DURATION) + checkedTimestamp = checkedWellKnown(exprpb.Type_TIMESTAMP) + // Json-based type equivalents. + checkedNull = &exprpb.Type{ + TypeKind: &exprpb.Type_Null{ + Null: structpb.NullValue_NULL_VALUE}} + checkedListDyn = &exprpb.Type{ + TypeKind: &exprpb.Type_ListType_{ + ListType: &exprpb.Type_ListType{ElemType: checkedDyn}}} + checkedMapStringDyn = &exprpb.Type{ + TypeKind: &exprpb.Type_MapType_{ + MapType: &exprpb.Type_MapType{ + KeyType: checkedString, + ValueType: checkedDyn}}} +) diff --git a/vendor/github.com/google/cel-go/common/types/pb/enum.go b/vendor/github.com/google/cel-go/common/types/pb/enum.go new file mode 100644 index 000000000..6e122672a --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/pb/enum.go @@ -0,0 +1,36 @@ +// 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 pb + +import ( + descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" +) + +// EnumDescription maps a qualified enum name to its numeric value. +type EnumDescription struct { + enumName string + file *FileDescription + desc *descpb.EnumValueDescriptorProto +} + +// Name of the enum. +func (ed *EnumDescription) Name() string { + return ed.enumName +} + +// Value (numeric) of the enum. +func (ed *EnumDescription) Value() int32 { + return ed.desc.GetNumber() +} diff --git a/vendor/github.com/google/cel-go/common/types/pb/file.go b/vendor/github.com/google/cel-go/common/types/pb/file.go new file mode 100644 index 000000000..18c7bda6b --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/pb/file.go @@ -0,0 +1,113 @@ +// 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 pb + +import ( + "fmt" + "sync/atomic" + + descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" +) + +// FileDescription holds a map of all types and enums declared within a .proto +// file. +type FileDescription struct { + pbdb *Db + desc *descpb.FileDescriptorProto + types map[string]*TypeDescription + enums map[string]*EnumDescription +} + +// GetEnumDescription returns an EnumDescription for a qualified enum value +// name declared within the .proto file. +func (fd *FileDescription) GetEnumDescription(enumName string) (*EnumDescription, error) { + if ed, found := fd.enums[sanitizeProtoName(enumName)]; found { + return ed, nil + } + return nil, fmt.Errorf("no such enum value '%s'", enumName) +} + +// GetEnumNames returns the string names of all enum values in the file. +func (fd *FileDescription) GetEnumNames() []string { + enumNames := make([]string, len(fd.enums)) + i := 0 + for _, e := range fd.enums { + enumNames[i] = e.Name() + i++ + } + return enumNames +} + +// GetTypeDescription returns a TypeDescription for a qualified type name +// declared within the .proto file. +func (fd *FileDescription) GetTypeDescription(typeName string) (*TypeDescription, error) { + if td, found := fd.types[sanitizeProtoName(typeName)]; found { + return td, nil + } + return nil, fmt.Errorf("no such type '%s'", typeName) +} + +// GetTypeNames returns the list of all type names contained within the file. +func (fd *FileDescription) GetTypeNames() []string { + typeNames := make([]string, len(fd.types)) + i := 0 + for _, t := range fd.types { + typeNames[i] = t.Name() + i++ + } + return typeNames +} + +// Package returns the file's qualified package name. +func (fd *FileDescription) Package() string { + return fd.desc.GetPackage() +} + +func (fd *FileDescription) indexEnums(pkg string, enumTypes []*descpb.EnumDescriptorProto) { + for _, enumType := range enumTypes { + for _, enumValue := range enumType.Value { + enumValueName := fmt.Sprintf( + "%s.%s.%s", pkg, enumType.GetName(), enumValue.GetName()) + fd.enums[enumValueName] = &EnumDescription{ + enumName: enumValueName, + file: fd, + desc: enumValue} + fd.pbdb.revFileDescriptorMap[enumValueName] = fd + } + } +} + +func (fd *FileDescription) indexTypes(pkg string, msgTypes []*descpb.DescriptorProto) { + for _, msgType := range msgTypes { + msgName := fmt.Sprintf("%s.%s", pkg, msgType.GetName()) + td := &TypeDescription{ + typeName: msgName, + file: fd, + desc: msgType, + metadata: &atomic.Value{}, + } + fd.types[msgName] = td + fd.indexTypes(msgName, msgType.NestedType) + fd.indexEnums(msgName, msgType.EnumType) + fd.pbdb.revFileDescriptorMap[msgName] = fd + } +} + +func sanitizeProtoName(name string) string { + if name != "" && name[0] == '.' { + return name[1:] + } + return name +} diff --git a/vendor/github.com/google/cel-go/common/types/pb/pb.go b/vendor/github.com/google/cel-go/common/types/pb/pb.go new file mode 100644 index 000000000..4e1988b9b --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/pb/pb.go @@ -0,0 +1,149 @@ +// 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 pb reflects over protocol buffer descriptors to generate objects +// that simplify type, enum, and field lookup. +package pb + +import ( + "bytes" + "compress/gzip" + "fmt" + "io/ioutil" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + + descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" + anypb "github.com/golang/protobuf/ptypes/any" + durpb "github.com/golang/protobuf/ptypes/duration" + structpb "github.com/golang/protobuf/ptypes/struct" + tspb "github.com/golang/protobuf/ptypes/timestamp" + wrapperspb "github.com/golang/protobuf/ptypes/wrappers" +) + +// Db maps from file / message / enum name to file description. +type Db struct { + revFileDescriptorMap map[string]*FileDescription +} + +var ( + // DefaultDb used at evaluation time or unless overridden at check time. + DefaultDb = &Db{ + revFileDescriptorMap: make(map[string]*FileDescription), + } +) + +// NewDb creates a new `pb.Db` with an empty type name to file description map. +func NewDb() *Db { + pbdb := &Db{ + revFileDescriptorMap: make(map[string]*FileDescription), + } + for k, v := range DefaultDb.revFileDescriptorMap { + pbdb.revFileDescriptorMap[k] = v + } + return pbdb +} + +// RegisterDescriptor produces a `FileDescription` from a `FileDescriptorProto` and registers the +// message and enum types into the `pb.Db`. +func (pbdb *Db) RegisterDescriptor(fileDesc *descpb.FileDescriptorProto) (*FileDescription, error) { + fd, err := pbdb.describeFileInternal(fileDesc) + if err != nil { + return nil, err + } + pkg := fd.Package() + fd.indexTypes(pkg, fileDesc.MessageType) + fd.indexEnums(pkg, fileDesc.EnumType) + return fd, nil +} + +// RegisterMessage produces a `FileDescription` from a `message` and registers the message and all +// other definitions within the message file into the `pb.Db`. +func (pbdb *Db) RegisterMessage(message proto.Message) (*FileDescription, error) { + typeName := sanitizeProtoName(proto.MessageName(message)) + if fd, found := pbdb.revFileDescriptorMap[typeName]; found { + return fd, nil + } + fileDesc, _ := descriptor.ForMessage(message.(descriptor.Message)) + return pbdb.RegisterDescriptor(fileDesc) +} + +// DescribeFile gets the `FileDescription` for the `message` type if it exists in the `pb.Db`. +func (pbdb *Db) DescribeFile(message proto.Message) (*FileDescription, error) { + typeName := sanitizeProtoName(proto.MessageName(message)) + if fd, found := pbdb.revFileDescriptorMap[typeName]; found { + return fd, nil + } + return nil, fmt.Errorf("unrecognized proto type name '%s'", typeName) +} + +// DescribeEnum takes a qualified enum name and returns an `EnumDescription` if it exists in the +// `pb.Db`. +func (pbdb *Db) DescribeEnum(enumName string) (*EnumDescription, error) { + enumName = sanitizeProtoName(enumName) + if fd, found := pbdb.revFileDescriptorMap[enumName]; found { + return fd.GetEnumDescription(enumName) + } + return nil, fmt.Errorf("unrecognized enum '%s'", enumName) +} + +// DescribeType returns a `TypeDescription` for the `typeName` if it exists in the `pb.Db`. +func (pbdb *Db) DescribeType(typeName string) (*TypeDescription, error) { + typeName = sanitizeProtoName(typeName) + if fd, found := pbdb.revFileDescriptorMap[typeName]; found { + return fd.GetTypeDescription(typeName) + } + return nil, fmt.Errorf("unrecognized type '%s'", typeName) +} + +func (pbdb *Db) describeFileInternal(fileDesc *descpb.FileDescriptorProto) (*FileDescription, error) { + fd := &FileDescription{ + pbdb: pbdb, + desc: fileDesc, + types: make(map[string]*TypeDescription), + enums: make(map[string]*EnumDescription)} + return fd, nil +} + +func fileDescriptor(protoFileName string) (*descpb.FileDescriptorProto, error) { + gzipped := proto.FileDescriptor(protoFileName) + r, err := gzip.NewReader(bytes.NewReader(gzipped)) + if err != nil { + return nil, fmt.Errorf("bad gzipped descriptor: %v", err) + } + unzipped, err := ioutil.ReadAll(r) + if err != nil { + return nil, fmt.Errorf("bad gzipped descriptor: %v", err) + } + fd := &descpb.FileDescriptorProto{} + if err := proto.Unmarshal(unzipped, fd); err != nil { + return nil, fmt.Errorf("bad gzipped descriptor: %v", err) + } + return fd, nil +} + +func init() { + // Describe well-known types to ensure they can always be resolved by the check and interpret + // execution phases. + // + // The following subset of message types is enough to ensure that all well-known types can + // resolved in the runtime, since describing the value results in describing the whole file + // where the message is declared. + DefaultDb.RegisterMessage(&anypb.Any{}) + DefaultDb.RegisterMessage(&durpb.Duration{}) + DefaultDb.RegisterMessage(&tspb.Timestamp{}) + DefaultDb.RegisterMessage(&structpb.Value{}) + DefaultDb.RegisterMessage(&wrapperspb.BoolValue{}) +} 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 new file mode 100644 index 000000000..bccdb3a43 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/pb/type.go @@ -0,0 +1,381 @@ +// 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 pb + +import ( + "fmt" + "reflect" + "strings" + "sync/atomic" + + "github.com/golang/protobuf/proto" + descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// TypeDescription is a collection of type metadata relevant to expression +// checking and evaluation. +type TypeDescription struct { + typeName string + file *FileDescription + desc *descpb.DescriptorProto + metadata *atomic.Value +} + +type typeMetadata struct { + fields map[string]*FieldDescription // fields by name (proto) + fieldIndices map[int][]*FieldDescription // fields by Go struct idx + fieldProperties *proto.StructProperties + reflectedType *reflect.Type + reflectedVal *reflect.Value +} + +// FieldCount returns the number of fields declared within the type. +func (td *TypeDescription) FieldCount() int { + // The number of keys in the field indices map corresponds to the number + // of fields on the proto message. + return len(td.getMetadata().fieldIndices) +} + +// FieldByName returns the FieldDescription associated with a field name. +func (td *TypeDescription) FieldByName(name string) (*FieldDescription, bool) { + fd, found := td.getMetadata().fields[name] + return fd, found +} + +// Name of the type. +func (td *TypeDescription) Name() string { + return td.typeName +} + +// ReflectType returns the reflected struct type of the generated proto struct. +func (td *TypeDescription) ReflectType() reflect.Type { + if td.getMetadata().reflectedType == nil { + return nil + } + return *td.getMetadata().reflectedType +} + +// DefaultValue returns an empty instance of the proto message associated with the type. +func (td *TypeDescription) DefaultValue() proto.Message { + refVal := td.getMetadata().reflectedVal + if refVal == nil { + return nil + } + return (*refVal).Interface().(proto.Message) +} + +func (td *TypeDescription) getMetadata() *typeMetadata { + meta, ok := td.metadata.Load().(*typeMetadata) + if ok { + return meta + } + meta = td.makeMetadata() + td.metadata.Store(meta) + return meta +} + +func (td *TypeDescription) makeMetadata() *typeMetadata { + refType := proto.MessageType(td.typeName) + meta := &typeMetadata{ + fields: make(map[string]*FieldDescription), + fieldIndices: make(map[int][]*FieldDescription), + } + if refType != nil { + // Set the reflected type if non-nil. + meta.reflectedType = &refType + + // Unwrap the pointer reference for the sake of later checks. + elemType := refType + if elemType.Kind() == reflect.Ptr { + elemType = elemType.Elem() + } + if elemType.Kind() == reflect.Struct { + meta.fieldProperties = proto.GetProperties(elemType) + } + refVal := reflect.New(elemType) + meta.reflectedVal = &refVal + } + + fieldIndexMap := make(map[string]int) + fieldDescMap := make(map[string]*descpb.FieldDescriptorProto) + for i, f := range td.desc.Field { + fieldDescMap[f.GetName()] = f + fieldIndexMap[f.GetName()] = i + } + if meta.fieldProperties != nil { + // This is a proper message type. + for i, prop := range meta.fieldProperties.Prop { + if strings.HasPrefix(prop.OrigName, "XXX_") { + // Book-keeping fields generated by protoc start with XXX_ + continue + } + desc := fieldDescMap[prop.OrigName] + fd := td.newFieldDesc(desc, prop, i) + meta.fields[prop.OrigName] = fd + meta.fieldIndices[i] = append(meta.fieldIndices[i], fd) + } + for _, oneofProp := range meta.fieldProperties.OneofTypes { + desc := fieldDescMap[oneofProp.Prop.OrigName] + fd := td.newOneofFieldDesc(desc, oneofProp, oneofProp.Field) + meta.fields[oneofProp.Prop.OrigName] = fd + meta.fieldIndices[oneofProp.Field] = append(meta.fieldIndices[oneofProp.Field], fd) + } + } else { + for fieldName, desc := range fieldDescMap { + fd := td.newMapFieldDesc(desc) + meta.fields[fieldName] = fd + index := fieldIndexMap[fieldName] + meta.fieldIndices[index] = append(meta.fieldIndices[index], fd) + } + } + return meta +} + +func (td *TypeDescription) newFieldDesc( + desc *descpb.FieldDescriptorProto, + prop *proto.Properties, + index int) *FieldDescription { + fieldDesc := &FieldDescription{ + desc: desc, + index: index, + getter: fmt.Sprintf("Get%s", prop.Name), + prop: prop, + isProto3: td.file.desc.GetSyntax() == "proto3", + isWrapper: isWrapperType(desc), + } + if desc.GetType() == descpb.FieldDescriptorProto_TYPE_MESSAGE { + typeName := sanitizeProtoName(desc.GetTypeName()) + fieldType, _ := td.file.pbdb.DescribeType(typeName) + fieldDesc.td = fieldType + return fieldDesc + } + return fieldDesc +} + +func (td *TypeDescription) newOneofFieldDesc( + desc *descpb.FieldDescriptorProto, + oneofProp *proto.OneofProperties, + index int) *FieldDescription { + fieldDesc := td.newFieldDesc(desc, oneofProp.Prop, index) + fieldDesc.oneofProp = oneofProp + return fieldDesc +} + +func (td *TypeDescription) newMapFieldDesc(desc *descpb.FieldDescriptorProto) *FieldDescription { + return &FieldDescription{ + desc: desc, + index: int(desc.GetNumber()), + isProto3: td.file.desc.GetSyntax() == "proto3", + } +} + +func isWrapperType(desc *descpb.FieldDescriptorProto) bool { + if desc.GetType() != descpb.FieldDescriptorProto_TYPE_MESSAGE { + return false + } + switch sanitizeProtoName(desc.GetTypeName()) { + case "google.protobuf.BoolValue", + "google.protobuf.BytesValue", + "google.protobuf.DoubleValue", + "google.protobuf.FloatValue", + "google.protobuf.Int32Value", + "google.protobuf.Int64Value", + "google.protobuf.StringValue", + "google.protobuf.UInt32Value", + "google.protobuf.UInt64Value": + return true + } + return false +} + +// FieldDescription holds metadata related to fields declared within a type. +type FieldDescription struct { + // getter is the name of the accessor method to obtain the field value. + getter string + // isProto3 indicates whether the field is defined in a proto3 syntax. + isProto3 bool + // isWrapper indicates whether the field is a wrapper type. + isWrapper bool + + // td is the type description for message typed fields. + td *TypeDescription + + // proto descriptor data. + desc *descpb.FieldDescriptorProto + index int + prop *proto.Properties + oneofProp *proto.OneofProperties +} + +// CheckedType returns the type-definition used at type-check time. +func (fd *FieldDescription) CheckedType() *exprpb.Type { + if fd.IsMap() { + // Get the FieldDescriptors for the type arranged by their index within the + // generated Go struct. + fieldIndices := fd.getFieldIndicies() + // Map keys and values are represented as repeated entries in a list. + key := fieldIndices[0][0] + val := fieldIndices[1][0] + return &exprpb.Type{ + TypeKind: &exprpb.Type_MapType_{ + MapType: &exprpb.Type_MapType{ + KeyType: key.typeDefToType(), + ValueType: val.typeDefToType()}}} + } + if fd.IsRepeated() { + return &exprpb.Type{ + TypeKind: &exprpb.Type_ListType_{ + ListType: &exprpb.Type_ListType{ + ElemType: fd.typeDefToType()}}} + } + return fd.typeDefToType() +} + +// GetterName returns the accessor method name associated with the field +// on the proto generated struct. +func (fd *FieldDescription) GetterName() string { + return fd.getter +} + +// Index returns the field index within a reflected value. +func (fd *FieldDescription) Index() int { + return fd.index +} + +// IsEnum returns true if the field type refers to an enum value. +func (fd *FieldDescription) IsEnum() bool { + return fd.desc.GetType() == descpb.FieldDescriptorProto_TYPE_ENUM +} + +// IsMap returns true if the field is of map type. +func (fd *FieldDescription) IsMap() bool { + if !fd.IsRepeated() || !fd.IsMessage() { + return false + } + if fd.td == nil { + return false + } + return fd.td.desc.GetOptions().GetMapEntry() +} + +// IsMessage returns true if the field is of message type. +func (fd *FieldDescription) IsMessage() bool { + return fd.desc.GetType() == descpb.FieldDescriptorProto_TYPE_MESSAGE +} + +// IsOneof returns true if the field is declared within a oneof block. +func (fd *FieldDescription) IsOneof() bool { + if fd.desc != nil { + return fd.desc.OneofIndex != nil + } + return fd.oneofProp != nil +} + +// IsRepeated returns true if the field is a repeated value. +// +// This method will also return true for map values, so check whether the +// field is also a map. +func (fd *FieldDescription) IsRepeated() bool { + return *fd.desc.Label == descpb.FieldDescriptorProto_LABEL_REPEATED +} + +// IsWrapper returns true if the field type is a primitive wrapper type. +func (fd *FieldDescription) IsWrapper() bool { + return fd.isWrapper +} + +// OneofType returns the reflect.Type value of a oneof field. +// +// Oneof field values are wrapped in a struct which contains one field whose +// value is a proto.Message. +func (fd *FieldDescription) OneofType() reflect.Type { + return fd.oneofProp.Type +} + +// OrigName returns the snake_case name of the field as it was declared within +// the proto. This is the same name format that is expected within expressions. +func (fd *FieldDescription) OrigName() string { + if fd.desc != nil && fd.desc.Name != nil { + return *fd.desc.Name + } + return fd.prop.OrigName +} + +// Name returns the CamelCase name of the field within the proto-based struct. +func (fd *FieldDescription) Name() string { + return fd.prop.Name +} + +// SupportsPresence returns true if the field supports presence detection. +func (fd *FieldDescription) SupportsPresence() bool { + return !fd.IsRepeated() && (fd.IsMessage() || !fd.isProto3) +} + +// String returns a struct-like field definition string. +func (fd *FieldDescription) String() string { + return fmt.Sprintf("%s %s `oneof=%t`", + fd.TypeName(), fd.OrigName(), fd.IsOneof()) +} + +// Type returns the TypeDescription for the field. +func (fd *FieldDescription) Type() *TypeDescription { + return fd.td +} + +// TypeName returns the type name of the field. +func (fd *FieldDescription) TypeName() string { + return sanitizeProtoName(fd.desc.GetTypeName()) +} + +func (fd *FieldDescription) getFieldIndicies() map[int][]*FieldDescription { + return fd.td.getMetadata().fieldIndices +} + +func (fd *FieldDescription) typeDefToType() *exprpb.Type { + if fd.IsMessage() { + if wk, found := CheckedWellKnowns[fd.TypeName()]; found { + return wk + } + return checkedMessageType(fd.TypeName()) + } + if fd.IsEnum() { + return checkedInt + } + if p, found := CheckedPrimitives[fd.desc.GetType()]; found { + return p + } + return CheckedPrimitives[fd.desc.GetType()] +} + +func checkedMessageType(name string) *exprpb.Type { + return &exprpb.Type{ + TypeKind: &exprpb.Type_MessageType{MessageType: name}} +} + +func checkedPrimitive(primitive exprpb.Type_PrimitiveType) *exprpb.Type { + return &exprpb.Type{ + TypeKind: &exprpb.Type_Primitive{Primitive: primitive}} +} + +func checkedWellKnown(wellKnown exprpb.Type_WellKnownType) *exprpb.Type { + return &exprpb.Type{ + TypeKind: &exprpb.Type_WellKnown{WellKnown: wellKnown}} +} + +func checkedWrap(t *exprpb.Type) *exprpb.Type { + return &exprpb.Type{ + TypeKind: &exprpb.Type_Wrapper{Wrapper: t.GetPrimitive()}} +} diff --git a/vendor/github.com/google/cel-go/common/types/provider.go b/vendor/github.com/google/cel-go/common/types/provider.go new file mode 100644 index 000000000..68ad87d52 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/provider.go @@ -0,0 +1,518 @@ +// 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 ( + "reflect" + + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes" + + "github.com/google/cel-go/common/types/pb" + "github.com/google/cel-go/common/types/ref" + + descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" + anypb "github.com/golang/protobuf/ptypes/any" + dpb "github.com/golang/protobuf/ptypes/duration" + structpb "github.com/golang/protobuf/ptypes/struct" + tpb "github.com/golang/protobuf/ptypes/timestamp" + wrapperspb "github.com/golang/protobuf/ptypes/wrappers" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +type protoTypeRegistry struct { + revTypeMap map[string]ref.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 { + p := &protoTypeRegistry{ + revTypeMap: make(map[string]ref.Type), + pbdb: pb.NewDb(), + } + p.RegisterType( + BoolType, + BytesType, + DoubleType, + DurationType, + DynType, + IntType, + ListType, + MapType, + NullType, + StringType, + TimestampType, + TypeType, + UintType) + + for _, msgType := range types { + fd, err := p.pbdb.RegisterMessage(msgType) + if err != nil { + panic(err) + } + for _, typeName := range fd.GetTypeNames() { + p.RegisterType(NewObjectTypeValue(typeName)) + } + } + return p +} + +func (p *protoTypeRegistry) EnumValue(enumName string) ref.Val { + enumVal, err := p.pbdb.DescribeEnum(enumName) + if err != nil { + return NewErr("unknown enum name '%s'", enumName) + } + return Int(enumVal.Value()) +} + +func (p *protoTypeRegistry) FindFieldType(messageType string, + fieldName string) (*ref.FieldType, bool) { + msgType, err := p.pbdb.DescribeType(messageType) + if err != nil { + return nil, false + } + field, found := msgType.FieldByName(fieldName) + if !found { + return nil, false + } + return &ref.FieldType{ + Type: field.CheckedType(), + SupportsPresence: field.SupportsPresence()}, + true +} + +func (p *protoTypeRegistry) FindIdent(identName string) (ref.Val, bool) { + if t, found := p.revTypeMap[identName]; found { + return t.(ref.Val), true + } + if enumVal, err := p.pbdb.DescribeEnum(identName); err == nil { + return Int(enumVal.Value()), true + } + return nil, false +} + +func (p *protoTypeRegistry) FindType(typeName string) (*exprpb.Type, bool) { + if _, err := p.pbdb.DescribeType(typeName); err != nil { + return nil, false + } + if typeName != "" && typeName[0] == '.' { + typeName = typeName[1:] + } + return &exprpb.Type{ + TypeKind: &exprpb.Type_Type{ + Type: &exprpb.Type{ + TypeKind: &exprpb.Type_MessageType{ + MessageType: typeName}}}}, true +} + +func (p *protoTypeRegistry) NewValue(typeName string, fields map[string]ref.Val) ref.Val { + td, err := p.pbdb.DescribeType(typeName) + if err != nil { + return NewErr("unknown type '%s'", typeName) + } + refType := td.ReflectType() + // create the new type instance. + value := reflect.New(refType.Elem()) + pbValue := value.Elem() + + // for all of the field names referenced, set the provided value. + for name, value := range fields { + fd, found := td.FieldByName(name) + if !found { + return NewErr("no such field '%s'", name) + } + refField := pbValue.Field(fd.Index()) + if !refField.IsValid() { + return NewErr("no such field '%s'", name) + } + + dstType := refField.Type() + // Oneof fields are defined with wrapper structs that have a single proto.Message + // field value. The oneof wrapper is not a proto.Message instance. + if fd.IsOneof() { + oneofVal := reflect.New(fd.OneofType().Elem()) + refField.Set(oneofVal) + refField = oneofVal.Elem().Field(0) + dstType = refField.Type() + } + fieldValue, err := value.ConvertToNative(dstType) + if err != nil { + return &Err{err} + } + refField.Set(reflect.ValueOf(fieldValue)) + } + return p.NativeToValue(value.Interface()) +} + +func (p *protoTypeRegistry) RegisterDescriptor(fileDesc *descpb.FileDescriptorProto) error { + fd, err := p.pbdb.RegisterDescriptor(fileDesc) + if err != nil { + return err + } + return p.registerAllTypes(fd) +} + +func (p *protoTypeRegistry) RegisterMessage(message proto.Message) error { + fd, err := p.pbdb.RegisterMessage(message) + if err != nil { + return err + } + return p.registerAllTypes(fd) +} + +func (p *protoTypeRegistry) RegisterType(types ...ref.Type) error { + for _, t := range types { + p.revTypeMap[t.TypeName()] = t + } + // TODO: generate an error when the type name is registered more than once. + return nil +} + +func (p *protoTypeRegistry) registerAllTypes(fd *pb.FileDescription) error { + for _, typeName := range fd.GetTypeNames() { + err := p.RegisterType(NewObjectTypeValue(typeName)) + if err != nil { + return err + } + } + return nil +} + +// NativeToValue converts various "native" types to ref.Val with this specific implementation +// providing support for custom proto-based types. +// +// This method should be the inverse of ref.Val.ConvertToNative. +func (p *protoTypeRegistry) NativeToValue(value interface{}) ref.Val { + switch value.(type) { + case ref.Val: + return DefaultTypeAdapter.NativeToValue(value) + // Adapt common types and aggregate specializations using the DefaultTypeAdapter. + case bool, *bool, + float32, *float32, float64, *float64, + int, *int, int32, *int32, int64, *int64, + string, *string, + uint, *uint, uint32, *uint32, uint64, *uint64, + []byte, + []string, + map[string]string: + return DefaultTypeAdapter.NativeToValue(value) + // Adapt well-known proto-types using the DefaultTypeAdapter. + case *dpb.Duration, + *tpb.Timestamp, + *structpb.ListValue, + structpb.NullValue, + *structpb.Struct, + *structpb.Value, + *wrapperspb.BoolValue, + *wrapperspb.BytesValue, + *wrapperspb.DoubleValue, + *wrapperspb.FloatValue, + *wrapperspb.Int32Value, + *wrapperspb.Int64Value, + *wrapperspb.StringValue, + *wrapperspb.UInt32Value, + *wrapperspb.UInt64Value: + return DefaultTypeAdapter.NativeToValue(value) + // Override the Any type by ensuring that custom proto-types are considered on recursive calls. + case *anypb.Any: + val := value.(*anypb.Any) + if val == nil { + return NewErr("unsupported type conversion: '%T'", value) + } + unpackedAny := ptypes.DynamicAny{} + if ptypes.UnmarshalAny(val, &unpackedAny) != nil { + return NewErr("unknown type: '%s'", val.GetTypeUrl()) + } + return p.NativeToValue(unpackedAny.Message) + // Convert custom proto types to CEL values based on type's presence within the pb.Db. + case proto.Message: + pbVal := value.(proto.Message) + typeName := proto.MessageName(pbVal) + td, err := p.pbdb.DescribeType(typeName) + if err != nil { + return NewErr("unknown type: '%s'", typeName) + } + return NewObject(p, td, pbVal) + // Override default handling for list and maps to ensure that blends of Go + proto types + // are appropriately adapted on recursive calls or subsequent inspection of the aggregate + // value. + default: + refValue := reflect.ValueOf(value) + if refValue.Kind() == reflect.Ptr { + if refValue.IsNil() { + return NewErr("unsupported type conversion: '%T'", value) + } + refValue = refValue.Elem() + } + refKind := refValue.Kind() + switch refKind { + case reflect.Array, reflect.Slice: + return NewDynamicList(p, value) + case reflect.Map: + return NewDynamicMap(p, value) + } + } + // By default return the default type adapter's conversion to CEL. + return DefaultTypeAdapter.NativeToValue(value) +} + +// defaultTypeAdapter converts go native types to CEL values. +type defaultTypeAdapter struct{} + +var ( + // DefaultTypeAdapter adapts canonical CEL types from their equivalent Go values. + DefaultTypeAdapter = &defaultTypeAdapter{} +) + +// NativeToValue implements the ref.TypeAdapter interface. +func (a *defaultTypeAdapter) NativeToValue(value interface{}) ref.Val { + switch value.(type) { + case nil: + return NullValue + case *Bool: + if ptr := value.(*Bool); ptr != nil { + return ptr + } + case *Bytes: + if ptr := value.(*Bytes); ptr != nil { + return ptr + } + case *Double: + if ptr := value.(*Double); ptr != nil { + return ptr + } + case *Int: + if ptr := value.(*Int); ptr != nil { + return ptr + } + case *String: + if ptr := value.(*String); ptr != nil { + return ptr + } + case *Uint: + if ptr := value.(*Uint); ptr != nil { + return ptr + } + case ref.Val: + return value.(ref.Val) + case bool: + return Bool(value.(bool)) + case int: + return Int(value.(int)) + case int32: + return Int(value.(int32)) + case int64: + return Int(value.(int64)) + case uint: + return Uint(value.(uint)) + case uint32: + return Uint(value.(uint32)) + case uint64: + return Uint(value.(uint64)) + case float32: + return Double(value.(float32)) + case float64: + return Double(value.(float64)) + case string: + return String(value.(string)) + case *bool: + if ptr := value.(*bool); ptr != nil { + return Bool(*ptr) + } + case *float32: + if ptr := value.(*float32); ptr != nil { + return Double(*ptr) + } + case *float64: + if ptr := value.(*float64); ptr != nil { + return Double(*ptr) + } + case *int: + if ptr := value.(*int); ptr != nil { + return Int(*ptr) + } + case *int32: + if ptr := value.(*int32); ptr != nil { + return Int(*ptr) + } + case *int64: + if ptr := value.(*int64); ptr != nil { + return Int(*ptr) + } + case *string: + if ptr := value.(*string); ptr != nil { + return String(*ptr) + } + case *uint: + if ptr := value.(*uint); ptr != nil { + return Uint(*ptr) + } + case *uint32: + if ptr := value.(*uint32); ptr != nil { + return Uint(*ptr) + } + case *uint64: + if ptr := value.(*uint64); ptr != nil { + return Uint(*ptr) + } + case []byte: + return Bytes(value.([]byte)) + case []string: + return NewStringList(a, value.([]string)) + case map[string]string: + return NewStringStringMap(a, value.(map[string]string)) + case *dpb.Duration: + if ptr := value.(*dpb.Duration); ptr != nil { + return Duration{ptr} + } + case *structpb.ListValue: + if ptr := value.(*structpb.ListValue); ptr != nil { + return NewJSONList(a, ptr) + } + case structpb.NullValue, *structpb.NullValue: + return NullValue + case *structpb.Struct: + if ptr := value.(*structpb.Struct); ptr != nil { + return NewJSONStruct(a, ptr) + } + case *structpb.Value: + v := value.(*structpb.Value) + if v == nil { + return NullValue + } + switch v.Kind.(type) { + case *structpb.Value_BoolValue: + return a.NativeToValue(v.GetBoolValue()) + case *structpb.Value_ListValue: + return a.NativeToValue(v.GetListValue()) + case *structpb.Value_NullValue: + return NullValue + case *structpb.Value_NumberValue: + return a.NativeToValue(v.GetNumberValue()) + case *structpb.Value_StringValue: + return a.NativeToValue(v.GetStringValue()) + case *structpb.Value_StructValue: + return a.NativeToValue(v.GetStructValue()) + } + case *tpb.Timestamp: + if ptr := value.(*tpb.Timestamp); ptr != nil { + return Timestamp{ptr} + } + case *anypb.Any: + val := value.(*anypb.Any) + if val == nil { + return NewErr("unsupported type conversion") + } + unpackedAny := ptypes.DynamicAny{} + if ptypes.UnmarshalAny(val, &unpackedAny) != nil { + return NewErr("unknown type: %s", val.GetTypeUrl()) + } + return a.NativeToValue(unpackedAny.Message) + case *wrapperspb.BoolValue: + val := value.(*wrapperspb.BoolValue) + if val == nil { + return NewErr("unsupported type conversion") + } + return Bool(val.GetValue()) + case *wrapperspb.BytesValue: + val := value.(*wrapperspb.BytesValue) + if val == nil { + return NewErr("unsupported type conversion") + } + return Bytes(val.GetValue()) + case *wrapperspb.DoubleValue: + val := value.(*wrapperspb.DoubleValue) + if val == nil { + return NewErr("unsupported type conversion") + } + return Double(val.GetValue()) + case *wrapperspb.FloatValue: + val := value.(*wrapperspb.FloatValue) + if val == nil { + return NewErr("unsupported type conversion") + } + return Double(val.GetValue()) + case *wrapperspb.Int32Value: + val := value.(*wrapperspb.Int32Value) + if val == nil { + return NewErr("unsupported type conversion") + } + return Int(val.GetValue()) + case *wrapperspb.Int64Value: + val := value.(*wrapperspb.Int64Value) + if val == nil { + return NewErr("unsupported type conversion") + } + return Int(val.GetValue()) + case *wrapperspb.StringValue: + val := value.(*wrapperspb.StringValue) + if val == nil { + return NewErr("unsupported type conversion") + } + return String(val.GetValue()) + case *wrapperspb.UInt32Value: + val := value.(*wrapperspb.UInt32Value) + if val == nil { + return NewErr("unsupported type conversion") + } + return Uint(val.GetValue()) + case *wrapperspb.UInt64Value: + val := value.(*wrapperspb.UInt64Value) + if val == nil { + return NewErr("unsupported type conversion") + } + return Uint(val.GetValue()) + default: + refValue := reflect.ValueOf(value) + if refValue.Kind() == reflect.Ptr { + if refValue.IsNil() { + return NewErr("unsupported type conversion: '%T'", value) + } + refValue = refValue.Elem() + } + refKind := refValue.Kind() + switch refKind { + case reflect.Array, reflect.Slice: + return NewDynamicList(a, value) + case reflect.Map: + return NewDynamicMap(a, value) + // type aliases of primitive types cannot be asserted as that type, but rather need + // to be downcast to int32 before being converted to a CEL representation. + case reflect.Int32: + intType := reflect.TypeOf(int32(0)) + return Int(refValue.Convert(intType).Interface().(int32)) + case reflect.Int64: + intType := reflect.TypeOf(int64(0)) + return Int(refValue.Convert(intType).Interface().(int64)) + case reflect.Uint32: + uintType := reflect.TypeOf(uint32(0)) + return Uint(refValue.Convert(uintType).Interface().(uint32)) + case reflect.Uint64: + uintType := reflect.TypeOf(uint64(0)) + return Uint(refValue.Convert(uintType).Interface().(uint64)) + case reflect.Float32: + doubleType := reflect.TypeOf(float32(0)) + return Double(refValue.Convert(doubleType).Interface().(float32)) + case reflect.Float64: + doubleType := reflect.TypeOf(float64(0)) + return Double(refValue.Convert(doubleType).Interface().(float64)) + } + } + return NewErr("unsupported type conversion: '%T'", value) +} 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 new file mode 100644 index 000000000..7586daccf --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/ref/provider.go @@ -0,0 +1,91 @@ +// 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 ref + +import ( + "github.com/golang/protobuf/proto" + + descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// TypeProvider specifies functions for creating new object instances and for +// resolving enum values by name. +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(identName string) (Val, bool) + + // FindType looks up the Type given a qualified typeName. Returns false + // if not found. + // + // Used during type-checking only. + 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. + // + // Used during type-checking only. + FindFieldType(messageType string, 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(typeName string, fields map[string]Val) Val +} + +// TypeAdapter converts native Go values of varying type and complexity to equivalent CEL values. +type TypeAdapter interface { + // NativeToValue converts the input `value` to a CEL `ref.Val`. + NativeToValue(value interface{}) Val +} + +// TypeRegistry allows third-parties to add custom types to CEL. Not all `TypeProvider` +// 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. +type TypeRegistry interface { + TypeAdapter + TypeProvider + + // RegisterDescriptor registers the contents of a protocol buffer `FileDescriptor`. + RegisterDescriptor(fileDesc *descpb.FileDescriptorProto) error + + // RegisterMessage registers a protocol buffer message and its dependencies. + RegisterMessage(message proto.Message) 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 a type is provided more than once with an alternative definition, the + // call will result in an error. + RegisterType(types ...Type) error +} + +// FieldType represents a field's type value and whether that field supports +// presence detection. +type FieldType struct { + // SupportsPresence indicates if the field having been set can be detected. + SupportsPresence bool + + // Type of the field. + Type *exprpb.Type +} 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 new file mode 100644 index 000000000..e12169988 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/ref/reference.go @@ -0,0 +1,59 @@ +// 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 ref contains the reference interfaces used throughout the types +// components. +package ref + +import ( + "reflect" +) + +// Type interface indicate the name of a given type. +type Type interface { + // HasTrait returns whether the type has a given trait associated with it. + // + // See common/types/traits/traits.go for a list of supported traits. + HasTrait(trait int) bool + + // TypeName returns the qualified type name of the type. + // + // The type name is also used as the type's identifier name at type-check + // and interpretation time. + TypeName() string +} + +// Val interface defines the functions supported by all expression values. +// Val implementations may specialize the behavior of the value through the +// addition of traits. +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. + ConvertToNative(typeDesc reflect.Type) (interface{}, error) + + // ConvertToType supports type conversions between 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. + Equal(other Val) Val + + // Type returns the TypeValue of the value. + Type() Type + + // Value returns the raw value of the instance which may not be directly + // compatible with the expression language types. + Value() interface{} +} diff --git a/vendor/github.com/google/cel-go/common/types/string.go b/vendor/github.com/google/cel-go/common/types/string.go new file mode 100644 index 000000000..4838eef65 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/string.go @@ -0,0 +1,216 @@ +// 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" + "regexp" + "strconv" + "strings" + "time" + + "github.com/golang/protobuf/ptypes" + + "github.com/google/cel-go/common/overloads" + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + + structpb "github.com/golang/protobuf/ptypes/struct" + wrapperspb "github.com/golang/protobuf/ptypes/wrappers" +) + +// String type implementation which supports addition, comparison, matching, +// and size functions. +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, + } + + stringWrapperType = reflect.TypeOf(&wrapperspb.StringValue{}) +) + +// Add implements traits.Adder.Add. +func (s String) Add(other ref.Val) ref.Val { + otherString, ok := other.(String) + if !ok { + return ValOrErr(other, "no such overload") + } + return s + otherString +} + +// Compare implements traits.Comparer.Compare. +func (s String) Compare(other ref.Val) ref.Val { + otherString, ok := other.(String) + if !ok { + return ValOrErr(other, "no such overload") + } + return Int(strings.Compare(s.Value().(string), otherString.Value().(string))) +} + +// ConvertToNative implements ref.Val.ConvertToNative. +func (s String) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + switch typeDesc.Kind() { + case reflect.String: + return s.Value(), nil + case reflect.Ptr: + switch typeDesc { + case anyValueType: + // Primitives must be wrapped before being set on an Any field. + return ptypes.MarshalAny(&wrapperspb.StringValue{Value: string(s)}) + case jsonValueType: + // Convert to a protobuf representation of a JSON String. + return &structpb.Value{ + Kind: &structpb.Value_StringValue{StringValue: string(s)}, + }, nil + case stringWrapperType: + // Convert to a protobuf.StringValue. + return &wrapperspb.StringValue{Value: string(s)}, nil + } + if typeDesc.Elem().Kind() == reflect.String { + p := s.Value().(string) + return &p, nil + } + case reflect.Interface: + if reflect.TypeOf(s).Implements(typeDesc) { + return s, nil + } + } + return nil, fmt.Errorf( + "unsupported native conversion from string to '%v'", typeDesc) +} + +// ConvertToType implements ref.Val.ConvertToType. +func (s String) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case IntType: + if n, err := strconv.ParseInt(s.Value().(string), 10, 64); err == nil { + return Int(n) + } + case UintType: + if n, err := strconv.ParseUint(s.Value().(string), 10, 64); err == nil { + return Uint(n) + } + case DoubleType: + if n, err := strconv.ParseFloat(s.Value().(string), 64); err == nil { + return Double(n) + } + case BoolType: + if b, err := strconv.ParseBool(s.Value().(string)); err == nil { + return Bool(b) + } + case BytesType: + return Bytes(s) + case DurationType: + if d, err := time.ParseDuration(s.Value().(string)); err == nil { + return Duration{ptypes.DurationProto(d)} + } + case TimestampType: + if t, err := time.Parse(time.RFC3339, s.Value().(string)); err == nil { + if ts, err := ptypes.TimestampProto(t); err == nil { + return Timestamp{ts} + } + } + case StringType: + return s + case TypeType: + return StringType + } + return NewErr("type conversion error from '%s' to '%s'", StringType, typeVal) +} + +// Equal implements ref.Val.Equal. +func (s String) Equal(other ref.Val) ref.Val { + otherString, ok := other.(String) + if !ok { + return ValOrErr(other, "no such overload") + } + return Bool(s == otherString) +} + +// Match implements traits.Matcher.Match. +func (s String) Match(pattern ref.Val) ref.Val { + pat, ok := pattern.(String) + if !ok { + return ValOrErr(pattern, "no such overload") + } + matched, err := regexp.MatchString(pat.Value().(string), s.Value().(string)) + if err != nil { + return &Err{err} + } + return Bool(matched) +} + +// Receive implements traits.Reciever.Receive. +func (s String) Receive(function string, overload string, args []ref.Val) ref.Val { + switch len(args) { + case 1: + if f, found := stringOneArgOverloads[function]; found { + return f(s, args[0]) + } + } + return NewErr("no such overload") +} + +// Size implements traits.Sizer.Size. +func (s String) Size() ref.Val { + return Int(len([]rune(s.Value().(string)))) +} + +// Type implements ref.Val.Type. +func (s String) Type() ref.Type { + return StringType +} + +// Value implements ref.Val.Value. +func (s String) Value() interface{} { + return string(s) +} + +func stringContains(s String, sub ref.Val) ref.Val { + subStr, ok := sub.(String) + if !ok { + return ValOrErr(sub, "no such overload") + } + return Bool(strings.Contains(string(s), string(subStr))) +} + +func stringEndsWith(s String, suf ref.Val) ref.Val { + sufStr, ok := suf.(String) + if !ok { + return ValOrErr(suf, "no such overload") + } + return Bool(strings.HasSuffix(string(s), string(sufStr))) +} + +func stringStartsWith(s String, pre ref.Val) ref.Val { + preStr, ok := pre.(String) + if !ok { + return ValOrErr(pre, "no such overload") + } + return Bool(strings.HasPrefix(string(s), 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 new file mode 100644 index 000000000..b9fe33c77 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/timestamp.go @@ -0,0 +1,328 @@ +// 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" + "strconv" + "strings" + "time" + + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes" + + "github.com/google/cel-go/common/overloads" + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + + structpb "github.com/golang/protobuf/ptypes/struct" + tpb "github.com/golang/protobuf/ptypes/timestamp" +) + +// Timestamp type implementation which supports add, compare, and subtract +// operations. Timestamps are also capable of participating in dynamic +// function dispatch to instance methods. +type Timestamp struct { + *tpb.Timestamp +} + +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() { + case DurationType: + return other.(Duration).Add(t) + } + return ValOrErr(other, "no such overload") +} + +// Compare implements traits.Comparer.Compare. +func (t Timestamp) Compare(other ref.Val) ref.Val { + if TimestampType != other.Type() { + return ValOrErr(other, "no such overload") + } + ts1, err := ptypes.Timestamp(t.Timestamp) + if err != nil { + return &Err{err} + } + ts2, err := ptypes.Timestamp(other.(Timestamp).Timestamp) + if err != nil { + return &Err{err} + } + ts := ts1.Sub(ts2) + if ts < 0 { + return IntNegOne + } + if ts > 0 { + return IntOne + } + return IntZero +} + +// ConvertToNative implements ref.Val.ConvertToNative. +func (t Timestamp) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + switch typeDesc { + case anyValueType: + // Pack the underlying protobuf.Timestamp to an Any value. + return ptypes.MarshalAny(t.Timestamp) + case jsonValueType: + // CEL follows the proto3 to JSON conversion which formats as an RFC 3339 encoded JSON + // string. + v := t.ConvertToType(StringType) + if IsError(v) { + return nil, v.(*Err) + } + return &structpb.Value{ + Kind: &structpb.Value_StringValue{StringValue: string(v.(String))}, + }, nil + case timestampValueType: + // Unwrap the underlying protobuf.Timestamp. + return t.Value(), nil + } + // If the timestamp is already assignable to the desired type return it. + if reflect.TypeOf(t).AssignableTo(typeDesc) { + return t, nil + } + return nil, fmt.Errorf("type conversion error from "+ + "'google.protobuf.Timestamp' to '%v'", typeDesc) +} + +// ConvertToType implements ref.Val.ConvertToType. +func (t Timestamp) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case StringType: + return String(ptypes.TimestampString(t.Timestamp)) + case IntType: + if ts, err := ptypes.Timestamp(t.Timestamp); err == nil { + // Return the Unix time in seconds since 1970 + return Int(ts.Unix()) + } + case TimestampType: + return t + case TypeType: + return TimestampType + } + return NewErr("type conversion error from '%s' to '%s'", TimestampType, typeVal) +} + +// Equal implements ref.Val.Equal. +func (t Timestamp) Equal(other ref.Val) ref.Val { + if TimestampType != other.Type() { + return ValOrErr(other, "no such overload") + } + return Bool(proto.Equal(t.Timestamp, other.Value().(proto.Message))) +} + +// Receive implements traits.Reciever.Receive. +func (t Timestamp) Receive(function string, overload string, args []ref.Val) ref.Val { + ts := t.Timestamp + tstamp, err := ptypes.Timestamp(ts) + if err != nil { + return &Err{err} + } + switch len(args) { + case 0: + if f, found := timestampZeroArgOverloads[function]; found { + return f(tstamp) + } + case 1: + if f, found := timestampOneArgOverloads[function]; found { + return f(tstamp, args[0]) + } + } + return NewErr("no such overload") +} + +// Subtract implements traits.Subtractor.Subtract. +func (t Timestamp) Subtract(subtrahend ref.Val) ref.Val { + switch subtrahend.Type() { + case DurationType: + ts, err := ptypes.Timestamp(t.Timestamp) + if err != nil { + return &Err{err} + } + dur, err := ptypes.Duration(subtrahend.(Duration).Duration) + if err != nil { + return &Err{err} + } + tstamp, err := ptypes.TimestampProto(ts.Add(-dur)) + if err != nil { + return &Err{err} + } + return Timestamp{tstamp} + case TimestampType: + ts1, err := ptypes.Timestamp(t.Timestamp) + if err != nil { + return &Err{err} + } + ts2, err := ptypes.Timestamp(subtrahend.(Timestamp).Timestamp) + if err != nil { + return &Err{err} + } + return Duration{ptypes.DurationProto(ts1.Sub(ts2))} + } + return ValOrErr(subtrahend, "no such overload") +} + +// Type implements ref.Val.Type. +func (t Timestamp) Type() ref.Type { + return TimestampType +} + +// Value implements ref.Val.Value. +func (t Timestamp) Value() interface{} { + return t.Timestamp +} + +var ( + timestampValueType = reflect.TypeOf(&tpb.Timestamp{}) + + timestampZeroArgOverloads = map[string]func(time.Time) ref.Val{ + overloads.TimeGetFullYear: timestampGetFullYear, + overloads.TimeGetMonth: timestampGetMonth, + overloads.TimeGetDayOfYear: timestampGetDayOfYear, + overloads.TimeGetDate: timestampGetDayOfMonthOneBased, + overloads.TimeGetDayOfMonth: timestampGetDayOfMonthZeroBased, + overloads.TimeGetDayOfWeek: timestampGetDayOfWeek, + overloads.TimeGetHours: timestampGetHours, + overloads.TimeGetMinutes: timestampGetMinutes, + overloads.TimeGetSeconds: timestampGetSeconds, + overloads.TimeGetMilliseconds: timestampGetMilliseconds} + + timestampOneArgOverloads = map[string]func(time.Time, ref.Val) ref.Val{ + overloads.TimeGetFullYear: timestampGetFullYearWithTz, + overloads.TimeGetMonth: timestampGetMonthWithTz, + overloads.TimeGetDayOfYear: timestampGetDayOfYearWithTz, + overloads.TimeGetDate: timestampGetDayOfMonthOneBasedWithTz, + overloads.TimeGetDayOfMonth: timestampGetDayOfMonthZeroBasedWithTz, + overloads.TimeGetDayOfWeek: timestampGetDayOfWeekWithTz, + overloads.TimeGetHours: timestampGetHoursWithTz, + overloads.TimeGetMinutes: timestampGetMinutesWithTz, + overloads.TimeGetSeconds: timestampGetSecondsWithTz, + overloads.TimeGetMilliseconds: timestampGetMillisecondsWithTz} +) + +type timestampVisitor func(time.Time) ref.Val + +func timestampGetFullYear(t time.Time) ref.Val { + return Int(t.Year()) +} +func timestampGetMonth(t time.Time) ref.Val { + // CEL spec indicates that the month should be 0-based, but the Time value + // for Month() is 1-based. + return Int(t.Month() - 1) +} +func timestampGetDayOfYear(t time.Time) ref.Val { + return Int(t.YearDay() - 1) +} +func timestampGetDayOfMonthZeroBased(t time.Time) ref.Val { + return Int(t.Day() - 1) +} +func timestampGetDayOfMonthOneBased(t time.Time) ref.Val { + return Int(t.Day()) +} +func timestampGetDayOfWeek(t time.Time) ref.Val { + return Int(t.Weekday()) +} +func timestampGetHours(t time.Time) ref.Val { + return Int(t.Hour()) +} +func timestampGetMinutes(t time.Time) ref.Val { + return Int(t.Minute()) +} +func timestampGetSeconds(t time.Time) ref.Val { + return Int(t.Second()) +} +func timestampGetMilliseconds(t time.Time) ref.Val { + return Int(t.Nanosecond() / 1000000) +} + +func timestampGetFullYearWithTz(t time.Time, tz ref.Val) ref.Val { + return timeZone(tz, timestampGetFullYear)(t) +} +func timestampGetMonthWithTz(t time.Time, tz ref.Val) ref.Val { + return timeZone(tz, timestampGetMonth)(t) +} +func timestampGetDayOfYearWithTz(t time.Time, tz ref.Val) ref.Val { + return timeZone(tz, timestampGetDayOfYear)(t) +} +func timestampGetDayOfMonthZeroBasedWithTz(t time.Time, tz ref.Val) ref.Val { + return timeZone(tz, timestampGetDayOfMonthZeroBased)(t) +} +func timestampGetDayOfMonthOneBasedWithTz(t time.Time, tz ref.Val) ref.Val { + return timeZone(tz, timestampGetDayOfMonthOneBased)(t) +} +func timestampGetDayOfWeekWithTz(t time.Time, tz ref.Val) ref.Val { + return timeZone(tz, timestampGetDayOfWeek)(t) +} +func timestampGetHoursWithTz(t time.Time, tz ref.Val) ref.Val { + return timeZone(tz, timestampGetHours)(t) +} +func timestampGetMinutesWithTz(t time.Time, tz ref.Val) ref.Val { + return timeZone(tz, timestampGetMinutes)(t) +} +func timestampGetSecondsWithTz(t time.Time, tz ref.Val) ref.Val { + return timeZone(tz, timestampGetSeconds)(t) +} +func timestampGetMillisecondsWithTz(t time.Time, tz ref.Val) ref.Val { + return timeZone(tz, timestampGetMilliseconds)(t) +} + +func timeZone(tz ref.Val, visitor timestampVisitor) timestampVisitor { + return func(t time.Time) ref.Val { + if StringType != tz.Type() { + return ValOrErr(tz, "no such overload") + } + val := string(tz.(String)) + ind := strings.Index(val, ":") + if ind == -1 { + loc, err := time.LoadLocation(val) + if err != nil { + return &Err{err} + } + return visitor(t.In(loc)) + } + + // If the input is not the name of a timezone (for example, 'US/Central'), it should be a numerical offset from UTC + // 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 &Err{err} + } + min, err := strconv.Atoi(string(val[ind+1])) + if err != nil { + return &Err{err} + } + var offset int + if string(val[0]) == "-" { + offset = hr*60 - min + } else { + offset = hr*60 + min + } + secondsEastOfUTC := int((time.Duration(offset) * time.Minute).Seconds()) + timezone := time.FixedZone("", secondsEastOfUTC) + return visitor(t.In(timezone)) + } +} diff --git a/vendor/github.com/google/cel-go/common/types/traits/comparer.go b/vendor/github.com/google/cel-go/common/types/traits/comparer.go new file mode 100644 index 000000000..b531d9ae2 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/traits/comparer.go @@ -0,0 +1,33 @@ +// 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 traits + +import ( + "github.com/google/cel-go/common/types/ref" +) + +// Comparer interface for ordering comparisons between values in order to +// support '<', '<=', '>=', '>' overloads. +type Comparer interface { + // Compare this value to the input other value, returning an Int: + // + // this < other -> Int(-1) + // this == other -> Int(0) + // this > other -> Int(1) + // + // If the comparison cannot be made or is not supported, an error should + // be returned. + Compare(other ref.Val) ref.Val +} diff --git a/vendor/github.com/google/cel-go/common/types/traits/container.go b/vendor/github.com/google/cel-go/common/types/traits/container.go new file mode 100644 index 000000000..cf5c621ae --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/traits/container.go @@ -0,0 +1,23 @@ +// 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 traits + +import "github.com/google/cel-go/common/types/ref" + +// Container interface which permits containment tests such as 'a in b'. +type Container interface { + // Contains returns true if the value exists within the object. + Contains(value ref.Val) ref.Val +} diff --git a/vendor/github.com/google/cel-go/common/types/traits/field_tester.go b/vendor/github.com/google/cel-go/common/types/traits/field_tester.go new file mode 100644 index 000000000..816a95652 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/traits/field_tester.go @@ -0,0 +1,30 @@ +// 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 traits + +import ( + "github.com/google/cel-go/common/types/ref" +) + +// FieldTester indicates if a defined field on an object type is set to a +// non-default value. +// +// For use with the `has()` macro. +type FieldTester interface { + // IsSet returns true if the field is defined and set to a non-default + // value. The method will return false if defined and not set, and an error + // if the field is not defined. + IsSet(field ref.Val) ref.Val +} diff --git a/vendor/github.com/google/cel-go/common/types/traits/indexer.go b/vendor/github.com/google/cel-go/common/types/traits/indexer.go new file mode 100644 index 000000000..662c6836c --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/traits/indexer.go @@ -0,0 +1,25 @@ +// 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 traits + +import ( + "github.com/google/cel-go/common/types/ref" +) + +// Indexer permits random access of elements by index 'a[b()]'. +type Indexer interface { + // Get the value at the specified index or error. + Get(index ref.Val) ref.Val +} diff --git a/vendor/github.com/google/cel-go/common/types/traits/iterator.go b/vendor/github.com/google/cel-go/common/types/traits/iterator.go new file mode 100644 index 000000000..42dd371aa --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/traits/iterator.go @@ -0,0 +1,36 @@ +// 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 traits + +import ( + "github.com/google/cel-go/common/types/ref" +) + +// Iterable aggregate types permit traversal over their elements. +type Iterable interface { + // Iterator returns a new iterator view of the struct. + Iterator() Iterator +} + +// Iterator permits safe traversal over the contents of an aggregate type. +type Iterator interface { + ref.Val + + // HasNext returns true if there are unvisited elements in the Iterator. + HasNext() ref.Val + + // Next returns the next element. + Next() ref.Val +} diff --git a/vendor/github.com/google/cel-go/common/types/traits/lister.go b/vendor/github.com/google/cel-go/common/types/traits/lister.go new file mode 100644 index 000000000..7b05c301d --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/traits/lister.go @@ -0,0 +1,27 @@ +// 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 traits + +import "github.com/google/cel-go/common/types/ref" + +// Lister interface which aggregates the traits of a list. +type Lister interface { + ref.Val + Adder + Container + Indexer + Iterable + Sizer +} diff --git a/vendor/github.com/google/cel-go/common/types/traits/mapper.go b/vendor/github.com/google/cel-go/common/types/traits/mapper.go new file mode 100644 index 000000000..5edd8f61b --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/traits/mapper.go @@ -0,0 +1,33 @@ +// 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 traits + +import "github.com/google/cel-go/common/types/ref" + +// Mapper interface which aggregates the traits of a maps. +type Mapper interface { + ref.Val + Container + Indexer + Iterable + Sizer + + // Find a value by key if it exists. + // + // When the value exists, the result will be non-nil, true. When the value does not exist, + // the result will be nil, false. When an error occurs, the value will be non-nil and the + // found result false. + Find(key ref.Val) (ref.Val, bool) +} diff --git a/vendor/github.com/google/cel-go/common/types/traits/matcher.go b/vendor/github.com/google/cel-go/common/types/traits/matcher.go new file mode 100644 index 000000000..085dc94ff --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/traits/matcher.go @@ -0,0 +1,23 @@ +// 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 traits + +import "github.com/google/cel-go/common/types/ref" + +// Matcher interface for supporting 'matches()' overloads. +type Matcher interface { + // Match returns true if the pattern matches the current value. + Match(pattern ref.Val) ref.Val +} diff --git a/vendor/github.com/google/cel-go/common/types/traits/math.go b/vendor/github.com/google/cel-go/common/types/traits/math.go new file mode 100644 index 000000000..86d5b9137 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/traits/math.go @@ -0,0 +1,62 @@ +// 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 traits + +import "github.com/google/cel-go/common/types/ref" + +// Adder interface to support '+' operator overloads. +type Adder interface { + // Add returns a combination of the current value and other value. + // + // If the other value is an unsupported type, an error is returned. + Add(other ref.Val) ref.Val +} + +// Divider interface to support '/' operator overloads. +type Divider interface { + // Divide returns the result of dividing the current value by the input + // denominator. + // + // A denominator value of zero results in an error. + Divide(denominator ref.Val) ref.Val +} + +// Modder interface to support '%' operator overloads. +type Modder interface { + // Modulo returns the result of taking the modulus of the current value + // by the denominator. + // + // A denominator value of zero results in an error. + Modulo(denominator ref.Val) ref.Val +} + +// Multiplier interface to support '*' operator overloads. +type Multiplier interface { + // Multiply returns the result of multiplying the current and input value. + Multiply(other ref.Val) ref.Val +} + +// Negater interface to support unary '-' and '!' operator overloads. +type Negater interface { + // Negate returns the complement of the current value. + Negate() ref.Val +} + +// Subtractor interface to support binary '-' operator overloads. +type Subtractor interface { + // Subtract returns the result of subtracting the input from the current + // value. + Subtract(subtrahend ref.Val) ref.Val +} diff --git a/vendor/github.com/google/cel-go/common/types/traits/receiver.go b/vendor/github.com/google/cel-go/common/types/traits/receiver.go new file mode 100644 index 000000000..8f41db45e --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/traits/receiver.go @@ -0,0 +1,24 @@ +// 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 traits + +import "github.com/google/cel-go/common/types/ref" + +// Receiver interface for routing instance method calls within a value. +type Receiver interface { + // Receive accepts a function name, overload id, and arguments and returns + // a value. + Receive(function string, overload string, args []ref.Val) ref.Val +} diff --git a/vendor/github.com/google/cel-go/common/types/traits/sizer.go b/vendor/github.com/google/cel-go/common/types/traits/sizer.go new file mode 100644 index 000000000..b80d25137 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/traits/sizer.go @@ -0,0 +1,25 @@ +// 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 traits + +import ( + "github.com/google/cel-go/common/types/ref" +) + +// Sizer interface for supporting 'size()' overloads. +type Sizer interface { + // Size returns the number of elements or length of the value. + Size() ref.Val +} diff --git a/vendor/github.com/google/cel-go/common/types/traits/traits.go b/vendor/github.com/google/cel-go/common/types/traits/traits.go new file mode 100644 index 000000000..6da3e6a3e --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/traits/traits.go @@ -0,0 +1,64 @@ +// 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 traits defines interfaces that a type may implement to participate +// in operator overloads and function dispatch. +package traits + +const ( + // AdderType types provide a '+' operator overload. + AdderType = 1 << iota + + // ComparerType types support ordering comparisons '<', '<=', '>', '>='. + ComparerType + + // ContainerType types support 'in' operations. + ContainerType + + // DividerType types support '/' operations. + DividerType + + // FieldTesterType types support the detection of field value presence. + FieldTesterType + + // IndexerType types support index access with dynamic values. + IndexerType + + // IterableType types can be iterated over in comprehensions. + IterableType + + // IteratorType types support iterator semantics. + IteratorType + + // MatcherType types support pattern matching via 'matches' method. + MatcherType + + // ModderType types support modulus operations '%' + ModderType + + // MultiplierType types support '*' operations. + MultiplierType + + // NegatorType types support either negation via '!' or '-' + NegatorType + + // ReceiverType types support dynamic dispatch to instance methods. + ReceiverType + + // SizerType types support the size() method. + SizerType + + // SubtractorType type support '-' operations. + SubtractorType +) diff --git a/vendor/github.com/google/cel-go/common/types/type.go b/vendor/github.com/google/cel-go/common/types/type.go new file mode 100644 index 000000000..4d65fa88f --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/type.go @@ -0,0 +1,104 @@ +// 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) (interface{}, 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 t + 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 { + if TypeType != other.Type() { + return ValOrErr(other, "no such overload") + } + return Bool(t.TypeName() == other.(ref.Type).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() interface{} { + return t.name +} diff --git a/vendor/github.com/google/cel-go/common/types/uint.go b/vendor/github.com/google/cel-go/common/types/uint.go new file mode 100644 index 000000000..e94f24ff1 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/uint.go @@ -0,0 +1,210 @@ +// 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" + "strconv" + + "github.com/golang/protobuf/ptypes" + + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + + structpb "github.com/golang/protobuf/ptypes/struct" + wrapperspb "github.com/golang/protobuf/ptypes/wrappers" +) + +// Uint type implementation which supports comparison and math operators. +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{}) +) + +// Uint constants +const ( + uintZero = Uint(0) +) + +// Add implements traits.Adder.Add. +func (i Uint) Add(other ref.Val) ref.Val { + otherUint, ok := other.(Uint) + if !ok { + return ValOrErr(other, "no such overload") + } + return i + otherUint +} + +// Compare implements traits.Comparer.Compare. +func (i Uint) Compare(other ref.Val) ref.Val { + otherUint, ok := other.(Uint) + if !ok { + return ValOrErr(other, "no such overload") + } + if i < otherUint { + return IntNegOne + } + if i > otherUint { + return IntOne + } + return IntZero +} + +// ConvertToNative implements ref.Val.ConvertToNative. +func (i Uint) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + switch typeDesc.Kind() { + case reflect.Uint32: + return uint32(i), nil + case reflect.Uint64: + return uint64(i), nil + case reflect.Ptr: + switch typeDesc { + case anyValueType: + // Primitives must be wrapped before being set on an Any field. + return ptypes.MarshalAny(&wrapperspb.UInt64Value{Value: uint64(i)}) + case jsonValueType: + // JSON can accurately represent 32-bit uints as floating point values. + if i.isJSONSafe() { + return &structpb.Value{ + Kind: &structpb.Value_NumberValue{ + NumberValue: float64(i), + }, + }, nil + } + // Proto3 to JSON conversion requires string-formatted uint64 values + // since the conversion to floating point would result in truncation. + return &structpb.Value{ + Kind: &structpb.Value_StringValue{ + StringValue: strconv.FormatUint(uint64(i), 10), + }, + }, nil + case uint32WrapperType: + // Convert the value to a protobuf.UInt32Value (with truncation). + return &wrapperspb.UInt32Value{Value: uint32(i)}, nil + case uint64WrapperType: + // Convert the value to a protobuf.UInt64Value. + return &wrapperspb.UInt64Value{Value: uint64(i)}, nil + } + switch typeDesc.Elem().Kind() { + case reflect.Uint32: + p := uint32(i) + return &p, nil + case reflect.Uint64: + p := uint64(i) + return &p, nil + } + case reflect.Interface: + if reflect.TypeOf(i).Implements(typeDesc) { + return i, nil + } + } + return nil, fmt.Errorf("unsupported type conversion from 'uint' to %v", typeDesc) +} + +// ConvertToType implements ref.Val.ConvertToType. +func (i Uint) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case IntType: + return Int(i) + case UintType: + return i + case DoubleType: + return Double(i) + case StringType: + return String(fmt.Sprintf("%d", uint64(i))) + case TypeType: + return UintType + } + return NewErr("type conversion error from '%s' to '%s'", UintType, typeVal) +} + +// Divide implements traits.Divider.Divide. +func (i Uint) Divide(other ref.Val) ref.Val { + otherUint, ok := other.(Uint) + if !ok { + return ValOrErr(other, "no such overload") + } + if otherUint == uintZero { + return NewErr("divide by zero") + } + return i / otherUint +} + +// Equal implements ref.Val.Equal. +func (i Uint) Equal(other ref.Val) ref.Val { + otherUint, ok := other.(Uint) + if !ok { + return ValOrErr(other, "no such overload") + } + return Bool(i == otherUint) +} + +// Modulo implements traits.Modder.Modulo. +func (i Uint) Modulo(other ref.Val) ref.Val { + otherUint, ok := other.(Uint) + if !ok { + return ValOrErr(other, "no such overload") + } + if otherUint == uintZero { + return NewErr("modulus by zero") + } + return i % otherUint +} + +// Multiply implements traits.Multiplier.Multiply. +func (i Uint) Multiply(other ref.Val) ref.Val { + otherUint, ok := other.(Uint) + if !ok { + return ValOrErr(other, "no such overload") + } + return i * otherUint +} + +// Subtract implements traits.Subtractor.Subtract. +func (i Uint) Subtract(subtrahend ref.Val) ref.Val { + subtraUint, ok := subtrahend.(Uint) + if !ok { + return ValOrErr(subtrahend, "no such overload") + } + return i - subtraUint +} + +// Type implements ref.Val.Type. +func (i Uint) Type() ref.Type { + return UintType +} + +// Value implements ref.Val.Value. +func (i Uint) Value() interface{} { + return uint64(i) +} + +// isJSONSafe indicates whether the uint is safely representable as a floating point value in JSON. +func (i Uint) isJSONSafe() bool { + return i <= maxIntJSON +} diff --git a/vendor/github.com/google/cel-go/common/types/unknown.go b/vendor/github.com/google/cel-go/common/types/unknown.go new file mode 100644 index 000000000..a950920d6 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/unknown.go @@ -0,0 +1,61 @@ +// 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 ( + "reflect" + + "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") +) + +// ConvertToNative implements ref.Val.ConvertToNative. +func (u Unknown) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + return u.Value(), nil +} + +// ConvertToType implements ref.Val.ConvertToType. +func (u Unknown) ConvertToType(typeVal ref.Type) ref.Val { + return u +} + +// Equal implements ref.Val.Equal. +func (u Unknown) Equal(other ref.Val) ref.Val { + return u +} + +// Type implements ref.Val.Type. +func (u Unknown) Type() ref.Type { + return UnknownType +} + +// Value implements ref.Val.Value. +func (u Unknown) Value() interface{} { + return []int64(u) +} + +// IsUnknown returns whether the element ref.Type or ref.Val is equal to the +// UnknownType singleton. +func IsUnknown(val ref.Val) bool { + return val.Type() == UnknownType +} diff --git a/vendor/github.com/google/cel-go/common/types/util.go b/vendor/github.com/google/cel-go/common/types/util.go new file mode 100644 index 000000000..761c512d7 --- /dev/null +++ b/vendor/github.com/google/cel-go/common/types/util.go @@ -0,0 +1,38 @@ +// 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 ( + "github.com/google/cel-go/common/types/ref" +) + +// IsUnknownOrError returns whether the input element ref.Val is an ErrType or UnknonwType. +func IsUnknownOrError(val ref.Val) bool { + switch val.Type() { + case UnknownType, ErrType: + return true + } + return false +} + +// IsPrimitiveType returns whether the input element ref.Val is a primitive type. +// Note, primitive types do not include well-known types such as Duration and Timestamp. +func IsPrimitiveType(val ref.Val) bool { + switch val.Type() { + case BoolType, BytesType, DoubleType, IntType, StringType, UintType: + return true + } + return false +} diff --git a/vendor/github.com/google/cel-go/interpreter/activation.go b/vendor/github.com/google/cel-go/interpreter/activation.go new file mode 100644 index 000000000..d30f774bb --- /dev/null +++ b/vendor/github.com/google/cel-go/interpreter/activation.go @@ -0,0 +1,182 @@ +// 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 interpreter + +import ( + "errors" + "fmt" + "sync" + + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" +) + +// Activation used to resolve identifiers by name and references by id. +// +// An Activation is the primary mechanism by which a caller supplies input into a CEL program. +type Activation interface { + // ResolveName returns a value from the activation by qualified name, or false if the name + // could not be found. + ResolveName(name string) (ref.Val, bool) + + // Parent returns the parent of the current activation, may be nil. + // If non-nil, the parent will be searched during resolve calls. + Parent() Activation +} + +// EmptyActivation returns a variable free activation. +func EmptyActivation() Activation { + // This call cannot fail. + a, _ := NewActivation(map[string]interface{}{}) + return a +} + +// NewActivation returns an activation based on a map-based binding where the map keys are +// expected to be qualified names used with ResolveName calls. +// +// The input `bindings` may either be of type `Activation` or `map[string]interface{}`. +// +// When the bindings are a `map` form whose values are not of `ref.Val` type, the values will be +// converted to CEL values (if possible) using the `types.DefaultTypeAdapter`. +func NewActivation(bindings interface{}) (Activation, error) { + return NewAdaptingActivation(types.DefaultTypeAdapter, bindings) +} + +// NewAdaptingActivation returns an actvation which is capable of adapting `bindings` from native +// Go values to equivalent CEL `ref.Val` objects. +// +// The input `bindings` may either be of type `Activation` or `map[string]interface{}`. +// +// When the bindings are a `map` the values may be one of the following types: +// - `ref.Val`: a CEL value instance. +// - `func() ref.Val`: a CEL value supplier. +// - other: a native value which must be converted to a CEL `ref.Val` by the `adapter`. +func NewAdaptingActivation(adapter ref.TypeAdapter, bindings interface{}) (Activation, error) { + if adapter == nil { + return nil, errors.New("adapter must be non-nil") + } + if bindings == nil { + return nil, errors.New("bindings must be non-nil") + } + a, isActivation := bindings.(Activation) + if isActivation { + return a, nil + } + m, isMap := bindings.(map[string]interface{}) + if !isMap { + return nil, fmt.Errorf( + "activation input must be an activation or map[string]interface: got %T", + bindings) + } + return &mapActivation{adapter: adapter, bindings: m}, nil +} + +// mapActivation which implements Activation and maps of named values. +// +// Named bindings may lazily supply values by providing a function which accepts no arguments and +// produces an interface value. +type mapActivation struct { + adapter ref.TypeAdapter + bindings map[string]interface{} +} + +// Parent implements the Activation interface method. +func (a *mapActivation) Parent() Activation { + return nil +} + +// ResolveName implements the Activation interface method. +func (a *mapActivation) ResolveName(name string) (ref.Val, bool) { + if object, found := a.bindings[name]; found { + switch object.(type) { + // Resolve a lazily bound value. + case func() ref.Val: + val := object.(func() ref.Val)() + val = a.adapter.NativeToValue(val) + a.bindings[name] = val + return val, true + // Otherwise, return the bound value. + default: + return a.adapter.NativeToValue(object), true + } + } + return nil, false +} + +// hierarchicalActivation which implements Activation and contains a parent and +// child activation. +type hierarchicalActivation struct { + parent Activation + child Activation +} + +// Parent implements the Activation interface method. +func (a *hierarchicalActivation) Parent() Activation { + return a.parent +} + +// ResolveName implements the Activation interface method. +func (a *hierarchicalActivation) ResolveName(name string) (ref.Val, bool) { + if object, found := a.child.ResolveName(name); found { + return object, found + } + return a.parent.ResolveName(name) +} + +// NewHierarchicalActivation takes two activations and produces a new one which prioritizes +// resolution in the child first and parent(s) second. +func NewHierarchicalActivation(parent Activation, child Activation) Activation { + return &hierarchicalActivation{parent, child} +} + +// newVarActivation returns a new varActivation instance. +func newVarActivation(parent Activation, name string) *varActivation { + return &varActivation{ + parent: parent, + name: name, + } +} + +// varActivation represents a single mutable variable binding. +// +// This activation type should only be used within folds as the fold loop controls the object +// life-cycle. +type varActivation struct { + parent Activation + name string + val ref.Val +} + +// Parent implements the Activation interface method. +func (v *varActivation) Parent() Activation { + return v.parent +} + +// ResolveName implements the Activation interface method. +func (v *varActivation) ResolveName(name string) (ref.Val, bool) { + if name == v.name { + return v.val, true + } + return v.parent.ResolveName(name) +} + +var ( + // pool of var activations to reduce allocations during folds. + varActivationPool = &sync.Pool{ + New: func() interface{} { + return &varActivation{} + }, + } +) diff --git a/vendor/github.com/google/cel-go/interpreter/decorators.go b/vendor/github.com/google/cel-go/interpreter/decorators.go new file mode 100644 index 000000000..e7dec33c7 --- /dev/null +++ b/vendor/github.com/google/cel-go/interpreter/decorators.go @@ -0,0 +1,177 @@ +// 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 interpreter + +import ( + "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" +) + +// InterpretableDecorator is a functional interface for decorating or replacing +// Interpretable expression nodes at construction time. +type InterpretableDecorator func(Interpretable) (Interpretable, error) + +// evalObserver is a functional interface that accepts an expression id and an observed value. +type evalObserver func(int64, ref.Val) + +// decObserveEval records evaluation state into an EvalState object. +func decObserveEval(observer evalObserver) InterpretableDecorator { + return func(i Interpretable) (Interpretable, error) { + return &evalWatch{ + inst: i, + observer: observer, + }, nil + } +} + +// decDisableShortcircuits ensures that all branches of an expression will be evaluated, no short-circuiting. +func decDisableShortcircuits() InterpretableDecorator { + return func(i Interpretable) (Interpretable, error) { + switch i.(type) { + case *evalOr: + or := i.(*evalOr) + return &evalExhaustiveOr{ + id: or.id, + lhs: or.lhs, + rhs: or.rhs, + }, nil + case *evalAnd: + and := i.(*evalAnd) + return &evalExhaustiveAnd{ + id: and.id, + lhs: and.lhs, + rhs: and.rhs, + }, nil + case *evalConditional: + cond := i.(*evalConditional) + return &evalExhaustiveConditional{ + id: cond.id, + expr: cond.expr, + truthy: cond.truthy, + falsy: cond.falsy, + }, nil + case *evalFold: + fold := i.(*evalFold) + return &evalExhaustiveFold{ + id: fold.id, + accu: fold.accu, + accuVar: fold.accuVar, + iterRange: fold.iterRange, + iterVar: fold.iterVar, + cond: fold.cond, + step: fold.step, + result: fold.result, + }, nil + } + return i, nil + } +} + +// decOptimize optimizes the program plan by looking for common evaluation patterns and +// conditionally precomputating the result. +// - build list and map values with constant elements. +// - convert 'in' operations to set membership tests if possible. +func decOptimize() InterpretableDecorator { + return func(i Interpretable) (Interpretable, error) { + switch i.(type) { + case *evalList: + return maybeBuildListLiteral(i, i.(*evalList)) + case *evalMap: + return maybeBuildMapLiteral(i, i.(*evalMap)) + case *evalBinary: + call := i.(*evalBinary) + if call.overload == overloads.InList { + return maybeOptimizeSetMembership(i, call) + } + } + return i, nil + } +} + +func maybeBuildListLiteral(i Interpretable, l *evalList) (Interpretable, error) { + for _, elem := range l.elems { + _, isConst := elem.(*evalConst) + if !isConst { + return i, nil + } + } + val := l.Eval(EmptyActivation()) + return &evalConst{ + id: l.id, + val: val, + }, nil +} + +func maybeBuildMapLiteral(i Interpretable, mp *evalMap) (Interpretable, error) { + for idx, key := range mp.keys { + _, isConst := key.(*evalConst) + if !isConst { + return i, nil + } + _, isConst = mp.vals[idx].(*evalConst) + if !isConst { + return i, nil + } + } + val := mp.Eval(EmptyActivation()) + return &evalConst{ + id: mp.id, + val: val, + }, nil +} + +// maybeOptimizeSetMembership may convert an 'in' operation against a list to map key membership +// test if the following conditions are true: +// - the list is a constant with homogeneous element types. +// - the elements are all of primitive type. +func maybeOptimizeSetMembership(i Interpretable, inlist *evalBinary) (Interpretable, error) { + l, isConst := inlist.rhs.(*evalConst) + if !isConst { + return i, nil + } + // When the incoming binary call is flagged with as the InList overload, the value will + // always be convertible to a `traits.Lister` type. + list := l.val.(traits.Lister) + if list.Size() == types.IntZero { + return &evalConst{ + id: inlist.id, + val: types.False, + }, nil + } + it := list.Iterator() + var typ ref.Type + 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. + return i, nil + } + if typ == nil { + typ = elem.Type() + } else if typ.TypeName() != elem.Type().TypeName() { + return i, nil + } + valueSet[elem] = types.True + } + return &evalSetMembership{ + inst: inlist, + arg: inlist.lhs, + argTypeName: typ.TypeName(), + valueSet: valueSet, + }, nil +} diff --git a/vendor/github.com/google/cel-go/interpreter/dispatcher.go b/vendor/github.com/google/cel-go/interpreter/dispatcher.go new file mode 100644 index 000000000..2c6516f24 --- /dev/null +++ b/vendor/github.com/google/cel-go/interpreter/dispatcher.go @@ -0,0 +1,100 @@ +// 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 interpreter + +import ( + "fmt" + + "github.com/google/cel-go/interpreter/functions" +) + +// Dispatcher resolves function calls to their appropriate overload. +type Dispatcher interface { + // Add one or more overloads, returning an error if any Overload has the same Overload#Name. + Add(overloads ...*functions.Overload) error + + // FindOverload returns an Overload definition matching the provided name. + FindOverload(overload string) (*functions.Overload, bool) + + // OverloadIds returns the set of all overload identifiers configured for dispatch. + OverloadIds() []string +} + +// NewDispatcher returns an empty Dispatcher instance. +func NewDispatcher() Dispatcher { + return &defaultDispatcher{ + overloads: make(map[string]*functions.Overload)} +} + +// ExtendDispatcher returns a Dispatcher which inherits the overloads of its parent, and +// provides an isolation layer between built-ins and extension functions which is useful +// for forward compatibility. +func ExtendDispatcher(parent Dispatcher) Dispatcher { + return &defaultDispatcher{ + parent: parent, + overloads: make(map[string]*functions.Overload)} +} + +// overloadMap helper type for indexing overloads by function name. +type overloadMap map[string]*functions.Overload + +// defaultDispatcher struct which contains an overload map. +type defaultDispatcher struct { + parent Dispatcher + overloads overloadMap +} + +// Add implements the Dispatcher.Add interface method. +func (d *defaultDispatcher) Add(overloads ...*functions.Overload) error { + for _, o := range overloads { + // add the overload unless an overload of the same name has already been provided. + if _, found := d.overloads[o.Operator]; found { + return fmt.Errorf("overload already exists '%s'", o.Operator) + } + // index the overload by function name. + d.overloads[o.Operator] = o + } + return nil +} + +// FindOverload implements the Dispatcher.FindOverload interface method. +func (d *defaultDispatcher) FindOverload(overload string) (*functions.Overload, bool) { + o, found := d.overloads[overload] + // Attempt to dispatch to an overload defined in the parent. + if !found && d.parent != nil { + return d.parent.FindOverload(overload) + } + return o, found +} + +// OverloadIds implements the Dispatcher interface method. +func (d *defaultDispatcher) OverloadIds() []string { + i := 0 + overloads := make([]string, len(d.overloads), len(d.overloads)) + for name := range d.overloads { + overloads[i] = name + i++ + } + if d.parent == nil { + return overloads + } + parentOverloads := d.parent.OverloadIds() + for _, pName := range parentOverloads { + if _, found := d.overloads[pName]; !found { + overloads = append(overloads, pName) + } + } + return overloads +} diff --git a/vendor/github.com/google/cel-go/interpreter/evalstate.go b/vendor/github.com/google/cel-go/interpreter/evalstate.go new file mode 100644 index 000000000..cc0d3e6f9 --- /dev/null +++ b/vendor/github.com/google/cel-go/interpreter/evalstate.go @@ -0,0 +1,75 @@ +// 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 interpreter + +import ( + "github.com/google/cel-go/common/types/ref" +) + +// EvalState tracks the values associated with expression ids during execution. +type EvalState interface { + // IDs returns the list of ids with recorded values. + IDs() []int64 + + // Value returns the observed value of the given expression id if found, and a nil false + // result if not. + Value(int64) (ref.Val, bool) + + // SetValue sets the observed value of the expression id. + SetValue(int64, ref.Val) + + // Reset clears the previously recorded expression values. + Reset() +} + +// evalState permits the mutation of evaluation state for a given expression id. +type evalState struct { + values map[int64]ref.Val +} + +// NewEvalState returns an EvalState instanced used to observe the intermediate +// evaluations of an expression. +func NewEvalState() EvalState { + return &evalState{ + values: make(map[int64]ref.Val), + } +} + +// IDs implements the EvalState interface method. +func (s *evalState) IDs() []int64 { + var ids []int64 + for k, v := range s.values { + if v != nil { + ids = append(ids, k) + } + } + return ids +} + +// Value is an implementation of the EvalState interface method. +func (s *evalState) Value(exprID int64) (ref.Val, bool) { + val, found := s.values[exprID] + return val, found +} + +// SetValue is an implementation of the EvalState interface method. +func (s *evalState) SetValue(exprID int64, val ref.Val) { + s.values[exprID] = val +} + +// Reset implements the EvalState interface method. +func (s *evalState) Reset() { + s.values = map[int64]ref.Val{} +} diff --git a/vendor/github.com/google/cel-go/interpreter/functions/functions.go b/vendor/github.com/google/cel-go/interpreter/functions/functions.go new file mode 100644 index 000000000..4ca706e96 --- /dev/null +++ b/vendor/github.com/google/cel-go/interpreter/functions/functions.go @@ -0,0 +1,58 @@ +// 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 defines the standard builtin functions supported by the +// interpreter and as declared within the checker#StandardDeclarations. +package functions + +import "github.com/google/cel-go/common/types/ref" + +// Overload defines a named overload of a function, indicating an operand trait +// which must be present on the first argument to the overload as well as one +// of either a unary, binary, or function implementation. +// +// The majority of operators within the expression language are unary or binary +// and the specializations simplify the call contract for implementers of +// types with operator overloads. Any added complexity is assumed to be handled +// by the generic FunctionOp. +type Overload struct { + // Operator name as written in an expression or defined within + // operators.go. + Operator string + + // Operand trait used to dispatch the call. The zero-value indicates a + // global function overload or that one of the Unary / Binary / Function + // definitions should be used to execute the call. + OperandTrait int + + // Unary defines the overload with a UnaryOp implementation. May be nil. + Unary UnaryOp + + // Binary defines the overload with a BinaryOp implementation. May be nil. + Binary BinaryOp + + // Function defines the overload with a FunctionOp implementation. May be + // nil. + Function FunctionOp +} + +// UnaryOp is a function that takes a single value and produces an output. +type UnaryOp func(value ref.Val) ref.Val + +// BinaryOp is a function that takes two values and produces an output. +type BinaryOp func(lhs ref.Val, rhs ref.Val) ref.Val + +// FunctionOp is a function with accepts zero or more arguments and produces +// an value (as interface{}) or error as a result. +type FunctionOp func(values ...ref.Val) ref.Val diff --git a/vendor/github.com/google/cel-go/interpreter/functions/standard.go b/vendor/github.com/google/cel-go/interpreter/functions/standard.go new file mode 100644 index 000000000..be225364c --- /dev/null +++ b/vendor/github.com/google/cel-go/interpreter/functions/standard.go @@ -0,0 +1,260 @@ +// 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 { + 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 + }}, + + // TODO: Verify overflow, NaN, underflow cases for numeric values. + + // 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 { + 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) + }}, + + {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 new file mode 100644 index 000000000..899e768c1 --- /dev/null +++ b/vendor/github.com/google/cel-go/interpreter/interpretable.go @@ -0,0 +1,766 @@ +// Copyright 2019 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 ( + "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 +// an accompanying EvalState which can be used to inspect whether additional +// data might be necessary to complete the evaluation. +type Interpretable interface { + // ID value corresponding to the expression node. + ID() int64 + + // Eval an Activation to produce an output. + Eval(activation Activation) ref.Val +} + +// Core Interpretable implementations used during the program planning phase. + +type evalIdent struct { + id int64 + name string + provider ref.TypeProvider + resolveID func(Activation) (ref.Val, bool) +} + +// ID implements the Interpretable interface method. +func (id *evalIdent) ID() int64 { + return id.id +} + +// Eval implements the Interpretable interface method. +func (id *evalIdent) Eval(ctx Activation) ref.Val { + idName := id.name + if id.resolveID != nil { + // When the resolveID function is non-nil, the name could be relative + // to the container. + if val, found := id.resolveID(ctx); found { + return val + } + } else { + // Resolve the simple name directly as a type or ident. + val, found := ctx.ResolveName(idName) + if found { + return val + } + typeVal, found := id.provider.FindIdent(idName) + if found { + return typeVal + } + } + return types.Unknown{id.id} + +} + +type evalSelect struct { + id int64 + op Interpretable + field types.String + resolveID func(Activation) (ref.Val, bool) +} + +// ID implements the Interpretable interface method. +func (sel *evalSelect) ID() int64 { + return sel.id +} + +// Eval implements the Interpretable interface method. +func (sel *evalSelect) Eval(ctx Activation) ref.Val { + // If the select is actually a qualified identifier return. + if sel.resolveID != nil { + if resolve, found := sel.resolveID(ctx); found { + return resolve + } + } + // Otherwise, evaluate the operand and select the field. + obj := sel.op.Eval(ctx) + indexer, ok := obj.(traits.Indexer) + if !ok { + return types.ValOrErr(obj, "invalid type for field selection.") + } + return indexer.Get(sel.field) +} + +type evalTestOnly struct { + id int64 + op Interpretable + field types.String +} + +// ID implements the Interpretable interface method. +func (test *evalTestOnly) ID() int64 { + return test.id +} + +// Eval implements the Interpretable interface method. +func (test *evalTestOnly) Eval(ctx Activation) ref.Val { + obj := test.op.Eval(ctx) + tester, ok := obj.(traits.FieldTester) + if ok { + return tester.IsSet(test.field) + } + container, ok := obj.(traits.Container) + if ok { + return container.Contains(test.field) + } + return types.ValOrErr(obj, "invalid type for field selection.") + +} + +type evalConst struct { + id int64 + val ref.Val +} + +// ID implements the Interpretable interface method. +func (cons *evalConst) ID() int64 { + return cons.id +} + +// Eval implements the Interpretable interface method. +func (cons *evalConst) Eval(ctx Activation) ref.Val { + return cons.val +} + +type evalOr struct { + id int64 + lhs Interpretable + rhs Interpretable +} + +// ID implements the Interpretable interface method. +func (or *evalOr) ID() int64 { + return or.id +} + +// 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 + } + if types.IsUnknown(rVal) { + return rVal + } + // If the left-hand side is non-boolean return it as the error. + if types.IsError(lVal) { + return lVal + } + return types.ValOrErr(rVal, "no such overload") +} + +type evalAnd struct { + id int64 + lhs Interpretable + rhs Interpretable +} + +// ID implements the Interpretable interface method. +func (and *evalAnd) ID() int64 { + return and.id +} + +// 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 + } + if types.IsUnknown(rVal) { + return rVal + } + // If the left-hand side is non-boolean return it as the error. + if types.IsError(lVal) { + return lVal + } + return types.ValOrErr(rVal, "no such overload") +} + +type evalConditional struct { + id int64 + expr Interpretable + truthy Interpretable + falsy Interpretable +} + +// ID implements the Interpretable interface method. +func (cond *evalConditional) ID() int64 { + return cond.id +} + +// Eval implements the Interpretable interface method. +func (cond *evalConditional) Eval(ctx Activation) ref.Val { + condVal := cond.expr.Eval(ctx) + condBool, ok := condVal.(types.Bool) + if !ok { + return types.ValOrErr(condVal, "no such overload") + } + if condBool { + return cond.truthy.Eval(ctx) + } + return cond.falsy.Eval(ctx) +} + +type evalEq struct { + id int64 + lhs Interpretable + rhs Interpretable +} + +// ID implements the Interpretable interface method. +func (eq *evalEq) ID() int64 { + return eq.id +} + +// Eval implements the Interpretable interface method. +func (eq *evalEq) Eval(ctx Activation) ref.Val { + lVal := eq.lhs.Eval(ctx) + rVal := eq.rhs.Eval(ctx) + return lVal.Equal(rVal) +} + +type evalNe struct { + id int64 + lhs Interpretable + rhs Interpretable +} + +// ID implements the Interpretable interface method. +func (ne *evalNe) ID() int64 { + return ne.id +} + +// Eval implements the Interpretable interface method. +func (ne *evalNe) Eval(ctx Activation) ref.Val { + lVal := ne.lhs.Eval(ctx) + rVal := ne.rhs.Eval(ctx) + eqVal := lVal.Equal(rVal) + eqBool, ok := eqVal.(types.Bool) + if !ok { + if types.IsUnknown(eqVal) { + return eqVal + } + return types.NewErr("no such overload: _!=_") + } + return !eqBool +} + +type evalZeroArity struct { + id int64 + impl functions.FunctionOp +} + +// ID implements the Interpretable interface method. +func (zero *evalZeroArity) ID() int64 { + return zero.id +} + +// Eval implements the Interpretable interface method. +func (zero *evalZeroArity) Eval(ctx Activation) ref.Val { + return zero.impl() +} + +type evalUnary struct { + id int64 + function string + overload string + arg Interpretable + trait int + impl functions.UnaryOp +} + +// ID implements the Interpretable interface method. +func (un *evalUnary) ID() int64 { + return un.id +} + +// Eval implements the Interpretable interface method. +func (un *evalUnary) Eval(ctx Activation) ref.Val { + argVal := un.arg.Eval(ctx) + // Early return if the argument to the function is unknown or error. + if types.IsUnknownOrError(argVal) { + return argVal + } + // If the implementation is bound and the argument value has the right traits required to + // invoke it, then call the implementation. + if un.impl != nil && (un.trait == 0 || argVal.Type().HasTrait(un.trait)) { + return un.impl(argVal) + } + // Otherwise, if the argument is a ReceiverType attempt to invoke the receiver method on the + // operand (arg0). + if argVal.Type().HasTrait(traits.ReceiverType) { + return argVal.(traits.Receiver).Receive(un.function, un.overload, []ref.Val{}) + } + return types.NewErr("no such overload: %s", un.function) +} + +type evalBinary struct { + id int64 + function string + overload string + lhs Interpretable + rhs Interpretable + trait int + impl functions.BinaryOp +} + +// ID implements the Interpretable interface method. +func (bin *evalBinary) ID() int64 { + return bin.id +} + +// Eval implements the Interpretable interface method. +func (bin *evalBinary) Eval(ctx Activation) ref.Val { + lVal := bin.lhs.Eval(ctx) + rVal := bin.rhs.Eval(ctx) + // Early return if any argument to the function is unknown or error. + if types.IsUnknownOrError(lVal) { + return lVal + } + if types.IsUnknownOrError(rVal) { + return rVal + } + // If the implementation is bound and the argument value has the right traits required to + // invoke it, then call the implementation. + if bin.impl != nil && (bin.trait == 0 || lVal.Type().HasTrait(bin.trait)) { + return bin.impl(lVal, rVal) + } + // Otherwise, if the argument is a ReceiverType attempt to invoke the receiver method on the + // operand (arg0). + if lVal.Type().HasTrait(traits.ReceiverType) { + return lVal.(traits.Receiver).Receive(bin.function, bin.overload, []ref.Val{rVal}) + } + return types.NewErr("no such overload: %s", bin.function) +} + +type evalVarArgs struct { + id int64 + function string + overload string + args []Interpretable + trait int + impl functions.FunctionOp +} + +// ID implements the Interpretable interface method. +func (fn *evalVarArgs) ID() int64 { + return fn.id +} + +// Eval implements the Interpretable interface method. +func (fn *evalVarArgs) Eval(ctx Activation) ref.Val { + argVals := make([]ref.Val, len(fn.args), len(fn.args)) + // Early return if any argument to the function is unknown or error. + for i, arg := range fn.args { + argVals[i] = arg.Eval(ctx) + if types.IsUnknownOrError(argVals[i]) { + return argVals[i] + } + } + // If the implementation is bound and the argument value has the right traits required to + // invoke it, then call the implementation. + arg0 := argVals[0] + if fn.impl != nil && (fn.trait == 0 || arg0.Type().HasTrait(fn.trait)) { + return fn.impl(argVals...) + } + // Otherwise, if the argument is a ReceiverType attempt to invoke the receiver method on the + // operand (arg0). + if arg0.Type().HasTrait(traits.ReceiverType) { + return arg0.(traits.Receiver).Receive(fn.function, fn.overload, argVals[1:]) + } + return types.NewErr("no such overload: %s", fn.function) +} + +type evalList struct { + id int64 + elems []Interpretable + adapter ref.TypeAdapter +} + +// ID implements the Interpretable interface method. +func (l *evalList) ID() int64 { + return l.id +} + +// Eval implements the Interpretable interface method. +func (l *evalList) Eval(ctx Activation) ref.Val { + elemVals := make([]ref.Val, len(l.elems), 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 + } + return types.NewDynamicList(l.adapter, elemVals) +} + +type evalMap struct { + id int64 + keys []Interpretable + vals []Interpretable + adapter ref.TypeAdapter +} + +// ID implements the Interpretable interface method. +func (m *evalMap) ID() int64 { + return m.id +} + +// Eval implements the Interpretable interface method. +func (m *evalMap) Eval(ctx Activation) ref.Val { + entries := make(map[ref.Val]ref.Val) + // If any argument is unknown or error early terminate. + for i, key := range m.keys { + keyVal := key.Eval(ctx) + if types.IsUnknownOrError(keyVal) { + return keyVal + } + valVal := m.vals[i].Eval(ctx) + if types.IsUnknownOrError(valVal) { + return valVal + } + entries[keyVal] = valVal + } + return types.NewDynamicMap(m.adapter, entries) +} + +type evalObj struct { + id int64 + typeName string + fields []string + vals []Interpretable + provider ref.TypeProvider +} + +// ID implements the Interpretable interface method. +func (o *evalObj) ID() int64 { + return o.id +} + +// Eval implements the Interpretable interface method. +func (o *evalObj) Eval(ctx Activation) ref.Val { + fieldVals := make(map[string]ref.Val) + // If any argument is unknown or error early terminate. + for i, field := range o.fields { + val := o.vals[i].Eval(ctx) + if types.IsUnknownOrError(val) { + return val + } + fieldVals[field] = val + } + return o.provider.NewValue(o.typeName, fieldVals) +} + +type evalFold struct { + id int64 + accuVar string + iterVar string + iterRange Interpretable + accu Interpretable + cond Interpretable + step Interpretable + result Interpretable +} + +// ID implements the Interpretable interface method. +func (fold *evalFold) ID() int64 { + return fold.id +} + +// Eval implements the Interpretable interface method. +func (fold *evalFold) Eval(ctx Activation) ref.Val { + foldRange := fold.iterRange.Eval(ctx) + if !foldRange.Type().HasTrait(traits.IterableType) { + return types.ValOrErr(foldRange, "got '%T', expected iterable type", foldRange) + } + // Configure the fold activation with the accumulator initial value. + accuCtx := varActivationPool.Get().(*varActivation) + accuCtx.parent = ctx + accuCtx.name = fold.accuVar + accuCtx.val = fold.accu.Eval(ctx) + iterCtx := varActivationPool.Get().(*varActivation) + iterCtx.parent = accuCtx + iterCtx.name = fold.iterVar + it := foldRange.(traits.Iterable).Iterator() + for it.HasNext() == types.True { + // Modify the iter var in the fold activation. + iterCtx.val = it.Next() + + // Evaluate the condition, terminate the loop if false. + cond := fold.cond.Eval(iterCtx) + condBool, ok := cond.(types.Bool) + if !types.IsUnknown(cond) && ok && condBool != types.True { + break + } + + // Evalute the evaluation step into accu var. + accuCtx.val = fold.step.Eval(iterCtx) + } + // Compute the result. + res := fold.result.Eval(accuCtx) + varActivationPool.Put(iterCtx) + varActivationPool.Put(accuCtx) + return res +} + +// Optional Intepretable implementations that specialize, subsume, or extend the core evaluation +// plan via decorators. + +// evalSetMembership is an Interpretable implementation which tests whether an input value +// exists within the set of map keys used to model a set. +type evalSetMembership struct { + inst Interpretable + arg Interpretable + argTypeName string + valueSet map[ref.Val]ref.Val +} + +// ID implements the Interpretable interface method. +func (e *evalSetMembership) ID() int64 { + return e.inst.ID() +} + +// Eval implements the Interpretable interface method. +func (e *evalSetMembership) Eval(ctx Activation) ref.Val { + val := e.arg.Eval(ctx) + if val.Type().TypeName() != e.argTypeName { + return types.ValOrErr(val, "no such overload") + } + if ret, found := e.valueSet[val]; found { + return ret + } + return types.False +} + +// 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 { + inst Interpretable + observer evalObserver +} + +// ID implements the Interpretable interface method. +func (e *evalWatch) ID() int64 { + return e.inst.ID() +} + +// Eval implements the Interpretable interface method. +func (e *evalWatch) Eval(ctx Activation) ref.Val { + val := e.inst.Eval(ctx) + e.observer(e.inst.ID(), val) + return val +} + +// evalExhaustiveOr is just like evalOr, but does not short-circuit argument evaluation. +type evalExhaustiveOr struct { + id int64 + lhs Interpretable + rhs Interpretable +} + +// ID implements the Interpretable interface method. +func (or *evalExhaustiveOr) ID() int64 { + return or.id +} + +// 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 + } + rBool, rok := rVal.(types.Bool) + if rok && rBool == types.True { + return types.True + } + if lok && rok { + return types.False + } + if types.IsUnknown(lVal) { + return lVal + } + if types.IsUnknown(rVal) { + return rVal + } + // 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 + } + return types.ValOrErr(rVal, "no such overload") +} + +// evalExhaustiveAnd is just like evalAnd, but does not short-circuit argument evaluation. +type evalExhaustiveAnd struct { + id int64 + lhs Interpretable + rhs Interpretable +} + +// ID implements the Interpretable interface method. +func (and *evalExhaustiveAnd) ID() int64 { + return and.id +} + +// 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 + } + rBool, rok := rVal.(types.Bool) + if rok && rBool == types.False { + return types.False + } + if lok && rok { + return types.True + } + if types.IsUnknown(lVal) { + return lVal + } + if types.IsUnknown(rVal) { + return rVal + } + // 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 + } + return types.ValOrErr(rVal, "no such overload") +} + +// evalExhaustiveConditional is like evalConditional, but does not short-circuit argument +// evaluation. +type evalExhaustiveConditional struct { + id int64 + expr Interpretable + truthy Interpretable + falsy Interpretable +} + +// ID implements the Interpretable interface method. +func (cond *evalExhaustiveConditional) ID() int64 { + return cond.id +} + +// Eval implements the Interpretable interface method. +func (cond *evalExhaustiveConditional) Eval(ctx Activation) ref.Val { + cVal := cond.expr.Eval(ctx) + tVal := cond.truthy.Eval(ctx) + fVal := cond.falsy.Eval(ctx) + cBool, ok := cVal.(types.Bool) + if !ok { + return types.ValOrErr(cVal, "no such overload") + } + if cBool { + return tVal + } + return fVal +} + +// evalExhaustiveFold is like evalFold, but does not short-circuit argument evaluation. +type evalExhaustiveFold struct { + id int64 + accuVar string + iterVar string + iterRange Interpretable + accu Interpretable + cond Interpretable + step Interpretable + result Interpretable +} + +// ID implements the Interpretable interface method. +func (fold *evalExhaustiveFold) ID() int64 { + return fold.id +} + +// Eval implements the Interpretable interface method. +func (fold *evalExhaustiveFold) Eval(ctx Activation) ref.Val { + foldRange := fold.iterRange.Eval(ctx) + if !foldRange.Type().HasTrait(traits.IterableType) { + return types.ValOrErr(foldRange, "got '%T', expected iterable type", foldRange) + } + // Configure the fold activation with the accumulator initial value. + accuCtx := varActivationPool.Get().(*varActivation) + accuCtx.parent = ctx + accuCtx.name = fold.accuVar + accuCtx.val = fold.accu.Eval(ctx) + iterCtx := varActivationPool.Get().(*varActivation) + iterCtx.parent = accuCtx + iterCtx.name = fold.iterVar + it := foldRange.(traits.Iterable).Iterator() + for it.HasNext() == types.True { + // Modify the iter var in the fold activation. + iterCtx.val = it.Next() + + // Evaluate the condition, but don't terminate the loop as this is exhaustive eval! + fold.cond.Eval(iterCtx) + + // Evalute the evaluation step into accu var. + accuCtx.val = fold.step.Eval(iterCtx) + } + // Compute the result. + res := fold.result.Eval(accuCtx) + varActivationPool.Put(iterCtx) + varActivationPool.Put(accuCtx) + return res +} diff --git a/vendor/github.com/google/cel-go/interpreter/interpreter.go b/vendor/github.com/google/cel-go/interpreter/interpreter.go new file mode 100644 index 000000000..dcf7ffaa2 --- /dev/null +++ b/vendor/github.com/google/cel-go/interpreter/interpreter.go @@ -0,0 +1,129 @@ +// 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 interpreter provides functions to evaluate parsed expressions with +// the option to augment the evaluation with inputs and functions supplied at +// evaluation time. +package interpreter + +import ( + "github.com/google/cel-go/common/packages" + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/interpreter/functions" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// Interpreter generates a new Interpretable from a checked or unchecked expression. +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) + + // NewUncheckedInterpretable returns an Interpretable from a parsed expression + // and an optional list of InterpretableDecorator values. + NewUncheckedInterpretable(expr *exprpb.Expr, + decorators ...InterpretableDecorator) (Interpretable, error) +} + +// TrackState decorates each expression node with an observer which records the value +// associated with the given expression id. EvalState must be provided to the decorator. +// This decorator is not thread-safe, and the EvalState must be reset between Eval() +// calls. +func TrackState(state EvalState) InterpretableDecorator { + observer := func(id int64, val ref.Val) { + state.SetValue(id, val) + } + return decObserveEval(observer) +} + +// ExhaustiveEval replaces operations that short-circuit with versions that evaluate +// expressions and couples this behavior with the TrackState() decorator to provide +// insight into the evaluation state of the entire expression. EvalState must be +// provided to the decorator. This decorator is not thread-safe, and the EvalState +// must be reset between Eval() calls. +func ExhaustiveEval(state EvalState) InterpretableDecorator { + ex := decDisableShortcircuits() + obs := TrackState(state) + return func(i Interpretable) (Interpretable, error) { + var err error + i, err = ex(i) + if err != nil { + return nil, err + } + return obs(i) + } +} + +// Optimize will pre-compute operations such as list and map construction and optimize +// call arguments to set membership tests. The set of optimizations will increase over time. +func Optimize() InterpretableDecorator { + return decOptimize() +} + +type exprInterpreter struct { + dispatcher Dispatcher + packager packages.Packager + provider ref.TypeProvider + adapter ref.TypeAdapter +} + +// NewInterpreter builds an Interpreter from a Dispatcher and TypeProvider which will be used +// throughout the Eval of all Interpretable instances gerenated from it. +func NewInterpreter(dispatcher Dispatcher, packager packages.Packager, + provider ref.TypeProvider, + adapter ref.TypeAdapter) Interpreter { + return &exprInterpreter{ + dispatcher: dispatcher, + packager: packager, + provider: provider, + adapter: adapter} +} + +// NewStandardInterpreter builds a Dispatcher and TypeProvider with support for all of the CEL +// builtins defined in the language definition. +func NewStandardInterpreter(packager packages.Packager, provider ref.TypeProvider, + adapter ref.TypeAdapter) Interpreter { + dispatcher := NewDispatcher() + dispatcher.Add(functions.StandardOverloads()...) + return NewInterpreter(dispatcher, packager, provider, adapter) +} + +// NewIntepretable implements the Interpreter interface method. +func (i *exprInterpreter) NewInterpretable( + checked *exprpb.CheckedExpr, + decorators ...InterpretableDecorator) (Interpretable, error) { + p := newPlanner( + i.dispatcher, + i.provider, + i.adapter, + i.packager, + checked, + decorators...) + return p.Plan(checked.GetExpr()) +} + +// NewUncheckedIntepretable implements the Interpreter interface method. +func (i *exprInterpreter) NewUncheckedInterpretable( + expr *exprpb.Expr, + decorators ...InterpretableDecorator) (Interpretable, error) { + p := newUncheckedPlanner( + i.dispatcher, + i.provider, + i.adapter, + i.packager, + decorators...) + return p.Plan(expr) +} diff --git a/vendor/github.com/google/cel-go/interpreter/planner.go b/vendor/github.com/google/cel-go/interpreter/planner.go new file mode 100644 index 000000000..6ada6840c --- /dev/null +++ b/vendor/github.com/google/cel-go/interpreter/planner.go @@ -0,0 +1,622 @@ +// 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 interpreter + +import ( + "fmt" + + "github.com/google/cel-go/common/operators" + "github.com/google/cel-go/common/packages" + "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" +) + +// interpretablePlanner creates an Interpretable evaluation plan from a proto Expr value. +type interpretablePlanner interface { + // Plan generates an Interpretable value (or error) from the input proto Expr. + Plan(expr *exprpb.Expr) (Interpretable, error) +} + +// newPlanner creates an interpretablePlanner which references a Dispatcher, TypeProvider, +// TypeAdapter, Packager, and CheckedExpr value. These pieces of data are used to resolve +// 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, + pkg packages.Packager, + checked *exprpb.CheckedExpr, + decorators ...InterpretableDecorator) interpretablePlanner { + return &planner{ + disp: disp, + provider: provider, + adapter: adapter, + pkg: pkg, + identMap: make(map[string]Interpretable), + refMap: checked.GetReferenceMap(), + typeMap: checked.GetTypeMap(), + decorators: decorators, + } +} + +// newUncheckedPlanner creates an interpretablePlanner which references a Dispatcher, TypeProvider, +// TypeAdapter, and Packager 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, + pkg packages.Packager, + decorators ...InterpretableDecorator) interpretablePlanner { + return &planner{ + disp: disp, + provider: provider, + adapter: adapter, + pkg: pkg, + identMap: make(map[string]Interpretable), + refMap: make(map[int64]*exprpb.Reference), + typeMap: make(map[int64]*exprpb.Type), + decorators: decorators, + } +} + +// planner is an implementatio of the interpretablePlanner interface. +type planner struct { + disp Dispatcher + provider ref.TypeProvider + adapter ref.TypeAdapter + pkg packages.Packager + identMap map[string]Interpretable + refMap map[int64]*exprpb.Reference + typeMap map[int64]*exprpb.Type + decorators []InterpretableDecorator +} + +// Plan implements the interpretablePlanner interface. This implementation of the Plan method also +// applies decorators to each Interpretable generated as part of the overall plan. Decorators are +// useful for layering functionality into the evaluation that is not natively understood by CEL, +// such as state-tracking, expression re-write, and possibly efficient thread-safe memoization of +// repeated expressions. +func (p *planner) Plan(expr *exprpb.Expr) (Interpretable, error) { + switch expr.ExprKind.(type) { + case *exprpb.Expr_CallExpr: + return p.decorate(p.planCall(expr)) + case *exprpb.Expr_IdentExpr: + return p.decorate(p.planIdent(expr)) + case *exprpb.Expr_SelectExpr: + return p.decorate(p.planSelect(expr)) + case *exprpb.Expr_ListExpr: + return p.decorate(p.planCreateList(expr)) + case *exprpb.Expr_StructExpr: + return p.decorate(p.planCreateStruct(expr)) + case *exprpb.Expr_ComprehensionExpr: + return p.decorate(p.planComprehension(expr)) + case *exprpb.Expr_ConstExpr: + return p.decorate(p.planConst(expr)) + } + return nil, fmt.Errorf("unsupported expr: %v", expr) +} + +// decorate applies the InterpretableDecorator functions to the given Interpretable. +// Both the Interpretable and error generated by a Plan step are accepted as arguments +// for convenience. +func (p *planner) decorate(i Interpretable, err error) (Interpretable, error) { + if err != nil { + return nil, err + } + for _, dec := range p.decorators { + i, err = dec(i) + if err != nil { + return nil, err + } + } + return i, nil +} + +// planIdent creates an Interpretable that resolves an identifier from an Activation. +func (p *planner) planIdent(expr *exprpb.Expr) (Interpretable, error) { + ident := expr.GetIdentExpr() + idName := ident.Name + i, found := p.identMap[idName] + if found { + return i, nil + } + var resolver func(Activation) (ref.Val, bool) + if p.pkg.Package() != "" { + resolver = p.idResolver(idName) + } + i = &evalIdent{ + id: expr.Id, + name: idName, + provider: p.provider, + resolveID: resolver, + } + p.identMap[idName] = i + return i, nil +} + +// planSelect creates an Interpretable with either: +// a) selects a field from a map or proto. +// b) creates a field presence test for a select within a has() macro. +// c) resolves the select expression to a namespaced identifier. +func (p *planner) planSelect(expr *exprpb.Expr) (Interpretable, error) { + sel := expr.GetSelectExpr() + // If the Select was marked TestOnly, this is a presence test. + // + // Note: presence tests are defined for structured (e.g. proto) and dynamic values (map, json) + // as follows: + // - True if the object field has a non-default value, e.g. obj.str != "" + // - True if the dynamic value has the field defined, e.g. key in map + // + // However, presence tests are not defined for qualified identifier names with primitive types. + // If a string named 'a.b.c' is declared in the environment and referenced within `has(a.b.c)`, + // it is not clear whether has should error or follow the convention defined for structured + // values. + if sel.TestOnly { + op, err := p.Plan(sel.GetOperand()) + if err != nil { + return nil, err + } + return &evalTestOnly{ + id: expr.Id, + field: types.String(sel.Field), + op: op, + }, nil + } + + // If the Select id appears in the reference map from the CheckedExpr proto then it is either + // a namespaced identifier or enum value. + idRef, found := p.refMap[expr.Id] + if found { + idName := idRef.Name + // If the reference has a value, this id represents an enum. + if idRef.Value != nil { + return p.Plan(&exprpb.Expr{Id: expr.Id, + ExprKind: &exprpb.Expr_ConstExpr{ + ConstExpr: idRef.Value, + }}) + } + // If the identifier has already been encountered before, return the previous Iterable. + i, found := p.identMap[idName] + if found { + return i, nil + } + // Otherwise, generate an evalIdent Interpretable. + i = &evalIdent{ + id: expr.Id, + name: idName, + provider: p.provider, + } + p.identMap[idName] = i + return i, nil + } + + // Lastly, create a field selection Interpretable. + op, err := p.Plan(sel.GetOperand()) + if err != nil { + return nil, err + } + var resolver func(Activation) (ref.Val, bool) + if qualID, isID := p.getQualifiedID(sel); isID { + resolver = p.idResolver(qualID) + } + return &evalSelect{ + id: expr.Id, + field: types.String(sel.Field), + op: op, + resolveID: resolver, + }, nil +} + +// planCall creates a callable Interpretable while specializing for common functions and invocation +// patterns. Specifically, conditional operators &&, ||, ?:, and (in)equality functions result in +// optimized Interpretable values. +func (p *planner) planCall(expr *exprpb.Expr) (Interpretable, error) { + call := expr.GetCallExpr() + fnName := call.Function + argCount := len(call.GetArgs()) + var offset int + if call.Target != nil { + argCount++ + offset++ + } + args := make([]Interpretable, argCount, argCount) + if call.Target != nil { + arg, err := p.Plan(call.Target) + if err != nil { + return nil, err + } + args[0] = arg + } + for i, argExpr := range call.GetArgs() { + arg, err := p.Plan(argExpr) + if err != nil { + return nil, err + } + args[i+offset] = arg + } + var oName string + if oRef, found := p.refMap[expr.Id]; found && + len(oRef.GetOverloadId()) == 1 { + oName = oRef.GetOverloadId()[0] + } + + // Generate specialized Interpretable operators by function name if possible. + switch fnName { + case operators.LogicalAnd: + return p.planCallLogicalAnd(expr, args) + case operators.LogicalOr: + return p.planCallLogicalOr(expr, args) + case operators.Conditional: + return p.planCallConditional(expr, args) + case operators.Equals: + return p.planCallEqual(expr, args) + case operators.NotEquals: + return p.planCallNotEqual(expr, args) + } + + // Otherwise, generate Interpretable calls specialized by argument count. + // Try to find the specific function by overload id. + var fnDef *functions.Overload + if oName != "" { + fnDef, _ = p.disp.FindOverload(oName) + } + // If the overload id couldn't resolve the function, try the simple function name. + if fnDef == nil { + fnDef, _ = p.disp.FindOverload(fnName) + } + switch argCount { + case 0: + return p.planCallZero(expr, fnName, oName, fnDef) + case 1: + return p.planCallUnary(expr, fnName, oName, fnDef, args) + case 2: + return p.planCallBinary(expr, fnName, oName, fnDef, args) + default: + return p.planCallVarArgs(expr, fnName, oName, fnDef, args) + } +} + +// planCallZero generates a zero-arity callable Interpretable. +func (p *planner) planCallZero(expr *exprpb.Expr, + function string, + overload string, + impl *functions.Overload) (Interpretable, error) { + if impl == nil || impl.Function == nil { + return nil, fmt.Errorf("no such overload: %s()", function) + } + return &evalZeroArity{ + id: expr.Id, + impl: impl.Function, + }, nil +} + +// planCallUnary generates a unary callable Interpretable. +func (p *planner) planCallUnary(expr *exprpb.Expr, + function string, + overload string, + impl *functions.Overload, + args []Interpretable) (Interpretable, error) { + var fn functions.UnaryOp + var trait int + if impl != nil { + if impl.Unary == nil { + return nil, fmt.Errorf("no such overload: %s(arg)", function) + } + fn = impl.Unary + trait = impl.OperandTrait + } + return &evalUnary{ + id: expr.Id, + function: function, + overload: overload, + arg: args[0], + trait: trait, + impl: fn, + }, nil +} + +// planCallBinary generates a binary callable Interpretable. +func (p *planner) planCallBinary(expr *exprpb.Expr, + function string, + overload string, + impl *functions.Overload, + args []Interpretable) (Interpretable, error) { + var fn functions.BinaryOp + var trait int + if impl != nil { + if impl.Binary == nil { + return nil, fmt.Errorf("no such overload: %s(lhs, rhs)", function) + } + fn = impl.Binary + trait = impl.OperandTrait + } + return &evalBinary{ + id: expr.Id, + function: function, + overload: overload, + lhs: args[0], + rhs: args[1], + trait: trait, + impl: fn, + }, nil +} + +// planCallVarArgs generates a variable argument callable Interpretable. +func (p *planner) planCallVarArgs(expr *exprpb.Expr, + function string, + overload string, + impl *functions.Overload, + args []Interpretable) (Interpretable, error) { + var fn functions.FunctionOp + var trait int + if impl != nil { + if impl.Function == nil { + return nil, fmt.Errorf("no such overload: %s(...)", function) + } + fn = impl.Function + trait = impl.OperandTrait + } + return &evalVarArgs{ + id: expr.Id, + function: function, + overload: overload, + args: args, + trait: trait, + impl: fn, + }, nil +} + +// planCallEqual generates an equals (==) Interpretable. +func (p *planner) planCallEqual(expr *exprpb.Expr, + args []Interpretable) (Interpretable, error) { + return &evalEq{ + id: expr.Id, + lhs: args[0], + rhs: args[1], + }, nil +} + +// planCallNotEqual generates a not equals (!=) Interpretable. +func (p *planner) planCallNotEqual(expr *exprpb.Expr, + args []Interpretable) (Interpretable, error) { + return &evalNe{ + id: expr.Id, + lhs: args[0], + rhs: args[1], + }, nil +} + +// planCallLogicalAnd generates a logical and (&&) Interpretable. +func (p *planner) planCallLogicalAnd(expr *exprpb.Expr, + args []Interpretable) (Interpretable, error) { + return &evalAnd{ + id: expr.Id, + lhs: args[0], + rhs: args[1], + }, nil +} + +// planCallLogicalOr generates a logical or (||) Interpretable. +func (p *planner) planCallLogicalOr(expr *exprpb.Expr, + args []Interpretable) (Interpretable, error) { + return &evalOr{ + id: expr.Id, + lhs: args[0], + rhs: args[1], + }, nil +} + +// planCallConditional generates a conditional / ternary (c ? t : f) Interpretable. +func (p *planner) planCallConditional(expr *exprpb.Expr, + args []Interpretable) (Interpretable, error) { + return &evalConditional{ + id: expr.Id, + expr: args[0], + truthy: args[1], + falsy: args[2], + }, nil +} + +// planCreateList generates a list construction Interpretable. +func (p *planner) planCreateList(expr *exprpb.Expr) (Interpretable, error) { + list := expr.GetListExpr() + elems := make([]Interpretable, len(list.GetElements()), len(list.GetElements())) + for i, elem := range list.GetElements() { + elemVal, err := p.Plan(elem) + if err != nil { + return nil, err + } + elems[i] = elemVal + } + return &evalList{ + id: expr.Id, + elems: elems, + adapter: p.adapter, + }, nil +} + +// planCreateStruct generates a map or object construction Interpretable. +func (p *planner) planCreateStruct(expr *exprpb.Expr) (Interpretable, error) { + str := expr.GetStructExpr() + if len(str.MessageName) != 0 { + return p.planCreateObj(expr) + } + entries := str.GetEntries() + keys := make([]Interpretable, len(entries)) + vals := make([]Interpretable, len(entries)) + for i, entry := range entries { + keyVal, err := p.Plan(entry.GetMapKey()) + if err != nil { + return nil, err + } + keys[i] = keyVal + + valVal, err := p.Plan(entry.GetValue()) + if err != nil { + return nil, err + } + vals[i] = valVal + } + return &evalMap{ + id: expr.Id, + keys: keys, + vals: vals, + adapter: p.adapter, + }, nil +} + +// planCreateObj generates an object construction Interpretable. +func (p *planner) planCreateObj(expr *exprpb.Expr) (Interpretable, error) { + obj := expr.GetStructExpr() + typeName := obj.MessageName + var defined bool + for _, qualifiedTypeName := range p.pkg.ResolveCandidateNames(typeName) { + if _, found := p.provider.FindType(qualifiedTypeName); found { + typeName = qualifiedTypeName + defined = true + break + } + } + if !defined { + return nil, fmt.Errorf("unknown type: %s", typeName) + } + entries := obj.GetEntries() + fields := make([]string, len(entries)) + vals := make([]Interpretable, len(entries)) + for i, entry := range entries { + fields[i] = entry.GetFieldKey() + val, err := p.Plan(entry.GetValue()) + if err != nil { + return nil, err + } + vals[i] = val + } + return &evalObj{ + id: expr.Id, + typeName: typeName, + fields: fields, + vals: vals, + provider: p.provider, + }, nil +} + +// planComprehension generates an Interpretable fold operation. +func (p *planner) planComprehension(expr *exprpb.Expr) (Interpretable, error) { + fold := expr.GetComprehensionExpr() + accu, err := p.Plan(fold.GetAccuInit()) + if err != nil { + return nil, err + } + iterRange, err := p.Plan(fold.GetIterRange()) + if err != nil { + return nil, err + } + cond, err := p.Plan(fold.GetLoopCondition()) + if err != nil { + return nil, err + } + step, err := p.Plan(fold.GetLoopStep()) + if err != nil { + return nil, err + } + result, err := p.Plan(fold.GetResult()) + if err != nil { + return nil, err + } + return &evalFold{ + id: expr.Id, + accuVar: fold.AccuVar, + accu: accu, + iterVar: fold.IterVar, + iterRange: iterRange, + cond: cond, + step: step, + result: result, + }, nil +} + +// planConst generates a constant valued Interpretable. +func (p *planner) planConst(expr *exprpb.Expr) (Interpretable, error) { + val, err := p.constValue(expr.GetConstExpr()) + if err != nil { + return nil, err + } + return &evalConst{ + id: expr.Id, + val: val, + }, nil +} + +// constValue converts a proto Constant value to a ref.Val. +func (p *planner) constValue(c *exprpb.Constant) (ref.Val, error) { + switch c.ConstantKind.(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.Null(c.GetNullValue()), 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("unknown constant type: %v", c) +} + +// getQualifiedId converts a Select expression to a qualified identifier suitable for identifier +// resolution. If the expression is not an identifier, the second return will be false. +func (p *planner) getQualifiedID(sel *exprpb.Expr_Select) (string, bool) { + validIdent := true + resolvedIdent := false + ident := sel.Field + op := sel.Operand + for validIdent && !resolvedIdent { + switch op.ExprKind.(type) { + case *exprpb.Expr_IdentExpr: + ident = op.GetIdentExpr().Name + "." + ident + resolvedIdent = true + case *exprpb.Expr_SelectExpr: + nested := op.GetSelectExpr() + ident = nested.GetField() + "." + ident + op = nested.Operand + default: + validIdent = false + } + } + return ident, validIdent +} + +// idResolver returns a function that resolves an identifier to its appropriate namespace. +func (p *planner) idResolver(ident string) func(Activation) (ref.Val, bool) { + return func(ctx Activation) (ref.Val, bool) { + for _, id := range p.pkg.ResolveCandidateNames(ident) { + if object, found := ctx.ResolveName(id); found { + return object, found + } + if typeIdent, found := p.provider.FindIdent(id); found { + return typeIdent, found + } + } + return nil, false + } +} diff --git a/vendor/github.com/google/cel-go/interpreter/prune.go b/vendor/github.com/google/cel-go/interpreter/prune.go new file mode 100644 index 000000000..8858dfa9b --- /dev/null +++ b/vendor/github.com/google/cel-go/interpreter/prune.go @@ -0,0 +1,256 @@ +// 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 interpreter + +import ( + "github.com/google/cel-go/common/operators" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + + structpb "github.com/golang/protobuf/ptypes/struct" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +type astPruner struct { + expr *exprpb.Expr + state EvalState +} + +// TODO Consider having a separate walk of the AST that finds common +// subexpressions. This can be called before or after constant folding to find +// common subexpressions. + +// PruneAst prunes the given AST based on the given EvalState and generates a new AST. +// Given AST is copied on write and a new AST is returned. +// Couple of typical use cases this interface would be: +// +// A) +// 1) Evaluate expr with some unknowns, +// 2) If result is unknown: +// a) PruneAst +// b) Goto 1 +// Functional call results which are known would be effectively cached across +// iterations. +// +// B) +// 1) Compile the expression (maybe via a service and maybe after checking a +// compiled expression does not exists in local cache) +// 2) Prepare the environment and the interpreter. Activation might be empty. +// 3) Eval the expression. This might return unknown or error or a concrete +// value. +// 4) PruneAst +// 4) Maybe cache the expression +// This is effectively constant folding the expression. How the environment is +// prepared in step 2 is flexible. For example, If the caller caches the +// 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 { + pruner := &astPruner{ + expr: expr, + state: state} + newExpr, _ := pruner.prune(expr) + return newExpr +} + +func (p *astPruner) createLiteral(node *exprpb.Expr, val *exprpb.Constant) *exprpb.Expr { + newExpr := *node + newExpr.ExprKind = &exprpb.Expr_ConstExpr{ConstExpr: val} + return &newExpr +} + +func (p *astPruner) maybePruneAndOr(node *exprpb.Expr) (*exprpb.Expr, bool) { + if !p.existsWithUnknownValue(node.GetId()) { + return nil, false + } + + 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 p.existsWithKnownValue(call.Args[1].GetId()) { + return call.Args[0], true + } + return nil, false +} + +func (p *astPruner) maybePruneConditional(node *exprpb.Expr) (*exprpb.Expr, bool) { + if !p.existsWithUnknownValue(node.GetId()) { + return nil, false + } + + call := node.GetCallExpr() + condVal, condValueExists := p.value(call.Args[0].GetId()) + if !condValueExists || types.IsUnknownOrError(condVal) { + return nil, false + } + + if condVal.Value().(bool) { + return call.Args[1], true + } + return call.Args[2], true +} + +func (p *astPruner) maybePruneFunction(node *exprpb.Expr) (*exprpb.Expr, bool) { + call := node.GetCallExpr() + if call.Function == operators.LogicalOr || call.Function == operators.LogicalAnd { + return p.maybePruneAndOr(node) + } + if call.Function == operators.Conditional { + return p.maybePruneConditional(node) + } + + return nil, false +} + +func (p *astPruner) prune(node *exprpb.Expr) (*exprpb.Expr, bool) { + if node == nil { + return node, false + } + if val, valueExists := p.value(node.GetId()); valueExists && !types.IsUnknownOrError(val) { + + // TODO if we have a list or struct, create a list/struct + // expression. This is useful especially if these expressions + // are result of a function call. + + switch val.Type() { + case types.BoolType: + return p.createLiteral(node, + &exprpb.Constant{ConstantKind: &exprpb.Constant_BoolValue{BoolValue: val.Value().(bool)}}), true + case types.IntType: + return p.createLiteral(node, + &exprpb.Constant{ConstantKind: &exprpb.Constant_Int64Value{Int64Value: val.Value().(int64)}}), true + case types.UintType: + return p.createLiteral(node, + &exprpb.Constant{ConstantKind: &exprpb.Constant_Uint64Value{Uint64Value: val.Value().(uint64)}}), true + case types.StringType: + return p.createLiteral(node, + &exprpb.Constant{ConstantKind: &exprpb.Constant_StringValue{StringValue: val.Value().(string)}}), true + case types.DoubleType: + return p.createLiteral(node, + &exprpb.Constant{ConstantKind: &exprpb.Constant_DoubleValue{DoubleValue: val.Value().(float64)}}), true + case types.BytesType: + return p.createLiteral(node, + &exprpb.Constant{ConstantKind: &exprpb.Constant_BytesValue{BytesValue: val.Value().([]byte)}}), true + case types.NullType: + return p.createLiteral(node, + &exprpb.Constant{ConstantKind: &exprpb.Constant_NullValue{NullValue: val.Value().(structpb.NullValue)}}), true + } + } + + // We have either an unknown/error value, or something we dont want to + // transform, or expression was not evaluated. If possible, drill down + // more. + + switch node.ExprKind.(type) { + case *exprpb.Expr_SelectExpr: + if operand, pruned := p.prune(node.GetSelectExpr().Operand); pruned { + newExpr := *node + newSelect := *newExpr.GetSelectExpr() + newSelect.Operand = operand + newExpr.GetExprKind().(*exprpb.Expr_SelectExpr).SelectExpr = &newSelect + return &newExpr, true + } + case *exprpb.Expr_CallExpr: + if newExpr, pruned := p.maybePruneFunction(node); pruned { + newExpr, _ = p.prune(newExpr) + return newExpr, true + } + newCall := *node.GetCallExpr() + var prunedCall bool + var prunedArg bool + for i, arg := range node.GetCallExpr().Args { + if newCall.Args[i], prunedArg = p.prune(arg); prunedArg { + prunedCall = true + } + } + if newTarget, prunedTarget := p.prune(node.GetCallExpr().Target); prunedTarget { + prunedCall = true + newCall.Target = newTarget + } + if prunedCall { + newExpr := *node + newExpr.GetExprKind().(*exprpb.Expr_CallExpr).CallExpr = &newCall + return &newExpr, true + } + case *exprpb.Expr_ListExpr: + newList := *node.GetListExpr() + var prunedList bool + var prunedElem bool + for i, elem := range node.GetListExpr().Elements { + if newList.Elements[i], prunedElem = p.prune(elem); prunedElem { + prunedList = true + } + } + if prunedList { + newExpr := *node + newExpr.GetExprKind().(*exprpb.Expr_ListExpr).ListExpr = &newList + return &newExpr, true + } + case *exprpb.Expr_StructExpr: + newStruct := *node.GetStructExpr() + var prunedStruct bool + var prunedEntry bool + for i, entry := range node.GetStructExpr().Entries { + newEntry := *entry + if newKey, pruned := p.prune(entry.GetMapKey()); pruned { + prunedEntry = true + newEntry.GetKeyKind().(*exprpb.Expr_CreateStruct_Entry_MapKey).MapKey = newKey + } + if newValue, pruned := p.prune(entry.Value); pruned { + prunedEntry = true + newEntry.Value = newValue + } + if prunedEntry { + prunedStruct = true + newStruct.Entries[i] = &newEntry + } + } + if prunedStruct { + newExpr := *node + newExpr.GetExprKind().(*exprpb.Expr_StructExpr).StructExpr = &newStruct + return &newExpr, true + } + case *exprpb.Expr_ComprehensionExpr: + if newIterRange, pruned := p.prune(node.GetComprehensionExpr().IterRange); pruned { + newExpr := *node + newCompre := *newExpr.GetComprehensionExpr() + newCompre.IterRange = newIterRange + newExpr.GetExprKind().(*exprpb.Expr_ComprehensionExpr).ComprehensionExpr = &newCompre + return &newExpr, true + } + } + return node, false +} + +func (p *astPruner) value(id int64) (ref.Val, bool) { + val, found := p.state.Value(id) + 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) existsWithKnownValue(id int64) bool { + val, valueExists := p.value(id) + return valueExists && !types.IsUnknown(val) +} diff --git a/vendor/github.com/google/cel-go/parser/errors.go b/vendor/github.com/google/cel-go/parser/errors.go new file mode 100644 index 000000000..140beb953 --- /dev/null +++ b/vendor/github.com/google/cel-go/parser/errors.go @@ -0,0 +1,42 @@ +// 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 parser + +import ( + "fmt" + + "github.com/google/cel-go/common" +) + +// parseErrors is a specialization of Errors. +type parseErrors struct { + *common.Errors +} + +func (e *parseErrors) syntaxError(l common.Location, message string) { + e.ReportError(l, fmt.Sprintf("Syntax error: %s", message)) +} + +func (e *parseErrors) invalidHasArgument(l common.Location) { + e.ReportError(l, "Argument to the function 'has' must be a field selection") +} + +func (e *parseErrors) argumentIsNotIdent(l common.Location) { + e.ReportError(l, "Argument must be a simple name") +} + +func (e *parseErrors) notAQualifiedName(l common.Location) { + e.ReportError(l, "Expected a qualified name") +} 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 new file mode 100644 index 000000000..9f27b266f --- /dev/null +++ b/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go @@ -0,0 +1,195 @@ +// Generated from /Users/tswadell/lace/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.7. + +package gen // CEL +import "github.com/antlr/antlr4/runtime/Go/antlr" + +// BaseCELListener is a complete listener for a parse tree produced by CELParser. +type BaseCELListener struct{} + +var _ CELListener = &BaseCELListener{} + +// VisitTerminal is called when a terminal node is visited. +func (s *BaseCELListener) VisitTerminal(node antlr.TerminalNode) {} + +// VisitErrorNode is called when an error node is visited. +func (s *BaseCELListener) VisitErrorNode(node antlr.ErrorNode) {} + +// EnterEveryRule is called when any rule is entered. +func (s *BaseCELListener) EnterEveryRule(ctx antlr.ParserRuleContext) {} + +// ExitEveryRule is called when any rule is exited. +func (s *BaseCELListener) ExitEveryRule(ctx antlr.ParserRuleContext) {} + +// EnterStart is called when production start is entered. +func (s *BaseCELListener) EnterStart(ctx *StartContext) {} + +// ExitStart is called when production start is exited. +func (s *BaseCELListener) ExitStart(ctx *StartContext) {} + +// EnterExpr is called when production expr is entered. +func (s *BaseCELListener) EnterExpr(ctx *ExprContext) {} + +// ExitExpr is called when production expr is exited. +func (s *BaseCELListener) ExitExpr(ctx *ExprContext) {} + +// EnterConditionalOr is called when production conditionalOr is entered. +func (s *BaseCELListener) EnterConditionalOr(ctx *ConditionalOrContext) {} + +// ExitConditionalOr is called when production conditionalOr is exited. +func (s *BaseCELListener) ExitConditionalOr(ctx *ConditionalOrContext) {} + +// EnterConditionalAnd is called when production conditionalAnd is entered. +func (s *BaseCELListener) EnterConditionalAnd(ctx *ConditionalAndContext) {} + +// ExitConditionalAnd is called when production conditionalAnd is exited. +func (s *BaseCELListener) ExitConditionalAnd(ctx *ConditionalAndContext) {} + +// EnterRelation is called when production relation is entered. +func (s *BaseCELListener) EnterRelation(ctx *RelationContext) {} + +// ExitRelation is called when production relation is exited. +func (s *BaseCELListener) ExitRelation(ctx *RelationContext) {} + +// EnterCalc is called when production calc is entered. +func (s *BaseCELListener) EnterCalc(ctx *CalcContext) {} + +// ExitCalc is called when production calc is exited. +func (s *BaseCELListener) ExitCalc(ctx *CalcContext) {} + +// EnterMemberExpr is called when production MemberExpr is entered. +func (s *BaseCELListener) EnterMemberExpr(ctx *MemberExprContext) {} + +// ExitMemberExpr is called when production MemberExpr is exited. +func (s *BaseCELListener) ExitMemberExpr(ctx *MemberExprContext) {} + +// EnterLogicalNot is called when production LogicalNot is entered. +func (s *BaseCELListener) EnterLogicalNot(ctx *LogicalNotContext) {} + +// ExitLogicalNot is called when production LogicalNot is exited. +func (s *BaseCELListener) ExitLogicalNot(ctx *LogicalNotContext) {} + +// EnterNegate is called when production Negate is entered. +func (s *BaseCELListener) EnterNegate(ctx *NegateContext) {} + +// ExitNegate is called when production Negate is exited. +func (s *BaseCELListener) ExitNegate(ctx *NegateContext) {} + +// EnterSelectOrCall is called when production SelectOrCall is entered. +func (s *BaseCELListener) EnterSelectOrCall(ctx *SelectOrCallContext) {} + +// ExitSelectOrCall is called when production SelectOrCall is exited. +func (s *BaseCELListener) ExitSelectOrCall(ctx *SelectOrCallContext) {} + +// EnterPrimaryExpr is called when production PrimaryExpr is entered. +func (s *BaseCELListener) EnterPrimaryExpr(ctx *PrimaryExprContext) {} + +// ExitPrimaryExpr is called when production PrimaryExpr is exited. +func (s *BaseCELListener) ExitPrimaryExpr(ctx *PrimaryExprContext) {} + +// EnterIndex is called when production Index is entered. +func (s *BaseCELListener) EnterIndex(ctx *IndexContext) {} + +// ExitIndex is called when production Index is exited. +func (s *BaseCELListener) ExitIndex(ctx *IndexContext) {} + +// EnterCreateMessage is called when production CreateMessage is entered. +func (s *BaseCELListener) EnterCreateMessage(ctx *CreateMessageContext) {} + +// ExitCreateMessage is called when production CreateMessage is exited. +func (s *BaseCELListener) ExitCreateMessage(ctx *CreateMessageContext) {} + +// EnterIdentOrGlobalCall is called when production IdentOrGlobalCall is entered. +func (s *BaseCELListener) EnterIdentOrGlobalCall(ctx *IdentOrGlobalCallContext) {} + +// ExitIdentOrGlobalCall is called when production IdentOrGlobalCall is exited. +func (s *BaseCELListener) ExitIdentOrGlobalCall(ctx *IdentOrGlobalCallContext) {} + +// EnterNested is called when production Nested is entered. +func (s *BaseCELListener) EnterNested(ctx *NestedContext) {} + +// ExitNested is called when production Nested is exited. +func (s *BaseCELListener) ExitNested(ctx *NestedContext) {} + +// EnterCreateList is called when production CreateList is entered. +func (s *BaseCELListener) EnterCreateList(ctx *CreateListContext) {} + +// ExitCreateList is called when production CreateList is exited. +func (s *BaseCELListener) ExitCreateList(ctx *CreateListContext) {} + +// EnterCreateStruct is called when production CreateStruct is entered. +func (s *BaseCELListener) EnterCreateStruct(ctx *CreateStructContext) {} + +// ExitCreateStruct is called when production CreateStruct is exited. +func (s *BaseCELListener) ExitCreateStruct(ctx *CreateStructContext) {} + +// EnterConstantLiteral is called when production ConstantLiteral is entered. +func (s *BaseCELListener) EnterConstantLiteral(ctx *ConstantLiteralContext) {} + +// ExitConstantLiteral is called when production ConstantLiteral is exited. +func (s *BaseCELListener) ExitConstantLiteral(ctx *ConstantLiteralContext) {} + +// EnterExprList is called when production exprList is entered. +func (s *BaseCELListener) EnterExprList(ctx *ExprListContext) {} + +// ExitExprList is called when production exprList is exited. +func (s *BaseCELListener) ExitExprList(ctx *ExprListContext) {} + +// EnterFieldInitializerList is called when production fieldInitializerList is entered. +func (s *BaseCELListener) EnterFieldInitializerList(ctx *FieldInitializerListContext) {} + +// ExitFieldInitializerList is called when production fieldInitializerList is exited. +func (s *BaseCELListener) ExitFieldInitializerList(ctx *FieldInitializerListContext) {} + +// EnterMapInitializerList is called when production mapInitializerList is entered. +func (s *BaseCELListener) EnterMapInitializerList(ctx *MapInitializerListContext) {} + +// ExitMapInitializerList is called when production mapInitializerList is exited. +func (s *BaseCELListener) ExitMapInitializerList(ctx *MapInitializerListContext) {} + +// EnterInt is called when production Int is entered. +func (s *BaseCELListener) EnterInt(ctx *IntContext) {} + +// ExitInt is called when production Int is exited. +func (s *BaseCELListener) ExitInt(ctx *IntContext) {} + +// EnterUint is called when production Uint is entered. +func (s *BaseCELListener) EnterUint(ctx *UintContext) {} + +// ExitUint is called when production Uint is exited. +func (s *BaseCELListener) ExitUint(ctx *UintContext) {} + +// EnterDouble is called when production Double is entered. +func (s *BaseCELListener) EnterDouble(ctx *DoubleContext) {} + +// ExitDouble is called when production Double is exited. +func (s *BaseCELListener) ExitDouble(ctx *DoubleContext) {} + +// EnterString is called when production String is entered. +func (s *BaseCELListener) EnterString(ctx *StringContext) {} + +// ExitString is called when production String is exited. +func (s *BaseCELListener) ExitString(ctx *StringContext) {} + +// EnterBytes is called when production Bytes is entered. +func (s *BaseCELListener) EnterBytes(ctx *BytesContext) {} + +// ExitBytes is called when production Bytes is exited. +func (s *BaseCELListener) ExitBytes(ctx *BytesContext) {} + +// EnterBoolTrue is called when production BoolTrue is entered. +func (s *BaseCELListener) EnterBoolTrue(ctx *BoolTrueContext) {} + +// ExitBoolTrue is called when production BoolTrue is exited. +func (s *BaseCELListener) ExitBoolTrue(ctx *BoolTrueContext) {} + +// EnterBoolFalse is called when production BoolFalse is entered. +func (s *BaseCELListener) EnterBoolFalse(ctx *BoolFalseContext) {} + +// ExitBoolFalse is called when production BoolFalse is exited. +func (s *BaseCELListener) ExitBoolFalse(ctx *BoolFalseContext) {} + +// EnterNull is called when production Null is entered. +func (s *BaseCELListener) EnterNull(ctx *NullContext) {} + +// ExitNull is called when production Null is exited. +func (s *BaseCELListener) ExitNull(ctx *NullContext) {} 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 new file mode 100644 index 000000000..e4f32e619 --- /dev/null +++ b/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go @@ -0,0 +1,124 @@ +// Generated from /Users/tswadell/lace/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.7. + +package gen // CEL +import "github.com/antlr/antlr4/runtime/Go/antlr" + +type BaseCELVisitor struct { + *antlr.BaseParseTreeVisitor +} + +func (v *BaseCELVisitor) VisitStart(ctx *StartContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitExpr(ctx *ExprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitConditionalOr(ctx *ConditionalOrContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitConditionalAnd(ctx *ConditionalAndContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitRelation(ctx *RelationContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitCalc(ctx *CalcContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitMemberExpr(ctx *MemberExprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitLogicalNot(ctx *LogicalNotContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitNegate(ctx *NegateContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitSelectOrCall(ctx *SelectOrCallContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitPrimaryExpr(ctx *PrimaryExprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitIndex(ctx *IndexContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitCreateMessage(ctx *CreateMessageContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitIdentOrGlobalCall(ctx *IdentOrGlobalCallContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitNested(ctx *NestedContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitCreateList(ctx *CreateListContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitCreateStruct(ctx *CreateStructContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitConstantLiteral(ctx *ConstantLiteralContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitExprList(ctx *ExprListContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitFieldInitializerList(ctx *FieldInitializerListContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitMapInitializerList(ctx *MapInitializerListContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitInt(ctx *IntContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitUint(ctx *UintContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitDouble(ctx *DoubleContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitString(ctx *StringContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitBytes(ctx *BytesContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitBoolTrue(ctx *BoolTrueContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitBoolFalse(ctx *BoolFalseContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCELVisitor) VisitNull(ctx *NullContext) 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 new file mode 100644 index 000000000..e474a5b91 --- /dev/null +++ b/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go @@ -0,0 +1,319 @@ +// Generated from /Users/tswadell/lace/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.7. + +package gen + +import ( + "fmt" + "unicode" + + "github.com/antlr/antlr4/runtime/Go/antlr" +) + +// Suppress unused import error +var _ = fmt.Printf +var _ = unicode.IsLetter + +var serializedLexerAtn = []uint16{ + 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 38, 425, + 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, + 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, + 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, + 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, + 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, + 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, + 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, + 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, + 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 3, 2, 3, + 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, + 6, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, + 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, + 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, + 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, + 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, + 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 31, 3, 31, 3, + 32, 3, 32, 3, 33, 3, 33, 5, 33, 179, 10, 33, 3, 33, 6, 33, 182, 10, 33, + 13, 33, 14, 33, 183, 3, 34, 3, 34, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, + 36, 5, 36, 194, 10, 36, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, + 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, + 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, + 3, 40, 3, 40, 3, 40, 5, 40, 227, 10, 40, 3, 41, 6, 41, 230, 10, 41, 13, + 41, 14, 41, 231, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 7, 42, 240, + 10, 42, 12, 42, 14, 42, 243, 11, 42, 3, 42, 3, 42, 3, 43, 6, 43, 248, 10, + 43, 13, 43, 14, 43, 249, 3, 43, 3, 43, 6, 43, 254, 10, 43, 13, 43, 14, + 43, 255, 3, 43, 5, 43, 259, 10, 43, 3, 43, 6, 43, 262, 10, 43, 13, 43, + 14, 43, 263, 3, 43, 3, 43, 3, 43, 3, 43, 6, 43, 270, 10, 43, 13, 43, 14, + 43, 271, 3, 43, 5, 43, 275, 10, 43, 5, 43, 277, 10, 43, 3, 44, 6, 44, 280, + 10, 44, 13, 44, 14, 44, 281, 3, 44, 3, 44, 3, 44, 3, 44, 6, 44, 288, 10, + 44, 13, 44, 14, 44, 289, 5, 44, 292, 10, 44, 3, 45, 6, 45, 295, 10, 45, + 13, 45, 14, 45, 296, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 6, 45, 305, + 10, 45, 13, 45, 14, 45, 306, 3, 45, 3, 45, 5, 45, 311, 10, 45, 3, 46, 3, + 46, 3, 46, 7, 46, 316, 10, 46, 12, 46, 14, 46, 319, 11, 46, 3, 46, 3, 46, + 3, 46, 3, 46, 7, 46, 325, 10, 46, 12, 46, 14, 46, 328, 11, 46, 3, 46, 3, + 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 7, 46, 337, 10, 46, 12, 46, 14, + 46, 340, 11, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, + 3, 46, 7, 46, 351, 10, 46, 12, 46, 14, 46, 354, 11, 46, 3, 46, 3, 46, 3, + 46, 3, 46, 3, 46, 3, 46, 7, 46, 362, 10, 46, 12, 46, 14, 46, 365, 11, 46, + 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 7, 46, 372, 10, 46, 12, 46, 14, 46, + 375, 11, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 7, + 46, 385, 10, 46, 12, 46, 14, 46, 388, 11, 46, 3, 46, 3, 46, 3, 46, 3, 46, + 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 7, 46, 400, 10, 46, 12, 46, 14, + 46, 403, 11, 46, 3, 46, 3, 46, 3, 46, 3, 46, 5, 46, 409, 10, 46, 3, 47, + 3, 47, 3, 47, 3, 48, 3, 48, 5, 48, 416, 10, 48, 3, 48, 3, 48, 3, 48, 7, + 48, 421, 10, 48, 12, 48, 14, 48, 424, 11, 48, 6, 338, 352, 386, 401, 2, + 49, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, + 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, + 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53, 28, 55, 29, 57, 30, + 59, 2, 61, 2, 63, 2, 65, 2, 67, 2, 69, 2, 71, 2, 73, 2, 75, 2, 77, 2, 79, + 2, 81, 31, 83, 32, 85, 33, 87, 34, 89, 35, 91, 36, 93, 37, 95, 38, 3, 2, + 18, 4, 2, 67, 92, 99, 124, 4, 2, 71, 71, 103, 103, 4, 2, 45, 45, 47, 47, + 5, 2, 50, 59, 67, 72, 99, 104, 4, 2, 84, 84, 116, 116, 12, 2, 36, 36, 41, + 41, 65, 65, 94, 94, 98, 100, 104, 104, 112, 112, 116, 116, 118, 118, 120, + 120, 4, 2, 90, 90, 122, 122, 5, 2, 11, 12, 14, 15, 34, 34, 3, 2, 12, 12, + 4, 2, 87, 87, 119, 119, 6, 2, 12, 12, 15, 15, 36, 36, 94, 94, 6, 2, 12, + 12, 15, 15, 41, 41, 94, 94, 3, 2, 94, 94, 5, 2, 12, 12, 15, 15, 36, 36, + 5, 2, 12, 12, 15, 15, 41, 41, 4, 2, 68, 68, 100, 100, 2, 458, 2, 3, 3, + 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, + 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, + 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, + 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, + 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, + 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, + 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 2, 57, 3, + 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, + 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, + 95, 3, 2, 2, 2, 3, 97, 3, 2, 2, 2, 5, 100, 3, 2, 2, 2, 7, 103, 3, 2, 2, + 2, 9, 106, 3, 2, 2, 2, 11, 108, 3, 2, 2, 2, 13, 111, 3, 2, 2, 2, 15, 114, + 3, 2, 2, 2, 17, 116, 3, 2, 2, 2, 19, 119, 3, 2, 2, 2, 21, 122, 3, 2, 2, + 2, 23, 124, 3, 2, 2, 2, 25, 126, 3, 2, 2, 2, 27, 128, 3, 2, 2, 2, 29, 130, + 3, 2, 2, 2, 31, 132, 3, 2, 2, 2, 33, 134, 3, 2, 2, 2, 35, 136, 3, 2, 2, + 2, 37, 138, 3, 2, 2, 2, 39, 140, 3, 2, 2, 2, 41, 142, 3, 2, 2, 2, 43, 144, + 3, 2, 2, 2, 45, 146, 3, 2, 2, 2, 47, 148, 3, 2, 2, 2, 49, 150, 3, 2, 2, + 2, 51, 152, 3, 2, 2, 2, 53, 154, 3, 2, 2, 2, 55, 159, 3, 2, 2, 2, 57, 165, + 3, 2, 2, 2, 59, 170, 3, 2, 2, 2, 61, 172, 3, 2, 2, 2, 63, 174, 3, 2, 2, + 2, 65, 176, 3, 2, 2, 2, 67, 185, 3, 2, 2, 2, 69, 187, 3, 2, 2, 2, 71, 193, + 3, 2, 2, 2, 73, 195, 3, 2, 2, 2, 75, 198, 3, 2, 2, 2, 77, 203, 3, 2, 2, + 2, 79, 226, 3, 2, 2, 2, 81, 229, 3, 2, 2, 2, 83, 235, 3, 2, 2, 2, 85, 276, + 3, 2, 2, 2, 87, 291, 3, 2, 2, 2, 89, 310, 3, 2, 2, 2, 91, 408, 3, 2, 2, + 2, 93, 410, 3, 2, 2, 2, 95, 415, 3, 2, 2, 2, 97, 98, 7, 107, 2, 2, 98, + 99, 7, 112, 2, 2, 99, 4, 3, 2, 2, 2, 100, 101, 7, 63, 2, 2, 101, 102, 7, + 63, 2, 2, 102, 6, 3, 2, 2, 2, 103, 104, 7, 35, 2, 2, 104, 105, 7, 63, 2, + 2, 105, 8, 3, 2, 2, 2, 106, 107, 7, 62, 2, 2, 107, 10, 3, 2, 2, 2, 108, + 109, 7, 62, 2, 2, 109, 110, 7, 63, 2, 2, 110, 12, 3, 2, 2, 2, 111, 112, + 7, 64, 2, 2, 112, 113, 7, 63, 2, 2, 113, 14, 3, 2, 2, 2, 114, 115, 7, 64, + 2, 2, 115, 16, 3, 2, 2, 2, 116, 117, 7, 40, 2, 2, 117, 118, 7, 40, 2, 2, + 118, 18, 3, 2, 2, 2, 119, 120, 7, 126, 2, 2, 120, 121, 7, 126, 2, 2, 121, + 20, 3, 2, 2, 2, 122, 123, 7, 93, 2, 2, 123, 22, 3, 2, 2, 2, 124, 125, 7, + 95, 2, 2, 125, 24, 3, 2, 2, 2, 126, 127, 7, 125, 2, 2, 127, 26, 3, 2, 2, + 2, 128, 129, 7, 127, 2, 2, 129, 28, 3, 2, 2, 2, 130, 131, 7, 42, 2, 2, + 131, 30, 3, 2, 2, 2, 132, 133, 7, 43, 2, 2, 133, 32, 3, 2, 2, 2, 134, 135, + 7, 48, 2, 2, 135, 34, 3, 2, 2, 2, 136, 137, 7, 46, 2, 2, 137, 36, 3, 2, + 2, 2, 138, 139, 7, 47, 2, 2, 139, 38, 3, 2, 2, 2, 140, 141, 7, 35, 2, 2, + 141, 40, 3, 2, 2, 2, 142, 143, 7, 65, 2, 2, 143, 42, 3, 2, 2, 2, 144, 145, + 7, 60, 2, 2, 145, 44, 3, 2, 2, 2, 146, 147, 7, 45, 2, 2, 147, 46, 3, 2, + 2, 2, 148, 149, 7, 44, 2, 2, 149, 48, 3, 2, 2, 2, 150, 151, 7, 49, 2, 2, + 151, 50, 3, 2, 2, 2, 152, 153, 7, 39, 2, 2, 153, 52, 3, 2, 2, 2, 154, 155, + 7, 118, 2, 2, 155, 156, 7, 116, 2, 2, 156, 157, 7, 119, 2, 2, 157, 158, + 7, 103, 2, 2, 158, 54, 3, 2, 2, 2, 159, 160, 7, 104, 2, 2, 160, 161, 7, + 99, 2, 2, 161, 162, 7, 110, 2, 2, 162, 163, 7, 117, 2, 2, 163, 164, 7, + 103, 2, 2, 164, 56, 3, 2, 2, 2, 165, 166, 7, 112, 2, 2, 166, 167, 7, 119, + 2, 2, 167, 168, 7, 110, 2, 2, 168, 169, 7, 110, 2, 2, 169, 58, 3, 2, 2, + 2, 170, 171, 7, 94, 2, 2, 171, 60, 3, 2, 2, 2, 172, 173, 9, 2, 2, 2, 173, + 62, 3, 2, 2, 2, 174, 175, 4, 50, 59, 2, 175, 64, 3, 2, 2, 2, 176, 178, + 9, 3, 2, 2, 177, 179, 9, 4, 2, 2, 178, 177, 3, 2, 2, 2, 178, 179, 3, 2, + 2, 2, 179, 181, 3, 2, 2, 2, 180, 182, 5, 63, 32, 2, 181, 180, 3, 2, 2, + 2, 182, 183, 3, 2, 2, 2, 183, 181, 3, 2, 2, 2, 183, 184, 3, 2, 2, 2, 184, + 66, 3, 2, 2, 2, 185, 186, 9, 5, 2, 2, 186, 68, 3, 2, 2, 2, 187, 188, 9, + 6, 2, 2, 188, 70, 3, 2, 2, 2, 189, 194, 5, 73, 37, 2, 190, 194, 5, 77, + 39, 2, 191, 194, 5, 79, 40, 2, 192, 194, 5, 75, 38, 2, 193, 189, 3, 2, + 2, 2, 193, 190, 3, 2, 2, 2, 193, 191, 3, 2, 2, 2, 193, 192, 3, 2, 2, 2, + 194, 72, 3, 2, 2, 2, 195, 196, 5, 59, 30, 2, 196, 197, 9, 7, 2, 2, 197, + 74, 3, 2, 2, 2, 198, 199, 5, 59, 30, 2, 199, 200, 4, 50, 53, 2, 200, 201, + 4, 50, 57, 2, 201, 202, 4, 50, 57, 2, 202, 76, 3, 2, 2, 2, 203, 204, 5, + 59, 30, 2, 204, 205, 9, 8, 2, 2, 205, 206, 5, 67, 34, 2, 206, 207, 5, 67, + 34, 2, 207, 78, 3, 2, 2, 2, 208, 209, 5, 59, 30, 2, 209, 210, 7, 119, 2, + 2, 210, 211, 5, 67, 34, 2, 211, 212, 5, 67, 34, 2, 212, 213, 5, 67, 34, + 2, 213, 214, 5, 67, 34, 2, 214, 227, 3, 2, 2, 2, 215, 216, 5, 59, 30, 2, + 216, 217, 7, 87, 2, 2, 217, 218, 5, 67, 34, 2, 218, 219, 5, 67, 34, 2, + 219, 220, 5, 67, 34, 2, 220, 221, 5, 67, 34, 2, 221, 222, 5, 67, 34, 2, + 222, 223, 5, 67, 34, 2, 223, 224, 5, 67, 34, 2, 224, 225, 5, 67, 34, 2, + 225, 227, 3, 2, 2, 2, 226, 208, 3, 2, 2, 2, 226, 215, 3, 2, 2, 2, 227, + 80, 3, 2, 2, 2, 228, 230, 9, 9, 2, 2, 229, 228, 3, 2, 2, 2, 230, 231, 3, + 2, 2, 2, 231, 229, 3, 2, 2, 2, 231, 232, 3, 2, 2, 2, 232, 233, 3, 2, 2, + 2, 233, 234, 8, 41, 2, 2, 234, 82, 3, 2, 2, 2, 235, 236, 7, 49, 2, 2, 236, + 237, 7, 49, 2, 2, 237, 241, 3, 2, 2, 2, 238, 240, 10, 10, 2, 2, 239, 238, + 3, 2, 2, 2, 240, 243, 3, 2, 2, 2, 241, 239, 3, 2, 2, 2, 241, 242, 3, 2, + 2, 2, 242, 244, 3, 2, 2, 2, 243, 241, 3, 2, 2, 2, 244, 245, 8, 42, 2, 2, + 245, 84, 3, 2, 2, 2, 246, 248, 5, 63, 32, 2, 247, 246, 3, 2, 2, 2, 248, + 249, 3, 2, 2, 2, 249, 247, 3, 2, 2, 2, 249, 250, 3, 2, 2, 2, 250, 251, + 3, 2, 2, 2, 251, 253, 7, 48, 2, 2, 252, 254, 5, 63, 32, 2, 253, 252, 3, + 2, 2, 2, 254, 255, 3, 2, 2, 2, 255, 253, 3, 2, 2, 2, 255, 256, 3, 2, 2, + 2, 256, 258, 3, 2, 2, 2, 257, 259, 5, 65, 33, 2, 258, 257, 3, 2, 2, 2, + 258, 259, 3, 2, 2, 2, 259, 277, 3, 2, 2, 2, 260, 262, 5, 63, 32, 2, 261, + 260, 3, 2, 2, 2, 262, 263, 3, 2, 2, 2, 263, 261, 3, 2, 2, 2, 263, 264, + 3, 2, 2, 2, 264, 265, 3, 2, 2, 2, 265, 266, 5, 65, 33, 2, 266, 277, 3, + 2, 2, 2, 267, 269, 7, 48, 2, 2, 268, 270, 5, 63, 32, 2, 269, 268, 3, 2, + 2, 2, 270, 271, 3, 2, 2, 2, 271, 269, 3, 2, 2, 2, 271, 272, 3, 2, 2, 2, + 272, 274, 3, 2, 2, 2, 273, 275, 5, 65, 33, 2, 274, 273, 3, 2, 2, 2, 274, + 275, 3, 2, 2, 2, 275, 277, 3, 2, 2, 2, 276, 247, 3, 2, 2, 2, 276, 261, + 3, 2, 2, 2, 276, 267, 3, 2, 2, 2, 277, 86, 3, 2, 2, 2, 278, 280, 5, 63, + 32, 2, 279, 278, 3, 2, 2, 2, 280, 281, 3, 2, 2, 2, 281, 279, 3, 2, 2, 2, + 281, 282, 3, 2, 2, 2, 282, 292, 3, 2, 2, 2, 283, 284, 7, 50, 2, 2, 284, + 285, 7, 122, 2, 2, 285, 287, 3, 2, 2, 2, 286, 288, 5, 67, 34, 2, 287, 286, + 3, 2, 2, 2, 288, 289, 3, 2, 2, 2, 289, 287, 3, 2, 2, 2, 289, 290, 3, 2, + 2, 2, 290, 292, 3, 2, 2, 2, 291, 279, 3, 2, 2, 2, 291, 283, 3, 2, 2, 2, + 292, 88, 3, 2, 2, 2, 293, 295, 5, 63, 32, 2, 294, 293, 3, 2, 2, 2, 295, + 296, 3, 2, 2, 2, 296, 294, 3, 2, 2, 2, 296, 297, 3, 2, 2, 2, 297, 298, + 3, 2, 2, 2, 298, 299, 9, 11, 2, 2, 299, 311, 3, 2, 2, 2, 300, 301, 7, 50, + 2, 2, 301, 302, 7, 122, 2, 2, 302, 304, 3, 2, 2, 2, 303, 305, 5, 67, 34, + 2, 304, 303, 3, 2, 2, 2, 305, 306, 3, 2, 2, 2, 306, 304, 3, 2, 2, 2, 306, + 307, 3, 2, 2, 2, 307, 308, 3, 2, 2, 2, 308, 309, 9, 11, 2, 2, 309, 311, + 3, 2, 2, 2, 310, 294, 3, 2, 2, 2, 310, 300, 3, 2, 2, 2, 311, 90, 3, 2, + 2, 2, 312, 317, 7, 36, 2, 2, 313, 316, 5, 71, 36, 2, 314, 316, 10, 12, + 2, 2, 315, 313, 3, 2, 2, 2, 315, 314, 3, 2, 2, 2, 316, 319, 3, 2, 2, 2, + 317, 315, 3, 2, 2, 2, 317, 318, 3, 2, 2, 2, 318, 320, 3, 2, 2, 2, 319, + 317, 3, 2, 2, 2, 320, 409, 7, 36, 2, 2, 321, 326, 7, 41, 2, 2, 322, 325, + 5, 71, 36, 2, 323, 325, 10, 13, 2, 2, 324, 322, 3, 2, 2, 2, 324, 323, 3, + 2, 2, 2, 325, 328, 3, 2, 2, 2, 326, 324, 3, 2, 2, 2, 326, 327, 3, 2, 2, + 2, 327, 329, 3, 2, 2, 2, 328, 326, 3, 2, 2, 2, 329, 409, 7, 41, 2, 2, 330, + 331, 7, 36, 2, 2, 331, 332, 7, 36, 2, 2, 332, 333, 7, 36, 2, 2, 333, 338, + 3, 2, 2, 2, 334, 337, 5, 71, 36, 2, 335, 337, 10, 14, 2, 2, 336, 334, 3, + 2, 2, 2, 336, 335, 3, 2, 2, 2, 337, 340, 3, 2, 2, 2, 338, 339, 3, 2, 2, + 2, 338, 336, 3, 2, 2, 2, 339, 341, 3, 2, 2, 2, 340, 338, 3, 2, 2, 2, 341, + 342, 7, 36, 2, 2, 342, 343, 7, 36, 2, 2, 343, 409, 7, 36, 2, 2, 344, 345, + 7, 41, 2, 2, 345, 346, 7, 41, 2, 2, 346, 347, 7, 41, 2, 2, 347, 352, 3, + 2, 2, 2, 348, 351, 5, 71, 36, 2, 349, 351, 10, 14, 2, 2, 350, 348, 3, 2, + 2, 2, 350, 349, 3, 2, 2, 2, 351, 354, 3, 2, 2, 2, 352, 353, 3, 2, 2, 2, + 352, 350, 3, 2, 2, 2, 353, 355, 3, 2, 2, 2, 354, 352, 3, 2, 2, 2, 355, + 356, 7, 41, 2, 2, 356, 357, 7, 41, 2, 2, 357, 409, 7, 41, 2, 2, 358, 359, + 5, 69, 35, 2, 359, 363, 7, 36, 2, 2, 360, 362, 10, 15, 2, 2, 361, 360, + 3, 2, 2, 2, 362, 365, 3, 2, 2, 2, 363, 361, 3, 2, 2, 2, 363, 364, 3, 2, + 2, 2, 364, 366, 3, 2, 2, 2, 365, 363, 3, 2, 2, 2, 366, 367, 7, 36, 2, 2, + 367, 409, 3, 2, 2, 2, 368, 369, 5, 69, 35, 2, 369, 373, 7, 41, 2, 2, 370, + 372, 10, 16, 2, 2, 371, 370, 3, 2, 2, 2, 372, 375, 3, 2, 2, 2, 373, 371, + 3, 2, 2, 2, 373, 374, 3, 2, 2, 2, 374, 376, 3, 2, 2, 2, 375, 373, 3, 2, + 2, 2, 376, 377, 7, 41, 2, 2, 377, 409, 3, 2, 2, 2, 378, 379, 5, 69, 35, + 2, 379, 380, 7, 36, 2, 2, 380, 381, 7, 36, 2, 2, 381, 382, 7, 36, 2, 2, + 382, 386, 3, 2, 2, 2, 383, 385, 11, 2, 2, 2, 384, 383, 3, 2, 2, 2, 385, + 388, 3, 2, 2, 2, 386, 387, 3, 2, 2, 2, 386, 384, 3, 2, 2, 2, 387, 389, + 3, 2, 2, 2, 388, 386, 3, 2, 2, 2, 389, 390, 7, 36, 2, 2, 390, 391, 7, 36, + 2, 2, 391, 392, 7, 36, 2, 2, 392, 409, 3, 2, 2, 2, 393, 394, 5, 69, 35, + 2, 394, 395, 7, 41, 2, 2, 395, 396, 7, 41, 2, 2, 396, 397, 7, 41, 2, 2, + 397, 401, 3, 2, 2, 2, 398, 400, 11, 2, 2, 2, 399, 398, 3, 2, 2, 2, 400, + 403, 3, 2, 2, 2, 401, 402, 3, 2, 2, 2, 401, 399, 3, 2, 2, 2, 402, 404, + 3, 2, 2, 2, 403, 401, 3, 2, 2, 2, 404, 405, 7, 41, 2, 2, 405, 406, 7, 41, + 2, 2, 406, 407, 7, 41, 2, 2, 407, 409, 3, 2, 2, 2, 408, 312, 3, 2, 2, 2, + 408, 321, 3, 2, 2, 2, 408, 330, 3, 2, 2, 2, 408, 344, 3, 2, 2, 2, 408, + 358, 3, 2, 2, 2, 408, 368, 3, 2, 2, 2, 408, 378, 3, 2, 2, 2, 408, 393, + 3, 2, 2, 2, 409, 92, 3, 2, 2, 2, 410, 411, 9, 17, 2, 2, 411, 412, 5, 91, + 46, 2, 412, 94, 3, 2, 2, 2, 413, 416, 5, 61, 31, 2, 414, 416, 7, 97, 2, + 2, 415, 413, 3, 2, 2, 2, 415, 414, 3, 2, 2, 2, 416, 422, 3, 2, 2, 2, 417, + 421, 5, 61, 31, 2, 418, 421, 5, 63, 32, 2, 419, 421, 7, 97, 2, 2, 420, + 417, 3, 2, 2, 2, 420, 418, 3, 2, 2, 2, 420, 419, 3, 2, 2, 2, 421, 424, + 3, 2, 2, 2, 422, 420, 3, 2, 2, 2, 422, 423, 3, 2, 2, 2, 423, 96, 3, 2, + 2, 2, 424, 422, 3, 2, 2, 2, 38, 2, 178, 183, 193, 226, 231, 241, 249, 255, + 258, 263, 271, 274, 276, 281, 289, 291, 296, 306, 310, 315, 317, 324, 326, + 336, 338, 350, 352, 363, 373, 386, 401, 408, 415, 420, 422, 3, 2, 3, 2, +} + +var lexerChannelNames = []string{ + "DEFAULT_TOKEN_CHANNEL", "HIDDEN", +} + +var lexerModeNames = []string{ + "DEFAULT_MODE", +} + +var lexerLiteralNames = []string{ + "", "'in'", "'=='", "'!='", "'<'", "'<='", "'>='", "'>'", "'&&'", "'||'", + "'['", "']'", "'{'", "'}'", "'('", "')'", "'.'", "','", "'-'", "'!'", "'?'", + "':'", "'+'", "'*'", "'/'", "'%'", "'true'", "'false'", "'null'", +} + +var lexerSymbolicNames = []string{ + "", "", "EQUALS", "NOT_EQUALS", "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", "TRUE", "FALSE", "NULL", "WHITESPACE", + "COMMENT", "NUM_FLOAT", "NUM_INT", "NUM_UINT", "STRING", "BYTES", "IDENTIFIER", +} + +var lexerRuleNames = []string{ + "T__0", "EQUALS", "NOT_EQUALS", "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", "TRUE", "FALSE", "NULL", "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", +} + +type CELLexer struct { + *antlr.BaseLexer + channelNames []string + modeNames []string + // TODO: EOF string +} + +func NewCELLexer(input antlr.CharStream) *CELLexer { + + l := new(CELLexer) + lexerDeserializer := antlr.NewATNDeserializer(nil) + lexerAtn := lexerDeserializer.DeserializeFromUInt16(serializedLexerAtn) + lexerDecisionToDFA := make([]*antlr.DFA, len(lexerAtn.DecisionToState)) + for index, ds := range lexerAtn.DecisionToState { + lexerDecisionToDFA[index] = antlr.NewDFA(ds, index) + } + + l.BaseLexer = antlr.NewBaseLexer(input) + l.Interpreter = antlr.NewLexerATNSimulator(l, lexerAtn, lexerDecisionToDFA, antlr.NewPredictionContextCache()) + + l.channelNames = lexerChannelNames + l.modeNames = lexerModeNames + l.RuleNames = lexerRuleNames + l.LiteralNames = lexerLiteralNames + l.SymbolicNames = lexerSymbolicNames + l.GrammarFileName = "CEL.g4" + // TODO: l.EOF = antlr.TokenEOF + + return l +} + +// CELLexer tokens. +const ( + CELLexerT__0 = 1 + CELLexerEQUALS = 2 + CELLexerNOT_EQUALS = 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 + CELLexerTRUE = 26 + CELLexerFALSE = 27 + CELLexerNULL = 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 new file mode 100644 index 000000000..7eaba7264 --- /dev/null +++ b/vendor/github.com/google/cel-go/parser/gen/cel_listener.go @@ -0,0 +1,183 @@ +// Generated from /Users/tswadell/lace/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.7. + +package gen // CEL +import "github.com/antlr/antlr4/runtime/Go/antlr" + +// CELListener is a complete listener for a parse tree produced by CELParser. +type CELListener interface { + antlr.ParseTreeListener + + // EnterStart is called when entering the start production. + EnterStart(c *StartContext) + + // EnterExpr is called when entering the expr production. + EnterExpr(c *ExprContext) + + // EnterConditionalOr is called when entering the conditionalOr production. + EnterConditionalOr(c *ConditionalOrContext) + + // EnterConditionalAnd is called when entering the conditionalAnd production. + EnterConditionalAnd(c *ConditionalAndContext) + + // EnterRelation is called when entering the relation production. + EnterRelation(c *RelationContext) + + // EnterCalc is called when entering the calc production. + EnterCalc(c *CalcContext) + + // EnterMemberExpr is called when entering the MemberExpr production. + EnterMemberExpr(c *MemberExprContext) + + // EnterLogicalNot is called when entering the LogicalNot production. + EnterLogicalNot(c *LogicalNotContext) + + // EnterNegate is called when entering the Negate production. + EnterNegate(c *NegateContext) + + // EnterSelectOrCall is called when entering the SelectOrCall production. + EnterSelectOrCall(c *SelectOrCallContext) + + // EnterPrimaryExpr is called when entering the PrimaryExpr production. + EnterPrimaryExpr(c *PrimaryExprContext) + + // EnterIndex is called when entering the Index production. + EnterIndex(c *IndexContext) + + // EnterCreateMessage is called when entering the CreateMessage production. + EnterCreateMessage(c *CreateMessageContext) + + // EnterIdentOrGlobalCall is called when entering the IdentOrGlobalCall production. + EnterIdentOrGlobalCall(c *IdentOrGlobalCallContext) + + // EnterNested is called when entering the Nested production. + EnterNested(c *NestedContext) + + // EnterCreateList is called when entering the CreateList production. + EnterCreateList(c *CreateListContext) + + // EnterCreateStruct is called when entering the CreateStruct production. + EnterCreateStruct(c *CreateStructContext) + + // EnterConstantLiteral is called when entering the ConstantLiteral production. + EnterConstantLiteral(c *ConstantLiteralContext) + + // EnterExprList is called when entering the exprList production. + EnterExprList(c *ExprListContext) + + // EnterFieldInitializerList is called when entering the fieldInitializerList production. + EnterFieldInitializerList(c *FieldInitializerListContext) + + // EnterMapInitializerList is called when entering the mapInitializerList production. + EnterMapInitializerList(c *MapInitializerListContext) + + // EnterInt is called when entering the Int production. + EnterInt(c *IntContext) + + // EnterUint is called when entering the Uint production. + EnterUint(c *UintContext) + + // EnterDouble is called when entering the Double production. + EnterDouble(c *DoubleContext) + + // EnterString is called when entering the String production. + EnterString(c *StringContext) + + // EnterBytes is called when entering the Bytes production. + EnterBytes(c *BytesContext) + + // EnterBoolTrue is called when entering the BoolTrue production. + EnterBoolTrue(c *BoolTrueContext) + + // EnterBoolFalse is called when entering the BoolFalse production. + EnterBoolFalse(c *BoolFalseContext) + + // EnterNull is called when entering the Null production. + EnterNull(c *NullContext) + + // ExitStart is called when exiting the start production. + ExitStart(c *StartContext) + + // ExitExpr is called when exiting the expr production. + ExitExpr(c *ExprContext) + + // ExitConditionalOr is called when exiting the conditionalOr production. + ExitConditionalOr(c *ConditionalOrContext) + + // ExitConditionalAnd is called when exiting the conditionalAnd production. + ExitConditionalAnd(c *ConditionalAndContext) + + // ExitRelation is called when exiting the relation production. + ExitRelation(c *RelationContext) + + // ExitCalc is called when exiting the calc production. + ExitCalc(c *CalcContext) + + // ExitMemberExpr is called when exiting the MemberExpr production. + ExitMemberExpr(c *MemberExprContext) + + // ExitLogicalNot is called when exiting the LogicalNot production. + ExitLogicalNot(c *LogicalNotContext) + + // ExitNegate is called when exiting the Negate production. + ExitNegate(c *NegateContext) + + // ExitSelectOrCall is called when exiting the SelectOrCall production. + ExitSelectOrCall(c *SelectOrCallContext) + + // ExitPrimaryExpr is called when exiting the PrimaryExpr production. + ExitPrimaryExpr(c *PrimaryExprContext) + + // ExitIndex is called when exiting the Index production. + ExitIndex(c *IndexContext) + + // ExitCreateMessage is called when exiting the CreateMessage production. + ExitCreateMessage(c *CreateMessageContext) + + // ExitIdentOrGlobalCall is called when exiting the IdentOrGlobalCall production. + ExitIdentOrGlobalCall(c *IdentOrGlobalCallContext) + + // ExitNested is called when exiting the Nested production. + ExitNested(c *NestedContext) + + // ExitCreateList is called when exiting the CreateList production. + ExitCreateList(c *CreateListContext) + + // ExitCreateStruct is called when exiting the CreateStruct production. + ExitCreateStruct(c *CreateStructContext) + + // ExitConstantLiteral is called when exiting the ConstantLiteral production. + ExitConstantLiteral(c *ConstantLiteralContext) + + // ExitExprList is called when exiting the exprList production. + ExitExprList(c *ExprListContext) + + // ExitFieldInitializerList is called when exiting the fieldInitializerList production. + ExitFieldInitializerList(c *FieldInitializerListContext) + + // ExitMapInitializerList is called when exiting the mapInitializerList production. + ExitMapInitializerList(c *MapInitializerListContext) + + // ExitInt is called when exiting the Int production. + ExitInt(c *IntContext) + + // ExitUint is called when exiting the Uint production. + ExitUint(c *UintContext) + + // ExitDouble is called when exiting the Double production. + ExitDouble(c *DoubleContext) + + // ExitString is called when exiting the String production. + ExitString(c *StringContext) + + // ExitBytes is called when exiting the Bytes production. + ExitBytes(c *BytesContext) + + // ExitBoolTrue is called when exiting the BoolTrue production. + ExitBoolTrue(c *BoolTrueContext) + + // ExitBoolFalse is called when exiting the BoolFalse production. + ExitBoolFalse(c *BoolFalseContext) + + // ExitNull is called when exiting the Null production. + ExitNull(c *NullContext) +} 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 new file mode 100644 index 000000000..a7d65397a --- /dev/null +++ b/vendor/github.com/google/cel-go/parser/gen/cel_parser.go @@ -0,0 +1,4065 @@ +// Generated from /Users/tswadell/lace/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.7. + +package gen // CEL +import ( + "fmt" + "reflect" + "strconv" + + "github.com/antlr/antlr4/runtime/Go/antlr" +) + +// Suppress unused import errors +var _ = fmt.Printf +var _ = reflect.Copy +var _ = strconv.Itoa + +var parserATN = []uint16{ + 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 38, 205, + 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, + 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, + 9, 13, 4, 14, 9, 14, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 5, 3, 38, 10, 3, 3, 4, 3, 4, 3, 4, 7, 4, 43, 10, 4, 12, 4, 14, 4, 46, + 11, 4, 3, 5, 3, 5, 3, 5, 7, 5, 51, 10, 5, 12, 5, 14, 5, 54, 11, 5, 3, 6, + 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 7, 6, 62, 10, 6, 12, 6, 14, 6, 65, 11, 6, + 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 7, 7, 76, 10, 7, + 12, 7, 14, 7, 79, 11, 7, 3, 8, 3, 8, 6, 8, 83, 10, 8, 13, 8, 14, 8, 84, + 3, 8, 3, 8, 6, 8, 89, 10, 8, 13, 8, 14, 8, 90, 3, 8, 5, 8, 94, 10, 8, 3, + 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 104, 10, 9, 3, 9, 5, + 9, 107, 10, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 117, + 10, 9, 3, 9, 7, 9, 120, 10, 9, 12, 9, 14, 9, 123, 11, 9, 3, 10, 5, 10, + 126, 10, 10, 3, 10, 3, 10, 3, 10, 5, 10, 131, 10, 10, 3, 10, 5, 10, 134, + 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 5, 10, 142, 10, 10, 3, + 10, 5, 10, 145, 10, 10, 3, 10, 3, 10, 3, 10, 5, 10, 150, 10, 10, 3, 10, + 3, 10, 5, 10, 154, 10, 10, 3, 11, 3, 11, 3, 11, 7, 11, 159, 10, 11, 12, + 11, 14, 11, 162, 11, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, + 7, 12, 171, 10, 12, 12, 12, 14, 12, 174, 11, 12, 3, 13, 3, 13, 3, 13, 3, + 13, 3, 13, 3, 13, 3, 13, 3, 13, 7, 13, 184, 10, 13, 12, 13, 14, 13, 187, + 11, 13, 3, 14, 5, 14, 190, 10, 14, 3, 14, 3, 14, 3, 14, 5, 14, 195, 10, + 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 5, 14, 203, 10, 14, 3, 14, + 2, 5, 10, 12, 16, 15, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 2, + 5, 3, 2, 3, 9, 3, 2, 25, 27, 4, 2, 20, 20, 24, 24, 2, 229, 2, 28, 3, 2, + 2, 2, 4, 31, 3, 2, 2, 2, 6, 39, 3, 2, 2, 2, 8, 47, 3, 2, 2, 2, 10, 55, + 3, 2, 2, 2, 12, 66, 3, 2, 2, 2, 14, 93, 3, 2, 2, 2, 16, 95, 3, 2, 2, 2, + 18, 153, 3, 2, 2, 2, 20, 155, 3, 2, 2, 2, 22, 163, 3, 2, 2, 2, 24, 175, + 3, 2, 2, 2, 26, 202, 3, 2, 2, 2, 28, 29, 5, 4, 3, 2, 29, 30, 7, 2, 2, 3, + 30, 3, 3, 2, 2, 2, 31, 37, 5, 6, 4, 2, 32, 33, 7, 22, 2, 2, 33, 34, 5, + 6, 4, 2, 34, 35, 7, 23, 2, 2, 35, 36, 5, 4, 3, 2, 36, 38, 3, 2, 2, 2, 37, + 32, 3, 2, 2, 2, 37, 38, 3, 2, 2, 2, 38, 5, 3, 2, 2, 2, 39, 44, 5, 8, 5, + 2, 40, 41, 7, 11, 2, 2, 41, 43, 5, 8, 5, 2, 42, 40, 3, 2, 2, 2, 43, 46, + 3, 2, 2, 2, 44, 42, 3, 2, 2, 2, 44, 45, 3, 2, 2, 2, 45, 7, 3, 2, 2, 2, + 46, 44, 3, 2, 2, 2, 47, 52, 5, 10, 6, 2, 48, 49, 7, 10, 2, 2, 49, 51, 5, + 10, 6, 2, 50, 48, 3, 2, 2, 2, 51, 54, 3, 2, 2, 2, 52, 50, 3, 2, 2, 2, 52, + 53, 3, 2, 2, 2, 53, 9, 3, 2, 2, 2, 54, 52, 3, 2, 2, 2, 55, 56, 8, 6, 1, + 2, 56, 57, 5, 12, 7, 2, 57, 63, 3, 2, 2, 2, 58, 59, 12, 3, 2, 2, 59, 60, + 9, 2, 2, 2, 60, 62, 5, 10, 6, 4, 61, 58, 3, 2, 2, 2, 62, 65, 3, 2, 2, 2, + 63, 61, 3, 2, 2, 2, 63, 64, 3, 2, 2, 2, 64, 11, 3, 2, 2, 2, 65, 63, 3, + 2, 2, 2, 66, 67, 8, 7, 1, 2, 67, 68, 5, 14, 8, 2, 68, 77, 3, 2, 2, 2, 69, + 70, 12, 4, 2, 2, 70, 71, 9, 3, 2, 2, 71, 76, 5, 12, 7, 5, 72, 73, 12, 3, + 2, 2, 73, 74, 9, 4, 2, 2, 74, 76, 5, 12, 7, 4, 75, 69, 3, 2, 2, 2, 75, + 72, 3, 2, 2, 2, 76, 79, 3, 2, 2, 2, 77, 75, 3, 2, 2, 2, 77, 78, 3, 2, 2, + 2, 78, 13, 3, 2, 2, 2, 79, 77, 3, 2, 2, 2, 80, 94, 5, 16, 9, 2, 81, 83, + 7, 21, 2, 2, 82, 81, 3, 2, 2, 2, 83, 84, 3, 2, 2, 2, 84, 82, 3, 2, 2, 2, + 84, 85, 3, 2, 2, 2, 85, 86, 3, 2, 2, 2, 86, 94, 5, 16, 9, 2, 87, 89, 7, + 20, 2, 2, 88, 87, 3, 2, 2, 2, 89, 90, 3, 2, 2, 2, 90, 88, 3, 2, 2, 2, 90, + 91, 3, 2, 2, 2, 91, 92, 3, 2, 2, 2, 92, 94, 5, 16, 9, 2, 93, 80, 3, 2, + 2, 2, 93, 82, 3, 2, 2, 2, 93, 88, 3, 2, 2, 2, 94, 15, 3, 2, 2, 2, 95, 96, + 8, 9, 1, 2, 96, 97, 5, 18, 10, 2, 97, 121, 3, 2, 2, 2, 98, 99, 12, 5, 2, + 2, 99, 100, 7, 18, 2, 2, 100, 106, 7, 38, 2, 2, 101, 103, 7, 16, 2, 2, + 102, 104, 5, 20, 11, 2, 103, 102, 3, 2, 2, 2, 103, 104, 3, 2, 2, 2, 104, + 105, 3, 2, 2, 2, 105, 107, 7, 17, 2, 2, 106, 101, 3, 2, 2, 2, 106, 107, + 3, 2, 2, 2, 107, 120, 3, 2, 2, 2, 108, 109, 12, 4, 2, 2, 109, 110, 7, 12, + 2, 2, 110, 111, 5, 4, 3, 2, 111, 112, 7, 13, 2, 2, 112, 120, 3, 2, 2, 2, + 113, 114, 12, 3, 2, 2, 114, 116, 7, 14, 2, 2, 115, 117, 5, 22, 12, 2, 116, + 115, 3, 2, 2, 2, 116, 117, 3, 2, 2, 2, 117, 118, 3, 2, 2, 2, 118, 120, + 7, 15, 2, 2, 119, 98, 3, 2, 2, 2, 119, 108, 3, 2, 2, 2, 119, 113, 3, 2, + 2, 2, 120, 123, 3, 2, 2, 2, 121, 119, 3, 2, 2, 2, 121, 122, 3, 2, 2, 2, + 122, 17, 3, 2, 2, 2, 123, 121, 3, 2, 2, 2, 124, 126, 7, 18, 2, 2, 125, + 124, 3, 2, 2, 2, 125, 126, 3, 2, 2, 2, 126, 127, 3, 2, 2, 2, 127, 133, + 7, 38, 2, 2, 128, 130, 7, 16, 2, 2, 129, 131, 5, 20, 11, 2, 130, 129, 3, + 2, 2, 2, 130, 131, 3, 2, 2, 2, 131, 132, 3, 2, 2, 2, 132, 134, 7, 17, 2, + 2, 133, 128, 3, 2, 2, 2, 133, 134, 3, 2, 2, 2, 134, 154, 3, 2, 2, 2, 135, + 136, 7, 16, 2, 2, 136, 137, 5, 4, 3, 2, 137, 138, 7, 17, 2, 2, 138, 154, + 3, 2, 2, 2, 139, 141, 7, 12, 2, 2, 140, 142, 5, 20, 11, 2, 141, 140, 3, + 2, 2, 2, 141, 142, 3, 2, 2, 2, 142, 144, 3, 2, 2, 2, 143, 145, 7, 19, 2, + 2, 144, 143, 3, 2, 2, 2, 144, 145, 3, 2, 2, 2, 145, 146, 3, 2, 2, 2, 146, + 154, 7, 13, 2, 2, 147, 149, 7, 14, 2, 2, 148, 150, 5, 24, 13, 2, 149, 148, + 3, 2, 2, 2, 149, 150, 3, 2, 2, 2, 150, 151, 3, 2, 2, 2, 151, 154, 7, 15, + 2, 2, 152, 154, 5, 26, 14, 2, 153, 125, 3, 2, 2, 2, 153, 135, 3, 2, 2, + 2, 153, 139, 3, 2, 2, 2, 153, 147, 3, 2, 2, 2, 153, 152, 3, 2, 2, 2, 154, + 19, 3, 2, 2, 2, 155, 160, 5, 4, 3, 2, 156, 157, 7, 19, 2, 2, 157, 159, + 5, 4, 3, 2, 158, 156, 3, 2, 2, 2, 159, 162, 3, 2, 2, 2, 160, 158, 3, 2, + 2, 2, 160, 161, 3, 2, 2, 2, 161, 21, 3, 2, 2, 2, 162, 160, 3, 2, 2, 2, + 163, 164, 7, 38, 2, 2, 164, 165, 7, 23, 2, 2, 165, 172, 5, 4, 3, 2, 166, + 167, 7, 19, 2, 2, 167, 168, 7, 38, 2, 2, 168, 169, 7, 23, 2, 2, 169, 171, + 5, 4, 3, 2, 170, 166, 3, 2, 2, 2, 171, 174, 3, 2, 2, 2, 172, 170, 3, 2, + 2, 2, 172, 173, 3, 2, 2, 2, 173, 23, 3, 2, 2, 2, 174, 172, 3, 2, 2, 2, + 175, 176, 5, 4, 3, 2, 176, 177, 7, 23, 2, 2, 177, 185, 5, 4, 3, 2, 178, + 179, 7, 19, 2, 2, 179, 180, 5, 4, 3, 2, 180, 181, 7, 23, 2, 2, 181, 182, + 5, 4, 3, 2, 182, 184, 3, 2, 2, 2, 183, 178, 3, 2, 2, 2, 184, 187, 3, 2, + 2, 2, 185, 183, 3, 2, 2, 2, 185, 186, 3, 2, 2, 2, 186, 25, 3, 2, 2, 2, + 187, 185, 3, 2, 2, 2, 188, 190, 7, 20, 2, 2, 189, 188, 3, 2, 2, 2, 189, + 190, 3, 2, 2, 2, 190, 191, 3, 2, 2, 2, 191, 203, 7, 34, 2, 2, 192, 203, + 7, 35, 2, 2, 193, 195, 7, 20, 2, 2, 194, 193, 3, 2, 2, 2, 194, 195, 3, + 2, 2, 2, 195, 196, 3, 2, 2, 2, 196, 203, 7, 33, 2, 2, 197, 203, 7, 36, + 2, 2, 198, 203, 7, 37, 2, 2, 199, 203, 7, 28, 2, 2, 200, 203, 7, 29, 2, + 2, 201, 203, 7, 30, 2, 2, 202, 189, 3, 2, 2, 2, 202, 192, 3, 2, 2, 2, 202, + 194, 3, 2, 2, 2, 202, 197, 3, 2, 2, 2, 202, 198, 3, 2, 2, 2, 202, 199, + 3, 2, 2, 2, 202, 200, 3, 2, 2, 2, 202, 201, 3, 2, 2, 2, 203, 27, 3, 2, + 2, 2, 29, 37, 44, 52, 63, 75, 77, 84, 90, 93, 103, 106, 116, 119, 121, + 125, 130, 133, 141, 144, 149, 153, 160, 172, 185, 189, 194, 202, +} + +var literalNames = []string{ + "", "'in'", "'=='", "'!='", "'<'", "'<='", "'>='", "'>'", "'&&'", "'||'", + "'['", "']'", "'{'", "'}'", "'('", "')'", "'.'", "','", "'-'", "'!'", "'?'", + "':'", "'+'", "'*'", "'/'", "'%'", "'true'", "'false'", "'null'", +} +var symbolicNames = []string{ + "", "", "EQUALS", "NOT_EQUALS", "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", "TRUE", "FALSE", "NULL", "WHITESPACE", + "COMMENT", "NUM_FLOAT", "NUM_INT", "NUM_UINT", "STRING", "BYTES", "IDENTIFIER", +} + +var ruleNames = []string{ + "start", "expr", "conditionalOr", "conditionalAnd", "relation", "calc", + "unary", "member", "primary", "exprList", "fieldInitializerList", "mapInitializerList", + "literal", +} + +type CELParser struct { + *antlr.BaseParser +} + +func NewCELParser(input antlr.TokenStream) *CELParser { + this := new(CELParser) + deserializer := antlr.NewATNDeserializer(nil) + deserializedATN := deserializer.DeserializeFromUInt16(parserATN) + decisionToDFA := make([]*antlr.DFA, len(deserializedATN.DecisionToState)) + for index, ds := range deserializedATN.DecisionToState { + decisionToDFA[index] = antlr.NewDFA(ds, index) + } + this.BaseParser = antlr.NewBaseParser(input) + + this.Interpreter = antlr.NewParserATNSimulator(this, deserializedATN, decisionToDFA, antlr.NewPredictionContextCache()) + this.RuleNames = ruleNames + this.LiteralNames = literalNames + this.SymbolicNames = symbolicNames + this.GrammarFileName = "CEL.g4" + + return this +} + +// CELParser tokens. +const ( + CELParserEOF = antlr.TokenEOF + CELParserT__0 = 1 + CELParserEQUALS = 2 + CELParserNOT_EQUALS = 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 + CELParserTRUE = 26 + CELParserFALSE = 27 + CELParserNULL = 28 + CELParserWHITESPACE = 29 + CELParserCOMMENT = 30 + CELParserNUM_FLOAT = 31 + CELParserNUM_INT = 32 + CELParserNUM_UINT = 33 + CELParserSTRING = 34 + CELParserBYTES = 35 + CELParserIDENTIFIER = 36 +) + +// CELParser rules. +const ( + CELParserRULE_start = 0 + CELParserRULE_expr = 1 + CELParserRULE_conditionalOr = 2 + CELParserRULE_conditionalAnd = 3 + CELParserRULE_relation = 4 + CELParserRULE_calc = 5 + CELParserRULE_unary = 6 + CELParserRULE_member = 7 + CELParserRULE_primary = 8 + CELParserRULE_exprList = 9 + CELParserRULE_fieldInitializerList = 10 + CELParserRULE_mapInitializerList = 11 + CELParserRULE_literal = 12 +) + +// IStartContext is an interface to support dynamic dispatch. +type IStartContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetE returns the e rule contexts. + GetE() IExprContext + + // SetE sets the e rule contexts. + SetE(IExprContext) + + // IsStartContext differentiates from other interfaces. + IsStartContext() +} + +type StartContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + e IExprContext +} + +func NewEmptyStartContext() *StartContext { + var p = new(StartContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CELParserRULE_start + return p +} + +func (*StartContext) IsStartContext() {} + +func NewStartContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *StartContext { + var p = new(StartContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CELParserRULE_start + + return p +} + +func (s *StartContext) GetParser() antlr.Parser { return s.parser } + +func (s *StartContext) GetE() IExprContext { return s.e } + +func (s *StartContext) SetE(v IExprContext) { s.e = v } + +func (s *StartContext) EOF() antlr.TerminalNode { + return s.GetToken(CELParserEOF, 0) +} + +func (s *StartContext) Expr() IExprContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IExprContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *StartContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *StartContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *StartContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CELListener); ok { + listenerT.EnterStart(s) + } +} + +func (s *StartContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CELListener); ok { + listenerT.ExitStart(s) + } +} + +func (s *StartContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CELVisitor: + return t.VisitStart(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CELParser) Start() (localctx IStartContext) { + localctx = NewStartContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 0, CELParserRULE_start) + + defer func() { + p.ExitRule() + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(26) + + var _x = p.Expr() + + localctx.(*StartContext).e = _x + } + { + p.SetState(27) + p.Match(CELParserEOF) + } + + return localctx +} + +// IExprContext is an interface to support dynamic dispatch. +type IExprContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetOp returns the op token. + GetOp() antlr.Token + + // SetOp sets the op token. + SetOp(antlr.Token) + + // GetE returns the e rule contexts. + GetE() IConditionalOrContext + + // GetE1 returns the e1 rule contexts. + GetE1() IConditionalOrContext + + // GetE2 returns the e2 rule contexts. + GetE2() IExprContext + + // SetE sets the e rule contexts. + SetE(IConditionalOrContext) + + // SetE1 sets the e1 rule contexts. + SetE1(IConditionalOrContext) + + // SetE2 sets the e2 rule contexts. + SetE2(IExprContext) + + // IsExprContext differentiates from other interfaces. + IsExprContext() +} + +type ExprContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + e IConditionalOrContext + op antlr.Token + e1 IConditionalOrContext + e2 IExprContext +} + +func NewEmptyExprContext() *ExprContext { + var p = new(ExprContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CELParserRULE_expr + return p +} + +func (*ExprContext) IsExprContext() {} + +func NewExprContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ExprContext { + var p = new(ExprContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CELParserRULE_expr + + return p +} + +func (s *ExprContext) GetParser() antlr.Parser { return s.parser } + +func (s *ExprContext) GetOp() antlr.Token { return s.op } + +func (s *ExprContext) SetOp(v antlr.Token) { s.op = v } + +func (s *ExprContext) GetE() IConditionalOrContext { return s.e } + +func (s *ExprContext) GetE1() IConditionalOrContext { return s.e1 } + +func (s *ExprContext) GetE2() IExprContext { return s.e2 } + +func (s *ExprContext) SetE(v IConditionalOrContext) { s.e = v } + +func (s *ExprContext) SetE1(v IConditionalOrContext) { s.e1 = v } + +func (s *ExprContext) SetE2(v IExprContext) { s.e2 = v } + +func (s *ExprContext) AllConditionalOr() []IConditionalOrContext { + var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IConditionalOrContext)(nil)).Elem()) + var tst = make([]IConditionalOrContext, len(ts)) + + for i, t := range ts { + if t != nil { + tst[i] = t.(IConditionalOrContext) + } + } + + return tst +} + +func (s *ExprContext) ConditionalOr(i int) IConditionalOrContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IConditionalOrContext)(nil)).Elem(), i) + + if t == nil { + return nil + } + + return t.(IConditionalOrContext) +} + +func (s *ExprContext) Expr() IExprContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IExprContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *ExprContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *ExprContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *ExprContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CELListener); ok { + listenerT.EnterExpr(s) + } +} + +func (s *ExprContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CELListener); ok { + listenerT.ExitExpr(s) + } +} + +func (s *ExprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CELVisitor: + return t.VisitExpr(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CELParser) Expr() (localctx IExprContext) { + localctx = NewExprContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 2, CELParserRULE_expr) + var _la int + + defer func() { + p.ExitRule() + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(29) + + var _x = p.ConditionalOr() + + localctx.(*ExprContext).e = _x + } + p.SetState(35) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + if _la == CELParserQUESTIONMARK { + { + p.SetState(30) + + var _m = p.Match(CELParserQUESTIONMARK) + + localctx.(*ExprContext).op = _m + } + { + p.SetState(31) + + var _x = p.ConditionalOr() + + localctx.(*ExprContext).e1 = _x + } + { + p.SetState(32) + p.Match(CELParserCOLON) + } + { + p.SetState(33) + + var _x = p.Expr() + + localctx.(*ExprContext).e2 = _x + } + + } + + return localctx +} + +// IConditionalOrContext is an interface to support dynamic dispatch. +type IConditionalOrContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetS9 returns the s9 token. + GetS9() antlr.Token + + // SetS9 sets the s9 token. + SetS9(antlr.Token) + + // GetOps returns the ops token list. + GetOps() []antlr.Token + + // SetOps sets the ops token list. + SetOps([]antlr.Token) + + // GetE returns the e rule contexts. + GetE() IConditionalAndContext + + // Get_conditionalAnd returns the _conditionalAnd rule contexts. + Get_conditionalAnd() IConditionalAndContext + + // SetE sets the e rule contexts. + SetE(IConditionalAndContext) + + // Set_conditionalAnd sets the _conditionalAnd rule contexts. + Set_conditionalAnd(IConditionalAndContext) + + // GetE1 returns the e1 rule context list. + GetE1() []IConditionalAndContext + + // SetE1 sets the e1 rule context list. + SetE1([]IConditionalAndContext) + + // IsConditionalOrContext differentiates from other interfaces. + IsConditionalOrContext() +} + +type ConditionalOrContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + e IConditionalAndContext + s9 antlr.Token + ops []antlr.Token + _conditionalAnd IConditionalAndContext + e1 []IConditionalAndContext +} + +func NewEmptyConditionalOrContext() *ConditionalOrContext { + var p = new(ConditionalOrContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CELParserRULE_conditionalOr + return p +} + +func (*ConditionalOrContext) IsConditionalOrContext() {} + +func NewConditionalOrContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ConditionalOrContext { + var p = new(ConditionalOrContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CELParserRULE_conditionalOr + + return p +} + +func (s *ConditionalOrContext) GetParser() antlr.Parser { return s.parser } + +func (s *ConditionalOrContext) GetS9() antlr.Token { return s.s9 } + +func (s *ConditionalOrContext) SetS9(v antlr.Token) { s.s9 = v } + +func (s *ConditionalOrContext) GetOps() []antlr.Token { return s.ops } + +func (s *ConditionalOrContext) SetOps(v []antlr.Token) { s.ops = v } + +func (s *ConditionalOrContext) GetE() IConditionalAndContext { return s.e } + +func (s *ConditionalOrContext) Get_conditionalAnd() IConditionalAndContext { return s._conditionalAnd } + +func (s *ConditionalOrContext) SetE(v IConditionalAndContext) { s.e = v } + +func (s *ConditionalOrContext) Set_conditionalAnd(v IConditionalAndContext) { s._conditionalAnd = v } + +func (s *ConditionalOrContext) GetE1() []IConditionalAndContext { return s.e1 } + +func (s *ConditionalOrContext) SetE1(v []IConditionalAndContext) { s.e1 = v } + +func (s *ConditionalOrContext) AllConditionalAnd() []IConditionalAndContext { + var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IConditionalAndContext)(nil)).Elem()) + var tst = make([]IConditionalAndContext, len(ts)) + + for i, t := range ts { + if t != nil { + tst[i] = t.(IConditionalAndContext) + } + } + + return tst +} + +func (s *ConditionalOrContext) ConditionalAnd(i int) IConditionalAndContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IConditionalAndContext)(nil)).Elem(), i) + + if t == nil { + return nil + } + + return t.(IConditionalAndContext) +} + +func (s *ConditionalOrContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *ConditionalOrContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *ConditionalOrContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CELListener); ok { + listenerT.EnterConditionalOr(s) + } +} + +func (s *ConditionalOrContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CELListener); ok { + listenerT.ExitConditionalOr(s) + } +} + +func (s *ConditionalOrContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CELVisitor: + return t.VisitConditionalOr(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CELParser) ConditionalOr() (localctx IConditionalOrContext) { + localctx = NewConditionalOrContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 4, CELParserRULE_conditionalOr) + var _la int + + defer func() { + p.ExitRule() + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(37) + + var _x = p.ConditionalAnd() + + localctx.(*ConditionalOrContext).e = _x + } + p.SetState(42) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + for _la == CELParserLOGICAL_OR { + { + p.SetState(38) + + var _m = p.Match(CELParserLOGICAL_OR) + + localctx.(*ConditionalOrContext).s9 = _m + } + localctx.(*ConditionalOrContext).ops = append(localctx.(*ConditionalOrContext).ops, localctx.(*ConditionalOrContext).s9) + { + p.SetState(39) + + var _x = p.ConditionalAnd() + + localctx.(*ConditionalOrContext)._conditionalAnd = _x + } + localctx.(*ConditionalOrContext).e1 = append(localctx.(*ConditionalOrContext).e1, localctx.(*ConditionalOrContext)._conditionalAnd) + + p.SetState(44) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + } + + return localctx +} + +// IConditionalAndContext is an interface to support dynamic dispatch. +type IConditionalAndContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetS8 returns the s8 token. + GetS8() antlr.Token + + // SetS8 sets the s8 token. + SetS8(antlr.Token) + + // GetOps returns the ops token list. + GetOps() []antlr.Token + + // SetOps sets the ops token list. + SetOps([]antlr.Token) + + // GetE returns the e rule contexts. + GetE() IRelationContext + + // Get_relation returns the _relation rule contexts. + Get_relation() IRelationContext + + // SetE sets the e rule contexts. + SetE(IRelationContext) + + // Set_relation sets the _relation rule contexts. + Set_relation(IRelationContext) + + // GetE1 returns the e1 rule context list. + GetE1() []IRelationContext + + // SetE1 sets the e1 rule context list. + SetE1([]IRelationContext) + + // IsConditionalAndContext differentiates from other interfaces. + IsConditionalAndContext() +} + +type ConditionalAndContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + e IRelationContext + s8 antlr.Token + ops []antlr.Token + _relation IRelationContext + e1 []IRelationContext +} + +func NewEmptyConditionalAndContext() *ConditionalAndContext { + var p = new(ConditionalAndContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CELParserRULE_conditionalAnd + return p +} + +func (*ConditionalAndContext) IsConditionalAndContext() {} + +func NewConditionalAndContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ConditionalAndContext { + var p = new(ConditionalAndContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CELParserRULE_conditionalAnd + + return p +} + +func (s *ConditionalAndContext) GetParser() antlr.Parser { return s.parser } + +func (s *ConditionalAndContext) GetS8() antlr.Token { return s.s8 } + +func (s *ConditionalAndContext) SetS8(v antlr.Token) { s.s8 = v } + +func (s *ConditionalAndContext) GetOps() []antlr.Token { return s.ops } + +func (s *ConditionalAndContext) SetOps(v []antlr.Token) { s.ops = v } + +func (s *ConditionalAndContext) GetE() IRelationContext { return s.e } + +func (s *ConditionalAndContext) Get_relation() IRelationContext { return s._relation } + +func (s *ConditionalAndContext) SetE(v IRelationContext) { s.e = v } + +func (s *ConditionalAndContext) Set_relation(v IRelationContext) { s._relation = v } + +func (s *ConditionalAndContext) GetE1() []IRelationContext { return s.e1 } + +func (s *ConditionalAndContext) SetE1(v []IRelationContext) { s.e1 = v } + +func (s *ConditionalAndContext) AllRelation() []IRelationContext { + var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IRelationContext)(nil)).Elem()) + var tst = make([]IRelationContext, len(ts)) + + for i, t := range ts { + if t != nil { + tst[i] = t.(IRelationContext) + } + } + + return tst +} + +func (s *ConditionalAndContext) Relation(i int) IRelationContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IRelationContext)(nil)).Elem(), i) + + if t == nil { + return nil + } + + return t.(IRelationContext) +} + +func (s *ConditionalAndContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *ConditionalAndContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *ConditionalAndContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CELListener); ok { + listenerT.EnterConditionalAnd(s) + } +} + +func (s *ConditionalAndContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CELListener); ok { + listenerT.ExitConditionalAnd(s) + } +} + +func (s *ConditionalAndContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CELVisitor: + return t.VisitConditionalAnd(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CELParser) ConditionalAnd() (localctx IConditionalAndContext) { + localctx = NewConditionalAndContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 6, CELParserRULE_conditionalAnd) + var _la int + + defer func() { + p.ExitRule() + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(45) + + var _x = p.relation(0) + + localctx.(*ConditionalAndContext).e = _x + } + p.SetState(50) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + for _la == CELParserLOGICAL_AND { + { + p.SetState(46) + + var _m = p.Match(CELParserLOGICAL_AND) + + localctx.(*ConditionalAndContext).s8 = _m + } + localctx.(*ConditionalAndContext).ops = append(localctx.(*ConditionalAndContext).ops, localctx.(*ConditionalAndContext).s8) + { + p.SetState(47) + + var _x = p.relation(0) + + localctx.(*ConditionalAndContext)._relation = _x + } + localctx.(*ConditionalAndContext).e1 = append(localctx.(*ConditionalAndContext).e1, localctx.(*ConditionalAndContext)._relation) + + p.SetState(52) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + } + + return localctx +} + +// IRelationContext is an interface to support dynamic dispatch. +type IRelationContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetOp returns the op token. + GetOp() antlr.Token + + // SetOp sets the op token. + SetOp(antlr.Token) + + // IsRelationContext differentiates from other interfaces. + IsRelationContext() +} + +type RelationContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + op antlr.Token +} + +func NewEmptyRelationContext() *RelationContext { + var p = new(RelationContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CELParserRULE_relation + return p +} + +func (*RelationContext) IsRelationContext() {} + +func NewRelationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *RelationContext { + var p = new(RelationContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CELParserRULE_relation + + return p +} + +func (s *RelationContext) GetParser() antlr.Parser { return s.parser } + +func (s *RelationContext) GetOp() antlr.Token { return s.op } + +func (s *RelationContext) SetOp(v antlr.Token) { s.op = v } + +func (s *RelationContext) Calc() ICalcContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*ICalcContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(ICalcContext) +} + +func (s *RelationContext) AllRelation() []IRelationContext { + var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IRelationContext)(nil)).Elem()) + var tst = make([]IRelationContext, len(ts)) + + for i, t := range ts { + if t != nil { + tst[i] = t.(IRelationContext) + } + } + + return tst +} + +func (s *RelationContext) Relation(i int) IRelationContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IRelationContext)(nil)).Elem(), i) + + if t == nil { + return nil + } + + return t.(IRelationContext) +} + +func (s *RelationContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *RelationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *RelationContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CELListener); ok { + listenerT.EnterRelation(s) + } +} + +func (s *RelationContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CELListener); ok { + listenerT.ExitRelation(s) + } +} + +func (s *RelationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CELVisitor: + return t.VisitRelation(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CELParser) Relation() (localctx IRelationContext) { + return p.relation(0) +} + +func (p *CELParser) relation(_p int) (localctx IRelationContext) { + var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext() + _parentState := p.GetState() + localctx = NewRelationContext(p, p.GetParserRuleContext(), _parentState) + var _prevctx IRelationContext = localctx + var _ antlr.ParserRuleContext = _prevctx // TODO: To prevent unused variable warning. + _startState := 8 + p.EnterRecursionRule(localctx, 8, CELParserRULE_relation, _p) + var _la int + + defer func() { + p.UnrollRecursionContexts(_parentctx) + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + var _alt int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(54) + p.calc(0) + } + + p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) + p.SetState(61) + p.GetErrorHandler().Sync(p) + _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 3, p.GetParserRuleContext()) + + for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { + if _alt == 1 { + if p.GetParseListeners() != nil { + p.TriggerExitRuleEvent() + } + _prevctx = localctx + localctx = NewRelationContext(p, _parentctx, _parentState) + p.PushNewRecursionContext(localctx, _startState, CELParserRULE_relation) + p.SetState(56) + + if !(p.Precpred(p.GetParserRuleContext(), 1)) { + panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 1)", "")) + } + p.SetState(57) + + var _lt = p.GetTokenStream().LT(1) + + localctx.(*RelationContext).op = _lt + + _la = p.GetTokenStream().LA(1) + + if !(((_la)&-(0x1f+1)) == 0 && ((1<::`. + // + // When the macros is a var-arg style macro, the `arg-count` value is represented as a `*`. + MacroKey() string + + // Expander returns the MacroExpander to apply when the macro key matches the parsed call + // signature. + Expander() MacroExpander +} + +// Macro type which declares the function name and arg count expected for the +// macro, as well as a macro expansion function. +type macro struct { + function string + receiverStyle bool + varArgStyle bool + argCount int + expander MacroExpander +} + +// Function returns the macro's function name (i.e. the function whose syntax it mimics). +func (m *macro) Function() string { + return m.function +} + +// ArgCount returns the number of arguments the macro expects. +func (m *macro) ArgCount() int { + return m.argCount +} + +// IsReceiverStyle returns whether the macro is receiver style. +func (m *macro) IsReceiverStyle() bool { + return m.receiverStyle +} + +// Expander implements the Macro interface method. +func (m *macro) Expander() MacroExpander { + return m.expander +} + +// MacroKey implements the Macro interface method. +func (m *macro) MacroKey() string { + if m.varArgStyle { + return makeVarArgMacroKey(m.function, m.receiverStyle) + } + return makeMacroKey(m.function, m.argCount, m.receiverStyle) +} + +func makeMacroKey(name string, args int, receiverStyle bool) string { + return fmt.Sprintf("%s:%d:%v", name, args, receiverStyle) +} + +func makeVarArgMacroKey(name string, receiverStyle bool) string { + return fmt.Sprintf("%s:*:%v", name, receiverStyle) +} + +// MacroExpander converts the target and args of a function call that matches a Macro. +// +// Note: when the Macros.IsReceiverStyle() is true, the target argument will be nil. +type MacroExpander func(eh ExprHelper, + target *exprpb.Expr, + args []*exprpb.Expr) (*exprpb.Expr, *common.Error) + +// ExprHelper assists with the manipulation of proto-based Expr values in a manner which is +// consistent with the source position and expression id generation code leveraged by both +// the parser and type-checker. +type ExprHelper interface { + // LiteralBool creates an Expr value for a bool literal. + LiteralBool(value bool) *exprpb.Expr + + // LiteralBytes creates an Expr value for a byte literal. + LiteralBytes(value []byte) *exprpb.Expr + + // LiteralDouble creates an Expr value for double literal. + LiteralDouble(value float64) *exprpb.Expr + + // LiteralInt creates an Expr value for an int literal. + LiteralInt(value int64) *exprpb.Expr + + // LiteralString creates am Expr value for a string literal. + LiteralString(value string) *exprpb.Expr + + // LiteralUint creates an Expr value for a uint literal. + LiteralUint(value uint64) *exprpb.Expr + + // NewList creates a CreateList instruction where the list is comprised of the optional set + // of elements provided as arguments. + NewList(elems ...*exprpb.Expr) *exprpb.Expr + + // NewMap creates a CreateStruct instruction for a map where the map is comprised of the + // optional set of key, value entries. + NewMap(entries ...*exprpb.Expr_CreateStruct_Entry) *exprpb.Expr + + // NewMapEntry creates a Map Entry for the key, value pair. + NewMapEntry(key *exprpb.Expr, val *exprpb.Expr) *exprpb.Expr_CreateStruct_Entry + + // NewObject creates a CreateStruct instruction for an object with a given type name and + // optional set of field initializers. + NewObject(typeName string, fieldInits ...*exprpb.Expr_CreateStruct_Entry) *exprpb.Expr + + // NewObjectFieldInit creates a new Object field initializer from the field name and value. + NewObjectFieldInit(field string, init *exprpb.Expr) *exprpb.Expr_CreateStruct_Entry + + // Fold creates a fold comprehension instruction. + // + // - iterVar is the iteration variable name. + // - iterRange represents the expression that resolves to a list or map where the elements or + // keys (respectively) will be iterated over. + // - accuVar is the accumulation variable name, typically parser.AccumulatorName. + // - accuInit is the initial expression whose value will be set for the accuVar prior to + // folding. + // - condition is the expression to test to determine whether to continue folding. + // - step is the expression to evaluation at the conclusion of a single fold iteration. + // - result is the computation to evaluate at the conclusion of the fold. + // + // The accuVar should not shadow variable names that you would like to reference within the + // environment in the step and condition expressions. Presently, the name __result__ is commonly + // used by built-in macros but this may change in the future. + Fold(iterVar string, + iterRange *exprpb.Expr, + accuVar string, + accuInit *exprpb.Expr, + condition *exprpb.Expr, + step *exprpb.Expr, + result *exprpb.Expr) *exprpb.Expr + + // Ident creates an identifier Expr value. + Ident(name string) *exprpb.Expr + + // GlobalCall creates a function call Expr value for a global (free) function. + GlobalCall(function string, args ...*exprpb.Expr) *exprpb.Expr + + // ReceiverCall creates a function call Expr value for a receiver-style function. + ReceiverCall(function string, target *exprpb.Expr, args ...*exprpb.Expr) *exprpb.Expr + + // PresenceTest creates a Select TestOnly Expr value for modelling has() semantics. + PresenceTest(operand *exprpb.Expr, field string) *exprpb.Expr + + // Select create a field traversal Expr value. + Select(operand *exprpb.Expr, field string) *exprpb.Expr + + // OffsetLocation returns the Location of the expression identifier. + OffsetLocation(exprID int64) common.Location +} + +var ( + // AllMacros includes the list of all spec-supported macros. + AllMacros = []Macro{ + // The macro "has(m.f)" which tests the presence of a field, avoiding the need to specify + // the field as a string. + NewGlobalMacro(operators.Has, 1, makeHas), + + // The macro "range.all(var, predicate)", which is true if for all elements in range the + // predicate holds. + NewReceiverMacro(operators.All, 2, makeAll), + + // The macro "range.exists(var, predicate)", which is true if for at least one element in + // range the predicate holds. + NewReceiverMacro(operators.Exists, 2, makeExists), + + // The macro "range.exists_one(var, predicate)", which is true if for exactly one element + // in range the predicate holds. + NewReceiverMacro(operators.ExistsOne, 2, makeExistsOne), + + // The macro "range.map(var, function)", applies the function to the vars in the range. + NewReceiverMacro(operators.Map, 2, makeMap), + + // The macro "range.map(var, predicate, function)", applies the function to the vars in + // the range for which the predicate holds true. The other variables are filtered out. + NewReceiverMacro(operators.Map, 3, makeMap), + + // The macro "range.filter(var, predicate)", filters out the variables for which the + // predicate is false. + NewReceiverMacro(operators.Filter, 2, makeFilter), + } + + // NoMacros list. + NoMacros = []Macro{} +) + +// AccumulatorName is the traditional variable name assigned to the fold accumulator variable. +const AccumulatorName = "__result__" + +type quantifierKind int + +const ( + quantifierAll quantifierKind = iota + quantifierExists + quantifierExistsOne +) + +func makeAll(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + return makeQuantifier(quantifierAll, eh, target, args) +} + +func makeExists(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + return makeQuantifier(quantifierExists, eh, target, args) +} + +func makeExistsOne(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + return makeQuantifier(quantifierExistsOne, eh, target, args) +} + +func makeQuantifier(kind quantifierKind, eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + v, found := extractIdent(args[0]) + if !found { + location := eh.OffsetLocation(args[0].Id) + return nil, &common.Error{ + Message: "argument must be a simple name", + Location: location} + } + accuIdent := func() *exprpb.Expr { + return eh.Ident(AccumulatorName) + } + + var init *exprpb.Expr + var condition *exprpb.Expr + var step *exprpb.Expr + var result *exprpb.Expr + switch kind { + case quantifierAll: + init = eh.LiteralBool(true) + condition = eh.GlobalCall(operators.NotStrictlyFalse, accuIdent()) + step = eh.GlobalCall(operators.LogicalAnd, accuIdent(), args[1]) + result = accuIdent() + case quantifierExists: + init = eh.LiteralBool(false) + condition = eh.GlobalCall( + operators.NotStrictlyFalse, + eh.GlobalCall(operators.LogicalNot, accuIdent())) + step = eh.GlobalCall(operators.LogicalOr, accuIdent(), args[1]) + result = accuIdent() + case quantifierExistsOne: + // TODO: make consistent with the CEL semantics. + zeroExpr := eh.LiteralInt(0) + oneExpr := eh.LiteralInt(1) + init = zeroExpr + condition = eh.GlobalCall(operators.LessEquals, accuIdent(), oneExpr) + step = eh.GlobalCall(operators.Conditional, args[1], + eh.GlobalCall(operators.Add, accuIdent(), oneExpr), accuIdent()) + result = eh.GlobalCall(operators.Equals, accuIdent(), oneExpr) + default: + return nil, &common.Error{Message: fmt.Sprintf("unrecognized quantifier '%v'", kind)} + } + return eh.Fold(v, target, AccumulatorName, init, condition, step, result), nil +} + +func makeMap(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + v, found := extractIdent(args[0]) + if !found { + return nil, &common.Error{Message: "argument is not an identifier"} + } + + var fn *exprpb.Expr + var filter *exprpb.Expr + + if len(args) == 3 { + filter = args[1] + fn = args[2] + } else { + filter = nil + fn = args[1] + } + + accuExpr := eh.Ident(AccumulatorName) + init := eh.NewList() + condition := eh.LiteralBool(true) + // TODO: use compiler internal method for faster, stateful add. + step := eh.GlobalCall(operators.Add, accuExpr, eh.NewList(fn)) + + if filter != nil { + step = eh.GlobalCall(operators.Conditional, filter, step, accuExpr) + } + return eh.Fold(v, target, AccumulatorName, init, condition, step, accuExpr), nil +} + +func makeFilter(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + v, found := extractIdent(args[0]) + if !found { + return nil, &common.Error{Message: "argument is not an identifier"} + } + + filter := args[1] + accuExpr := eh.Ident(AccumulatorName) + init := eh.NewList() + condition := eh.LiteralBool(true) + // TODO: use compiler internal method for faster, stateful add. + step := eh.GlobalCall(operators.Add, accuExpr, eh.NewList(args[0])) + step = eh.GlobalCall(operators.Conditional, filter, step, accuExpr) + return eh.Fold(v, target, AccumulatorName, init, condition, step, accuExpr), nil +} + +func extractIdent(e *exprpb.Expr) (string, bool) { + switch e.ExprKind.(type) { + case *exprpb.Expr_IdentExpr: + return e.GetIdentExpr().Name, true + } + return "", false +} + +func makeHas(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + if s, ok := args[0].ExprKind.(*exprpb.Expr_SelectExpr); ok { + return eh.PresenceTest(s.SelectExpr.Operand, s.SelectExpr.Field), nil + } + return nil, &common.Error{Message: "invalid argument to has() macro"} +} diff --git a/vendor/github.com/google/cel-go/parser/parser.go b/vendor/github.com/google/cel-go/parser/parser.go new file mode 100644 index 000000000..63fe5fca7 --- /dev/null +++ b/vendor/github.com/google/cel-go/parser/parser.go @@ -0,0 +1,607 @@ +// 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 parser declares an expression parser with support for macro +// expansion. +package parser + +import ( + "fmt" + "reflect" + "strconv" + + "github.com/antlr/antlr4/runtime/Go/antlr" + + "github.com/google/cel-go/common" + "github.com/google/cel-go/common/operators" + "github.com/google/cel-go/parser/gen" + + structpb "github.com/golang/protobuf/ptypes/struct" + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// reservedIds are not legal to use as variables. We exclude them post-parse, as they *are* valid +// field names for protos, and it would complicate the grammar to distinguish the cases. +var reservedIds = []string{ + "as", "break", "const", "continue", "else", "false", "for", "function", "if", + "import", "in", "let", "loop", "package", "namespace", "null", "return", + "true", "var", "void", "while", +} + +// Parse converts a source input a parsed expression. +// This function calls ParseWithMacros with AllMacros. +func Parse(source common.Source) (*exprpb.ParsedExpr, *common.Errors) { + return ParseWithMacros(source, AllMacros) +} + +// ParseWithMacros converts a source input and macros set to a parsed expression. +func ParseWithMacros(source common.Source, macros []Macro) (*exprpb.ParsedExpr, *common.Errors) { + macroMap := make(map[string]Macro) + for _, m := range macros { + macroMap[m.MacroKey()] = m + } + p := parser{ + errors: &parseErrors{common.NewErrors(source)}, + helper: newParserHelper(source), + macros: macroMap, + } + e := p.parse(source.Content()) + return &exprpb.ParsedExpr{ + Expr: e, + SourceInfo: p.helper.getSourceInfo(), + }, p.errors.Errors +} + +type parser struct { + gen.BaseCELVisitor + errors *parseErrors + helper *parserHelper + macros map[string]Macro +} + +var _ gen.CELVisitor = (*parser)(nil) + +func (p *parser) parse(expression string) *exprpb.Expr { + stream := antlr.NewInputStream(expression) + lexer := gen.NewCELLexer(stream) + prsr := gen.NewCELParser(antlr.NewCommonTokenStream(lexer, 0)) + + lexer.RemoveErrorListeners() + prsr.RemoveErrorListeners() + lexer.AddErrorListener(p) + prsr.AddErrorListener(p) + + return p.Visit(prsr.Start()).(*exprpb.Expr) +} + +// Visitor implementations. +func (p *parser) Visit(tree antlr.ParseTree) interface{} { + switch tree.(type) { + case *gen.StartContext: + return p.VisitStart(tree.(*gen.StartContext)) + case *gen.ExprContext: + return p.VisitExpr(tree.(*gen.ExprContext)) + case *gen.ConditionalAndContext: + return p.VisitConditionalAnd(tree.(*gen.ConditionalAndContext)) + case *gen.ConditionalOrContext: + return p.VisitConditionalOr(tree.(*gen.ConditionalOrContext)) + case *gen.RelationContext: + return p.VisitRelation(tree.(*gen.RelationContext)) + case *gen.CalcContext: + return p.VisitCalc(tree.(*gen.CalcContext)) + case *gen.LogicalNotContext: + return p.VisitLogicalNot(tree.(*gen.LogicalNotContext)) + case *gen.MemberExprContext: + return p.VisitMemberExpr(tree.(*gen.MemberExprContext)) + case *gen.PrimaryExprContext: + return p.VisitPrimaryExpr(tree.(*gen.PrimaryExprContext)) + case *gen.SelectOrCallContext: + return p.VisitSelectOrCall(tree.(*gen.SelectOrCallContext)) + case *gen.MapInitializerListContext: + return p.VisitMapInitializerList(tree.(*gen.MapInitializerListContext)) + case *gen.NegateContext: + return p.VisitNegate(tree.(*gen.NegateContext)) + case *gen.IndexContext: + return p.VisitIndex(tree.(*gen.IndexContext)) + case *gen.UnaryContext: + return p.VisitUnary(tree.(*gen.UnaryContext)) + case *gen.CreateListContext: + return p.VisitCreateList(tree.(*gen.CreateListContext)) + case *gen.CreateMessageContext: + return p.VisitCreateMessage(tree.(*gen.CreateMessageContext)) + case *gen.CreateStructContext: + return p.VisitCreateStruct(tree.(*gen.CreateStructContext)) + } + + text := "<>" + if tree != nil { + text = tree.GetText() + } + panic(fmt.Sprintf("unknown parsetree type: '%+v': %+v [%s]", reflect.TypeOf(tree), tree, text)) +} + +// Visit a parse tree produced by CELParser#start. +func (p *parser) VisitStart(ctx *gen.StartContext) interface{} { + return p.Visit(ctx.Expr()) +} + +// Visit a parse tree produced by CELParser#expr. +func (p *parser) VisitExpr(ctx *gen.ExprContext) interface{} { + result := p.Visit(ctx.GetE()).(*exprpb.Expr) + if ctx.GetOp() == nil { + return result + } + opID := p.helper.id(ctx.GetOp()) + ifTrue := p.Visit(ctx.GetE1()).(*exprpb.Expr) + ifFalse := p.Visit(ctx.GetE2()).(*exprpb.Expr) + return p.globalCallOrMacro(opID, operators.Conditional, result, ifTrue, ifFalse) +} + +// Visit a parse tree produced by CELParser#conditionalOr. +func (p *parser) VisitConditionalOr(ctx *gen.ConditionalOrContext) interface{} { + result := p.Visit(ctx.GetE()).(*exprpb.Expr) + if ctx.GetOps() == nil { + return result + } + b := newBalancer(p.helper, operators.LogicalOr, result) + for i, op := range ctx.GetOps() { + next := p.Visit(ctx.GetE1()[i]).(*exprpb.Expr) + opID := p.helper.id(op) + b.addTerm(opID, next) + } + return b.balance() +} + +// Visit a parse tree produced by CELParser#conditionalAnd. +func (p *parser) VisitConditionalAnd(ctx *gen.ConditionalAndContext) interface{} { + result := p.Visit(ctx.GetE()).(*exprpb.Expr) + if ctx.GetOps() == nil { + return result + } + b := newBalancer(p.helper, operators.LogicalAnd, result) + for i, op := range ctx.GetOps() { + next := p.Visit(ctx.GetE1()[i]).(*exprpb.Expr) + opID := p.helper.id(op) + b.addTerm(opID, next) + } + return b.balance() +} + +// Visit a parse tree produced by CELParser#relation. +func (p *parser) VisitRelation(ctx *gen.RelationContext) interface{} { + if ctx.Calc() != nil { + return p.Visit(ctx.Calc()) + } + opText := "" + if ctx.GetOp() != nil { + opText = ctx.GetOp().GetText() + } + if op, found := operators.Find(opText); found { + lhs := p.Visit(ctx.Relation(0)).(*exprpb.Expr) + opID := p.helper.id(ctx.GetOp()) + rhs := p.Visit(ctx.Relation(1)).(*exprpb.Expr) + return p.globalCallOrMacro(opID, op, lhs, rhs) + } + return p.reportError(ctx, "operator not found") +} + +// Visit a parse tree produced by CELParser#calc. +func (p *parser) VisitCalc(ctx *gen.CalcContext) interface{} { + if ctx.Unary() != nil { + return p.Visit(ctx.Unary()) + } + opText := "" + if ctx.GetOp() != nil { + opText = ctx.GetOp().GetText() + } + if op, found := operators.Find(opText); found { + lhs := p.Visit(ctx.Calc(0)).(*exprpb.Expr) + opID := p.helper.id(ctx.GetOp()) + rhs := p.Visit(ctx.Calc(1)).(*exprpb.Expr) + return p.globalCallOrMacro(opID, op, lhs, rhs) + } + return p.reportError(ctx, "operator not found") +} + +func (p *parser) VisitUnary(ctx *gen.UnaryContext) interface{} { + return p.helper.newLiteralString(ctx, "<>") +} + +// Visit a parse tree produced by CELParser#MemberExpr. +func (p *parser) VisitMemberExpr(ctx *gen.MemberExprContext) interface{} { + switch ctx.Member().(type) { + case *gen.PrimaryExprContext: + return p.VisitPrimaryExpr(ctx.Member().(*gen.PrimaryExprContext)) + case *gen.SelectOrCallContext: + return p.VisitSelectOrCall(ctx.Member().(*gen.SelectOrCallContext)) + case *gen.IndexContext: + return p.VisitIndex(ctx.Member().(*gen.IndexContext)) + case *gen.CreateMessageContext: + return p.VisitCreateMessage(ctx.Member().(*gen.CreateMessageContext)) + } + return p.reportError(ctx, "unsupported simple expression") +} + +// Visit a parse tree produced by CELParser#LogicalNot. +func (p *parser) VisitLogicalNot(ctx *gen.LogicalNotContext) interface{} { + if len(ctx.GetOps())%2 == 0 { + return p.Visit(ctx.Member()) + } + opID := p.helper.id(ctx.GetOps()[0]) + target := p.Visit(ctx.Member()).(*exprpb.Expr) + return p.globalCallOrMacro(opID, operators.LogicalNot, target) +} + +func (p *parser) VisitNegate(ctx *gen.NegateContext) interface{} { + if len(ctx.GetOps())%2 == 0 { + return p.Visit(ctx.Member()) + } + opID := p.helper.id(ctx.GetOps()[0]) + target := p.Visit(ctx.Member()).(*exprpb.Expr) + return p.globalCallOrMacro(opID, operators.Negate, target) +} + +// Visit a parse tree produced by CELParser#SelectOrCall. +func (p *parser) VisitSelectOrCall(ctx *gen.SelectOrCallContext) interface{} { + operand := p.Visit(ctx.Member()).(*exprpb.Expr) + // Handle the error case where no valid identifier is specified. + if ctx.GetId() == nil { + return p.helper.newExpr(ctx) + } + id := ctx.GetId().GetText() + if ctx.GetOpen() != nil { + opID := p.helper.id(ctx.GetOpen()) + return p.receiverCallOrMacro(opID, id, operand, p.visitList(ctx.GetArgs())...) + } + return p.helper.newSelect(ctx.GetOp(), operand, id) +} + +// Visit a parse tree produced by CELParser#PrimaryExpr. +func (p *parser) VisitPrimaryExpr(ctx *gen.PrimaryExprContext) interface{} { + switch ctx.Primary().(type) { + case *gen.NestedContext: + return p.VisitNested(ctx.Primary().(*gen.NestedContext)) + case *gen.IdentOrGlobalCallContext: + return p.VisitIdentOrGlobalCall(ctx.Primary().(*gen.IdentOrGlobalCallContext)) + case *gen.CreateListContext: + return p.VisitCreateList(ctx.Primary().(*gen.CreateListContext)) + case *gen.CreateStructContext: + return p.VisitCreateStruct(ctx.Primary().(*gen.CreateStructContext)) + case *gen.ConstantLiteralContext: + return p.VisitConstantLiteral(ctx.Primary().(*gen.ConstantLiteralContext)) + } + + return p.reportError(ctx, "invalid primary expression") +} + +// Visit a parse tree produced by CELParser#Index. +func (p *parser) VisitIndex(ctx *gen.IndexContext) interface{} { + target := p.Visit(ctx.Member()).(*exprpb.Expr) + opID := p.helper.id(ctx.GetOp()) + index := p.Visit(ctx.GetIndex()).(*exprpb.Expr) + return p.globalCallOrMacro(opID, operators.Index, target, index) +} + +// Visit a parse tree produced by CELParser#CreateMessage. +func (p *parser) VisitCreateMessage(ctx *gen.CreateMessageContext) interface{} { + target := p.Visit(ctx.Member()).(*exprpb.Expr) + objID := p.helper.id(ctx.GetOp()) + if messageName, found := p.extractQualifiedName(target); found { + entries := p.VisitIFieldInitializerList(ctx.GetEntries()).([]*exprpb.Expr_CreateStruct_Entry) + return p.helper.newObject(objID, messageName, entries...) + } + return p.helper.newExpr(objID) +} + +// Visit a parse tree of field initializers. +func (p *parser) VisitIFieldInitializerList(ctx gen.IFieldInitializerListContext) interface{} { + if ctx == nil || ctx.GetFields() == nil { + return []*exprpb.Expr_CreateStruct_Entry{} + } + + result := make([]*exprpb.Expr_CreateStruct_Entry, len(ctx.GetFields())) + for i, f := range ctx.GetFields() { + initID := p.helper.id(ctx.GetCols()[i]) + value := p.Visit(ctx.GetValues()[i]).(*exprpb.Expr) + field := p.helper.newObjectField(initID, f.GetText(), value) + result[i] = field + } + return result +} + +// Visit a parse tree produced by CELParser#IdentOrGlobalCall. +func (p *parser) VisitIdentOrGlobalCall(ctx *gen.IdentOrGlobalCallContext) interface{} { + identName := "" + if ctx.GetLeadingDot() != nil { + identName = "." + } + // Handle the error case where no valid identifier is specified. + if ctx.GetId() == nil { + return p.helper.newExpr(ctx) + } + // Handle reserved identifiers. + id := ctx.GetId().GetText() + for _, r := range reservedIds { + if r == id { + return p.reportError(ctx, "reserved identifier: %s", r) + } + } + identName += id + if ctx.GetOp() != nil { + opID := p.helper.id(ctx.GetOp()) + return p.globalCallOrMacro(opID, identName, p.visitList(ctx.GetArgs())...) + } + return p.helper.newIdent(ctx.GetId(), identName) +} + +// Visit a parse tree produced by CELParser#Nested. +func (p *parser) VisitNested(ctx *gen.NestedContext) interface{} { + return p.Visit(ctx.GetE()) +} + +// Visit a parse tree produced by CELParser#CreateList. +func (p *parser) VisitCreateList(ctx *gen.CreateListContext) interface{} { + listID := p.helper.id(ctx.GetOp()) + return p.helper.newList(listID, p.visitList(ctx.GetElems())...) +} + +// Visit a parse tree produced by CELParser#CreateStruct. +func (p *parser) VisitCreateStruct(ctx *gen.CreateStructContext) interface{} { + structID := p.helper.id(ctx.GetOp()) + entries := []*exprpb.Expr_CreateStruct_Entry{} + if ctx.GetEntries() != nil { + entries = p.Visit(ctx.GetEntries()).([]*exprpb.Expr_CreateStruct_Entry) + } + return p.helper.newMap(structID, entries...) +} + +// Visit a parse tree produced by CELParser#ConstantLiteral. +func (p *parser) VisitConstantLiteral(ctx *gen.ConstantLiteralContext) interface{} { + switch ctx.Literal().(type) { + case *gen.IntContext: + return p.VisitInt(ctx.Literal().(*gen.IntContext)) + case *gen.UintContext: + return p.VisitUint(ctx.Literal().(*gen.UintContext)) + case *gen.DoubleContext: + return p.VisitDouble(ctx.Literal().(*gen.DoubleContext)) + case *gen.StringContext: + return p.VisitString(ctx.Literal().(*gen.StringContext)) + case *gen.BytesContext: + return p.VisitBytes(ctx.Literal().(*gen.BytesContext)) + case *gen.BoolFalseContext: + return p.VisitBoolFalse(ctx.Literal().(*gen.BoolFalseContext)) + case *gen.BoolTrueContext: + return p.VisitBoolTrue(ctx.Literal().(*gen.BoolTrueContext)) + case *gen.NullContext: + return p.VisitNull(ctx.Literal().(*gen.NullContext)) + } + return p.reportError(ctx, "invalid literal") +} + +// Visit a parse tree produced by CELParser#exprList. +func (p *parser) VisitExprList(ctx *gen.ExprListContext) interface{} { + if ctx == nil || ctx.GetE() == nil { + return []*exprpb.Expr{} + } + + result := make([]*exprpb.Expr, len(ctx.GetE())) + for i, e := range ctx.GetE() { + exp := p.Visit(e).(*exprpb.Expr) + result[i] = exp + } + return result +} + +// Visit a parse tree produced by CELParser#mapInitializerList. +func (p *parser) VisitMapInitializerList(ctx *gen.MapInitializerListContext) interface{} { + if ctx == nil || ctx.GetKeys() == nil { + return []*exprpb.Expr_CreateStruct_Entry{} + } + + result := make([]*exprpb.Expr_CreateStruct_Entry, len(ctx.GetCols())) + for i, col := range ctx.GetCols() { + colID := p.helper.id(col) + key := p.Visit(ctx.GetKeys()[i]).(*exprpb.Expr) + value := p.Visit(ctx.GetValues()[i]).(*exprpb.Expr) + entry := p.helper.newMapEntry(colID, key, value) + result[i] = entry + } + return result +} + +// Visit a parse tree produced by CELParser#Int. +func (p *parser) VisitInt(ctx *gen.IntContext) interface{} { + text := ctx.GetTok().GetText() + if ctx.GetSign() != nil { + text = ctx.GetSign().GetText() + text + } + i, err := strconv.ParseInt(text, 10, 64) + if err != nil { + return p.reportError(ctx, "invalid int literal") + } + return p.helper.newLiteralInt(ctx, i) +} + +// Visit a parse tree produced by CELParser#Uint. +func (p *parser) VisitUint(ctx *gen.UintContext) interface{} { + text := ctx.GetTok().GetText() + // trim the 'u' designator included in the uint literal. + text = text[:len(text)-1] + i, err := strconv.ParseUint(text, 10, 64) + if err != nil { + return p.reportError(ctx, "invalid uint literal") + } + return p.helper.newLiteralUint(ctx, i) +} + +// Visit a parse tree produced by CELParser#Double. +func (p *parser) VisitDouble(ctx *gen.DoubleContext) interface{} { + txt := ctx.GetTok().GetText() + if ctx.GetSign() != nil { + txt = ctx.GetSign().GetText() + txt + } + f, err := strconv.ParseFloat(txt, 64) + if err != nil { + return p.reportError(ctx, "invalid double literal") + } + return p.helper.newLiteralDouble(ctx, f) + +} + +// Visit a parse tree produced by CELParser#String. +func (p *parser) VisitString(ctx *gen.StringContext) interface{} { + s := p.unquote(ctx, ctx.GetText(), false) + return p.helper.newLiteralString(ctx, s) +} + +// Visit a parse tree produced by CELParser#Bytes. +func (p *parser) VisitBytes(ctx *gen.BytesContext) interface{} { + b := []byte(p.unquote(ctx, ctx.GetTok().GetText()[1:], true)) + return p.helper.newLiteralBytes(ctx, b) +} + +// Visit a parse tree produced by CELParser#BoolTrue. +func (p *parser) VisitBoolTrue(ctx *gen.BoolTrueContext) interface{} { + return p.helper.newLiteralBool(ctx, true) +} + +// Visit a parse tree produced by CELParser#BoolFalse. +func (p *parser) VisitBoolFalse(ctx *gen.BoolFalseContext) interface{} { + return p.helper.newLiteralBool(ctx, false) +} + +// Visit a parse tree produced by CELParser#Null. +func (p *parser) VisitNull(ctx *gen.NullContext) interface{} { + return p.helper.newLiteral(ctx, + &exprpb.Constant{ + ConstantKind: &exprpb.Constant_NullValue{ + NullValue: structpb.NullValue_NULL_VALUE}}) +} + +func (p *parser) visitList(ctx gen.IExprListContext) []*exprpb.Expr { + if ctx == nil { + return []*exprpb.Expr{} + } + return p.visitSlice(ctx.GetE()) +} + +func (p *parser) visitSlice(expressions []gen.IExprContext) []*exprpb.Expr { + if expressions == nil { + return []*exprpb.Expr{} + } + result := make([]*exprpb.Expr, len(expressions)) + for i, e := range expressions { + ex := p.Visit(e).(*exprpb.Expr) + result[i] = ex + } + return result +} + +func (p *parser) extractQualifiedName(e *exprpb.Expr) (string, bool) { + if e == nil { + return "", false + } + switch e.ExprKind.(type) { + case *exprpb.Expr_IdentExpr: + return e.GetIdentExpr().Name, true + case *exprpb.Expr_SelectExpr: + s := e.GetSelectExpr() + if prefix, found := p.extractQualifiedName(s.Operand); found { + return prefix + "." + s.Field, true + } + } + // TODO: Add a method to Source to get location from character offset. + location := p.helper.getLocation(e.Id) + p.reportError(location, "expected a qualified name") + return "", false +} + +func (p *parser) unquote(ctx interface{}, value string, isBytes bool) string { + text, err := unescape(value, isBytes) + if err != nil { + p.reportError(ctx, "%s", err.Error()) + return value + } + return text +} + +func (p *parser) reportError(ctx interface{}, format string, args ...interface{}) *exprpb.Expr { + var location common.Location + switch ctx.(type) { + case common.Location: + location = ctx.(common.Location) + case antlr.Token, antlr.ParserRuleContext: + err := p.helper.newExpr(ctx) + location = p.helper.getLocation(err.Id) + } + err := p.helper.newExpr(ctx) + // Provide arguments to the report error. + p.errors.ReportError(location, format, args...) + return err +} + +// ANTLR Parse listener implementations +func (p *parser) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) { + // TODO: Snippet + l := common.NewLocation(line, column) + p.errors.syntaxError(l, msg) +} + +func (p *parser) ReportAmbiguity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, exact bool, ambigAlts *antlr.BitSet, configs antlr.ATNConfigSet) { + // Intentional +} + +func (p *parser) ReportAttemptingFullContext(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, conflictingAlts *antlr.BitSet, configs antlr.ATNConfigSet) { + // Intentional +} + +func (p *parser) ReportContextSensitivity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex, prediction int, configs antlr.ATNConfigSet) { + // Intentional +} + +func (p *parser) globalCallOrMacro(exprID int64, function string, args ...*exprpb.Expr) *exprpb.Expr { + if expr, found := p.expandMacro(exprID, function, nil, args...); found { + return expr + } + return p.helper.newGlobalCall(exprID, function, args...) +} + +func (p *parser) receiverCallOrMacro(exprID int64, function string, target *exprpb.Expr, args ...*exprpb.Expr) *exprpb.Expr { + if expr, found := p.expandMacro(exprID, function, target, args...); found { + return expr + } + return p.helper.newReceiverCall(exprID, function, target, args...) +} + +func (p *parser) expandMacro(exprID int64, function string, target *exprpb.Expr, args ...*exprpb.Expr) (*exprpb.Expr, bool) { + macro, found := p.macros[makeMacroKey(function, len(args), target != nil)] + if !found { + macro, found = p.macros[makeVarArgMacroKey(function, target != nil)] + if !found { + return nil, false + } + } + eh := exprHelperPool.Get().(*exprHelper) + defer exprHelperPool.Put(eh) + eh.parserHelper = p.helper + eh.id = exprID + expr, err := macro.Expander()(eh, target, args) + if err != nil { + if err.Location != nil { + return p.reportError(err.Location, err.Message), true + } + return p.reportError(p.helper.getLocation(exprID), err.Message), true + } + return expr, true +} diff --git a/vendor/github.com/google/cel-go/parser/unescape.go b/vendor/github.com/google/cel-go/parser/unescape.go new file mode 100644 index 000000000..27c57a9f3 --- /dev/null +++ b/vendor/github.com/google/cel-go/parser/unescape.go @@ -0,0 +1,237 @@ +// 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 parser + +import ( + "fmt" + "strings" + "unicode/utf8" +) + +// Unescape takes a quoted string, unquotes, and unescapes it. +// +// This function performs escaping compatible with GoogleSQL. +func unescape(value string, isBytes bool) (string, error) { + // All strings normalize newlines to the \n representation. + value = newlineNormalizer.Replace(value) + n := len(value) + + // Nothing to unescape / decode. + if n < 2 { + return value, fmt.Errorf("unable to unescape string") + } + + // Raw string preceded by the 'r|R' prefix. + isRawLiteral := false + if value[0] == 'r' || value[0] == 'R' { + value = value[1:] + n = len(value) + isRawLiteral = true + } + + // Quoted string of some form, must have same first and last char. + if value[0] != value[n-1] || (value[0] != '"' && value[0] != '\'') { + return value, fmt.Errorf("unable to unescape string") + } + + // Normalize the multi-line CEL string representation to a standard + // Go quoted string. + if n >= 6 { + if strings.HasPrefix(value, "'''") { + if !strings.HasSuffix(value, "'''") { + return value, fmt.Errorf("unable to unescape string") + } + value = "\"" + value[3:n-3] + "\"" + } else if strings.HasPrefix(value, `"""`) { + if !strings.HasSuffix(value, `"""`) { + return value, fmt.Errorf("unable to unescape string") + } + value = "\"" + value[3:n-3] + "\"" + } + n = len(value) + } + value = value[1 : n-1] + // If there is nothing to escape, then return. + if isRawLiteral || !strings.ContainsRune(value, '\\') { + return value, nil + } + + // Otherwise the string contains escape characters. + // The following logic is adapted from `strconv/quote.go` + var runeTmp [utf8.UTFMax]byte + buf := make([]byte, 0, 3*n/2) + for len(value) > 0 { + c, encode, rest, err := unescapeChar(value, isBytes) + if err != nil { + return "", err + } + value = rest + if c < utf8.RuneSelf || !encode { + buf = append(buf, byte(c)) + } else { + n := utf8.EncodeRune(runeTmp[:], c) + buf = append(buf, runeTmp[:n]...) + } + } + return string(buf), nil +} + +// unescapeChar takes a string input and returns the following info: +// +// value - the escaped unicode rune at the front of the string. +// encode - the value should be unicode-encoded +// tail - the remainder of the input string. +// err - error value, if the character could not be unescaped. +// +// When encode is true the return value may still fit within a single byte, +// but unicode encoding is attempted which is more expensive than when the +// value is known to self-represent as a single byte. +// +// If isBytes is set, unescape as a bytes literal so octal and hex escapes +// represent byte values, not unicode code points. +func unescapeChar(s string, isBytes bool) (value rune, encode bool, tail string, err error) { + // 1. Character is not an escape sequence. + switch c := s[0]; { + case c >= utf8.RuneSelf: + r, size := utf8.DecodeRuneInString(s) + return r, true, s[size:], nil + case c != '\\': + return rune(s[0]), false, s[1:], nil + } + + // 2. Last character is the start of an escape sequence. + if len(s) <= 1 { + err = fmt.Errorf("unable to unescape string, found '\\' as last character") + return + } + + c := s[1] + s = s[2:] + // 3. Common escape sequences shared with Google SQL + switch c { + case 'a': + value = '\a' + case 'b': + value = '\b' + case 'f': + value = '\f' + case 'n': + value = '\n' + case 'r': + value = '\r' + case 't': + value = '\t' + case 'v': + value = '\v' + case '\\': + value = '\\' + case '\'': + value = '\'' + case '"': + value = '"' + case '`': + value = '`' + case '?': + value = '?' + + // 4. Unicode escape sequences, reproduced from `strconv/quote.go` + case 'x', 'X', 'u', 'U': + n := 0 + encode = true + switch c { + case 'x', 'X': + n = 2 + encode = !isBytes + case 'u': + n = 4 + if isBytes { + err = fmt.Errorf("unable to unescape string") + return + } + case 'U': + n = 8 + if isBytes { + err = fmt.Errorf("unable to unescape string") + return + } + } + var v rune + if len(s) < n { + err = fmt.Errorf("unable to unescape string") + return + } + for j := 0; j < n; j++ { + x, ok := unhex(s[j]) + if !ok { + err = fmt.Errorf("unable to unescape string") + return + } + v = v<<4 | x + } + s = s[n:] + if !isBytes && v > utf8.MaxRune { + err = fmt.Errorf("unable to unescape string") + return + } + value = v + + // 5. Octal escape sequences, must be three digits \[0-3][0-7][0-7] + case '0', '1', '2', '3': + if len(s) < 2 { + err = fmt.Errorf("unable to unescape octal sequence in string") + return + } + v := rune(c - '0') + for j := 0; j < 2; j++ { + x := s[j] + if x < '0' || x > '7' { + err = fmt.Errorf("unable to unescape octal sequence in string") + return + } + v = v*8 + rune(x-'0') + } + if !isBytes && v > utf8.MaxRune { + err = fmt.Errorf("unable to unescape string") + return + } + value = v + s = s[2:] + encode = !isBytes + + // Unknown escape sequence. + default: + err = fmt.Errorf("unable to unescape string") + } + + tail = s + return +} + +func unhex(b byte) (rune, bool) { + c := rune(b) + switch { + case '0' <= c && c <= '9': + return c - '0', true + case 'a' <= c && c <= 'f': + return c - 'a' + 10, true + case 'A' <= c && c <= 'F': + return c - 'A' + 10, true + } + return 0, false +} + +var ( + newlineNormalizer = strings.NewReplacer("\r\n", "\n", "\r", "\n") +) diff --git a/vendor/github.com/google/cel-go/parser/unparser.go b/vendor/github.com/google/cel-go/parser/unparser.go new file mode 100644 index 000000000..47ee899b3 --- /dev/null +++ b/vendor/github.com/google/cel-go/parser/unparser.go @@ -0,0 +1,475 @@ +// Copyright 2019 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 parser + +import ( + "fmt" + "strconv" + "strings" + + "github.com/google/cel-go/common/operators" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// Unparse takes an input expression and source position information and generates a human-readable +// expression. +// +// Note, unparsing an AST will often generate the same expression as was originally parsed, but some +// formatting may be lost in translation, notably: +// +// - All quoted literals are doubled quoted. +// - Byte literals are represented as utf8-string rather than byte, octal, or unicode escapes. +// - Floating point values are converted to the small number of digits needed to represent the value. +// - Spacing around punctuation marks may be lost. +// - Parentheses will only be applied when they affect operator precedence. +func Unparse(expr *exprpb.Expr, info *exprpb.SourceInfo) (string, error) { + un := &unparser{info: info} + err := un.visit(expr) + if err != nil { + return "", err + } + // Test whether newlines need to be applied. + breaks := info.GetLineOffsets() + if len(breaks) <= 1 { + return un.str.String(), nil + } + // Apply the newlines. + txt := []rune(un.str.String()) + sz := int32(len(txt)) + for _, br := range breaks { + for ; br-1 < sz; br++ { + if txt[br-1] == rune(' ') { + txt[br-1] = rune('\n') + break + } + } + } + return string(txt), nil +} + +// unparser visits an expression to reconstruct a human-readable string from an AST. +type unparser struct { + info *exprpb.SourceInfo + str strings.Builder + offset int32 +} + +func (un *unparser) visit(expr *exprpb.Expr) error { + switch expr.ExprKind.(type) { + case *exprpb.Expr_CallExpr: + return un.visitCall(expr) + // TODO: Comprehensions are currently not supported. + case *exprpb.Expr_ComprehensionExpr: + return un.visitComprehension(expr) + case *exprpb.Expr_ConstExpr: + return un.visitConst(expr) + case *exprpb.Expr_IdentExpr: + return un.visitIdent(expr) + case *exprpb.Expr_ListExpr: + return un.visitList(expr) + case *exprpb.Expr_SelectExpr: + return un.visitSelect(expr) + case *exprpb.Expr_StructExpr: + return un.visitStruct(expr) + } + return fmt.Errorf("unsupported expr: %v", expr) +} + +func (un *unparser) visitCall(expr *exprpb.Expr) error { + c := expr.GetCallExpr() + fun := c.GetFunction() + switch fun { + // ternary operator + case operators.Conditional: + return un.visitCallConditional(expr) + // index operator + case operators.Index: + return un.visitCallIndex(expr) + // unary operators + case operators.LogicalNot, operators.Negate: + return un.visitCallUnary(expr) + // binary operators + case operators.Add, + operators.Divide, + operators.Equals, + operators.Greater, + operators.GreaterEquals, + operators.In, + operators.Less, + operators.LessEquals, + operators.LogicalAnd, + operators.LogicalOr, + operators.Modulo, + operators.Multiply, + operators.NotEquals, + operators.OldIn, + operators.Subtract: + return un.visitCallBinary(expr) + // standard function calls. + default: + return un.visitCallFunc(expr) + } +} + +func (un *unparser) visitCallBinary(expr *exprpb.Expr) error { + c := expr.GetCallExpr() + fun := c.GetFunction() + args := c.GetArgs() + lhs := args[0] + // add parens if the current operator is lower precedence than the lhs expr operator. + lhsParen := isComplexOperatorWithRespectTo(fun, lhs) + rhs := args[1] + // add parens if the current operator is lower precedence than the rhs expr operator, + // or the same precedence and the operator is left recursive. + rhsParen := isComplexOperatorWithRespectTo(fun, rhs) + if !rhsParen && isLeftRecursive(fun) { + rhsParen = isSamePrecedence(fun, rhs) + } + err := un.visitMaybeNested(lhs, lhsParen) + if err != nil { + return err + } + unmangled, found := operators.FindReverseBinaryOperator(fun) + if !found { + return fmt.Errorf("cannot unmangle operator: %s", fun) + } + un.str.WriteString(" ") + un.pad(expr.GetId()) + un.str.WriteString(unmangled) + un.str.WriteString(" ") + return un.visitMaybeNested(rhs, rhsParen) +} + +func (un *unparser) visitCallConditional(expr *exprpb.Expr) error { + c := expr.GetCallExpr() + args := c.GetArgs() + // add parens if operand is a conditional itself. + nested := isSamePrecedence(operators.Conditional, args[0]) || + isComplexOperator(args[0]) + err := un.visitMaybeNested(args[0], nested) + if err != nil { + return err + } + un.pad(expr.GetId()) + un.str.WriteString("? ") + // add parens if operand is a conditional itself. + nested = isSamePrecedence(operators.Conditional, args[1]) || + isComplexOperator(args[1]) + err = un.visitMaybeNested(args[1], nested) + if err != nil { + return err + } + un.str.WriteString(" : ") + // add parens if operand is a conditional itself. + nested = isSamePrecedence(operators.Conditional, args[2]) || + isComplexOperator(args[2]) + + return un.visitMaybeNested(args[2], nested) +} + +func (un *unparser) visitCallFunc(expr *exprpb.Expr) error { + c := expr.GetCallExpr() + fun := c.GetFunction() + args := c.GetArgs() + if c.GetTarget() != nil { + nested := isBinaryOrTernaryOperator(c.GetTarget()) + err := un.visitMaybeNested(c.GetTarget(), nested) + if err != nil { + return err + } + un.str.WriteString(".") + } + un.str.WriteString(fun) + un.pad(expr.GetId()) + un.str.WriteString("(") + for i, arg := range args { + err := un.visit(arg) + if err != nil { + return err + } + if i < len(args)-1 { + un.str.WriteString(",") + } + } + un.str.WriteString(")") + return nil +} + +func (un *unparser) visitCallIndex(expr *exprpb.Expr) error { + c := expr.GetCallExpr() + args := c.GetArgs() + nested := isBinaryOrTernaryOperator(args[0]) + err := un.visitMaybeNested(args[0], nested) + if err != nil { + return err + } + un.pad(expr.GetId()) + un.str.WriteString("[") + err = un.visit(args[1]) + if err != nil { + return err + } + un.str.WriteString("]") + return nil +} + +func (un *unparser) visitCallUnary(expr *exprpb.Expr) error { + un.pad(expr.GetId()) + c := expr.GetCallExpr() + fun := c.GetFunction() + args := c.GetArgs() + unmangled, found := operators.FindReverse(fun) + if !found { + return fmt.Errorf("cannot unmangle operator: %s", fun) + } + un.str.WriteString(unmangled) + nested := isComplexOperator(args[0]) + return un.visitMaybeNested(args[0], nested) +} + +func (un *unparser) visitComprehension(expr *exprpb.Expr) error { + // TODO: introduce a macro expansion map between the top-level comprehension id and the + // function call that the macro replaces. + return fmt.Errorf("unimplemented : %v", expr) +} + +func (un *unparser) visitConst(expr *exprpb.Expr) error { + un.pad(expr.GetId()) + c := expr.GetConstExpr() + switch c.ConstantKind.(type) { + case *exprpb.Constant_BoolValue: + un.str.WriteString(strconv.FormatBool(c.GetBoolValue())) + case *exprpb.Constant_BytesValue: + // bytes constants are surrounded with b"" + b := c.GetBytesValue() + un.str.WriteString(`b"`) + un.str.Write(b) + un.str.WriteString(`"`) + case *exprpb.Constant_DoubleValue: + // represent the float using the minimum required digits + d := strconv.FormatFloat(c.GetDoubleValue(), 'g', -1, 64) + un.str.WriteString(d) + case *exprpb.Constant_Int64Value: + i := strconv.FormatInt(c.GetInt64Value(), 10) + un.str.WriteString(i) + case *exprpb.Constant_NullValue: + un.str.WriteString("null") + case *exprpb.Constant_StringValue: + // strings will be double quoted with quotes escaped. + un.str.WriteString(strconv.Quote(c.GetStringValue())) + case *exprpb.Constant_Uint64Value: + // uint literals have a 'u' suffix. + ui := strconv.FormatUint(c.GetUint64Value(), 10) + un.str.WriteString(ui) + un.str.WriteString("u") + default: + return fmt.Errorf("unimplemented : %v", expr) + } + return nil +} + +func (un *unparser) visitIdent(expr *exprpb.Expr) error { + un.pad(expr.GetId()) + un.str.WriteString(expr.GetIdentExpr().GetName()) + return nil +} + +func (un *unparser) visitList(expr *exprpb.Expr) error { + l := expr.GetListExpr() + elems := l.GetElements() + un.pad(expr.GetId()) + un.str.WriteString("[") + for i, elem := range elems { + err := un.visit(elem) + if err != nil { + return err + } + if i < len(elems)-1 { + un.str.WriteString(",") + } + } + un.str.WriteString("]") + return nil +} + +func (un *unparser) visitSelect(expr *exprpb.Expr) error { + sel := expr.GetSelectExpr() + // handle the case when the select expression was generated by the has() macro. + if sel.GetTestOnly() { + un.str.WriteString("has(") + } + nested := !sel.GetTestOnly() && isBinaryOrTernaryOperator(sel.GetOperand()) + err := un.visitMaybeNested(sel.GetOperand(), nested) + if err != nil { + return err + } + un.pad(expr.GetId()) + un.str.WriteString(".") + un.str.WriteString(sel.GetField()) + if sel.GetTestOnly() { + un.str.WriteString(")") + } + return nil +} + +func (un *unparser) visitStruct(expr *exprpb.Expr) error { + s := expr.GetStructExpr() + // If the message name is non-empty, then this should be treated as message construction. + if s.GetMessageName() != "" { + return un.visitStructMsg(expr) + } + // Otherwise, build a map. + return un.visitStructMap(expr) +} + +func (un *unparser) visitStructMsg(expr *exprpb.Expr) error { + m := expr.GetStructExpr() + entries := m.GetEntries() + un.str.WriteString(m.GetMessageName()) + un.pad(expr.GetId()) + un.str.WriteString("{") + for i, entry := range entries { + f := entry.GetFieldKey() + un.str.WriteString(f) + un.pad(entry.GetId()) + un.str.WriteString(": ") + v := entry.GetValue() + err := un.visit(v) + if err != nil { + return err + } + if i < len(entries)-1 { + un.str.WriteString(", ") + } + } + un.str.WriteString("}") + return nil +} + +func (un *unparser) visitStructMap(expr *exprpb.Expr) error { + m := expr.GetStructExpr() + entries := m.GetEntries() + un.pad(expr.GetId()) + un.str.WriteString("{") + for i, entry := range entries { + k := entry.GetMapKey() + err := un.visit(k) + if err != nil { + return err + } + un.pad(entry.GetId()) + un.str.WriteString(": ") + v := entry.GetValue() + err = un.visit(v) + if err != nil { + return err + } + if i < len(entries)-1 { + un.str.WriteString(", ") + } + } + un.str.WriteString("}") + return nil +} + +func (un *unparser) visitMaybeNested(expr *exprpb.Expr, nested bool) error { + if nested { + un.str.WriteString("(") + } + err := un.visit(expr) + if err != nil { + return err + } + if nested { + un.str.WriteString(")") + } + return nil +} + +// pos returns the source character offset of the expression id. +func (un *unparser) pos(id int64) int32 { + return un.info.GetPositions()[id] +} + +// pad potentially adds spaces from the current string builder position to the original position +// of the input expression id. +func (un *unparser) pad(id int64) { + last := int32(un.str.Len()) + next := un.pos(id) + for ; last < next; last++ { + un.str.WriteString(" ") + } +} + +// isLeftRecursive indicates whether the parser resolves the call in a left-recursive manner as +// this can have an effect of how parentheses affect the order of operations in the AST. +func isLeftRecursive(op string) bool { + return op != operators.LogicalAnd && op != operators.LogicalOr +} + +// isSamePrecedence indicates whether the precedence of the input operator is the same as the +// precedence of the (possible) operation represented in the input Expr. +// +// If the expr is not a Call, the result is false. +func isSamePrecedence(op string, expr *exprpb.Expr) bool { + if expr.GetCallExpr() == nil { + return false + } + c := expr.GetCallExpr() + other := c.GetFunction() + return operators.Precedence(op) == operators.Precedence(other) +} + +// isLowerPrecedence indicates whether the precedence of the input operator is lower precedence +// than the (possible) operation represented in the input Expr. +// +// If the expr is not a Call, the result is false. +func isLowerPrecedence(op string, expr *exprpb.Expr) bool { + if expr.GetCallExpr() == nil { + return false + } + c := expr.GetCallExpr() + other := c.GetFunction() + return operators.Precedence(op) < operators.Precedence(other) +} + +// Indicates whether the expr is a complex operator, i.e., a call expression +// with 2 or more arguments. +func isComplexOperator(expr *exprpb.Expr) bool { + if expr.GetCallExpr() != nil || len(expr.GetCallExpr().GetArgs()) >= 2 { + return true + } + return false +} + +// Indicates whether it is a complex operation compared to another. +// expr is *not* considered complex if it is not a call expression or has +// less than two arguments, or if it has a higher precedence than op. +func isComplexOperatorWithRespectTo(op string, expr *exprpb.Expr) bool { + if expr.GetCallExpr() == nil || len(expr.GetCallExpr().GetArgs()) < 2 { + return false + } + return isLowerPrecedence(op, expr) +} + +// Indicate whether this is a binary or ternary operator. +func isBinaryOrTernaryOperator(expr *exprpb.Expr) bool { + if expr.GetCallExpr() == nil || len(expr.GetCallExpr().GetArgs()) < 2 { + return false + } + _, isBinaryOp := operators.FindReverseBinaryOperator(expr.GetCallExpr().GetFunction()) + return isBinaryOp || isSamePrecedence(operators.Conditional, expr) +} diff --git a/vendor/golang.org/x/text/width/gen.go b/vendor/golang.org/x/text/width/gen.go new file mode 100644 index 000000000..092277e1f --- /dev/null +++ b/vendor/golang.org/x/text/width/gen.go @@ -0,0 +1,115 @@ +// Copyright 2015 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. + +// +build ignore + +// This program generates the trie for width operations. The generated table +// includes width category information as well as the normalization mappings. +package main + +import ( + "bytes" + "fmt" + "io" + "log" + "math" + "unicode/utf8" + + "golang.org/x/text/internal/gen" + "golang.org/x/text/internal/triegen" +) + +// See gen_common.go for flags. + +func main() { + gen.Init() + genTables() + genTests() + gen.Repackage("gen_trieval.go", "trieval.go", "width") + gen.Repackage("gen_common.go", "common_test.go", "width") +} + +func genTables() { + t := triegen.NewTrie("width") + // fold and inverse mappings. See mapComment for a description of the format + // of each entry. Add dummy value to make an index of 0 mean no mapping. + inverse := [][4]byte{{}} + mapping := map[[4]byte]int{[4]byte{}: 0} + + getWidthData(func(r rune, tag elem, alt rune) { + idx := 0 + if alt != 0 { + var buf [4]byte + buf[0] = byte(utf8.EncodeRune(buf[1:], alt)) + s := string(r) + buf[buf[0]] ^= s[len(s)-1] + var ok bool + if idx, ok = mapping[buf]; !ok { + idx = len(mapping) + if idx > math.MaxUint8 { + log.Fatalf("Index %d does not fit in a byte.", idx) + } + mapping[buf] = idx + inverse = append(inverse, buf) + } + } + t.Insert(r, uint64(tag|elem(idx))) + }) + + w := &bytes.Buffer{} + gen.WriteUnicodeVersion(w) + + sz, err := t.Gen(w) + if err != nil { + log.Fatal(err) + } + + sz += writeMappings(w, inverse) + + fmt.Fprintf(w, "// Total table size %d bytes (%dKiB)\n", sz, sz/1024) + + gen.WriteVersionedGoFile(*outputFile, "width", w.Bytes()) +} + +const inverseDataComment = ` +// inverseData contains 4-byte entries of the following format: +// <0 padding> +// The last byte of the UTF-8-encoded rune is xor-ed with the last byte of the +// UTF-8 encoding of the original rune. Mappings often have the following +// pattern: +// A -> A (U+FF21 -> U+0041) +// B -> B (U+FF22 -> U+0042) +// ... +// By xor-ing the last byte the same entry can be shared by many mappings. This +// reduces the total number of distinct entries by about two thirds. +// The resulting entry for the aforementioned mappings is +// { 0x01, 0xE0, 0x00, 0x00 } +// Using this entry to map U+FF21 (UTF-8 [EF BC A1]), we get +// E0 ^ A1 = 41. +// Similarly, for U+FF22 (UTF-8 [EF BC A2]), we get +// E0 ^ A2 = 42. +// Note that because of the xor-ing, the byte sequence stored in the entry is +// not valid UTF-8.` + +func writeMappings(w io.Writer, data [][4]byte) int { + fmt.Fprintln(w, inverseDataComment) + fmt.Fprintf(w, "var inverseData = [%d][4]byte{\n", len(data)) + for _, x := range data { + fmt.Fprintf(w, "{ 0x%02x, 0x%02x, 0x%02x, 0x%02x },\n", x[0], x[1], x[2], x[3]) + } + fmt.Fprintln(w, "}") + return len(data) * 4 +} + +func genTests() { + w := &bytes.Buffer{} + fmt.Fprintf(w, "\nvar mapRunes = map[rune]struct{r rune; e elem}{\n") + getWidthData(func(r rune, tag elem, alt rune) { + if alt != 0 { + fmt.Fprintf(w, "\t0x%X: {0x%X, 0x%X},\n", r, alt, tag) + } + }) + fmt.Fprintln(w, "}") + gen.WriteGoFile("runes_test.go", "width", w.Bytes()) +} diff --git a/vendor/golang.org/x/text/width/gen_common.go b/vendor/golang.org/x/text/width/gen_common.go new file mode 100644 index 000000000..601e75268 --- /dev/null +++ b/vendor/golang.org/x/text/width/gen_common.go @@ -0,0 +1,96 @@ +// Copyright 2015 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. + +// +build ignore + +package main + +// This code is shared between the main code generator and the test code. + +import ( + "flag" + "log" + "strconv" + "strings" + + "golang.org/x/text/internal/gen" + "golang.org/x/text/internal/ucd" +) + +var ( + outputFile = flag.String("out", "tables.go", "output file") +) + +var typeMap = map[string]elem{ + "A": tagAmbiguous, + "N": tagNeutral, + "Na": tagNarrow, + "W": tagWide, + "F": tagFullwidth, + "H": tagHalfwidth, +} + +// getWidthData calls f for every entry for which it is defined. +// +// f may be called multiple times for the same rune. The last call to f is the +// correct value. f is not called for all runes. The default tag type is +// Neutral. +func getWidthData(f func(r rune, tag elem, alt rune)) { + // Set the default values for Unified Ideographs. In line with Annex 11, + // we encode full ranges instead of the defined runes in Unified_Ideograph. + for _, b := range []struct{ lo, hi rune }{ + {0x4E00, 0x9FFF}, // the CJK Unified Ideographs block, + {0x3400, 0x4DBF}, // the CJK Unified Ideographs Externsion A block, + {0xF900, 0xFAFF}, // the CJK Compatibility Ideographs block, + {0x20000, 0x2FFFF}, // the Supplementary Ideographic Plane, + {0x30000, 0x3FFFF}, // the Tertiary Ideographic Plane, + } { + for r := b.lo; r <= b.hi; r++ { + f(r, tagWide, 0) + } + } + + inverse := map[rune]rune{} + maps := map[string]bool{ + "": true, + "": true, + } + + // We cannot reuse package norm's decomposition, as we need an unexpanded + // decomposition. We make use of the opportunity to verify that the + // decomposition type is as expected. + ucd.Parse(gen.OpenUCDFile("UnicodeData.txt"), func(p *ucd.Parser) { + r := p.Rune(0) + s := strings.SplitN(p.String(ucd.DecompMapping), " ", 2) + if !maps[s[0]] { + return + } + x, err := strconv.ParseUint(s[1], 16, 32) + if err != nil { + log.Fatalf("Error parsing rune %q", s[1]) + } + if inverse[r] != 0 || inverse[rune(x)] != 0 { + log.Fatalf("Circular dependency in mapping between %U and %U", r, x) + } + inverse[r] = rune(x) + inverse[rune(x)] = r + }) + + // ; + ucd.Parse(gen.OpenUCDFile("EastAsianWidth.txt"), func(p *ucd.Parser) { + tag, ok := typeMap[p.String(1)] + if !ok { + log.Fatalf("Unknown width type %q", p.String(1)) + } + r := p.Rune(0) + alt, ok := inverse[r] + if tag == tagFullwidth || tag == tagHalfwidth && r != wonSign { + tag |= tagNeedsFold + if !ok { + log.Fatalf("Narrow or wide rune %U has no decomposition", r) + } + } + f(r, tag, alt) + }) +} diff --git a/vendor/golang.org/x/text/width/gen_trieval.go b/vendor/golang.org/x/text/width/gen_trieval.go new file mode 100644 index 000000000..c17334aa6 --- /dev/null +++ b/vendor/golang.org/x/text/width/gen_trieval.go @@ -0,0 +1,34 @@ +// Copyright 2015 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. + +// +build ignore + +package main + +// elem is an entry of the width trie. The high byte is used to encode the type +// of the rune. The low byte is used to store the index to a mapping entry in +// the inverseData array. +type elem uint16 + +const ( + tagNeutral elem = iota << typeShift + tagAmbiguous + tagWide + tagNarrow + tagFullwidth + tagHalfwidth +) + +const ( + numTypeBits = 3 + typeShift = 16 - numTypeBits + + // tagNeedsFold is true for all fullwidth and halfwidth runes except for + // the Won sign U+20A9. + tagNeedsFold = 0x1000 + + // The Korean Won sign is halfwidth, but SHOULD NOT be mapped to a wide + // variant. + wonSign rune = 0x20A9 +) diff --git a/vendor/golang.org/x/text/width/kind_string.go b/vendor/golang.org/x/text/width/kind_string.go new file mode 100644 index 000000000..dd3febd43 --- /dev/null +++ b/vendor/golang.org/x/text/width/kind_string.go @@ -0,0 +1,28 @@ +// Code generated by "stringer -type=Kind"; DO NOT EDIT. + +package width + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[Neutral-0] + _ = x[EastAsianAmbiguous-1] + _ = x[EastAsianWide-2] + _ = x[EastAsianNarrow-3] + _ = x[EastAsianFullwidth-4] + _ = x[EastAsianHalfwidth-5] +} + +const _Kind_name = "NeutralEastAsianAmbiguousEastAsianWideEastAsianNarrowEastAsianFullwidthEastAsianHalfwidth" + +var _Kind_index = [...]uint8{0, 7, 25, 38, 53, 71, 89} + +func (i Kind) String() string { + if i < 0 || i >= Kind(len(_Kind_index)-1) { + return "Kind(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _Kind_name[_Kind_index[i]:_Kind_index[i+1]] +} diff --git a/vendor/golang.org/x/text/width/tables10.0.0.go b/vendor/golang.org/x/text/width/tables10.0.0.go new file mode 100644 index 000000000..decb8e480 --- /dev/null +++ b/vendor/golang.org/x/text/width/tables10.0.0.go @@ -0,0 +1,1318 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build go1.10,!go1.13 + +package width + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "10.0.0" + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *widthTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return widthValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = widthIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = widthIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = widthIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *widthTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return widthValues[c0] + } + i := widthIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = widthIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = widthIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *widthTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return widthValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = widthIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = widthIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = widthIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *widthTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return widthValues[c0] + } + i := widthIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = widthIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = widthIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// widthTrie. Total size: 14336 bytes (14.00 KiB). Checksum: c59df54630d3dc4a. +type widthTrie struct{} + +func newWidthTrie(i int) *widthTrie { + return &widthTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *widthTrie) lookupValue(n uint32, b byte) uint16 { + switch { + default: + return uint16(widthValues[n<<6+uint32(b)]) + } +} + +// widthValues: 101 blocks, 6464 entries, 12928 bytes +// The third block is the zero block. +var widthValues = [6464]uint16{ + // Block 0x0, offset 0x0 + 0x20: 0x6001, 0x21: 0x6002, 0x22: 0x6002, 0x23: 0x6002, + 0x24: 0x6002, 0x25: 0x6002, 0x26: 0x6002, 0x27: 0x6002, 0x28: 0x6002, 0x29: 0x6002, + 0x2a: 0x6002, 0x2b: 0x6002, 0x2c: 0x6002, 0x2d: 0x6002, 0x2e: 0x6002, 0x2f: 0x6002, + 0x30: 0x6002, 0x31: 0x6002, 0x32: 0x6002, 0x33: 0x6002, 0x34: 0x6002, 0x35: 0x6002, + 0x36: 0x6002, 0x37: 0x6002, 0x38: 0x6002, 0x39: 0x6002, 0x3a: 0x6002, 0x3b: 0x6002, + 0x3c: 0x6002, 0x3d: 0x6002, 0x3e: 0x6002, 0x3f: 0x6002, + // Block 0x1, offset 0x40 + 0x40: 0x6003, 0x41: 0x6003, 0x42: 0x6003, 0x43: 0x6003, 0x44: 0x6003, 0x45: 0x6003, + 0x46: 0x6003, 0x47: 0x6003, 0x48: 0x6003, 0x49: 0x6003, 0x4a: 0x6003, 0x4b: 0x6003, + 0x4c: 0x6003, 0x4d: 0x6003, 0x4e: 0x6003, 0x4f: 0x6003, 0x50: 0x6003, 0x51: 0x6003, + 0x52: 0x6003, 0x53: 0x6003, 0x54: 0x6003, 0x55: 0x6003, 0x56: 0x6003, 0x57: 0x6003, + 0x58: 0x6003, 0x59: 0x6003, 0x5a: 0x6003, 0x5b: 0x6003, 0x5c: 0x6003, 0x5d: 0x6003, + 0x5e: 0x6003, 0x5f: 0x6003, 0x60: 0x6004, 0x61: 0x6004, 0x62: 0x6004, 0x63: 0x6004, + 0x64: 0x6004, 0x65: 0x6004, 0x66: 0x6004, 0x67: 0x6004, 0x68: 0x6004, 0x69: 0x6004, + 0x6a: 0x6004, 0x6b: 0x6004, 0x6c: 0x6004, 0x6d: 0x6004, 0x6e: 0x6004, 0x6f: 0x6004, + 0x70: 0x6004, 0x71: 0x6004, 0x72: 0x6004, 0x73: 0x6004, 0x74: 0x6004, 0x75: 0x6004, + 0x76: 0x6004, 0x77: 0x6004, 0x78: 0x6004, 0x79: 0x6004, 0x7a: 0x6004, 0x7b: 0x6004, + 0x7c: 0x6004, 0x7d: 0x6004, 0x7e: 0x6004, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xe1: 0x2000, 0xe2: 0x6005, 0xe3: 0x6005, + 0xe4: 0x2000, 0xe5: 0x6006, 0xe6: 0x6005, 0xe7: 0x2000, 0xe8: 0x2000, + 0xea: 0x2000, 0xec: 0x6007, 0xed: 0x2000, 0xee: 0x2000, 0xef: 0x6008, + 0xf0: 0x2000, 0xf1: 0x2000, 0xf2: 0x2000, 0xf3: 0x2000, 0xf4: 0x2000, + 0xf6: 0x2000, 0xf7: 0x2000, 0xf8: 0x2000, 0xf9: 0x2000, 0xfa: 0x2000, + 0xfc: 0x2000, 0xfd: 0x2000, 0xfe: 0x2000, 0xff: 0x2000, + // Block 0x4, offset 0x100 + 0x106: 0x2000, + 0x110: 0x2000, + 0x117: 0x2000, + 0x118: 0x2000, + 0x11e: 0x2000, 0x11f: 0x2000, 0x120: 0x2000, 0x121: 0x2000, + 0x126: 0x2000, 0x128: 0x2000, 0x129: 0x2000, + 0x12a: 0x2000, 0x12c: 0x2000, 0x12d: 0x2000, + 0x130: 0x2000, 0x132: 0x2000, 0x133: 0x2000, + 0x137: 0x2000, 0x138: 0x2000, 0x139: 0x2000, 0x13a: 0x2000, + 0x13c: 0x2000, 0x13e: 0x2000, + // Block 0x5, offset 0x140 + 0x141: 0x2000, + 0x151: 0x2000, + 0x153: 0x2000, + 0x15b: 0x2000, + 0x166: 0x2000, 0x167: 0x2000, + 0x16b: 0x2000, + 0x171: 0x2000, 0x172: 0x2000, 0x173: 0x2000, + 0x178: 0x2000, + 0x17f: 0x2000, + // Block 0x6, offset 0x180 + 0x180: 0x2000, 0x181: 0x2000, 0x182: 0x2000, 0x184: 0x2000, + 0x188: 0x2000, 0x189: 0x2000, 0x18a: 0x2000, 0x18b: 0x2000, + 0x18d: 0x2000, + 0x192: 0x2000, 0x193: 0x2000, + 0x1a6: 0x2000, 0x1a7: 0x2000, + 0x1ab: 0x2000, + // Block 0x7, offset 0x1c0 + 0x1ce: 0x2000, 0x1d0: 0x2000, + 0x1d2: 0x2000, 0x1d4: 0x2000, 0x1d6: 0x2000, + 0x1d8: 0x2000, 0x1da: 0x2000, 0x1dc: 0x2000, + // Block 0x8, offset 0x200 + 0x211: 0x2000, + 0x221: 0x2000, + // Block 0x9, offset 0x240 + 0x244: 0x2000, + 0x247: 0x2000, 0x249: 0x2000, 0x24a: 0x2000, 0x24b: 0x2000, + 0x24d: 0x2000, 0x250: 0x2000, + 0x258: 0x2000, 0x259: 0x2000, 0x25a: 0x2000, 0x25b: 0x2000, 0x25d: 0x2000, + 0x25f: 0x2000, + // Block 0xa, offset 0x280 + 0x280: 0x2000, 0x281: 0x2000, 0x282: 0x2000, 0x283: 0x2000, 0x284: 0x2000, 0x285: 0x2000, + 0x286: 0x2000, 0x287: 0x2000, 0x288: 0x2000, 0x289: 0x2000, 0x28a: 0x2000, 0x28b: 0x2000, + 0x28c: 0x2000, 0x28d: 0x2000, 0x28e: 0x2000, 0x28f: 0x2000, 0x290: 0x2000, 0x291: 0x2000, + 0x292: 0x2000, 0x293: 0x2000, 0x294: 0x2000, 0x295: 0x2000, 0x296: 0x2000, 0x297: 0x2000, + 0x298: 0x2000, 0x299: 0x2000, 0x29a: 0x2000, 0x29b: 0x2000, 0x29c: 0x2000, 0x29d: 0x2000, + 0x29e: 0x2000, 0x29f: 0x2000, 0x2a0: 0x2000, 0x2a1: 0x2000, 0x2a2: 0x2000, 0x2a3: 0x2000, + 0x2a4: 0x2000, 0x2a5: 0x2000, 0x2a6: 0x2000, 0x2a7: 0x2000, 0x2a8: 0x2000, 0x2a9: 0x2000, + 0x2aa: 0x2000, 0x2ab: 0x2000, 0x2ac: 0x2000, 0x2ad: 0x2000, 0x2ae: 0x2000, 0x2af: 0x2000, + 0x2b0: 0x2000, 0x2b1: 0x2000, 0x2b2: 0x2000, 0x2b3: 0x2000, 0x2b4: 0x2000, 0x2b5: 0x2000, + 0x2b6: 0x2000, 0x2b7: 0x2000, 0x2b8: 0x2000, 0x2b9: 0x2000, 0x2ba: 0x2000, 0x2bb: 0x2000, + 0x2bc: 0x2000, 0x2bd: 0x2000, 0x2be: 0x2000, 0x2bf: 0x2000, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x2000, 0x2c1: 0x2000, 0x2c2: 0x2000, 0x2c3: 0x2000, 0x2c4: 0x2000, 0x2c5: 0x2000, + 0x2c6: 0x2000, 0x2c7: 0x2000, 0x2c8: 0x2000, 0x2c9: 0x2000, 0x2ca: 0x2000, 0x2cb: 0x2000, + 0x2cc: 0x2000, 0x2cd: 0x2000, 0x2ce: 0x2000, 0x2cf: 0x2000, 0x2d0: 0x2000, 0x2d1: 0x2000, + 0x2d2: 0x2000, 0x2d3: 0x2000, 0x2d4: 0x2000, 0x2d5: 0x2000, 0x2d6: 0x2000, 0x2d7: 0x2000, + 0x2d8: 0x2000, 0x2d9: 0x2000, 0x2da: 0x2000, 0x2db: 0x2000, 0x2dc: 0x2000, 0x2dd: 0x2000, + 0x2de: 0x2000, 0x2df: 0x2000, 0x2e0: 0x2000, 0x2e1: 0x2000, 0x2e2: 0x2000, 0x2e3: 0x2000, + 0x2e4: 0x2000, 0x2e5: 0x2000, 0x2e6: 0x2000, 0x2e7: 0x2000, 0x2e8: 0x2000, 0x2e9: 0x2000, + 0x2ea: 0x2000, 0x2eb: 0x2000, 0x2ec: 0x2000, 0x2ed: 0x2000, 0x2ee: 0x2000, 0x2ef: 0x2000, + // Block 0xc, offset 0x300 + 0x311: 0x2000, + 0x312: 0x2000, 0x313: 0x2000, 0x314: 0x2000, 0x315: 0x2000, 0x316: 0x2000, 0x317: 0x2000, + 0x318: 0x2000, 0x319: 0x2000, 0x31a: 0x2000, 0x31b: 0x2000, 0x31c: 0x2000, 0x31d: 0x2000, + 0x31e: 0x2000, 0x31f: 0x2000, 0x320: 0x2000, 0x321: 0x2000, 0x323: 0x2000, + 0x324: 0x2000, 0x325: 0x2000, 0x326: 0x2000, 0x327: 0x2000, 0x328: 0x2000, 0x329: 0x2000, + 0x331: 0x2000, 0x332: 0x2000, 0x333: 0x2000, 0x334: 0x2000, 0x335: 0x2000, + 0x336: 0x2000, 0x337: 0x2000, 0x338: 0x2000, 0x339: 0x2000, 0x33a: 0x2000, 0x33b: 0x2000, + 0x33c: 0x2000, 0x33d: 0x2000, 0x33e: 0x2000, 0x33f: 0x2000, + // Block 0xd, offset 0x340 + 0x340: 0x2000, 0x341: 0x2000, 0x343: 0x2000, 0x344: 0x2000, 0x345: 0x2000, + 0x346: 0x2000, 0x347: 0x2000, 0x348: 0x2000, 0x349: 0x2000, + // Block 0xe, offset 0x380 + 0x381: 0x2000, + 0x390: 0x2000, 0x391: 0x2000, + 0x392: 0x2000, 0x393: 0x2000, 0x394: 0x2000, 0x395: 0x2000, 0x396: 0x2000, 0x397: 0x2000, + 0x398: 0x2000, 0x399: 0x2000, 0x39a: 0x2000, 0x39b: 0x2000, 0x39c: 0x2000, 0x39d: 0x2000, + 0x39e: 0x2000, 0x39f: 0x2000, 0x3a0: 0x2000, 0x3a1: 0x2000, 0x3a2: 0x2000, 0x3a3: 0x2000, + 0x3a4: 0x2000, 0x3a5: 0x2000, 0x3a6: 0x2000, 0x3a7: 0x2000, 0x3a8: 0x2000, 0x3a9: 0x2000, + 0x3aa: 0x2000, 0x3ab: 0x2000, 0x3ac: 0x2000, 0x3ad: 0x2000, 0x3ae: 0x2000, 0x3af: 0x2000, + 0x3b0: 0x2000, 0x3b1: 0x2000, 0x3b2: 0x2000, 0x3b3: 0x2000, 0x3b4: 0x2000, 0x3b5: 0x2000, + 0x3b6: 0x2000, 0x3b7: 0x2000, 0x3b8: 0x2000, 0x3b9: 0x2000, 0x3ba: 0x2000, 0x3bb: 0x2000, + 0x3bc: 0x2000, 0x3bd: 0x2000, 0x3be: 0x2000, 0x3bf: 0x2000, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x2000, 0x3c1: 0x2000, 0x3c2: 0x2000, 0x3c3: 0x2000, 0x3c4: 0x2000, 0x3c5: 0x2000, + 0x3c6: 0x2000, 0x3c7: 0x2000, 0x3c8: 0x2000, 0x3c9: 0x2000, 0x3ca: 0x2000, 0x3cb: 0x2000, + 0x3cc: 0x2000, 0x3cd: 0x2000, 0x3ce: 0x2000, 0x3cf: 0x2000, 0x3d1: 0x2000, + // Block 0x10, offset 0x400 + 0x400: 0x4000, 0x401: 0x4000, 0x402: 0x4000, 0x403: 0x4000, 0x404: 0x4000, 0x405: 0x4000, + 0x406: 0x4000, 0x407: 0x4000, 0x408: 0x4000, 0x409: 0x4000, 0x40a: 0x4000, 0x40b: 0x4000, + 0x40c: 0x4000, 0x40d: 0x4000, 0x40e: 0x4000, 0x40f: 0x4000, 0x410: 0x4000, 0x411: 0x4000, + 0x412: 0x4000, 0x413: 0x4000, 0x414: 0x4000, 0x415: 0x4000, 0x416: 0x4000, 0x417: 0x4000, + 0x418: 0x4000, 0x419: 0x4000, 0x41a: 0x4000, 0x41b: 0x4000, 0x41c: 0x4000, 0x41d: 0x4000, + 0x41e: 0x4000, 0x41f: 0x4000, 0x420: 0x4000, 0x421: 0x4000, 0x422: 0x4000, 0x423: 0x4000, + 0x424: 0x4000, 0x425: 0x4000, 0x426: 0x4000, 0x427: 0x4000, 0x428: 0x4000, 0x429: 0x4000, + 0x42a: 0x4000, 0x42b: 0x4000, 0x42c: 0x4000, 0x42d: 0x4000, 0x42e: 0x4000, 0x42f: 0x4000, + 0x430: 0x4000, 0x431: 0x4000, 0x432: 0x4000, 0x433: 0x4000, 0x434: 0x4000, 0x435: 0x4000, + 0x436: 0x4000, 0x437: 0x4000, 0x438: 0x4000, 0x439: 0x4000, 0x43a: 0x4000, 0x43b: 0x4000, + 0x43c: 0x4000, 0x43d: 0x4000, 0x43e: 0x4000, 0x43f: 0x4000, + // Block 0x11, offset 0x440 + 0x440: 0x4000, 0x441: 0x4000, 0x442: 0x4000, 0x443: 0x4000, 0x444: 0x4000, 0x445: 0x4000, + 0x446: 0x4000, 0x447: 0x4000, 0x448: 0x4000, 0x449: 0x4000, 0x44a: 0x4000, 0x44b: 0x4000, + 0x44c: 0x4000, 0x44d: 0x4000, 0x44e: 0x4000, 0x44f: 0x4000, 0x450: 0x4000, 0x451: 0x4000, + 0x452: 0x4000, 0x453: 0x4000, 0x454: 0x4000, 0x455: 0x4000, 0x456: 0x4000, 0x457: 0x4000, + 0x458: 0x4000, 0x459: 0x4000, 0x45a: 0x4000, 0x45b: 0x4000, 0x45c: 0x4000, 0x45d: 0x4000, + 0x45e: 0x4000, 0x45f: 0x4000, + // Block 0x12, offset 0x480 + 0x490: 0x2000, + 0x493: 0x2000, 0x494: 0x2000, 0x495: 0x2000, 0x496: 0x2000, + 0x498: 0x2000, 0x499: 0x2000, 0x49c: 0x2000, 0x49d: 0x2000, + 0x4a0: 0x2000, 0x4a1: 0x2000, 0x4a2: 0x2000, + 0x4a4: 0x2000, 0x4a5: 0x2000, 0x4a6: 0x2000, 0x4a7: 0x2000, + 0x4b0: 0x2000, 0x4b2: 0x2000, 0x4b3: 0x2000, 0x4b5: 0x2000, + 0x4bb: 0x2000, + 0x4be: 0x2000, + // Block 0x13, offset 0x4c0 + 0x4f4: 0x2000, + 0x4ff: 0x2000, + // Block 0x14, offset 0x500 + 0x501: 0x2000, 0x502: 0x2000, 0x503: 0x2000, 0x504: 0x2000, + 0x529: 0xa009, + 0x52c: 0x2000, + // Block 0x15, offset 0x540 + 0x543: 0x2000, 0x545: 0x2000, + 0x549: 0x2000, + 0x553: 0x2000, 0x556: 0x2000, + 0x561: 0x2000, 0x562: 0x2000, + 0x566: 0x2000, + 0x56b: 0x2000, + // Block 0x16, offset 0x580 + 0x593: 0x2000, 0x594: 0x2000, + 0x59b: 0x2000, 0x59c: 0x2000, 0x59d: 0x2000, + 0x59e: 0x2000, 0x5a0: 0x2000, 0x5a1: 0x2000, 0x5a2: 0x2000, 0x5a3: 0x2000, + 0x5a4: 0x2000, 0x5a5: 0x2000, 0x5a6: 0x2000, 0x5a7: 0x2000, 0x5a8: 0x2000, 0x5a9: 0x2000, + 0x5aa: 0x2000, 0x5ab: 0x2000, + 0x5b0: 0x2000, 0x5b1: 0x2000, 0x5b2: 0x2000, 0x5b3: 0x2000, 0x5b4: 0x2000, 0x5b5: 0x2000, + 0x5b6: 0x2000, 0x5b7: 0x2000, 0x5b8: 0x2000, 0x5b9: 0x2000, + // Block 0x17, offset 0x5c0 + 0x5c9: 0x2000, + 0x5d0: 0x200a, 0x5d1: 0x200b, + 0x5d2: 0x200a, 0x5d3: 0x200c, 0x5d4: 0x2000, 0x5d5: 0x2000, 0x5d6: 0x2000, 0x5d7: 0x2000, + 0x5d8: 0x2000, 0x5d9: 0x2000, + 0x5f8: 0x2000, 0x5f9: 0x2000, + // Block 0x18, offset 0x600 + 0x612: 0x2000, 0x614: 0x2000, + 0x627: 0x2000, + // Block 0x19, offset 0x640 + 0x640: 0x2000, 0x642: 0x2000, 0x643: 0x2000, + 0x647: 0x2000, 0x648: 0x2000, 0x64b: 0x2000, + 0x64f: 0x2000, 0x651: 0x2000, + 0x655: 0x2000, + 0x65a: 0x2000, 0x65d: 0x2000, + 0x65e: 0x2000, 0x65f: 0x2000, 0x660: 0x2000, 0x663: 0x2000, + 0x665: 0x2000, 0x667: 0x2000, 0x668: 0x2000, 0x669: 0x2000, + 0x66a: 0x2000, 0x66b: 0x2000, 0x66c: 0x2000, 0x66e: 0x2000, + 0x674: 0x2000, 0x675: 0x2000, + 0x676: 0x2000, 0x677: 0x2000, + 0x67c: 0x2000, 0x67d: 0x2000, + // Block 0x1a, offset 0x680 + 0x688: 0x2000, + 0x68c: 0x2000, + 0x692: 0x2000, + 0x6a0: 0x2000, 0x6a1: 0x2000, + 0x6a4: 0x2000, 0x6a5: 0x2000, 0x6a6: 0x2000, 0x6a7: 0x2000, + 0x6aa: 0x2000, 0x6ab: 0x2000, 0x6ae: 0x2000, 0x6af: 0x2000, + // Block 0x1b, offset 0x6c0 + 0x6c2: 0x2000, 0x6c3: 0x2000, + 0x6c6: 0x2000, 0x6c7: 0x2000, + 0x6d5: 0x2000, + 0x6d9: 0x2000, + 0x6e5: 0x2000, + 0x6ff: 0x2000, + // Block 0x1c, offset 0x700 + 0x712: 0x2000, + 0x71a: 0x4000, 0x71b: 0x4000, + 0x729: 0x4000, + 0x72a: 0x4000, + // Block 0x1d, offset 0x740 + 0x769: 0x4000, + 0x76a: 0x4000, 0x76b: 0x4000, 0x76c: 0x4000, + 0x770: 0x4000, 0x773: 0x4000, + // Block 0x1e, offset 0x780 + 0x7a0: 0x2000, 0x7a1: 0x2000, 0x7a2: 0x2000, 0x7a3: 0x2000, + 0x7a4: 0x2000, 0x7a5: 0x2000, 0x7a6: 0x2000, 0x7a7: 0x2000, 0x7a8: 0x2000, 0x7a9: 0x2000, + 0x7aa: 0x2000, 0x7ab: 0x2000, 0x7ac: 0x2000, 0x7ad: 0x2000, 0x7ae: 0x2000, 0x7af: 0x2000, + 0x7b0: 0x2000, 0x7b1: 0x2000, 0x7b2: 0x2000, 0x7b3: 0x2000, 0x7b4: 0x2000, 0x7b5: 0x2000, + 0x7b6: 0x2000, 0x7b7: 0x2000, 0x7b8: 0x2000, 0x7b9: 0x2000, 0x7ba: 0x2000, 0x7bb: 0x2000, + 0x7bc: 0x2000, 0x7bd: 0x2000, 0x7be: 0x2000, 0x7bf: 0x2000, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x2000, 0x7c1: 0x2000, 0x7c2: 0x2000, 0x7c3: 0x2000, 0x7c4: 0x2000, 0x7c5: 0x2000, + 0x7c6: 0x2000, 0x7c7: 0x2000, 0x7c8: 0x2000, 0x7c9: 0x2000, 0x7ca: 0x2000, 0x7cb: 0x2000, + 0x7cc: 0x2000, 0x7cd: 0x2000, 0x7ce: 0x2000, 0x7cf: 0x2000, 0x7d0: 0x2000, 0x7d1: 0x2000, + 0x7d2: 0x2000, 0x7d3: 0x2000, 0x7d4: 0x2000, 0x7d5: 0x2000, 0x7d6: 0x2000, 0x7d7: 0x2000, + 0x7d8: 0x2000, 0x7d9: 0x2000, 0x7da: 0x2000, 0x7db: 0x2000, 0x7dc: 0x2000, 0x7dd: 0x2000, + 0x7de: 0x2000, 0x7df: 0x2000, 0x7e0: 0x2000, 0x7e1: 0x2000, 0x7e2: 0x2000, 0x7e3: 0x2000, + 0x7e4: 0x2000, 0x7e5: 0x2000, 0x7e6: 0x2000, 0x7e7: 0x2000, 0x7e8: 0x2000, 0x7e9: 0x2000, + 0x7eb: 0x2000, 0x7ec: 0x2000, 0x7ed: 0x2000, 0x7ee: 0x2000, 0x7ef: 0x2000, + 0x7f0: 0x2000, 0x7f1: 0x2000, 0x7f2: 0x2000, 0x7f3: 0x2000, 0x7f4: 0x2000, 0x7f5: 0x2000, + 0x7f6: 0x2000, 0x7f7: 0x2000, 0x7f8: 0x2000, 0x7f9: 0x2000, 0x7fa: 0x2000, 0x7fb: 0x2000, + 0x7fc: 0x2000, 0x7fd: 0x2000, 0x7fe: 0x2000, 0x7ff: 0x2000, + // Block 0x20, offset 0x800 + 0x800: 0x2000, 0x801: 0x2000, 0x802: 0x200d, 0x803: 0x2000, 0x804: 0x2000, 0x805: 0x2000, + 0x806: 0x2000, 0x807: 0x2000, 0x808: 0x2000, 0x809: 0x2000, 0x80a: 0x2000, 0x80b: 0x2000, + 0x80c: 0x2000, 0x80d: 0x2000, 0x80e: 0x2000, 0x80f: 0x2000, 0x810: 0x2000, 0x811: 0x2000, + 0x812: 0x2000, 0x813: 0x2000, 0x814: 0x2000, 0x815: 0x2000, 0x816: 0x2000, 0x817: 0x2000, + 0x818: 0x2000, 0x819: 0x2000, 0x81a: 0x2000, 0x81b: 0x2000, 0x81c: 0x2000, 0x81d: 0x2000, + 0x81e: 0x2000, 0x81f: 0x2000, 0x820: 0x2000, 0x821: 0x2000, 0x822: 0x2000, 0x823: 0x2000, + 0x824: 0x2000, 0x825: 0x2000, 0x826: 0x2000, 0x827: 0x2000, 0x828: 0x2000, 0x829: 0x2000, + 0x82a: 0x2000, 0x82b: 0x2000, 0x82c: 0x2000, 0x82d: 0x2000, 0x82e: 0x2000, 0x82f: 0x2000, + 0x830: 0x2000, 0x831: 0x2000, 0x832: 0x2000, 0x833: 0x2000, 0x834: 0x2000, 0x835: 0x2000, + 0x836: 0x2000, 0x837: 0x2000, 0x838: 0x2000, 0x839: 0x2000, 0x83a: 0x2000, 0x83b: 0x2000, + 0x83c: 0x2000, 0x83d: 0x2000, 0x83e: 0x2000, 0x83f: 0x2000, + // Block 0x21, offset 0x840 + 0x840: 0x2000, 0x841: 0x2000, 0x842: 0x2000, 0x843: 0x2000, 0x844: 0x2000, 0x845: 0x2000, + 0x846: 0x2000, 0x847: 0x2000, 0x848: 0x2000, 0x849: 0x2000, 0x84a: 0x2000, 0x84b: 0x2000, + 0x850: 0x2000, 0x851: 0x2000, + 0x852: 0x2000, 0x853: 0x2000, 0x854: 0x2000, 0x855: 0x2000, 0x856: 0x2000, 0x857: 0x2000, + 0x858: 0x2000, 0x859: 0x2000, 0x85a: 0x2000, 0x85b: 0x2000, 0x85c: 0x2000, 0x85d: 0x2000, + 0x85e: 0x2000, 0x85f: 0x2000, 0x860: 0x2000, 0x861: 0x2000, 0x862: 0x2000, 0x863: 0x2000, + 0x864: 0x2000, 0x865: 0x2000, 0x866: 0x2000, 0x867: 0x2000, 0x868: 0x2000, 0x869: 0x2000, + 0x86a: 0x2000, 0x86b: 0x2000, 0x86c: 0x2000, 0x86d: 0x2000, 0x86e: 0x2000, 0x86f: 0x2000, + 0x870: 0x2000, 0x871: 0x2000, 0x872: 0x2000, 0x873: 0x2000, + // Block 0x22, offset 0x880 + 0x880: 0x2000, 0x881: 0x2000, 0x882: 0x2000, 0x883: 0x2000, 0x884: 0x2000, 0x885: 0x2000, + 0x886: 0x2000, 0x887: 0x2000, 0x888: 0x2000, 0x889: 0x2000, 0x88a: 0x2000, 0x88b: 0x2000, + 0x88c: 0x2000, 0x88d: 0x2000, 0x88e: 0x2000, 0x88f: 0x2000, + 0x892: 0x2000, 0x893: 0x2000, 0x894: 0x2000, 0x895: 0x2000, + 0x8a0: 0x200e, 0x8a1: 0x2000, 0x8a3: 0x2000, + 0x8a4: 0x2000, 0x8a5: 0x2000, 0x8a6: 0x2000, 0x8a7: 0x2000, 0x8a8: 0x2000, 0x8a9: 0x2000, + 0x8b2: 0x2000, 0x8b3: 0x2000, + 0x8b6: 0x2000, 0x8b7: 0x2000, + 0x8bc: 0x2000, 0x8bd: 0x2000, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x2000, 0x8c1: 0x2000, + 0x8c6: 0x2000, 0x8c7: 0x2000, 0x8c8: 0x2000, 0x8cb: 0x200f, + 0x8ce: 0x2000, 0x8cf: 0x2000, 0x8d0: 0x2000, 0x8d1: 0x2000, + 0x8e2: 0x2000, 0x8e3: 0x2000, + 0x8e4: 0x2000, 0x8e5: 0x2000, + 0x8ef: 0x2000, + 0x8fd: 0x4000, 0x8fe: 0x4000, + // Block 0x24, offset 0x900 + 0x905: 0x2000, + 0x906: 0x2000, 0x909: 0x2000, + 0x90e: 0x2000, 0x90f: 0x2000, + 0x914: 0x4000, 0x915: 0x4000, + 0x91c: 0x2000, + 0x91e: 0x2000, + // Block 0x25, offset 0x940 + 0x940: 0x2000, 0x942: 0x2000, + 0x948: 0x4000, 0x949: 0x4000, 0x94a: 0x4000, 0x94b: 0x4000, + 0x94c: 0x4000, 0x94d: 0x4000, 0x94e: 0x4000, 0x94f: 0x4000, 0x950: 0x4000, 0x951: 0x4000, + 0x952: 0x4000, 0x953: 0x4000, + 0x960: 0x2000, 0x961: 0x2000, 0x963: 0x2000, + 0x964: 0x2000, 0x965: 0x2000, 0x967: 0x2000, 0x968: 0x2000, 0x969: 0x2000, + 0x96a: 0x2000, 0x96c: 0x2000, 0x96d: 0x2000, 0x96f: 0x2000, + 0x97f: 0x4000, + // Block 0x26, offset 0x980 + 0x993: 0x4000, + 0x99e: 0x2000, 0x99f: 0x2000, 0x9a1: 0x4000, + 0x9aa: 0x4000, 0x9ab: 0x4000, + 0x9bd: 0x4000, 0x9be: 0x4000, 0x9bf: 0x2000, + // Block 0x27, offset 0x9c0 + 0x9c4: 0x4000, 0x9c5: 0x4000, + 0x9c6: 0x2000, 0x9c7: 0x2000, 0x9c8: 0x2000, 0x9c9: 0x2000, 0x9ca: 0x2000, 0x9cb: 0x2000, + 0x9cc: 0x2000, 0x9cd: 0x2000, 0x9ce: 0x4000, 0x9cf: 0x2000, 0x9d0: 0x2000, 0x9d1: 0x2000, + 0x9d2: 0x2000, 0x9d3: 0x2000, 0x9d4: 0x4000, 0x9d5: 0x2000, 0x9d6: 0x2000, 0x9d7: 0x2000, + 0x9d8: 0x2000, 0x9d9: 0x2000, 0x9da: 0x2000, 0x9db: 0x2000, 0x9dc: 0x2000, 0x9dd: 0x2000, + 0x9de: 0x2000, 0x9df: 0x2000, 0x9e0: 0x2000, 0x9e1: 0x2000, 0x9e3: 0x2000, + 0x9e8: 0x2000, 0x9e9: 0x2000, + 0x9ea: 0x4000, 0x9eb: 0x2000, 0x9ec: 0x2000, 0x9ed: 0x2000, 0x9ee: 0x2000, 0x9ef: 0x2000, + 0x9f0: 0x2000, 0x9f1: 0x2000, 0x9f2: 0x4000, 0x9f3: 0x4000, 0x9f4: 0x2000, 0x9f5: 0x4000, + 0x9f6: 0x2000, 0x9f7: 0x2000, 0x9f8: 0x2000, 0x9f9: 0x2000, 0x9fa: 0x4000, 0x9fb: 0x2000, + 0x9fc: 0x2000, 0x9fd: 0x4000, 0x9fe: 0x2000, 0x9ff: 0x2000, + // Block 0x28, offset 0xa00 + 0xa05: 0x4000, + 0xa0a: 0x4000, 0xa0b: 0x4000, + 0xa28: 0x4000, + 0xa3d: 0x2000, + // Block 0x29, offset 0xa40 + 0xa4c: 0x4000, 0xa4e: 0x4000, + 0xa53: 0x4000, 0xa54: 0x4000, 0xa55: 0x4000, 0xa57: 0x4000, + 0xa76: 0x2000, 0xa77: 0x2000, 0xa78: 0x2000, 0xa79: 0x2000, 0xa7a: 0x2000, 0xa7b: 0x2000, + 0xa7c: 0x2000, 0xa7d: 0x2000, 0xa7e: 0x2000, 0xa7f: 0x2000, + // Block 0x2a, offset 0xa80 + 0xa95: 0x4000, 0xa96: 0x4000, 0xa97: 0x4000, + 0xab0: 0x4000, + 0xabf: 0x4000, + // Block 0x2b, offset 0xac0 + 0xae6: 0x6000, 0xae7: 0x6000, 0xae8: 0x6000, 0xae9: 0x6000, + 0xaea: 0x6000, 0xaeb: 0x6000, 0xaec: 0x6000, 0xaed: 0x6000, + // Block 0x2c, offset 0xb00 + 0xb05: 0x6010, + 0xb06: 0x6011, + // Block 0x2d, offset 0xb40 + 0xb5b: 0x4000, 0xb5c: 0x4000, + // Block 0x2e, offset 0xb80 + 0xb90: 0x4000, + 0xb95: 0x4000, 0xb96: 0x2000, 0xb97: 0x2000, + 0xb98: 0x2000, 0xb99: 0x2000, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x4000, 0xbc1: 0x4000, 0xbc2: 0x4000, 0xbc3: 0x4000, 0xbc4: 0x4000, 0xbc5: 0x4000, + 0xbc6: 0x4000, 0xbc7: 0x4000, 0xbc8: 0x4000, 0xbc9: 0x4000, 0xbca: 0x4000, 0xbcb: 0x4000, + 0xbcc: 0x4000, 0xbcd: 0x4000, 0xbce: 0x4000, 0xbcf: 0x4000, 0xbd0: 0x4000, 0xbd1: 0x4000, + 0xbd2: 0x4000, 0xbd3: 0x4000, 0xbd4: 0x4000, 0xbd5: 0x4000, 0xbd6: 0x4000, 0xbd7: 0x4000, + 0xbd8: 0x4000, 0xbd9: 0x4000, 0xbdb: 0x4000, 0xbdc: 0x4000, 0xbdd: 0x4000, + 0xbde: 0x4000, 0xbdf: 0x4000, 0xbe0: 0x4000, 0xbe1: 0x4000, 0xbe2: 0x4000, 0xbe3: 0x4000, + 0xbe4: 0x4000, 0xbe5: 0x4000, 0xbe6: 0x4000, 0xbe7: 0x4000, 0xbe8: 0x4000, 0xbe9: 0x4000, + 0xbea: 0x4000, 0xbeb: 0x4000, 0xbec: 0x4000, 0xbed: 0x4000, 0xbee: 0x4000, 0xbef: 0x4000, + 0xbf0: 0x4000, 0xbf1: 0x4000, 0xbf2: 0x4000, 0xbf3: 0x4000, 0xbf4: 0x4000, 0xbf5: 0x4000, + 0xbf6: 0x4000, 0xbf7: 0x4000, 0xbf8: 0x4000, 0xbf9: 0x4000, 0xbfa: 0x4000, 0xbfb: 0x4000, + 0xbfc: 0x4000, 0xbfd: 0x4000, 0xbfe: 0x4000, 0xbff: 0x4000, + // Block 0x30, offset 0xc00 + 0xc00: 0x4000, 0xc01: 0x4000, 0xc02: 0x4000, 0xc03: 0x4000, 0xc04: 0x4000, 0xc05: 0x4000, + 0xc06: 0x4000, 0xc07: 0x4000, 0xc08: 0x4000, 0xc09: 0x4000, 0xc0a: 0x4000, 0xc0b: 0x4000, + 0xc0c: 0x4000, 0xc0d: 0x4000, 0xc0e: 0x4000, 0xc0f: 0x4000, 0xc10: 0x4000, 0xc11: 0x4000, + 0xc12: 0x4000, 0xc13: 0x4000, 0xc14: 0x4000, 0xc15: 0x4000, 0xc16: 0x4000, 0xc17: 0x4000, + 0xc18: 0x4000, 0xc19: 0x4000, 0xc1a: 0x4000, 0xc1b: 0x4000, 0xc1c: 0x4000, 0xc1d: 0x4000, + 0xc1e: 0x4000, 0xc1f: 0x4000, 0xc20: 0x4000, 0xc21: 0x4000, 0xc22: 0x4000, 0xc23: 0x4000, + 0xc24: 0x4000, 0xc25: 0x4000, 0xc26: 0x4000, 0xc27: 0x4000, 0xc28: 0x4000, 0xc29: 0x4000, + 0xc2a: 0x4000, 0xc2b: 0x4000, 0xc2c: 0x4000, 0xc2d: 0x4000, 0xc2e: 0x4000, 0xc2f: 0x4000, + 0xc30: 0x4000, 0xc31: 0x4000, 0xc32: 0x4000, 0xc33: 0x4000, + // Block 0x31, offset 0xc40 + 0xc40: 0x4000, 0xc41: 0x4000, 0xc42: 0x4000, 0xc43: 0x4000, 0xc44: 0x4000, 0xc45: 0x4000, + 0xc46: 0x4000, 0xc47: 0x4000, 0xc48: 0x4000, 0xc49: 0x4000, 0xc4a: 0x4000, 0xc4b: 0x4000, + 0xc4c: 0x4000, 0xc4d: 0x4000, 0xc4e: 0x4000, 0xc4f: 0x4000, 0xc50: 0x4000, 0xc51: 0x4000, + 0xc52: 0x4000, 0xc53: 0x4000, 0xc54: 0x4000, 0xc55: 0x4000, + 0xc70: 0x4000, 0xc71: 0x4000, 0xc72: 0x4000, 0xc73: 0x4000, 0xc74: 0x4000, 0xc75: 0x4000, + 0xc76: 0x4000, 0xc77: 0x4000, 0xc78: 0x4000, 0xc79: 0x4000, 0xc7a: 0x4000, 0xc7b: 0x4000, + // Block 0x32, offset 0xc80 + 0xc80: 0x9012, 0xc81: 0x4013, 0xc82: 0x4014, 0xc83: 0x4000, 0xc84: 0x4000, 0xc85: 0x4000, + 0xc86: 0x4000, 0xc87: 0x4000, 0xc88: 0x4000, 0xc89: 0x4000, 0xc8a: 0x4000, 0xc8b: 0x4000, + 0xc8c: 0x4015, 0xc8d: 0x4015, 0xc8e: 0x4000, 0xc8f: 0x4000, 0xc90: 0x4000, 0xc91: 0x4000, + 0xc92: 0x4000, 0xc93: 0x4000, 0xc94: 0x4000, 0xc95: 0x4000, 0xc96: 0x4000, 0xc97: 0x4000, + 0xc98: 0x4000, 0xc99: 0x4000, 0xc9a: 0x4000, 0xc9b: 0x4000, 0xc9c: 0x4000, 0xc9d: 0x4000, + 0xc9e: 0x4000, 0xc9f: 0x4000, 0xca0: 0x4000, 0xca1: 0x4000, 0xca2: 0x4000, 0xca3: 0x4000, + 0xca4: 0x4000, 0xca5: 0x4000, 0xca6: 0x4000, 0xca7: 0x4000, 0xca8: 0x4000, 0xca9: 0x4000, + 0xcaa: 0x4000, 0xcab: 0x4000, 0xcac: 0x4000, 0xcad: 0x4000, 0xcae: 0x4000, 0xcaf: 0x4000, + 0xcb0: 0x4000, 0xcb1: 0x4000, 0xcb2: 0x4000, 0xcb3: 0x4000, 0xcb4: 0x4000, 0xcb5: 0x4000, + 0xcb6: 0x4000, 0xcb7: 0x4000, 0xcb8: 0x4000, 0xcb9: 0x4000, 0xcba: 0x4000, 0xcbb: 0x4000, + 0xcbc: 0x4000, 0xcbd: 0x4000, 0xcbe: 0x4000, + // Block 0x33, offset 0xcc0 + 0xcc1: 0x4000, 0xcc2: 0x4000, 0xcc3: 0x4000, 0xcc4: 0x4000, 0xcc5: 0x4000, + 0xcc6: 0x4000, 0xcc7: 0x4000, 0xcc8: 0x4000, 0xcc9: 0x4000, 0xcca: 0x4000, 0xccb: 0x4000, + 0xccc: 0x4000, 0xccd: 0x4000, 0xcce: 0x4000, 0xccf: 0x4000, 0xcd0: 0x4000, 0xcd1: 0x4000, + 0xcd2: 0x4000, 0xcd3: 0x4000, 0xcd4: 0x4000, 0xcd5: 0x4000, 0xcd6: 0x4000, 0xcd7: 0x4000, + 0xcd8: 0x4000, 0xcd9: 0x4000, 0xcda: 0x4000, 0xcdb: 0x4000, 0xcdc: 0x4000, 0xcdd: 0x4000, + 0xcde: 0x4000, 0xcdf: 0x4000, 0xce0: 0x4000, 0xce1: 0x4000, 0xce2: 0x4000, 0xce3: 0x4000, + 0xce4: 0x4000, 0xce5: 0x4000, 0xce6: 0x4000, 0xce7: 0x4000, 0xce8: 0x4000, 0xce9: 0x4000, + 0xcea: 0x4000, 0xceb: 0x4000, 0xcec: 0x4000, 0xced: 0x4000, 0xcee: 0x4000, 0xcef: 0x4000, + 0xcf0: 0x4000, 0xcf1: 0x4000, 0xcf2: 0x4000, 0xcf3: 0x4000, 0xcf4: 0x4000, 0xcf5: 0x4000, + 0xcf6: 0x4000, 0xcf7: 0x4000, 0xcf8: 0x4000, 0xcf9: 0x4000, 0xcfa: 0x4000, 0xcfb: 0x4000, + 0xcfc: 0x4000, 0xcfd: 0x4000, 0xcfe: 0x4000, 0xcff: 0x4000, + // Block 0x34, offset 0xd00 + 0xd00: 0x4000, 0xd01: 0x4000, 0xd02: 0x4000, 0xd03: 0x4000, 0xd04: 0x4000, 0xd05: 0x4000, + 0xd06: 0x4000, 0xd07: 0x4000, 0xd08: 0x4000, 0xd09: 0x4000, 0xd0a: 0x4000, 0xd0b: 0x4000, + 0xd0c: 0x4000, 0xd0d: 0x4000, 0xd0e: 0x4000, 0xd0f: 0x4000, 0xd10: 0x4000, 0xd11: 0x4000, + 0xd12: 0x4000, 0xd13: 0x4000, 0xd14: 0x4000, 0xd15: 0x4000, 0xd16: 0x4000, + 0xd19: 0x4016, 0xd1a: 0x4017, 0xd1b: 0x4000, 0xd1c: 0x4000, 0xd1d: 0x4000, + 0xd1e: 0x4000, 0xd1f: 0x4000, 0xd20: 0x4000, 0xd21: 0x4018, 0xd22: 0x4019, 0xd23: 0x401a, + 0xd24: 0x401b, 0xd25: 0x401c, 0xd26: 0x401d, 0xd27: 0x401e, 0xd28: 0x401f, 0xd29: 0x4020, + 0xd2a: 0x4021, 0xd2b: 0x4022, 0xd2c: 0x4000, 0xd2d: 0x4010, 0xd2e: 0x4000, 0xd2f: 0x4023, + 0xd30: 0x4000, 0xd31: 0x4024, 0xd32: 0x4000, 0xd33: 0x4025, 0xd34: 0x4000, 0xd35: 0x4026, + 0xd36: 0x4000, 0xd37: 0x401a, 0xd38: 0x4000, 0xd39: 0x4027, 0xd3a: 0x4000, 0xd3b: 0x4028, + 0xd3c: 0x4000, 0xd3d: 0x4020, 0xd3e: 0x4000, 0xd3f: 0x4029, + // Block 0x35, offset 0xd40 + 0xd40: 0x4000, 0xd41: 0x402a, 0xd42: 0x4000, 0xd43: 0x402b, 0xd44: 0x402c, 0xd45: 0x4000, + 0xd46: 0x4017, 0xd47: 0x4000, 0xd48: 0x402d, 0xd49: 0x4000, 0xd4a: 0x402e, 0xd4b: 0x402f, + 0xd4c: 0x4030, 0xd4d: 0x4017, 0xd4e: 0x4016, 0xd4f: 0x4017, 0xd50: 0x4000, 0xd51: 0x4000, + 0xd52: 0x4031, 0xd53: 0x4000, 0xd54: 0x4000, 0xd55: 0x4031, 0xd56: 0x4000, 0xd57: 0x4000, + 0xd58: 0x4032, 0xd59: 0x4000, 0xd5a: 0x4000, 0xd5b: 0x4032, 0xd5c: 0x4000, 0xd5d: 0x4000, + 0xd5e: 0x4033, 0xd5f: 0x402e, 0xd60: 0x4034, 0xd61: 0x4035, 0xd62: 0x4034, 0xd63: 0x4036, + 0xd64: 0x4037, 0xd65: 0x4024, 0xd66: 0x4035, 0xd67: 0x4025, 0xd68: 0x4038, 0xd69: 0x4038, + 0xd6a: 0x4039, 0xd6b: 0x4039, 0xd6c: 0x403a, 0xd6d: 0x403a, 0xd6e: 0x4000, 0xd6f: 0x4035, + 0xd70: 0x4000, 0xd71: 0x4000, 0xd72: 0x403b, 0xd73: 0x403c, 0xd74: 0x4000, 0xd75: 0x4000, + 0xd76: 0x4000, 0xd77: 0x4000, 0xd78: 0x4000, 0xd79: 0x4000, 0xd7a: 0x4000, 0xd7b: 0x403d, + 0xd7c: 0x401c, 0xd7d: 0x4000, 0xd7e: 0x4000, 0xd7f: 0x4000, + // Block 0x36, offset 0xd80 + 0xd85: 0x4000, + 0xd86: 0x4000, 0xd87: 0x4000, 0xd88: 0x4000, 0xd89: 0x4000, 0xd8a: 0x4000, 0xd8b: 0x4000, + 0xd8c: 0x4000, 0xd8d: 0x4000, 0xd8e: 0x4000, 0xd8f: 0x4000, 0xd90: 0x4000, 0xd91: 0x4000, + 0xd92: 0x4000, 0xd93: 0x4000, 0xd94: 0x4000, 0xd95: 0x4000, 0xd96: 0x4000, 0xd97: 0x4000, + 0xd98: 0x4000, 0xd99: 0x4000, 0xd9a: 0x4000, 0xd9b: 0x4000, 0xd9c: 0x4000, 0xd9d: 0x4000, + 0xd9e: 0x4000, 0xd9f: 0x4000, 0xda0: 0x4000, 0xda1: 0x4000, 0xda2: 0x4000, 0xda3: 0x4000, + 0xda4: 0x4000, 0xda5: 0x4000, 0xda6: 0x4000, 0xda7: 0x4000, 0xda8: 0x4000, 0xda9: 0x4000, + 0xdaa: 0x4000, 0xdab: 0x4000, 0xdac: 0x4000, 0xdad: 0x4000, 0xdae: 0x4000, + 0xdb1: 0x403e, 0xdb2: 0x403e, 0xdb3: 0x403e, 0xdb4: 0x403e, 0xdb5: 0x403e, + 0xdb6: 0x403e, 0xdb7: 0x403e, 0xdb8: 0x403e, 0xdb9: 0x403e, 0xdba: 0x403e, 0xdbb: 0x403e, + 0xdbc: 0x403e, 0xdbd: 0x403e, 0xdbe: 0x403e, 0xdbf: 0x403e, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x4037, 0xdc1: 0x4037, 0xdc2: 0x4037, 0xdc3: 0x4037, 0xdc4: 0x4037, 0xdc5: 0x4037, + 0xdc6: 0x4037, 0xdc7: 0x4037, 0xdc8: 0x4037, 0xdc9: 0x4037, 0xdca: 0x4037, 0xdcb: 0x4037, + 0xdcc: 0x4037, 0xdcd: 0x4037, 0xdce: 0x4037, 0xdcf: 0x400e, 0xdd0: 0x403f, 0xdd1: 0x4040, + 0xdd2: 0x4041, 0xdd3: 0x4040, 0xdd4: 0x403f, 0xdd5: 0x4042, 0xdd6: 0x4043, 0xdd7: 0x4044, + 0xdd8: 0x4040, 0xdd9: 0x4041, 0xdda: 0x4040, 0xddb: 0x4045, 0xddc: 0x4009, 0xddd: 0x4045, + 0xdde: 0x4046, 0xddf: 0x4045, 0xde0: 0x4047, 0xde1: 0x400b, 0xde2: 0x400a, 0xde3: 0x400c, + 0xde4: 0x4048, 0xde5: 0x4000, 0xde6: 0x4000, 0xde7: 0x4000, 0xde8: 0x4000, 0xde9: 0x4000, + 0xdea: 0x4000, 0xdeb: 0x4000, 0xdec: 0x4000, 0xded: 0x4000, 0xdee: 0x4000, 0xdef: 0x4000, + 0xdf0: 0x4000, 0xdf1: 0x4000, 0xdf2: 0x4000, 0xdf3: 0x4000, 0xdf4: 0x4000, 0xdf5: 0x4000, + 0xdf6: 0x4000, 0xdf7: 0x4000, 0xdf8: 0x4000, 0xdf9: 0x4000, 0xdfa: 0x4000, 0xdfb: 0x4000, + 0xdfc: 0x4000, 0xdfd: 0x4000, 0xdfe: 0x4000, 0xdff: 0x4000, + // Block 0x38, offset 0xe00 + 0xe00: 0x4000, 0xe01: 0x4000, 0xe02: 0x4000, 0xe03: 0x4000, 0xe04: 0x4000, 0xe05: 0x4000, + 0xe06: 0x4000, 0xe07: 0x4000, 0xe08: 0x4000, 0xe09: 0x4000, 0xe0a: 0x4000, 0xe0b: 0x4000, + 0xe0c: 0x4000, 0xe0d: 0x4000, 0xe0e: 0x4000, 0xe10: 0x4000, 0xe11: 0x4000, + 0xe12: 0x4000, 0xe13: 0x4000, 0xe14: 0x4000, 0xe15: 0x4000, 0xe16: 0x4000, 0xe17: 0x4000, + 0xe18: 0x4000, 0xe19: 0x4000, 0xe1a: 0x4000, 0xe1b: 0x4000, 0xe1c: 0x4000, 0xe1d: 0x4000, + 0xe1e: 0x4000, 0xe1f: 0x4000, 0xe20: 0x4000, 0xe21: 0x4000, 0xe22: 0x4000, 0xe23: 0x4000, + 0xe24: 0x4000, 0xe25: 0x4000, 0xe26: 0x4000, 0xe27: 0x4000, 0xe28: 0x4000, 0xe29: 0x4000, + 0xe2a: 0x4000, 0xe2b: 0x4000, 0xe2c: 0x4000, 0xe2d: 0x4000, 0xe2e: 0x4000, 0xe2f: 0x4000, + 0xe30: 0x4000, 0xe31: 0x4000, 0xe32: 0x4000, 0xe33: 0x4000, 0xe34: 0x4000, 0xe35: 0x4000, + 0xe36: 0x4000, 0xe37: 0x4000, 0xe38: 0x4000, 0xe39: 0x4000, 0xe3a: 0x4000, + // Block 0x39, offset 0xe40 + 0xe40: 0x4000, 0xe41: 0x4000, 0xe42: 0x4000, 0xe43: 0x4000, 0xe44: 0x4000, 0xe45: 0x4000, + 0xe46: 0x4000, 0xe47: 0x4000, 0xe48: 0x4000, 0xe49: 0x4000, 0xe4a: 0x4000, 0xe4b: 0x4000, + 0xe4c: 0x4000, 0xe4d: 0x4000, 0xe4e: 0x4000, 0xe4f: 0x4000, 0xe50: 0x4000, 0xe51: 0x4000, + 0xe52: 0x4000, 0xe53: 0x4000, 0xe54: 0x4000, 0xe55: 0x4000, 0xe56: 0x4000, 0xe57: 0x4000, + 0xe58: 0x4000, 0xe59: 0x4000, 0xe5a: 0x4000, 0xe5b: 0x4000, 0xe5c: 0x4000, 0xe5d: 0x4000, + 0xe5e: 0x4000, 0xe5f: 0x4000, 0xe60: 0x4000, 0xe61: 0x4000, 0xe62: 0x4000, 0xe63: 0x4000, + 0xe70: 0x4000, 0xe71: 0x4000, 0xe72: 0x4000, 0xe73: 0x4000, 0xe74: 0x4000, 0xe75: 0x4000, + 0xe76: 0x4000, 0xe77: 0x4000, 0xe78: 0x4000, 0xe79: 0x4000, 0xe7a: 0x4000, 0xe7b: 0x4000, + 0xe7c: 0x4000, 0xe7d: 0x4000, 0xe7e: 0x4000, 0xe7f: 0x4000, + // Block 0x3a, offset 0xe80 + 0xe80: 0x4000, 0xe81: 0x4000, 0xe82: 0x4000, 0xe83: 0x4000, 0xe84: 0x4000, 0xe85: 0x4000, + 0xe86: 0x4000, 0xe87: 0x4000, 0xe88: 0x4000, 0xe89: 0x4000, 0xe8a: 0x4000, 0xe8b: 0x4000, + 0xe8c: 0x4000, 0xe8d: 0x4000, 0xe8e: 0x4000, 0xe8f: 0x4000, 0xe90: 0x4000, 0xe91: 0x4000, + 0xe92: 0x4000, 0xe93: 0x4000, 0xe94: 0x4000, 0xe95: 0x4000, 0xe96: 0x4000, 0xe97: 0x4000, + 0xe98: 0x4000, 0xe99: 0x4000, 0xe9a: 0x4000, 0xe9b: 0x4000, 0xe9c: 0x4000, 0xe9d: 0x4000, + 0xe9e: 0x4000, 0xea0: 0x4000, 0xea1: 0x4000, 0xea2: 0x4000, 0xea3: 0x4000, + 0xea4: 0x4000, 0xea5: 0x4000, 0xea6: 0x4000, 0xea7: 0x4000, 0xea8: 0x4000, 0xea9: 0x4000, + 0xeaa: 0x4000, 0xeab: 0x4000, 0xeac: 0x4000, 0xead: 0x4000, 0xeae: 0x4000, 0xeaf: 0x4000, + 0xeb0: 0x4000, 0xeb1: 0x4000, 0xeb2: 0x4000, 0xeb3: 0x4000, 0xeb4: 0x4000, 0xeb5: 0x4000, + 0xeb6: 0x4000, 0xeb7: 0x4000, 0xeb8: 0x4000, 0xeb9: 0x4000, 0xeba: 0x4000, 0xebb: 0x4000, + 0xebc: 0x4000, 0xebd: 0x4000, 0xebe: 0x4000, 0xebf: 0x4000, + // Block 0x3b, offset 0xec0 + 0xec0: 0x4000, 0xec1: 0x4000, 0xec2: 0x4000, 0xec3: 0x4000, 0xec4: 0x4000, 0xec5: 0x4000, + 0xec6: 0x4000, 0xec7: 0x4000, 0xec8: 0x2000, 0xec9: 0x2000, 0xeca: 0x2000, 0xecb: 0x2000, + 0xecc: 0x2000, 0xecd: 0x2000, 0xece: 0x2000, 0xecf: 0x2000, 0xed0: 0x4000, 0xed1: 0x4000, + 0xed2: 0x4000, 0xed3: 0x4000, 0xed4: 0x4000, 0xed5: 0x4000, 0xed6: 0x4000, 0xed7: 0x4000, + 0xed8: 0x4000, 0xed9: 0x4000, 0xeda: 0x4000, 0xedb: 0x4000, 0xedc: 0x4000, 0xedd: 0x4000, + 0xede: 0x4000, 0xedf: 0x4000, 0xee0: 0x4000, 0xee1: 0x4000, 0xee2: 0x4000, 0xee3: 0x4000, + 0xee4: 0x4000, 0xee5: 0x4000, 0xee6: 0x4000, 0xee7: 0x4000, 0xee8: 0x4000, 0xee9: 0x4000, + 0xeea: 0x4000, 0xeeb: 0x4000, 0xeec: 0x4000, 0xeed: 0x4000, 0xeee: 0x4000, 0xeef: 0x4000, + 0xef0: 0x4000, 0xef1: 0x4000, 0xef2: 0x4000, 0xef3: 0x4000, 0xef4: 0x4000, 0xef5: 0x4000, + 0xef6: 0x4000, 0xef7: 0x4000, 0xef8: 0x4000, 0xef9: 0x4000, 0xefa: 0x4000, 0xefb: 0x4000, + 0xefc: 0x4000, 0xefd: 0x4000, 0xefe: 0x4000, 0xeff: 0x4000, + // Block 0x3c, offset 0xf00 + 0xf00: 0x4000, 0xf01: 0x4000, 0xf02: 0x4000, 0xf03: 0x4000, 0xf04: 0x4000, 0xf05: 0x4000, + 0xf06: 0x4000, 0xf07: 0x4000, 0xf08: 0x4000, 0xf09: 0x4000, 0xf0a: 0x4000, 0xf0b: 0x4000, + 0xf0c: 0x4000, 0xf0d: 0x4000, 0xf0e: 0x4000, 0xf0f: 0x4000, 0xf10: 0x4000, 0xf11: 0x4000, + 0xf12: 0x4000, 0xf13: 0x4000, 0xf14: 0x4000, 0xf15: 0x4000, 0xf16: 0x4000, 0xf17: 0x4000, + 0xf18: 0x4000, 0xf19: 0x4000, 0xf1a: 0x4000, 0xf1b: 0x4000, 0xf1c: 0x4000, 0xf1d: 0x4000, + 0xf1e: 0x4000, 0xf1f: 0x4000, 0xf20: 0x4000, 0xf21: 0x4000, 0xf22: 0x4000, 0xf23: 0x4000, + 0xf24: 0x4000, 0xf25: 0x4000, 0xf26: 0x4000, 0xf27: 0x4000, 0xf28: 0x4000, 0xf29: 0x4000, + 0xf2a: 0x4000, 0xf2b: 0x4000, 0xf2c: 0x4000, 0xf2d: 0x4000, 0xf2e: 0x4000, 0xf2f: 0x4000, + 0xf30: 0x4000, 0xf31: 0x4000, 0xf32: 0x4000, 0xf33: 0x4000, 0xf34: 0x4000, 0xf35: 0x4000, + 0xf36: 0x4000, 0xf37: 0x4000, 0xf38: 0x4000, 0xf39: 0x4000, 0xf3a: 0x4000, 0xf3b: 0x4000, + 0xf3c: 0x4000, 0xf3d: 0x4000, 0xf3e: 0x4000, + // Block 0x3d, offset 0xf40 + 0xf40: 0x4000, 0xf41: 0x4000, 0xf42: 0x4000, 0xf43: 0x4000, 0xf44: 0x4000, 0xf45: 0x4000, + 0xf46: 0x4000, 0xf47: 0x4000, 0xf48: 0x4000, 0xf49: 0x4000, 0xf4a: 0x4000, 0xf4b: 0x4000, + 0xf4c: 0x4000, 0xf50: 0x4000, 0xf51: 0x4000, + 0xf52: 0x4000, 0xf53: 0x4000, 0xf54: 0x4000, 0xf55: 0x4000, 0xf56: 0x4000, 0xf57: 0x4000, + 0xf58: 0x4000, 0xf59: 0x4000, 0xf5a: 0x4000, 0xf5b: 0x4000, 0xf5c: 0x4000, 0xf5d: 0x4000, + 0xf5e: 0x4000, 0xf5f: 0x4000, 0xf60: 0x4000, 0xf61: 0x4000, 0xf62: 0x4000, 0xf63: 0x4000, + 0xf64: 0x4000, 0xf65: 0x4000, 0xf66: 0x4000, 0xf67: 0x4000, 0xf68: 0x4000, 0xf69: 0x4000, + 0xf6a: 0x4000, 0xf6b: 0x4000, 0xf6c: 0x4000, 0xf6d: 0x4000, 0xf6e: 0x4000, 0xf6f: 0x4000, + 0xf70: 0x4000, 0xf71: 0x4000, 0xf72: 0x4000, 0xf73: 0x4000, 0xf74: 0x4000, 0xf75: 0x4000, + 0xf76: 0x4000, 0xf77: 0x4000, 0xf78: 0x4000, 0xf79: 0x4000, 0xf7a: 0x4000, 0xf7b: 0x4000, + 0xf7c: 0x4000, 0xf7d: 0x4000, 0xf7e: 0x4000, 0xf7f: 0x4000, + // Block 0x3e, offset 0xf80 + 0xf80: 0x4000, 0xf81: 0x4000, 0xf82: 0x4000, 0xf83: 0x4000, 0xf84: 0x4000, 0xf85: 0x4000, + 0xf86: 0x4000, + // Block 0x3f, offset 0xfc0 + 0xfe0: 0x4000, 0xfe1: 0x4000, 0xfe2: 0x4000, 0xfe3: 0x4000, + 0xfe4: 0x4000, 0xfe5: 0x4000, 0xfe6: 0x4000, 0xfe7: 0x4000, 0xfe8: 0x4000, 0xfe9: 0x4000, + 0xfea: 0x4000, 0xfeb: 0x4000, 0xfec: 0x4000, 0xfed: 0x4000, 0xfee: 0x4000, 0xfef: 0x4000, + 0xff0: 0x4000, 0xff1: 0x4000, 0xff2: 0x4000, 0xff3: 0x4000, 0xff4: 0x4000, 0xff5: 0x4000, + 0xff6: 0x4000, 0xff7: 0x4000, 0xff8: 0x4000, 0xff9: 0x4000, 0xffa: 0x4000, 0xffb: 0x4000, + 0xffc: 0x4000, + // Block 0x40, offset 0x1000 + 0x1000: 0x4000, 0x1001: 0x4000, 0x1002: 0x4000, 0x1003: 0x4000, 0x1004: 0x4000, 0x1005: 0x4000, + 0x1006: 0x4000, 0x1007: 0x4000, 0x1008: 0x4000, 0x1009: 0x4000, 0x100a: 0x4000, 0x100b: 0x4000, + 0x100c: 0x4000, 0x100d: 0x4000, 0x100e: 0x4000, 0x100f: 0x4000, 0x1010: 0x4000, 0x1011: 0x4000, + 0x1012: 0x4000, 0x1013: 0x4000, 0x1014: 0x4000, 0x1015: 0x4000, 0x1016: 0x4000, 0x1017: 0x4000, + 0x1018: 0x4000, 0x1019: 0x4000, 0x101a: 0x4000, 0x101b: 0x4000, 0x101c: 0x4000, 0x101d: 0x4000, + 0x101e: 0x4000, 0x101f: 0x4000, 0x1020: 0x4000, 0x1021: 0x4000, 0x1022: 0x4000, 0x1023: 0x4000, + // Block 0x41, offset 0x1040 + 0x1040: 0x2000, 0x1041: 0x2000, 0x1042: 0x2000, 0x1043: 0x2000, 0x1044: 0x2000, 0x1045: 0x2000, + 0x1046: 0x2000, 0x1047: 0x2000, 0x1048: 0x2000, 0x1049: 0x2000, 0x104a: 0x2000, 0x104b: 0x2000, + 0x104c: 0x2000, 0x104d: 0x2000, 0x104e: 0x2000, 0x104f: 0x2000, 0x1050: 0x4000, 0x1051: 0x4000, + 0x1052: 0x4000, 0x1053: 0x4000, 0x1054: 0x4000, 0x1055: 0x4000, 0x1056: 0x4000, 0x1057: 0x4000, + 0x1058: 0x4000, 0x1059: 0x4000, + 0x1070: 0x4000, 0x1071: 0x4000, 0x1072: 0x4000, 0x1073: 0x4000, 0x1074: 0x4000, 0x1075: 0x4000, + 0x1076: 0x4000, 0x1077: 0x4000, 0x1078: 0x4000, 0x1079: 0x4000, 0x107a: 0x4000, 0x107b: 0x4000, + 0x107c: 0x4000, 0x107d: 0x4000, 0x107e: 0x4000, 0x107f: 0x4000, + // Block 0x42, offset 0x1080 + 0x1080: 0x4000, 0x1081: 0x4000, 0x1082: 0x4000, 0x1083: 0x4000, 0x1084: 0x4000, 0x1085: 0x4000, + 0x1086: 0x4000, 0x1087: 0x4000, 0x1088: 0x4000, 0x1089: 0x4000, 0x108a: 0x4000, 0x108b: 0x4000, + 0x108c: 0x4000, 0x108d: 0x4000, 0x108e: 0x4000, 0x108f: 0x4000, 0x1090: 0x4000, 0x1091: 0x4000, + 0x1092: 0x4000, 0x1094: 0x4000, 0x1095: 0x4000, 0x1096: 0x4000, 0x1097: 0x4000, + 0x1098: 0x4000, 0x1099: 0x4000, 0x109a: 0x4000, 0x109b: 0x4000, 0x109c: 0x4000, 0x109d: 0x4000, + 0x109e: 0x4000, 0x109f: 0x4000, 0x10a0: 0x4000, 0x10a1: 0x4000, 0x10a2: 0x4000, 0x10a3: 0x4000, + 0x10a4: 0x4000, 0x10a5: 0x4000, 0x10a6: 0x4000, 0x10a8: 0x4000, 0x10a9: 0x4000, + 0x10aa: 0x4000, 0x10ab: 0x4000, + // Block 0x43, offset 0x10c0 + 0x10c1: 0x9012, 0x10c2: 0x9012, 0x10c3: 0x9012, 0x10c4: 0x9012, 0x10c5: 0x9012, + 0x10c6: 0x9012, 0x10c7: 0x9012, 0x10c8: 0x9012, 0x10c9: 0x9012, 0x10ca: 0x9012, 0x10cb: 0x9012, + 0x10cc: 0x9012, 0x10cd: 0x9012, 0x10ce: 0x9012, 0x10cf: 0x9012, 0x10d0: 0x9012, 0x10d1: 0x9012, + 0x10d2: 0x9012, 0x10d3: 0x9012, 0x10d4: 0x9012, 0x10d5: 0x9012, 0x10d6: 0x9012, 0x10d7: 0x9012, + 0x10d8: 0x9012, 0x10d9: 0x9012, 0x10da: 0x9012, 0x10db: 0x9012, 0x10dc: 0x9012, 0x10dd: 0x9012, + 0x10de: 0x9012, 0x10df: 0x9012, 0x10e0: 0x9049, 0x10e1: 0x9049, 0x10e2: 0x9049, 0x10e3: 0x9049, + 0x10e4: 0x9049, 0x10e5: 0x9049, 0x10e6: 0x9049, 0x10e7: 0x9049, 0x10e8: 0x9049, 0x10e9: 0x9049, + 0x10ea: 0x9049, 0x10eb: 0x9049, 0x10ec: 0x9049, 0x10ed: 0x9049, 0x10ee: 0x9049, 0x10ef: 0x9049, + 0x10f0: 0x9049, 0x10f1: 0x9049, 0x10f2: 0x9049, 0x10f3: 0x9049, 0x10f4: 0x9049, 0x10f5: 0x9049, + 0x10f6: 0x9049, 0x10f7: 0x9049, 0x10f8: 0x9049, 0x10f9: 0x9049, 0x10fa: 0x9049, 0x10fb: 0x9049, + 0x10fc: 0x9049, 0x10fd: 0x9049, 0x10fe: 0x9049, 0x10ff: 0x9049, + // Block 0x44, offset 0x1100 + 0x1100: 0x9049, 0x1101: 0x9049, 0x1102: 0x9049, 0x1103: 0x9049, 0x1104: 0x9049, 0x1105: 0x9049, + 0x1106: 0x9049, 0x1107: 0x9049, 0x1108: 0x9049, 0x1109: 0x9049, 0x110a: 0x9049, 0x110b: 0x9049, + 0x110c: 0x9049, 0x110d: 0x9049, 0x110e: 0x9049, 0x110f: 0x9049, 0x1110: 0x9049, 0x1111: 0x9049, + 0x1112: 0x9049, 0x1113: 0x9049, 0x1114: 0x9049, 0x1115: 0x9049, 0x1116: 0x9049, 0x1117: 0x9049, + 0x1118: 0x9049, 0x1119: 0x9049, 0x111a: 0x9049, 0x111b: 0x9049, 0x111c: 0x9049, 0x111d: 0x9049, + 0x111e: 0x9049, 0x111f: 0x904a, 0x1120: 0x904b, 0x1121: 0xb04c, 0x1122: 0xb04d, 0x1123: 0xb04d, + 0x1124: 0xb04e, 0x1125: 0xb04f, 0x1126: 0xb050, 0x1127: 0xb051, 0x1128: 0xb052, 0x1129: 0xb053, + 0x112a: 0xb054, 0x112b: 0xb055, 0x112c: 0xb056, 0x112d: 0xb057, 0x112e: 0xb058, 0x112f: 0xb059, + 0x1130: 0xb05a, 0x1131: 0xb05b, 0x1132: 0xb05c, 0x1133: 0xb05d, 0x1134: 0xb05e, 0x1135: 0xb05f, + 0x1136: 0xb060, 0x1137: 0xb061, 0x1138: 0xb062, 0x1139: 0xb063, 0x113a: 0xb064, 0x113b: 0xb065, + 0x113c: 0xb052, 0x113d: 0xb066, 0x113e: 0xb067, 0x113f: 0xb055, + // Block 0x45, offset 0x1140 + 0x1140: 0xb068, 0x1141: 0xb069, 0x1142: 0xb06a, 0x1143: 0xb06b, 0x1144: 0xb05a, 0x1145: 0xb056, + 0x1146: 0xb06c, 0x1147: 0xb06d, 0x1148: 0xb06b, 0x1149: 0xb06e, 0x114a: 0xb06b, 0x114b: 0xb06f, + 0x114c: 0xb06f, 0x114d: 0xb070, 0x114e: 0xb070, 0x114f: 0xb071, 0x1150: 0xb056, 0x1151: 0xb072, + 0x1152: 0xb073, 0x1153: 0xb072, 0x1154: 0xb074, 0x1155: 0xb073, 0x1156: 0xb075, 0x1157: 0xb075, + 0x1158: 0xb076, 0x1159: 0xb076, 0x115a: 0xb077, 0x115b: 0xb077, 0x115c: 0xb073, 0x115d: 0xb078, + 0x115e: 0xb079, 0x115f: 0xb067, 0x1160: 0xb07a, 0x1161: 0xb07b, 0x1162: 0xb07b, 0x1163: 0xb07b, + 0x1164: 0xb07b, 0x1165: 0xb07b, 0x1166: 0xb07b, 0x1167: 0xb07b, 0x1168: 0xb07b, 0x1169: 0xb07b, + 0x116a: 0xb07b, 0x116b: 0xb07b, 0x116c: 0xb07b, 0x116d: 0xb07b, 0x116e: 0xb07b, 0x116f: 0xb07b, + 0x1170: 0xb07c, 0x1171: 0xb07c, 0x1172: 0xb07c, 0x1173: 0xb07c, 0x1174: 0xb07c, 0x1175: 0xb07c, + 0x1176: 0xb07c, 0x1177: 0xb07c, 0x1178: 0xb07c, 0x1179: 0xb07c, 0x117a: 0xb07c, 0x117b: 0xb07c, + 0x117c: 0xb07c, 0x117d: 0xb07c, 0x117e: 0xb07c, + // Block 0x46, offset 0x1180 + 0x1182: 0xb07d, 0x1183: 0xb07e, 0x1184: 0xb07f, 0x1185: 0xb080, + 0x1186: 0xb07f, 0x1187: 0xb07e, 0x118a: 0xb081, 0x118b: 0xb082, + 0x118c: 0xb083, 0x118d: 0xb07f, 0x118e: 0xb080, 0x118f: 0xb07f, + 0x1192: 0xb084, 0x1193: 0xb085, 0x1194: 0xb084, 0x1195: 0xb086, 0x1196: 0xb084, 0x1197: 0xb087, + 0x119a: 0xb088, 0x119b: 0xb089, 0x119c: 0xb08a, + 0x11a0: 0x908b, 0x11a1: 0x908b, 0x11a2: 0x908c, 0x11a3: 0x908d, + 0x11a4: 0x908b, 0x11a5: 0x908e, 0x11a6: 0x908f, 0x11a8: 0xb090, 0x11a9: 0xb091, + 0x11aa: 0xb092, 0x11ab: 0xb091, 0x11ac: 0xb093, 0x11ad: 0xb094, 0x11ae: 0xb095, + 0x11bd: 0x2000, + // Block 0x47, offset 0x11c0 + 0x11e0: 0x4000, 0x11e1: 0x4000, + // Block 0x48, offset 0x1200 + 0x1200: 0x4000, 0x1201: 0x4000, 0x1202: 0x4000, 0x1203: 0x4000, 0x1204: 0x4000, 0x1205: 0x4000, + 0x1206: 0x4000, 0x1207: 0x4000, 0x1208: 0x4000, 0x1209: 0x4000, 0x120a: 0x4000, 0x120b: 0x4000, + 0x120c: 0x4000, 0x120d: 0x4000, 0x120e: 0x4000, 0x120f: 0x4000, 0x1210: 0x4000, 0x1211: 0x4000, + 0x1212: 0x4000, 0x1213: 0x4000, 0x1214: 0x4000, 0x1215: 0x4000, 0x1216: 0x4000, 0x1217: 0x4000, + 0x1218: 0x4000, 0x1219: 0x4000, 0x121a: 0x4000, 0x121b: 0x4000, 0x121c: 0x4000, 0x121d: 0x4000, + 0x121e: 0x4000, 0x121f: 0x4000, 0x1220: 0x4000, 0x1221: 0x4000, 0x1222: 0x4000, 0x1223: 0x4000, + 0x1224: 0x4000, 0x1225: 0x4000, 0x1226: 0x4000, 0x1227: 0x4000, 0x1228: 0x4000, 0x1229: 0x4000, + 0x122a: 0x4000, 0x122b: 0x4000, 0x122c: 0x4000, + // Block 0x49, offset 0x1240 + 0x1240: 0x4000, 0x1241: 0x4000, 0x1242: 0x4000, 0x1243: 0x4000, 0x1244: 0x4000, 0x1245: 0x4000, + 0x1246: 0x4000, 0x1247: 0x4000, 0x1248: 0x4000, 0x1249: 0x4000, 0x124a: 0x4000, 0x124b: 0x4000, + 0x124c: 0x4000, 0x124d: 0x4000, 0x124e: 0x4000, 0x124f: 0x4000, 0x1250: 0x4000, 0x1251: 0x4000, + 0x1252: 0x4000, 0x1253: 0x4000, 0x1254: 0x4000, 0x1255: 0x4000, 0x1256: 0x4000, 0x1257: 0x4000, + 0x1258: 0x4000, 0x1259: 0x4000, 0x125a: 0x4000, 0x125b: 0x4000, 0x125c: 0x4000, 0x125d: 0x4000, + 0x125e: 0x4000, 0x125f: 0x4000, 0x1260: 0x4000, 0x1261: 0x4000, 0x1262: 0x4000, 0x1263: 0x4000, + 0x1264: 0x4000, 0x1265: 0x4000, 0x1266: 0x4000, 0x1267: 0x4000, 0x1268: 0x4000, 0x1269: 0x4000, + 0x126a: 0x4000, 0x126b: 0x4000, 0x126c: 0x4000, 0x126d: 0x4000, 0x126e: 0x4000, 0x126f: 0x4000, + 0x1270: 0x4000, 0x1271: 0x4000, 0x1272: 0x4000, + // Block 0x4a, offset 0x1280 + 0x1280: 0x4000, 0x1281: 0x4000, 0x1282: 0x4000, 0x1283: 0x4000, 0x1284: 0x4000, 0x1285: 0x4000, + 0x1286: 0x4000, 0x1287: 0x4000, 0x1288: 0x4000, 0x1289: 0x4000, 0x128a: 0x4000, 0x128b: 0x4000, + 0x128c: 0x4000, 0x128d: 0x4000, 0x128e: 0x4000, 0x128f: 0x4000, 0x1290: 0x4000, 0x1291: 0x4000, + 0x1292: 0x4000, 0x1293: 0x4000, 0x1294: 0x4000, 0x1295: 0x4000, 0x1296: 0x4000, 0x1297: 0x4000, + 0x1298: 0x4000, 0x1299: 0x4000, 0x129a: 0x4000, 0x129b: 0x4000, 0x129c: 0x4000, 0x129d: 0x4000, + 0x129e: 0x4000, + // Block 0x4b, offset 0x12c0 + 0x12f0: 0x4000, 0x12f1: 0x4000, 0x12f2: 0x4000, 0x12f3: 0x4000, 0x12f4: 0x4000, 0x12f5: 0x4000, + 0x12f6: 0x4000, 0x12f7: 0x4000, 0x12f8: 0x4000, 0x12f9: 0x4000, 0x12fa: 0x4000, 0x12fb: 0x4000, + 0x12fc: 0x4000, 0x12fd: 0x4000, 0x12fe: 0x4000, 0x12ff: 0x4000, + // Block 0x4c, offset 0x1300 + 0x1300: 0x4000, 0x1301: 0x4000, 0x1302: 0x4000, 0x1303: 0x4000, 0x1304: 0x4000, 0x1305: 0x4000, + 0x1306: 0x4000, 0x1307: 0x4000, 0x1308: 0x4000, 0x1309: 0x4000, 0x130a: 0x4000, 0x130b: 0x4000, + 0x130c: 0x4000, 0x130d: 0x4000, 0x130e: 0x4000, 0x130f: 0x4000, 0x1310: 0x4000, 0x1311: 0x4000, + 0x1312: 0x4000, 0x1313: 0x4000, 0x1314: 0x4000, 0x1315: 0x4000, 0x1316: 0x4000, 0x1317: 0x4000, + 0x1318: 0x4000, 0x1319: 0x4000, 0x131a: 0x4000, 0x131b: 0x4000, 0x131c: 0x4000, 0x131d: 0x4000, + 0x131e: 0x4000, 0x131f: 0x4000, 0x1320: 0x4000, 0x1321: 0x4000, 0x1322: 0x4000, 0x1323: 0x4000, + 0x1324: 0x4000, 0x1325: 0x4000, 0x1326: 0x4000, 0x1327: 0x4000, 0x1328: 0x4000, 0x1329: 0x4000, + 0x132a: 0x4000, 0x132b: 0x4000, 0x132c: 0x4000, 0x132d: 0x4000, 0x132e: 0x4000, 0x132f: 0x4000, + 0x1330: 0x4000, 0x1331: 0x4000, 0x1332: 0x4000, 0x1333: 0x4000, 0x1334: 0x4000, 0x1335: 0x4000, + 0x1336: 0x4000, 0x1337: 0x4000, 0x1338: 0x4000, 0x1339: 0x4000, 0x133a: 0x4000, 0x133b: 0x4000, + // Block 0x4d, offset 0x1340 + 0x1344: 0x4000, + // Block 0x4e, offset 0x1380 + 0x138f: 0x4000, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x2000, 0x13c1: 0x2000, 0x13c2: 0x2000, 0x13c3: 0x2000, 0x13c4: 0x2000, 0x13c5: 0x2000, + 0x13c6: 0x2000, 0x13c7: 0x2000, 0x13c8: 0x2000, 0x13c9: 0x2000, 0x13ca: 0x2000, + 0x13d0: 0x2000, 0x13d1: 0x2000, + 0x13d2: 0x2000, 0x13d3: 0x2000, 0x13d4: 0x2000, 0x13d5: 0x2000, 0x13d6: 0x2000, 0x13d7: 0x2000, + 0x13d8: 0x2000, 0x13d9: 0x2000, 0x13da: 0x2000, 0x13db: 0x2000, 0x13dc: 0x2000, 0x13dd: 0x2000, + 0x13de: 0x2000, 0x13df: 0x2000, 0x13e0: 0x2000, 0x13e1: 0x2000, 0x13e2: 0x2000, 0x13e3: 0x2000, + 0x13e4: 0x2000, 0x13e5: 0x2000, 0x13e6: 0x2000, 0x13e7: 0x2000, 0x13e8: 0x2000, 0x13e9: 0x2000, + 0x13ea: 0x2000, 0x13eb: 0x2000, 0x13ec: 0x2000, 0x13ed: 0x2000, + 0x13f0: 0x2000, 0x13f1: 0x2000, 0x13f2: 0x2000, 0x13f3: 0x2000, 0x13f4: 0x2000, 0x13f5: 0x2000, + 0x13f6: 0x2000, 0x13f7: 0x2000, 0x13f8: 0x2000, 0x13f9: 0x2000, 0x13fa: 0x2000, 0x13fb: 0x2000, + 0x13fc: 0x2000, 0x13fd: 0x2000, 0x13fe: 0x2000, 0x13ff: 0x2000, + // Block 0x50, offset 0x1400 + 0x1400: 0x2000, 0x1401: 0x2000, 0x1402: 0x2000, 0x1403: 0x2000, 0x1404: 0x2000, 0x1405: 0x2000, + 0x1406: 0x2000, 0x1407: 0x2000, 0x1408: 0x2000, 0x1409: 0x2000, 0x140a: 0x2000, 0x140b: 0x2000, + 0x140c: 0x2000, 0x140d: 0x2000, 0x140e: 0x2000, 0x140f: 0x2000, 0x1410: 0x2000, 0x1411: 0x2000, + 0x1412: 0x2000, 0x1413: 0x2000, 0x1414: 0x2000, 0x1415: 0x2000, 0x1416: 0x2000, 0x1417: 0x2000, + 0x1418: 0x2000, 0x1419: 0x2000, 0x141a: 0x2000, 0x141b: 0x2000, 0x141c: 0x2000, 0x141d: 0x2000, + 0x141e: 0x2000, 0x141f: 0x2000, 0x1420: 0x2000, 0x1421: 0x2000, 0x1422: 0x2000, 0x1423: 0x2000, + 0x1424: 0x2000, 0x1425: 0x2000, 0x1426: 0x2000, 0x1427: 0x2000, 0x1428: 0x2000, 0x1429: 0x2000, + 0x1430: 0x2000, 0x1431: 0x2000, 0x1432: 0x2000, 0x1433: 0x2000, 0x1434: 0x2000, 0x1435: 0x2000, + 0x1436: 0x2000, 0x1437: 0x2000, 0x1438: 0x2000, 0x1439: 0x2000, 0x143a: 0x2000, 0x143b: 0x2000, + 0x143c: 0x2000, 0x143d: 0x2000, 0x143e: 0x2000, 0x143f: 0x2000, + // Block 0x51, offset 0x1440 + 0x1440: 0x2000, 0x1441: 0x2000, 0x1442: 0x2000, 0x1443: 0x2000, 0x1444: 0x2000, 0x1445: 0x2000, + 0x1446: 0x2000, 0x1447: 0x2000, 0x1448: 0x2000, 0x1449: 0x2000, 0x144a: 0x2000, 0x144b: 0x2000, + 0x144c: 0x2000, 0x144d: 0x2000, 0x144e: 0x4000, 0x144f: 0x2000, 0x1450: 0x2000, 0x1451: 0x4000, + 0x1452: 0x4000, 0x1453: 0x4000, 0x1454: 0x4000, 0x1455: 0x4000, 0x1456: 0x4000, 0x1457: 0x4000, + 0x1458: 0x4000, 0x1459: 0x4000, 0x145a: 0x4000, 0x145b: 0x2000, 0x145c: 0x2000, 0x145d: 0x2000, + 0x145e: 0x2000, 0x145f: 0x2000, 0x1460: 0x2000, 0x1461: 0x2000, 0x1462: 0x2000, 0x1463: 0x2000, + 0x1464: 0x2000, 0x1465: 0x2000, 0x1466: 0x2000, 0x1467: 0x2000, 0x1468: 0x2000, 0x1469: 0x2000, + 0x146a: 0x2000, 0x146b: 0x2000, 0x146c: 0x2000, + // Block 0x52, offset 0x1480 + 0x1480: 0x4000, 0x1481: 0x4000, 0x1482: 0x4000, + 0x1490: 0x4000, 0x1491: 0x4000, + 0x1492: 0x4000, 0x1493: 0x4000, 0x1494: 0x4000, 0x1495: 0x4000, 0x1496: 0x4000, 0x1497: 0x4000, + 0x1498: 0x4000, 0x1499: 0x4000, 0x149a: 0x4000, 0x149b: 0x4000, 0x149c: 0x4000, 0x149d: 0x4000, + 0x149e: 0x4000, 0x149f: 0x4000, 0x14a0: 0x4000, 0x14a1: 0x4000, 0x14a2: 0x4000, 0x14a3: 0x4000, + 0x14a4: 0x4000, 0x14a5: 0x4000, 0x14a6: 0x4000, 0x14a7: 0x4000, 0x14a8: 0x4000, 0x14a9: 0x4000, + 0x14aa: 0x4000, 0x14ab: 0x4000, 0x14ac: 0x4000, 0x14ad: 0x4000, 0x14ae: 0x4000, 0x14af: 0x4000, + 0x14b0: 0x4000, 0x14b1: 0x4000, 0x14b2: 0x4000, 0x14b3: 0x4000, 0x14b4: 0x4000, 0x14b5: 0x4000, + 0x14b6: 0x4000, 0x14b7: 0x4000, 0x14b8: 0x4000, 0x14b9: 0x4000, 0x14ba: 0x4000, 0x14bb: 0x4000, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x4000, 0x14c1: 0x4000, 0x14c2: 0x4000, 0x14c3: 0x4000, 0x14c4: 0x4000, 0x14c5: 0x4000, + 0x14c6: 0x4000, 0x14c7: 0x4000, 0x14c8: 0x4000, + 0x14d0: 0x4000, 0x14d1: 0x4000, + 0x14e0: 0x4000, 0x14e1: 0x4000, 0x14e2: 0x4000, 0x14e3: 0x4000, + 0x14e4: 0x4000, 0x14e5: 0x4000, + // Block 0x54, offset 0x1500 + 0x1500: 0x4000, 0x1501: 0x4000, 0x1502: 0x4000, 0x1503: 0x4000, 0x1504: 0x4000, 0x1505: 0x4000, + 0x1506: 0x4000, 0x1507: 0x4000, 0x1508: 0x4000, 0x1509: 0x4000, 0x150a: 0x4000, 0x150b: 0x4000, + 0x150c: 0x4000, 0x150d: 0x4000, 0x150e: 0x4000, 0x150f: 0x4000, 0x1510: 0x4000, 0x1511: 0x4000, + 0x1512: 0x4000, 0x1513: 0x4000, 0x1514: 0x4000, 0x1515: 0x4000, 0x1516: 0x4000, 0x1517: 0x4000, + 0x1518: 0x4000, 0x1519: 0x4000, 0x151a: 0x4000, 0x151b: 0x4000, 0x151c: 0x4000, 0x151d: 0x4000, + 0x151e: 0x4000, 0x151f: 0x4000, 0x1520: 0x4000, + 0x152d: 0x4000, 0x152e: 0x4000, 0x152f: 0x4000, + 0x1530: 0x4000, 0x1531: 0x4000, 0x1532: 0x4000, 0x1533: 0x4000, 0x1534: 0x4000, 0x1535: 0x4000, + 0x1537: 0x4000, 0x1538: 0x4000, 0x1539: 0x4000, 0x153a: 0x4000, 0x153b: 0x4000, + 0x153c: 0x4000, 0x153d: 0x4000, 0x153e: 0x4000, 0x153f: 0x4000, + // Block 0x55, offset 0x1540 + 0x1540: 0x4000, 0x1541: 0x4000, 0x1542: 0x4000, 0x1543: 0x4000, 0x1544: 0x4000, 0x1545: 0x4000, + 0x1546: 0x4000, 0x1547: 0x4000, 0x1548: 0x4000, 0x1549: 0x4000, 0x154a: 0x4000, 0x154b: 0x4000, + 0x154c: 0x4000, 0x154d: 0x4000, 0x154e: 0x4000, 0x154f: 0x4000, 0x1550: 0x4000, 0x1551: 0x4000, + 0x1552: 0x4000, 0x1553: 0x4000, 0x1554: 0x4000, 0x1555: 0x4000, 0x1556: 0x4000, 0x1557: 0x4000, + 0x1558: 0x4000, 0x1559: 0x4000, 0x155a: 0x4000, 0x155b: 0x4000, 0x155c: 0x4000, 0x155d: 0x4000, + 0x155e: 0x4000, 0x155f: 0x4000, 0x1560: 0x4000, 0x1561: 0x4000, 0x1562: 0x4000, 0x1563: 0x4000, + 0x1564: 0x4000, 0x1565: 0x4000, 0x1566: 0x4000, 0x1567: 0x4000, 0x1568: 0x4000, 0x1569: 0x4000, + 0x156a: 0x4000, 0x156b: 0x4000, 0x156c: 0x4000, 0x156d: 0x4000, 0x156e: 0x4000, 0x156f: 0x4000, + 0x1570: 0x4000, 0x1571: 0x4000, 0x1572: 0x4000, 0x1573: 0x4000, 0x1574: 0x4000, 0x1575: 0x4000, + 0x1576: 0x4000, 0x1577: 0x4000, 0x1578: 0x4000, 0x1579: 0x4000, 0x157a: 0x4000, 0x157b: 0x4000, + 0x157c: 0x4000, 0x157e: 0x4000, 0x157f: 0x4000, + // Block 0x56, offset 0x1580 + 0x1580: 0x4000, 0x1581: 0x4000, 0x1582: 0x4000, 0x1583: 0x4000, 0x1584: 0x4000, 0x1585: 0x4000, + 0x1586: 0x4000, 0x1587: 0x4000, 0x1588: 0x4000, 0x1589: 0x4000, 0x158a: 0x4000, 0x158b: 0x4000, + 0x158c: 0x4000, 0x158d: 0x4000, 0x158e: 0x4000, 0x158f: 0x4000, 0x1590: 0x4000, 0x1591: 0x4000, + 0x1592: 0x4000, 0x1593: 0x4000, + 0x15a0: 0x4000, 0x15a1: 0x4000, 0x15a2: 0x4000, 0x15a3: 0x4000, + 0x15a4: 0x4000, 0x15a5: 0x4000, 0x15a6: 0x4000, 0x15a7: 0x4000, 0x15a8: 0x4000, 0x15a9: 0x4000, + 0x15aa: 0x4000, 0x15ab: 0x4000, 0x15ac: 0x4000, 0x15ad: 0x4000, 0x15ae: 0x4000, 0x15af: 0x4000, + 0x15b0: 0x4000, 0x15b1: 0x4000, 0x15b2: 0x4000, 0x15b3: 0x4000, 0x15b4: 0x4000, 0x15b5: 0x4000, + 0x15b6: 0x4000, 0x15b7: 0x4000, 0x15b8: 0x4000, 0x15b9: 0x4000, 0x15ba: 0x4000, 0x15bb: 0x4000, + 0x15bc: 0x4000, 0x15bd: 0x4000, 0x15be: 0x4000, 0x15bf: 0x4000, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x4000, 0x15c1: 0x4000, 0x15c2: 0x4000, 0x15c3: 0x4000, 0x15c4: 0x4000, 0x15c5: 0x4000, + 0x15c6: 0x4000, 0x15c7: 0x4000, 0x15c8: 0x4000, 0x15c9: 0x4000, 0x15ca: 0x4000, + 0x15cf: 0x4000, 0x15d0: 0x4000, 0x15d1: 0x4000, + 0x15d2: 0x4000, 0x15d3: 0x4000, + 0x15e0: 0x4000, 0x15e1: 0x4000, 0x15e2: 0x4000, 0x15e3: 0x4000, + 0x15e4: 0x4000, 0x15e5: 0x4000, 0x15e6: 0x4000, 0x15e7: 0x4000, 0x15e8: 0x4000, 0x15e9: 0x4000, + 0x15ea: 0x4000, 0x15eb: 0x4000, 0x15ec: 0x4000, 0x15ed: 0x4000, 0x15ee: 0x4000, 0x15ef: 0x4000, + 0x15f0: 0x4000, 0x15f4: 0x4000, + 0x15f8: 0x4000, 0x15f9: 0x4000, 0x15fa: 0x4000, 0x15fb: 0x4000, + 0x15fc: 0x4000, 0x15fd: 0x4000, 0x15fe: 0x4000, 0x15ff: 0x4000, + // Block 0x58, offset 0x1600 + 0x1600: 0x4000, 0x1602: 0x4000, 0x1603: 0x4000, 0x1604: 0x4000, 0x1605: 0x4000, + 0x1606: 0x4000, 0x1607: 0x4000, 0x1608: 0x4000, 0x1609: 0x4000, 0x160a: 0x4000, 0x160b: 0x4000, + 0x160c: 0x4000, 0x160d: 0x4000, 0x160e: 0x4000, 0x160f: 0x4000, 0x1610: 0x4000, 0x1611: 0x4000, + 0x1612: 0x4000, 0x1613: 0x4000, 0x1614: 0x4000, 0x1615: 0x4000, 0x1616: 0x4000, 0x1617: 0x4000, + 0x1618: 0x4000, 0x1619: 0x4000, 0x161a: 0x4000, 0x161b: 0x4000, 0x161c: 0x4000, 0x161d: 0x4000, + 0x161e: 0x4000, 0x161f: 0x4000, 0x1620: 0x4000, 0x1621: 0x4000, 0x1622: 0x4000, 0x1623: 0x4000, + 0x1624: 0x4000, 0x1625: 0x4000, 0x1626: 0x4000, 0x1627: 0x4000, 0x1628: 0x4000, 0x1629: 0x4000, + 0x162a: 0x4000, 0x162b: 0x4000, 0x162c: 0x4000, 0x162d: 0x4000, 0x162e: 0x4000, 0x162f: 0x4000, + 0x1630: 0x4000, 0x1631: 0x4000, 0x1632: 0x4000, 0x1633: 0x4000, 0x1634: 0x4000, 0x1635: 0x4000, + 0x1636: 0x4000, 0x1637: 0x4000, 0x1638: 0x4000, 0x1639: 0x4000, 0x163a: 0x4000, 0x163b: 0x4000, + 0x163c: 0x4000, 0x163d: 0x4000, 0x163e: 0x4000, 0x163f: 0x4000, + // Block 0x59, offset 0x1640 + 0x1640: 0x4000, 0x1641: 0x4000, 0x1642: 0x4000, 0x1643: 0x4000, 0x1644: 0x4000, 0x1645: 0x4000, + 0x1646: 0x4000, 0x1647: 0x4000, 0x1648: 0x4000, 0x1649: 0x4000, 0x164a: 0x4000, 0x164b: 0x4000, + 0x164c: 0x4000, 0x164d: 0x4000, 0x164e: 0x4000, 0x164f: 0x4000, 0x1650: 0x4000, 0x1651: 0x4000, + 0x1652: 0x4000, 0x1653: 0x4000, 0x1654: 0x4000, 0x1655: 0x4000, 0x1656: 0x4000, 0x1657: 0x4000, + 0x1658: 0x4000, 0x1659: 0x4000, 0x165a: 0x4000, 0x165b: 0x4000, 0x165c: 0x4000, 0x165d: 0x4000, + 0x165e: 0x4000, 0x165f: 0x4000, 0x1660: 0x4000, 0x1661: 0x4000, 0x1662: 0x4000, 0x1663: 0x4000, + 0x1664: 0x4000, 0x1665: 0x4000, 0x1666: 0x4000, 0x1667: 0x4000, 0x1668: 0x4000, 0x1669: 0x4000, + 0x166a: 0x4000, 0x166b: 0x4000, 0x166c: 0x4000, 0x166d: 0x4000, 0x166e: 0x4000, 0x166f: 0x4000, + 0x1670: 0x4000, 0x1671: 0x4000, 0x1672: 0x4000, 0x1673: 0x4000, 0x1674: 0x4000, 0x1675: 0x4000, + 0x1676: 0x4000, 0x1677: 0x4000, 0x1678: 0x4000, 0x1679: 0x4000, 0x167a: 0x4000, 0x167b: 0x4000, + 0x167c: 0x4000, 0x167f: 0x4000, + // Block 0x5a, offset 0x1680 + 0x1680: 0x4000, 0x1681: 0x4000, 0x1682: 0x4000, 0x1683: 0x4000, 0x1684: 0x4000, 0x1685: 0x4000, + 0x1686: 0x4000, 0x1687: 0x4000, 0x1688: 0x4000, 0x1689: 0x4000, 0x168a: 0x4000, 0x168b: 0x4000, + 0x168c: 0x4000, 0x168d: 0x4000, 0x168e: 0x4000, 0x168f: 0x4000, 0x1690: 0x4000, 0x1691: 0x4000, + 0x1692: 0x4000, 0x1693: 0x4000, 0x1694: 0x4000, 0x1695: 0x4000, 0x1696: 0x4000, 0x1697: 0x4000, + 0x1698: 0x4000, 0x1699: 0x4000, 0x169a: 0x4000, 0x169b: 0x4000, 0x169c: 0x4000, 0x169d: 0x4000, + 0x169e: 0x4000, 0x169f: 0x4000, 0x16a0: 0x4000, 0x16a1: 0x4000, 0x16a2: 0x4000, 0x16a3: 0x4000, + 0x16a4: 0x4000, 0x16a5: 0x4000, 0x16a6: 0x4000, 0x16a7: 0x4000, 0x16a8: 0x4000, 0x16a9: 0x4000, + 0x16aa: 0x4000, 0x16ab: 0x4000, 0x16ac: 0x4000, 0x16ad: 0x4000, 0x16ae: 0x4000, 0x16af: 0x4000, + 0x16b0: 0x4000, 0x16b1: 0x4000, 0x16b2: 0x4000, 0x16b3: 0x4000, 0x16b4: 0x4000, 0x16b5: 0x4000, + 0x16b6: 0x4000, 0x16b7: 0x4000, 0x16b8: 0x4000, 0x16b9: 0x4000, 0x16ba: 0x4000, 0x16bb: 0x4000, + 0x16bc: 0x4000, 0x16bd: 0x4000, + // Block 0x5b, offset 0x16c0 + 0x16cb: 0x4000, + 0x16cc: 0x4000, 0x16cd: 0x4000, 0x16ce: 0x4000, 0x16d0: 0x4000, 0x16d1: 0x4000, + 0x16d2: 0x4000, 0x16d3: 0x4000, 0x16d4: 0x4000, 0x16d5: 0x4000, 0x16d6: 0x4000, 0x16d7: 0x4000, + 0x16d8: 0x4000, 0x16d9: 0x4000, 0x16da: 0x4000, 0x16db: 0x4000, 0x16dc: 0x4000, 0x16dd: 0x4000, + 0x16de: 0x4000, 0x16df: 0x4000, 0x16e0: 0x4000, 0x16e1: 0x4000, 0x16e2: 0x4000, 0x16e3: 0x4000, + 0x16e4: 0x4000, 0x16e5: 0x4000, 0x16e6: 0x4000, 0x16e7: 0x4000, + 0x16fa: 0x4000, + // Block 0x5c, offset 0x1700 + 0x1715: 0x4000, 0x1716: 0x4000, + 0x1724: 0x4000, + // Block 0x5d, offset 0x1740 + 0x177b: 0x4000, + 0x177c: 0x4000, 0x177d: 0x4000, 0x177e: 0x4000, 0x177f: 0x4000, + // Block 0x5e, offset 0x1780 + 0x1780: 0x4000, 0x1781: 0x4000, 0x1782: 0x4000, 0x1783: 0x4000, 0x1784: 0x4000, 0x1785: 0x4000, + 0x1786: 0x4000, 0x1787: 0x4000, 0x1788: 0x4000, 0x1789: 0x4000, 0x178a: 0x4000, 0x178b: 0x4000, + 0x178c: 0x4000, 0x178d: 0x4000, 0x178e: 0x4000, 0x178f: 0x4000, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x4000, 0x17c1: 0x4000, 0x17c2: 0x4000, 0x17c3: 0x4000, 0x17c4: 0x4000, 0x17c5: 0x4000, + 0x17cc: 0x4000, 0x17d0: 0x4000, 0x17d1: 0x4000, + 0x17d2: 0x4000, + 0x17eb: 0x4000, 0x17ec: 0x4000, + 0x17f4: 0x4000, 0x17f5: 0x4000, + 0x17f6: 0x4000, 0x17f7: 0x4000, 0x17f8: 0x4000, + // Block 0x60, offset 0x1800 + 0x1810: 0x4000, 0x1811: 0x4000, + 0x1812: 0x4000, 0x1813: 0x4000, 0x1814: 0x4000, 0x1815: 0x4000, 0x1816: 0x4000, 0x1817: 0x4000, + 0x1818: 0x4000, 0x1819: 0x4000, 0x181a: 0x4000, 0x181b: 0x4000, 0x181c: 0x4000, 0x181d: 0x4000, + 0x181e: 0x4000, 0x181f: 0x4000, 0x1820: 0x4000, 0x1821: 0x4000, 0x1822: 0x4000, 0x1823: 0x4000, + 0x1824: 0x4000, 0x1825: 0x4000, 0x1826: 0x4000, 0x1827: 0x4000, 0x1828: 0x4000, 0x1829: 0x4000, + 0x182a: 0x4000, 0x182b: 0x4000, 0x182c: 0x4000, 0x182d: 0x4000, 0x182e: 0x4000, 0x182f: 0x4000, + 0x1830: 0x4000, 0x1831: 0x4000, 0x1832: 0x4000, 0x1833: 0x4000, 0x1834: 0x4000, 0x1835: 0x4000, + 0x1836: 0x4000, 0x1837: 0x4000, 0x1838: 0x4000, 0x1839: 0x4000, 0x183a: 0x4000, 0x183b: 0x4000, + 0x183c: 0x4000, 0x183d: 0x4000, 0x183e: 0x4000, + // Block 0x61, offset 0x1840 + 0x1840: 0x4000, 0x1841: 0x4000, 0x1842: 0x4000, 0x1843: 0x4000, 0x1844: 0x4000, 0x1845: 0x4000, + 0x1846: 0x4000, 0x1847: 0x4000, 0x1848: 0x4000, 0x1849: 0x4000, 0x184a: 0x4000, 0x184b: 0x4000, + 0x184c: 0x4000, 0x1850: 0x4000, 0x1851: 0x4000, + 0x1852: 0x4000, 0x1853: 0x4000, 0x1854: 0x4000, 0x1855: 0x4000, 0x1856: 0x4000, 0x1857: 0x4000, + 0x1858: 0x4000, 0x1859: 0x4000, 0x185a: 0x4000, 0x185b: 0x4000, 0x185c: 0x4000, 0x185d: 0x4000, + 0x185e: 0x4000, 0x185f: 0x4000, 0x1860: 0x4000, 0x1861: 0x4000, 0x1862: 0x4000, 0x1863: 0x4000, + 0x1864: 0x4000, 0x1865: 0x4000, 0x1866: 0x4000, 0x1867: 0x4000, 0x1868: 0x4000, 0x1869: 0x4000, + 0x186a: 0x4000, 0x186b: 0x4000, + // Block 0x62, offset 0x1880 + 0x1880: 0x4000, 0x1881: 0x4000, 0x1882: 0x4000, 0x1883: 0x4000, 0x1884: 0x4000, 0x1885: 0x4000, + 0x1886: 0x4000, 0x1887: 0x4000, 0x1888: 0x4000, 0x1889: 0x4000, 0x188a: 0x4000, 0x188b: 0x4000, + 0x188c: 0x4000, 0x188d: 0x4000, 0x188e: 0x4000, 0x188f: 0x4000, 0x1890: 0x4000, 0x1891: 0x4000, + 0x1892: 0x4000, 0x1893: 0x4000, 0x1894: 0x4000, 0x1895: 0x4000, 0x1896: 0x4000, 0x1897: 0x4000, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x4000, + 0x18d0: 0x4000, 0x18d1: 0x4000, + 0x18d2: 0x4000, 0x18d3: 0x4000, 0x18d4: 0x4000, 0x18d5: 0x4000, 0x18d6: 0x4000, 0x18d7: 0x4000, + 0x18d8: 0x4000, 0x18d9: 0x4000, 0x18da: 0x4000, 0x18db: 0x4000, 0x18dc: 0x4000, 0x18dd: 0x4000, + 0x18de: 0x4000, 0x18df: 0x4000, 0x18e0: 0x4000, 0x18e1: 0x4000, 0x18e2: 0x4000, 0x18e3: 0x4000, + 0x18e4: 0x4000, 0x18e5: 0x4000, 0x18e6: 0x4000, + // Block 0x64, offset 0x1900 + 0x1900: 0x2000, 0x1901: 0x2000, 0x1902: 0x2000, 0x1903: 0x2000, 0x1904: 0x2000, 0x1905: 0x2000, + 0x1906: 0x2000, 0x1907: 0x2000, 0x1908: 0x2000, 0x1909: 0x2000, 0x190a: 0x2000, 0x190b: 0x2000, + 0x190c: 0x2000, 0x190d: 0x2000, 0x190e: 0x2000, 0x190f: 0x2000, 0x1910: 0x2000, 0x1911: 0x2000, + 0x1912: 0x2000, 0x1913: 0x2000, 0x1914: 0x2000, 0x1915: 0x2000, 0x1916: 0x2000, 0x1917: 0x2000, + 0x1918: 0x2000, 0x1919: 0x2000, 0x191a: 0x2000, 0x191b: 0x2000, 0x191c: 0x2000, 0x191d: 0x2000, + 0x191e: 0x2000, 0x191f: 0x2000, 0x1920: 0x2000, 0x1921: 0x2000, 0x1922: 0x2000, 0x1923: 0x2000, + 0x1924: 0x2000, 0x1925: 0x2000, 0x1926: 0x2000, 0x1927: 0x2000, 0x1928: 0x2000, 0x1929: 0x2000, + 0x192a: 0x2000, 0x192b: 0x2000, 0x192c: 0x2000, 0x192d: 0x2000, 0x192e: 0x2000, 0x192f: 0x2000, + 0x1930: 0x2000, 0x1931: 0x2000, 0x1932: 0x2000, 0x1933: 0x2000, 0x1934: 0x2000, 0x1935: 0x2000, + 0x1936: 0x2000, 0x1937: 0x2000, 0x1938: 0x2000, 0x1939: 0x2000, 0x193a: 0x2000, 0x193b: 0x2000, + 0x193c: 0x2000, 0x193d: 0x2000, +} + +// widthIndex: 22 blocks, 1408 entries, 1408 bytes +// Block 0 is the zero block. +var widthIndex = [1408]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x02, 0xc4: 0x03, 0xc5: 0x04, 0xc7: 0x05, + 0xc9: 0x06, 0xcb: 0x07, 0xcc: 0x08, 0xcd: 0x09, 0xce: 0x0a, 0xcf: 0x0b, + 0xd0: 0x0c, 0xd1: 0x0d, + 0xe1: 0x02, 0xe2: 0x03, 0xe3: 0x04, 0xe4: 0x05, 0xe5: 0x06, 0xe6: 0x06, 0xe7: 0x06, + 0xe8: 0x06, 0xe9: 0x06, 0xea: 0x07, 0xeb: 0x06, 0xec: 0x06, 0xed: 0x08, 0xee: 0x09, 0xef: 0x0a, + 0xf0: 0x0f, 0xf3: 0x12, 0xf4: 0x13, + // Block 0x4, offset 0x100 + 0x104: 0x0e, 0x105: 0x0f, + // Block 0x5, offset 0x140 + 0x140: 0x10, 0x141: 0x11, 0x142: 0x12, 0x144: 0x13, 0x145: 0x14, 0x146: 0x15, 0x147: 0x16, + 0x148: 0x17, 0x149: 0x18, 0x14a: 0x19, 0x14c: 0x1a, 0x14f: 0x1b, + 0x151: 0x1c, 0x152: 0x08, 0x153: 0x1d, 0x154: 0x1e, 0x155: 0x1f, 0x156: 0x20, 0x157: 0x21, + 0x158: 0x22, 0x159: 0x23, 0x15a: 0x24, 0x15b: 0x25, 0x15c: 0x26, 0x15d: 0x27, 0x15e: 0x28, 0x15f: 0x29, + 0x166: 0x2a, + 0x16c: 0x2b, 0x16d: 0x2c, + 0x17a: 0x2d, 0x17b: 0x2e, 0x17c: 0x0e, 0x17d: 0x0e, 0x17e: 0x0e, 0x17f: 0x2f, + // Block 0x6, offset 0x180 + 0x180: 0x30, 0x181: 0x31, 0x182: 0x32, 0x183: 0x33, 0x184: 0x34, 0x185: 0x35, 0x186: 0x36, 0x187: 0x37, + 0x188: 0x38, 0x189: 0x39, 0x18a: 0x0e, 0x18b: 0x3a, 0x18c: 0x0e, 0x18d: 0x0e, 0x18e: 0x0e, 0x18f: 0x0e, + 0x190: 0x0e, 0x191: 0x0e, 0x192: 0x0e, 0x193: 0x0e, 0x194: 0x0e, 0x195: 0x0e, 0x196: 0x0e, 0x197: 0x0e, + 0x198: 0x0e, 0x199: 0x0e, 0x19a: 0x0e, 0x19b: 0x0e, 0x19c: 0x0e, 0x19d: 0x0e, 0x19e: 0x0e, 0x19f: 0x0e, + 0x1a0: 0x0e, 0x1a1: 0x0e, 0x1a2: 0x0e, 0x1a3: 0x0e, 0x1a4: 0x0e, 0x1a5: 0x0e, 0x1a6: 0x0e, 0x1a7: 0x0e, + 0x1a8: 0x0e, 0x1a9: 0x0e, 0x1aa: 0x0e, 0x1ab: 0x0e, 0x1ac: 0x0e, 0x1ad: 0x0e, 0x1ae: 0x0e, 0x1af: 0x0e, + 0x1b0: 0x0e, 0x1b1: 0x0e, 0x1b2: 0x0e, 0x1b3: 0x0e, 0x1b4: 0x0e, 0x1b5: 0x0e, 0x1b6: 0x0e, 0x1b7: 0x0e, + 0x1b8: 0x0e, 0x1b9: 0x0e, 0x1ba: 0x0e, 0x1bb: 0x0e, 0x1bc: 0x0e, 0x1bd: 0x0e, 0x1be: 0x0e, 0x1bf: 0x0e, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x0e, 0x1c1: 0x0e, 0x1c2: 0x0e, 0x1c3: 0x0e, 0x1c4: 0x0e, 0x1c5: 0x0e, 0x1c6: 0x0e, 0x1c7: 0x0e, + 0x1c8: 0x0e, 0x1c9: 0x0e, 0x1ca: 0x0e, 0x1cb: 0x0e, 0x1cc: 0x0e, 0x1cd: 0x0e, 0x1ce: 0x0e, 0x1cf: 0x0e, + 0x1d0: 0x0e, 0x1d1: 0x0e, 0x1d2: 0x0e, 0x1d3: 0x0e, 0x1d4: 0x0e, 0x1d5: 0x0e, 0x1d6: 0x0e, 0x1d7: 0x0e, + 0x1d8: 0x0e, 0x1d9: 0x0e, 0x1da: 0x0e, 0x1db: 0x0e, 0x1dc: 0x0e, 0x1dd: 0x0e, 0x1de: 0x0e, 0x1df: 0x0e, + 0x1e0: 0x0e, 0x1e1: 0x0e, 0x1e2: 0x0e, 0x1e3: 0x0e, 0x1e4: 0x0e, 0x1e5: 0x0e, 0x1e6: 0x0e, 0x1e7: 0x0e, + 0x1e8: 0x0e, 0x1e9: 0x0e, 0x1ea: 0x0e, 0x1eb: 0x0e, 0x1ec: 0x0e, 0x1ed: 0x0e, 0x1ee: 0x0e, 0x1ef: 0x0e, + 0x1f0: 0x0e, 0x1f1: 0x0e, 0x1f2: 0x0e, 0x1f3: 0x0e, 0x1f4: 0x0e, 0x1f5: 0x0e, 0x1f6: 0x0e, + 0x1f8: 0x0e, 0x1f9: 0x0e, 0x1fa: 0x0e, 0x1fb: 0x0e, 0x1fc: 0x0e, 0x1fd: 0x0e, 0x1fe: 0x0e, 0x1ff: 0x0e, + // Block 0x8, offset 0x200 + 0x200: 0x0e, 0x201: 0x0e, 0x202: 0x0e, 0x203: 0x0e, 0x204: 0x0e, 0x205: 0x0e, 0x206: 0x0e, 0x207: 0x0e, + 0x208: 0x0e, 0x209: 0x0e, 0x20a: 0x0e, 0x20b: 0x0e, 0x20c: 0x0e, 0x20d: 0x0e, 0x20e: 0x0e, 0x20f: 0x0e, + 0x210: 0x0e, 0x211: 0x0e, 0x212: 0x0e, 0x213: 0x0e, 0x214: 0x0e, 0x215: 0x0e, 0x216: 0x0e, 0x217: 0x0e, + 0x218: 0x0e, 0x219: 0x0e, 0x21a: 0x0e, 0x21b: 0x0e, 0x21c: 0x0e, 0x21d: 0x0e, 0x21e: 0x0e, 0x21f: 0x0e, + 0x220: 0x0e, 0x221: 0x0e, 0x222: 0x0e, 0x223: 0x0e, 0x224: 0x0e, 0x225: 0x0e, 0x226: 0x0e, 0x227: 0x0e, + 0x228: 0x0e, 0x229: 0x0e, 0x22a: 0x0e, 0x22b: 0x0e, 0x22c: 0x0e, 0x22d: 0x0e, 0x22e: 0x0e, 0x22f: 0x0e, + 0x230: 0x0e, 0x231: 0x0e, 0x232: 0x0e, 0x233: 0x0e, 0x234: 0x0e, 0x235: 0x0e, 0x236: 0x0e, 0x237: 0x0e, + 0x238: 0x0e, 0x239: 0x0e, 0x23a: 0x0e, 0x23b: 0x0e, 0x23c: 0x0e, 0x23d: 0x0e, 0x23e: 0x0e, 0x23f: 0x0e, + // Block 0x9, offset 0x240 + 0x240: 0x0e, 0x241: 0x0e, 0x242: 0x0e, 0x243: 0x0e, 0x244: 0x0e, 0x245: 0x0e, 0x246: 0x0e, 0x247: 0x0e, + 0x248: 0x0e, 0x249: 0x0e, 0x24a: 0x0e, 0x24b: 0x0e, 0x24c: 0x0e, 0x24d: 0x0e, 0x24e: 0x0e, 0x24f: 0x0e, + 0x250: 0x0e, 0x251: 0x0e, 0x252: 0x3b, 0x253: 0x3c, + 0x265: 0x3d, + 0x270: 0x0e, 0x271: 0x0e, 0x272: 0x0e, 0x273: 0x0e, 0x274: 0x0e, 0x275: 0x0e, 0x276: 0x0e, 0x277: 0x0e, + 0x278: 0x0e, 0x279: 0x0e, 0x27a: 0x0e, 0x27b: 0x0e, 0x27c: 0x0e, 0x27d: 0x0e, 0x27e: 0x0e, 0x27f: 0x0e, + // Block 0xa, offset 0x280 + 0x280: 0x0e, 0x281: 0x0e, 0x282: 0x0e, 0x283: 0x0e, 0x284: 0x0e, 0x285: 0x0e, 0x286: 0x0e, 0x287: 0x0e, + 0x288: 0x0e, 0x289: 0x0e, 0x28a: 0x0e, 0x28b: 0x0e, 0x28c: 0x0e, 0x28d: 0x0e, 0x28e: 0x0e, 0x28f: 0x0e, + 0x290: 0x0e, 0x291: 0x0e, 0x292: 0x0e, 0x293: 0x0e, 0x294: 0x0e, 0x295: 0x0e, 0x296: 0x0e, 0x297: 0x0e, + 0x298: 0x0e, 0x299: 0x0e, 0x29a: 0x0e, 0x29b: 0x0e, 0x29c: 0x0e, 0x29d: 0x0e, 0x29e: 0x3e, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x08, 0x2c1: 0x08, 0x2c2: 0x08, 0x2c3: 0x08, 0x2c4: 0x08, 0x2c5: 0x08, 0x2c6: 0x08, 0x2c7: 0x08, + 0x2c8: 0x08, 0x2c9: 0x08, 0x2ca: 0x08, 0x2cb: 0x08, 0x2cc: 0x08, 0x2cd: 0x08, 0x2ce: 0x08, 0x2cf: 0x08, + 0x2d0: 0x08, 0x2d1: 0x08, 0x2d2: 0x08, 0x2d3: 0x08, 0x2d4: 0x08, 0x2d5: 0x08, 0x2d6: 0x08, 0x2d7: 0x08, + 0x2d8: 0x08, 0x2d9: 0x08, 0x2da: 0x08, 0x2db: 0x08, 0x2dc: 0x08, 0x2dd: 0x08, 0x2de: 0x08, 0x2df: 0x08, + 0x2e0: 0x08, 0x2e1: 0x08, 0x2e2: 0x08, 0x2e3: 0x08, 0x2e4: 0x08, 0x2e5: 0x08, 0x2e6: 0x08, 0x2e7: 0x08, + 0x2e8: 0x08, 0x2e9: 0x08, 0x2ea: 0x08, 0x2eb: 0x08, 0x2ec: 0x08, 0x2ed: 0x08, 0x2ee: 0x08, 0x2ef: 0x08, + 0x2f0: 0x08, 0x2f1: 0x08, 0x2f2: 0x08, 0x2f3: 0x08, 0x2f4: 0x08, 0x2f5: 0x08, 0x2f6: 0x08, 0x2f7: 0x08, + 0x2f8: 0x08, 0x2f9: 0x08, 0x2fa: 0x08, 0x2fb: 0x08, 0x2fc: 0x08, 0x2fd: 0x08, 0x2fe: 0x08, 0x2ff: 0x08, + // Block 0xc, offset 0x300 + 0x300: 0x08, 0x301: 0x08, 0x302: 0x08, 0x303: 0x08, 0x304: 0x08, 0x305: 0x08, 0x306: 0x08, 0x307: 0x08, + 0x308: 0x08, 0x309: 0x08, 0x30a: 0x08, 0x30b: 0x08, 0x30c: 0x08, 0x30d: 0x08, 0x30e: 0x08, 0x30f: 0x08, + 0x310: 0x08, 0x311: 0x08, 0x312: 0x08, 0x313: 0x08, 0x314: 0x08, 0x315: 0x08, 0x316: 0x08, 0x317: 0x08, + 0x318: 0x08, 0x319: 0x08, 0x31a: 0x08, 0x31b: 0x08, 0x31c: 0x08, 0x31d: 0x08, 0x31e: 0x08, 0x31f: 0x08, + 0x320: 0x08, 0x321: 0x08, 0x322: 0x08, 0x323: 0x08, 0x324: 0x0e, 0x325: 0x0e, 0x326: 0x0e, 0x327: 0x0e, + 0x328: 0x0e, 0x329: 0x0e, 0x32a: 0x0e, 0x32b: 0x0e, + 0x338: 0x3f, 0x339: 0x40, 0x33c: 0x41, 0x33d: 0x42, 0x33e: 0x43, 0x33f: 0x44, + // Block 0xd, offset 0x340 + 0x37f: 0x45, + // Block 0xe, offset 0x380 + 0x380: 0x0e, 0x381: 0x0e, 0x382: 0x0e, 0x383: 0x0e, 0x384: 0x0e, 0x385: 0x0e, 0x386: 0x0e, 0x387: 0x0e, + 0x388: 0x0e, 0x389: 0x0e, 0x38a: 0x0e, 0x38b: 0x0e, 0x38c: 0x0e, 0x38d: 0x0e, 0x38e: 0x0e, 0x38f: 0x0e, + 0x390: 0x0e, 0x391: 0x0e, 0x392: 0x0e, 0x393: 0x0e, 0x394: 0x0e, 0x395: 0x0e, 0x396: 0x0e, 0x397: 0x0e, + 0x398: 0x0e, 0x399: 0x0e, 0x39a: 0x0e, 0x39b: 0x0e, 0x39c: 0x0e, 0x39d: 0x0e, 0x39e: 0x0e, 0x39f: 0x46, + 0x3a0: 0x0e, 0x3a1: 0x0e, 0x3a2: 0x0e, 0x3a3: 0x0e, 0x3a4: 0x0e, 0x3a5: 0x0e, 0x3a6: 0x0e, 0x3a7: 0x0e, + 0x3a8: 0x0e, 0x3a9: 0x0e, 0x3aa: 0x0e, 0x3ab: 0x47, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x0e, 0x3c1: 0x0e, 0x3c2: 0x0e, 0x3c3: 0x0e, 0x3c4: 0x48, 0x3c5: 0x49, 0x3c6: 0x0e, 0x3c7: 0x0e, + 0x3c8: 0x0e, 0x3c9: 0x0e, 0x3ca: 0x0e, 0x3cb: 0x4a, + // Block 0x10, offset 0x400 + 0x400: 0x4b, 0x403: 0x4c, 0x404: 0x4d, 0x405: 0x4e, 0x406: 0x4f, + 0x408: 0x50, 0x409: 0x51, 0x40c: 0x52, 0x40d: 0x53, 0x40e: 0x54, 0x40f: 0x55, + 0x410: 0x3a, 0x411: 0x56, 0x412: 0x0e, 0x413: 0x57, 0x414: 0x58, 0x415: 0x59, 0x416: 0x5a, 0x417: 0x5b, + 0x418: 0x0e, 0x419: 0x5c, 0x41a: 0x0e, 0x41b: 0x5d, + 0x424: 0x5e, 0x425: 0x5f, 0x426: 0x60, 0x427: 0x61, + // Block 0x11, offset 0x440 + 0x456: 0x0b, 0x457: 0x06, + 0x458: 0x0c, 0x45b: 0x0d, 0x45f: 0x0e, + 0x460: 0x06, 0x461: 0x06, 0x462: 0x06, 0x463: 0x06, 0x464: 0x06, 0x465: 0x06, 0x466: 0x06, 0x467: 0x06, + 0x468: 0x06, 0x469: 0x06, 0x46a: 0x06, 0x46b: 0x06, 0x46c: 0x06, 0x46d: 0x06, 0x46e: 0x06, 0x46f: 0x06, + 0x470: 0x06, 0x471: 0x06, 0x472: 0x06, 0x473: 0x06, 0x474: 0x06, 0x475: 0x06, 0x476: 0x06, 0x477: 0x06, + 0x478: 0x06, 0x479: 0x06, 0x47a: 0x06, 0x47b: 0x06, 0x47c: 0x06, 0x47d: 0x06, 0x47e: 0x06, 0x47f: 0x06, + // Block 0x12, offset 0x480 + 0x484: 0x08, 0x485: 0x08, 0x486: 0x08, 0x487: 0x09, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x08, 0x4c1: 0x08, 0x4c2: 0x08, 0x4c3: 0x08, 0x4c4: 0x08, 0x4c5: 0x08, 0x4c6: 0x08, 0x4c7: 0x08, + 0x4c8: 0x08, 0x4c9: 0x08, 0x4ca: 0x08, 0x4cb: 0x08, 0x4cc: 0x08, 0x4cd: 0x08, 0x4ce: 0x08, 0x4cf: 0x08, + 0x4d0: 0x08, 0x4d1: 0x08, 0x4d2: 0x08, 0x4d3: 0x08, 0x4d4: 0x08, 0x4d5: 0x08, 0x4d6: 0x08, 0x4d7: 0x08, + 0x4d8: 0x08, 0x4d9: 0x08, 0x4da: 0x08, 0x4db: 0x08, 0x4dc: 0x08, 0x4dd: 0x08, 0x4de: 0x08, 0x4df: 0x08, + 0x4e0: 0x08, 0x4e1: 0x08, 0x4e2: 0x08, 0x4e3: 0x08, 0x4e4: 0x08, 0x4e5: 0x08, 0x4e6: 0x08, 0x4e7: 0x08, + 0x4e8: 0x08, 0x4e9: 0x08, 0x4ea: 0x08, 0x4eb: 0x08, 0x4ec: 0x08, 0x4ed: 0x08, 0x4ee: 0x08, 0x4ef: 0x08, + 0x4f0: 0x08, 0x4f1: 0x08, 0x4f2: 0x08, 0x4f3: 0x08, 0x4f4: 0x08, 0x4f5: 0x08, 0x4f6: 0x08, 0x4f7: 0x08, + 0x4f8: 0x08, 0x4f9: 0x08, 0x4fa: 0x08, 0x4fb: 0x08, 0x4fc: 0x08, 0x4fd: 0x08, 0x4fe: 0x08, 0x4ff: 0x62, + // Block 0x14, offset 0x500 + 0x520: 0x10, + 0x530: 0x09, 0x531: 0x09, 0x532: 0x09, 0x533: 0x09, 0x534: 0x09, 0x535: 0x09, 0x536: 0x09, 0x537: 0x09, + 0x538: 0x09, 0x539: 0x09, 0x53a: 0x09, 0x53b: 0x09, 0x53c: 0x09, 0x53d: 0x09, 0x53e: 0x09, 0x53f: 0x11, + // Block 0x15, offset 0x540 + 0x540: 0x09, 0x541: 0x09, 0x542: 0x09, 0x543: 0x09, 0x544: 0x09, 0x545: 0x09, 0x546: 0x09, 0x547: 0x09, + 0x548: 0x09, 0x549: 0x09, 0x54a: 0x09, 0x54b: 0x09, 0x54c: 0x09, 0x54d: 0x09, 0x54e: 0x09, 0x54f: 0x11, +} + +// inverseData contains 4-byte entries of the following format: +// <0 padding> +// The last byte of the UTF-8-encoded rune is xor-ed with the last byte of the +// UTF-8 encoding of the original rune. Mappings often have the following +// pattern: +// A -> A (U+FF21 -> U+0041) +// B -> B (U+FF22 -> U+0042) +// ... +// By xor-ing the last byte the same entry can be shared by many mappings. This +// reduces the total number of distinct entries by about two thirds. +// The resulting entry for the aforementioned mappings is +// { 0x01, 0xE0, 0x00, 0x00 } +// Using this entry to map U+FF21 (UTF-8 [EF BC A1]), we get +// E0 ^ A1 = 41. +// Similarly, for U+FF22 (UTF-8 [EF BC A2]), we get +// E0 ^ A2 = 42. +// Note that because of the xor-ing, the byte sequence stored in the entry is +// not valid UTF-8. +var inverseData = [150][4]byte{ + {0x00, 0x00, 0x00, 0x00}, + {0x03, 0xe3, 0x80, 0xa0}, + {0x03, 0xef, 0xbc, 0xa0}, + {0x03, 0xef, 0xbc, 0xe0}, + {0x03, 0xef, 0xbd, 0xe0}, + {0x03, 0xef, 0xbf, 0x02}, + {0x03, 0xef, 0xbf, 0x00}, + {0x03, 0xef, 0xbf, 0x0e}, + {0x03, 0xef, 0xbf, 0x0c}, + {0x03, 0xef, 0xbf, 0x0f}, + {0x03, 0xef, 0xbf, 0x39}, + {0x03, 0xef, 0xbf, 0x3b}, + {0x03, 0xef, 0xbf, 0x3f}, + {0x03, 0xef, 0xbf, 0x2a}, + {0x03, 0xef, 0xbf, 0x0d}, + {0x03, 0xef, 0xbf, 0x25}, + {0x03, 0xef, 0xbd, 0x1a}, + {0x03, 0xef, 0xbd, 0x26}, + {0x01, 0xa0, 0x00, 0x00}, + {0x03, 0xef, 0xbd, 0x25}, + {0x03, 0xef, 0xbd, 0x23}, + {0x03, 0xef, 0xbd, 0x2e}, + {0x03, 0xef, 0xbe, 0x07}, + {0x03, 0xef, 0xbe, 0x05}, + {0x03, 0xef, 0xbd, 0x06}, + {0x03, 0xef, 0xbd, 0x13}, + {0x03, 0xef, 0xbd, 0x0b}, + {0x03, 0xef, 0xbd, 0x16}, + {0x03, 0xef, 0xbd, 0x0c}, + {0x03, 0xef, 0xbd, 0x15}, + {0x03, 0xef, 0xbd, 0x0d}, + {0x03, 0xef, 0xbd, 0x1c}, + {0x03, 0xef, 0xbd, 0x02}, + {0x03, 0xef, 0xbd, 0x1f}, + {0x03, 0xef, 0xbd, 0x1d}, + {0x03, 0xef, 0xbd, 0x17}, + {0x03, 0xef, 0xbd, 0x08}, + {0x03, 0xef, 0xbd, 0x09}, + {0x03, 0xef, 0xbd, 0x0e}, + {0x03, 0xef, 0xbd, 0x04}, + {0x03, 0xef, 0xbd, 0x05}, + {0x03, 0xef, 0xbe, 0x3f}, + {0x03, 0xef, 0xbe, 0x00}, + {0x03, 0xef, 0xbd, 0x2c}, + {0x03, 0xef, 0xbe, 0x06}, + {0x03, 0xef, 0xbe, 0x0c}, + {0x03, 0xef, 0xbe, 0x0f}, + {0x03, 0xef, 0xbe, 0x0d}, + {0x03, 0xef, 0xbe, 0x0b}, + {0x03, 0xef, 0xbe, 0x19}, + {0x03, 0xef, 0xbe, 0x15}, + {0x03, 0xef, 0xbe, 0x11}, + {0x03, 0xef, 0xbe, 0x31}, + {0x03, 0xef, 0xbe, 0x33}, + {0x03, 0xef, 0xbd, 0x0f}, + {0x03, 0xef, 0xbe, 0x30}, + {0x03, 0xef, 0xbe, 0x3e}, + {0x03, 0xef, 0xbe, 0x32}, + {0x03, 0xef, 0xbe, 0x36}, + {0x03, 0xef, 0xbd, 0x14}, + {0x03, 0xef, 0xbe, 0x2e}, + {0x03, 0xef, 0xbd, 0x1e}, + {0x03, 0xef, 0xbe, 0x10}, + {0x03, 0xef, 0xbf, 0x13}, + {0x03, 0xef, 0xbf, 0x15}, + {0x03, 0xef, 0xbf, 0x17}, + {0x03, 0xef, 0xbf, 0x1f}, + {0x03, 0xef, 0xbf, 0x1d}, + {0x03, 0xef, 0xbf, 0x1b}, + {0x03, 0xef, 0xbf, 0x09}, + {0x03, 0xef, 0xbf, 0x0b}, + {0x03, 0xef, 0xbf, 0x37}, + {0x03, 0xef, 0xbe, 0x04}, + {0x01, 0xe0, 0x00, 0x00}, + {0x03, 0xe2, 0xa6, 0x1a}, + {0x03, 0xe2, 0xa6, 0x26}, + {0x03, 0xe3, 0x80, 0x23}, + {0x03, 0xe3, 0x80, 0x2e}, + {0x03, 0xe3, 0x80, 0x25}, + {0x03, 0xe3, 0x83, 0x1e}, + {0x03, 0xe3, 0x83, 0x14}, + {0x03, 0xe3, 0x82, 0x06}, + {0x03, 0xe3, 0x82, 0x0b}, + {0x03, 0xe3, 0x82, 0x0c}, + {0x03, 0xe3, 0x82, 0x0d}, + {0x03, 0xe3, 0x82, 0x02}, + {0x03, 0xe3, 0x83, 0x0f}, + {0x03, 0xe3, 0x83, 0x08}, + {0x03, 0xe3, 0x83, 0x09}, + {0x03, 0xe3, 0x83, 0x2c}, + {0x03, 0xe3, 0x83, 0x0c}, + {0x03, 0xe3, 0x82, 0x13}, + {0x03, 0xe3, 0x82, 0x16}, + {0x03, 0xe3, 0x82, 0x15}, + {0x03, 0xe3, 0x82, 0x1c}, + {0x03, 0xe3, 0x82, 0x1f}, + {0x03, 0xe3, 0x82, 0x1d}, + {0x03, 0xe3, 0x82, 0x1a}, + {0x03, 0xe3, 0x82, 0x17}, + {0x03, 0xe3, 0x82, 0x08}, + {0x03, 0xe3, 0x82, 0x09}, + {0x03, 0xe3, 0x82, 0x0e}, + {0x03, 0xe3, 0x82, 0x04}, + {0x03, 0xe3, 0x82, 0x05}, + {0x03, 0xe3, 0x82, 0x3f}, + {0x03, 0xe3, 0x83, 0x00}, + {0x03, 0xe3, 0x83, 0x06}, + {0x03, 0xe3, 0x83, 0x05}, + {0x03, 0xe3, 0x83, 0x0d}, + {0x03, 0xe3, 0x83, 0x0b}, + {0x03, 0xe3, 0x83, 0x07}, + {0x03, 0xe3, 0x83, 0x19}, + {0x03, 0xe3, 0x83, 0x15}, + {0x03, 0xe3, 0x83, 0x11}, + {0x03, 0xe3, 0x83, 0x31}, + {0x03, 0xe3, 0x83, 0x33}, + {0x03, 0xe3, 0x83, 0x30}, + {0x03, 0xe3, 0x83, 0x3e}, + {0x03, 0xe3, 0x83, 0x32}, + {0x03, 0xe3, 0x83, 0x36}, + {0x03, 0xe3, 0x83, 0x2e}, + {0x03, 0xe3, 0x82, 0x07}, + {0x03, 0xe3, 0x85, 0x04}, + {0x03, 0xe3, 0x84, 0x10}, + {0x03, 0xe3, 0x85, 0x30}, + {0x03, 0xe3, 0x85, 0x0d}, + {0x03, 0xe3, 0x85, 0x13}, + {0x03, 0xe3, 0x85, 0x15}, + {0x03, 0xe3, 0x85, 0x17}, + {0x03, 0xe3, 0x85, 0x1f}, + {0x03, 0xe3, 0x85, 0x1d}, + {0x03, 0xe3, 0x85, 0x1b}, + {0x03, 0xe3, 0x85, 0x09}, + {0x03, 0xe3, 0x85, 0x0f}, + {0x03, 0xe3, 0x85, 0x0b}, + {0x03, 0xe3, 0x85, 0x37}, + {0x03, 0xe3, 0x85, 0x3b}, + {0x03, 0xe3, 0x85, 0x39}, + {0x03, 0xe3, 0x85, 0x3f}, + {0x02, 0xc2, 0x02, 0x00}, + {0x02, 0xc2, 0x0e, 0x00}, + {0x02, 0xc2, 0x0c, 0x00}, + {0x02, 0xc2, 0x00, 0x00}, + {0x03, 0xe2, 0x82, 0x0f}, + {0x03, 0xe2, 0x94, 0x2a}, + {0x03, 0xe2, 0x86, 0x39}, + {0x03, 0xe2, 0x86, 0x3b}, + {0x03, 0xe2, 0x86, 0x3f}, + {0x03, 0xe2, 0x96, 0x0d}, + {0x03, 0xe2, 0x97, 0x25}, +} + +// Total table size 14936 bytes (14KiB) diff --git a/vendor/golang.org/x/text/width/tables11.0.0.go b/vendor/golang.org/x/text/width/tables11.0.0.go new file mode 100644 index 000000000..d6def0e7b --- /dev/null +++ b/vendor/golang.org/x/text/width/tables11.0.0.go @@ -0,0 +1,1330 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build go1.13 + +package width + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "11.0.0" + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *widthTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return widthValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = widthIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = widthIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = widthIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *widthTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return widthValues[c0] + } + i := widthIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = widthIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = widthIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *widthTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return widthValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = widthIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = widthIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = widthIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *widthTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return widthValues[c0] + } + i := widthIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = widthIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = widthIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// widthTrie. Total size: 14336 bytes (14.00 KiB). Checksum: c0f7712776e71cd4. +type widthTrie struct{} + +func newWidthTrie(i int) *widthTrie { + return &widthTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *widthTrie) lookupValue(n uint32, b byte) uint16 { + switch { + default: + return uint16(widthValues[n<<6+uint32(b)]) + } +} + +// widthValues: 101 blocks, 6464 entries, 12928 bytes +// The third block is the zero block. +var widthValues = [6464]uint16{ + // Block 0x0, offset 0x0 + 0x20: 0x6001, 0x21: 0x6002, 0x22: 0x6002, 0x23: 0x6002, + 0x24: 0x6002, 0x25: 0x6002, 0x26: 0x6002, 0x27: 0x6002, 0x28: 0x6002, 0x29: 0x6002, + 0x2a: 0x6002, 0x2b: 0x6002, 0x2c: 0x6002, 0x2d: 0x6002, 0x2e: 0x6002, 0x2f: 0x6002, + 0x30: 0x6002, 0x31: 0x6002, 0x32: 0x6002, 0x33: 0x6002, 0x34: 0x6002, 0x35: 0x6002, + 0x36: 0x6002, 0x37: 0x6002, 0x38: 0x6002, 0x39: 0x6002, 0x3a: 0x6002, 0x3b: 0x6002, + 0x3c: 0x6002, 0x3d: 0x6002, 0x3e: 0x6002, 0x3f: 0x6002, + // Block 0x1, offset 0x40 + 0x40: 0x6003, 0x41: 0x6003, 0x42: 0x6003, 0x43: 0x6003, 0x44: 0x6003, 0x45: 0x6003, + 0x46: 0x6003, 0x47: 0x6003, 0x48: 0x6003, 0x49: 0x6003, 0x4a: 0x6003, 0x4b: 0x6003, + 0x4c: 0x6003, 0x4d: 0x6003, 0x4e: 0x6003, 0x4f: 0x6003, 0x50: 0x6003, 0x51: 0x6003, + 0x52: 0x6003, 0x53: 0x6003, 0x54: 0x6003, 0x55: 0x6003, 0x56: 0x6003, 0x57: 0x6003, + 0x58: 0x6003, 0x59: 0x6003, 0x5a: 0x6003, 0x5b: 0x6003, 0x5c: 0x6003, 0x5d: 0x6003, + 0x5e: 0x6003, 0x5f: 0x6003, 0x60: 0x6004, 0x61: 0x6004, 0x62: 0x6004, 0x63: 0x6004, + 0x64: 0x6004, 0x65: 0x6004, 0x66: 0x6004, 0x67: 0x6004, 0x68: 0x6004, 0x69: 0x6004, + 0x6a: 0x6004, 0x6b: 0x6004, 0x6c: 0x6004, 0x6d: 0x6004, 0x6e: 0x6004, 0x6f: 0x6004, + 0x70: 0x6004, 0x71: 0x6004, 0x72: 0x6004, 0x73: 0x6004, 0x74: 0x6004, 0x75: 0x6004, + 0x76: 0x6004, 0x77: 0x6004, 0x78: 0x6004, 0x79: 0x6004, 0x7a: 0x6004, 0x7b: 0x6004, + 0x7c: 0x6004, 0x7d: 0x6004, 0x7e: 0x6004, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xe1: 0x2000, 0xe2: 0x6005, 0xe3: 0x6005, + 0xe4: 0x2000, 0xe5: 0x6006, 0xe6: 0x6005, 0xe7: 0x2000, 0xe8: 0x2000, + 0xea: 0x2000, 0xec: 0x6007, 0xed: 0x2000, 0xee: 0x2000, 0xef: 0x6008, + 0xf0: 0x2000, 0xf1: 0x2000, 0xf2: 0x2000, 0xf3: 0x2000, 0xf4: 0x2000, + 0xf6: 0x2000, 0xf7: 0x2000, 0xf8: 0x2000, 0xf9: 0x2000, 0xfa: 0x2000, + 0xfc: 0x2000, 0xfd: 0x2000, 0xfe: 0x2000, 0xff: 0x2000, + // Block 0x4, offset 0x100 + 0x106: 0x2000, + 0x110: 0x2000, + 0x117: 0x2000, + 0x118: 0x2000, + 0x11e: 0x2000, 0x11f: 0x2000, 0x120: 0x2000, 0x121: 0x2000, + 0x126: 0x2000, 0x128: 0x2000, 0x129: 0x2000, + 0x12a: 0x2000, 0x12c: 0x2000, 0x12d: 0x2000, + 0x130: 0x2000, 0x132: 0x2000, 0x133: 0x2000, + 0x137: 0x2000, 0x138: 0x2000, 0x139: 0x2000, 0x13a: 0x2000, + 0x13c: 0x2000, 0x13e: 0x2000, + // Block 0x5, offset 0x140 + 0x141: 0x2000, + 0x151: 0x2000, + 0x153: 0x2000, + 0x15b: 0x2000, + 0x166: 0x2000, 0x167: 0x2000, + 0x16b: 0x2000, + 0x171: 0x2000, 0x172: 0x2000, 0x173: 0x2000, + 0x178: 0x2000, + 0x17f: 0x2000, + // Block 0x6, offset 0x180 + 0x180: 0x2000, 0x181: 0x2000, 0x182: 0x2000, 0x184: 0x2000, + 0x188: 0x2000, 0x189: 0x2000, 0x18a: 0x2000, 0x18b: 0x2000, + 0x18d: 0x2000, + 0x192: 0x2000, 0x193: 0x2000, + 0x1a6: 0x2000, 0x1a7: 0x2000, + 0x1ab: 0x2000, + // Block 0x7, offset 0x1c0 + 0x1ce: 0x2000, 0x1d0: 0x2000, + 0x1d2: 0x2000, 0x1d4: 0x2000, 0x1d6: 0x2000, + 0x1d8: 0x2000, 0x1da: 0x2000, 0x1dc: 0x2000, + // Block 0x8, offset 0x200 + 0x211: 0x2000, + 0x221: 0x2000, + // Block 0x9, offset 0x240 + 0x244: 0x2000, + 0x247: 0x2000, 0x249: 0x2000, 0x24a: 0x2000, 0x24b: 0x2000, + 0x24d: 0x2000, 0x250: 0x2000, + 0x258: 0x2000, 0x259: 0x2000, 0x25a: 0x2000, 0x25b: 0x2000, 0x25d: 0x2000, + 0x25f: 0x2000, + // Block 0xa, offset 0x280 + 0x280: 0x2000, 0x281: 0x2000, 0x282: 0x2000, 0x283: 0x2000, 0x284: 0x2000, 0x285: 0x2000, + 0x286: 0x2000, 0x287: 0x2000, 0x288: 0x2000, 0x289: 0x2000, 0x28a: 0x2000, 0x28b: 0x2000, + 0x28c: 0x2000, 0x28d: 0x2000, 0x28e: 0x2000, 0x28f: 0x2000, 0x290: 0x2000, 0x291: 0x2000, + 0x292: 0x2000, 0x293: 0x2000, 0x294: 0x2000, 0x295: 0x2000, 0x296: 0x2000, 0x297: 0x2000, + 0x298: 0x2000, 0x299: 0x2000, 0x29a: 0x2000, 0x29b: 0x2000, 0x29c: 0x2000, 0x29d: 0x2000, + 0x29e: 0x2000, 0x29f: 0x2000, 0x2a0: 0x2000, 0x2a1: 0x2000, 0x2a2: 0x2000, 0x2a3: 0x2000, + 0x2a4: 0x2000, 0x2a5: 0x2000, 0x2a6: 0x2000, 0x2a7: 0x2000, 0x2a8: 0x2000, 0x2a9: 0x2000, + 0x2aa: 0x2000, 0x2ab: 0x2000, 0x2ac: 0x2000, 0x2ad: 0x2000, 0x2ae: 0x2000, 0x2af: 0x2000, + 0x2b0: 0x2000, 0x2b1: 0x2000, 0x2b2: 0x2000, 0x2b3: 0x2000, 0x2b4: 0x2000, 0x2b5: 0x2000, + 0x2b6: 0x2000, 0x2b7: 0x2000, 0x2b8: 0x2000, 0x2b9: 0x2000, 0x2ba: 0x2000, 0x2bb: 0x2000, + 0x2bc: 0x2000, 0x2bd: 0x2000, 0x2be: 0x2000, 0x2bf: 0x2000, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x2000, 0x2c1: 0x2000, 0x2c2: 0x2000, 0x2c3: 0x2000, 0x2c4: 0x2000, 0x2c5: 0x2000, + 0x2c6: 0x2000, 0x2c7: 0x2000, 0x2c8: 0x2000, 0x2c9: 0x2000, 0x2ca: 0x2000, 0x2cb: 0x2000, + 0x2cc: 0x2000, 0x2cd: 0x2000, 0x2ce: 0x2000, 0x2cf: 0x2000, 0x2d0: 0x2000, 0x2d1: 0x2000, + 0x2d2: 0x2000, 0x2d3: 0x2000, 0x2d4: 0x2000, 0x2d5: 0x2000, 0x2d6: 0x2000, 0x2d7: 0x2000, + 0x2d8: 0x2000, 0x2d9: 0x2000, 0x2da: 0x2000, 0x2db: 0x2000, 0x2dc: 0x2000, 0x2dd: 0x2000, + 0x2de: 0x2000, 0x2df: 0x2000, 0x2e0: 0x2000, 0x2e1: 0x2000, 0x2e2: 0x2000, 0x2e3: 0x2000, + 0x2e4: 0x2000, 0x2e5: 0x2000, 0x2e6: 0x2000, 0x2e7: 0x2000, 0x2e8: 0x2000, 0x2e9: 0x2000, + 0x2ea: 0x2000, 0x2eb: 0x2000, 0x2ec: 0x2000, 0x2ed: 0x2000, 0x2ee: 0x2000, 0x2ef: 0x2000, + // Block 0xc, offset 0x300 + 0x311: 0x2000, + 0x312: 0x2000, 0x313: 0x2000, 0x314: 0x2000, 0x315: 0x2000, 0x316: 0x2000, 0x317: 0x2000, + 0x318: 0x2000, 0x319: 0x2000, 0x31a: 0x2000, 0x31b: 0x2000, 0x31c: 0x2000, 0x31d: 0x2000, + 0x31e: 0x2000, 0x31f: 0x2000, 0x320: 0x2000, 0x321: 0x2000, 0x323: 0x2000, + 0x324: 0x2000, 0x325: 0x2000, 0x326: 0x2000, 0x327: 0x2000, 0x328: 0x2000, 0x329: 0x2000, + 0x331: 0x2000, 0x332: 0x2000, 0x333: 0x2000, 0x334: 0x2000, 0x335: 0x2000, + 0x336: 0x2000, 0x337: 0x2000, 0x338: 0x2000, 0x339: 0x2000, 0x33a: 0x2000, 0x33b: 0x2000, + 0x33c: 0x2000, 0x33d: 0x2000, 0x33e: 0x2000, 0x33f: 0x2000, + // Block 0xd, offset 0x340 + 0x340: 0x2000, 0x341: 0x2000, 0x343: 0x2000, 0x344: 0x2000, 0x345: 0x2000, + 0x346: 0x2000, 0x347: 0x2000, 0x348: 0x2000, 0x349: 0x2000, + // Block 0xe, offset 0x380 + 0x381: 0x2000, + 0x390: 0x2000, 0x391: 0x2000, + 0x392: 0x2000, 0x393: 0x2000, 0x394: 0x2000, 0x395: 0x2000, 0x396: 0x2000, 0x397: 0x2000, + 0x398: 0x2000, 0x399: 0x2000, 0x39a: 0x2000, 0x39b: 0x2000, 0x39c: 0x2000, 0x39d: 0x2000, + 0x39e: 0x2000, 0x39f: 0x2000, 0x3a0: 0x2000, 0x3a1: 0x2000, 0x3a2: 0x2000, 0x3a3: 0x2000, + 0x3a4: 0x2000, 0x3a5: 0x2000, 0x3a6: 0x2000, 0x3a7: 0x2000, 0x3a8: 0x2000, 0x3a9: 0x2000, + 0x3aa: 0x2000, 0x3ab: 0x2000, 0x3ac: 0x2000, 0x3ad: 0x2000, 0x3ae: 0x2000, 0x3af: 0x2000, + 0x3b0: 0x2000, 0x3b1: 0x2000, 0x3b2: 0x2000, 0x3b3: 0x2000, 0x3b4: 0x2000, 0x3b5: 0x2000, + 0x3b6: 0x2000, 0x3b7: 0x2000, 0x3b8: 0x2000, 0x3b9: 0x2000, 0x3ba: 0x2000, 0x3bb: 0x2000, + 0x3bc: 0x2000, 0x3bd: 0x2000, 0x3be: 0x2000, 0x3bf: 0x2000, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x2000, 0x3c1: 0x2000, 0x3c2: 0x2000, 0x3c3: 0x2000, 0x3c4: 0x2000, 0x3c5: 0x2000, + 0x3c6: 0x2000, 0x3c7: 0x2000, 0x3c8: 0x2000, 0x3c9: 0x2000, 0x3ca: 0x2000, 0x3cb: 0x2000, + 0x3cc: 0x2000, 0x3cd: 0x2000, 0x3ce: 0x2000, 0x3cf: 0x2000, 0x3d1: 0x2000, + // Block 0x10, offset 0x400 + 0x400: 0x4000, 0x401: 0x4000, 0x402: 0x4000, 0x403: 0x4000, 0x404: 0x4000, 0x405: 0x4000, + 0x406: 0x4000, 0x407: 0x4000, 0x408: 0x4000, 0x409: 0x4000, 0x40a: 0x4000, 0x40b: 0x4000, + 0x40c: 0x4000, 0x40d: 0x4000, 0x40e: 0x4000, 0x40f: 0x4000, 0x410: 0x4000, 0x411: 0x4000, + 0x412: 0x4000, 0x413: 0x4000, 0x414: 0x4000, 0x415: 0x4000, 0x416: 0x4000, 0x417: 0x4000, + 0x418: 0x4000, 0x419: 0x4000, 0x41a: 0x4000, 0x41b: 0x4000, 0x41c: 0x4000, 0x41d: 0x4000, + 0x41e: 0x4000, 0x41f: 0x4000, 0x420: 0x4000, 0x421: 0x4000, 0x422: 0x4000, 0x423: 0x4000, + 0x424: 0x4000, 0x425: 0x4000, 0x426: 0x4000, 0x427: 0x4000, 0x428: 0x4000, 0x429: 0x4000, + 0x42a: 0x4000, 0x42b: 0x4000, 0x42c: 0x4000, 0x42d: 0x4000, 0x42e: 0x4000, 0x42f: 0x4000, + 0x430: 0x4000, 0x431: 0x4000, 0x432: 0x4000, 0x433: 0x4000, 0x434: 0x4000, 0x435: 0x4000, + 0x436: 0x4000, 0x437: 0x4000, 0x438: 0x4000, 0x439: 0x4000, 0x43a: 0x4000, 0x43b: 0x4000, + 0x43c: 0x4000, 0x43d: 0x4000, 0x43e: 0x4000, 0x43f: 0x4000, + // Block 0x11, offset 0x440 + 0x440: 0x4000, 0x441: 0x4000, 0x442: 0x4000, 0x443: 0x4000, 0x444: 0x4000, 0x445: 0x4000, + 0x446: 0x4000, 0x447: 0x4000, 0x448: 0x4000, 0x449: 0x4000, 0x44a: 0x4000, 0x44b: 0x4000, + 0x44c: 0x4000, 0x44d: 0x4000, 0x44e: 0x4000, 0x44f: 0x4000, 0x450: 0x4000, 0x451: 0x4000, + 0x452: 0x4000, 0x453: 0x4000, 0x454: 0x4000, 0x455: 0x4000, 0x456: 0x4000, 0x457: 0x4000, + 0x458: 0x4000, 0x459: 0x4000, 0x45a: 0x4000, 0x45b: 0x4000, 0x45c: 0x4000, 0x45d: 0x4000, + 0x45e: 0x4000, 0x45f: 0x4000, + // Block 0x12, offset 0x480 + 0x490: 0x2000, + 0x493: 0x2000, 0x494: 0x2000, 0x495: 0x2000, 0x496: 0x2000, + 0x498: 0x2000, 0x499: 0x2000, 0x49c: 0x2000, 0x49d: 0x2000, + 0x4a0: 0x2000, 0x4a1: 0x2000, 0x4a2: 0x2000, + 0x4a4: 0x2000, 0x4a5: 0x2000, 0x4a6: 0x2000, 0x4a7: 0x2000, + 0x4b0: 0x2000, 0x4b2: 0x2000, 0x4b3: 0x2000, 0x4b5: 0x2000, + 0x4bb: 0x2000, + 0x4be: 0x2000, + // Block 0x13, offset 0x4c0 + 0x4f4: 0x2000, + 0x4ff: 0x2000, + // Block 0x14, offset 0x500 + 0x501: 0x2000, 0x502: 0x2000, 0x503: 0x2000, 0x504: 0x2000, + 0x529: 0xa009, + 0x52c: 0x2000, + // Block 0x15, offset 0x540 + 0x543: 0x2000, 0x545: 0x2000, + 0x549: 0x2000, + 0x553: 0x2000, 0x556: 0x2000, + 0x561: 0x2000, 0x562: 0x2000, + 0x566: 0x2000, + 0x56b: 0x2000, + // Block 0x16, offset 0x580 + 0x593: 0x2000, 0x594: 0x2000, + 0x59b: 0x2000, 0x59c: 0x2000, 0x59d: 0x2000, + 0x59e: 0x2000, 0x5a0: 0x2000, 0x5a1: 0x2000, 0x5a2: 0x2000, 0x5a3: 0x2000, + 0x5a4: 0x2000, 0x5a5: 0x2000, 0x5a6: 0x2000, 0x5a7: 0x2000, 0x5a8: 0x2000, 0x5a9: 0x2000, + 0x5aa: 0x2000, 0x5ab: 0x2000, + 0x5b0: 0x2000, 0x5b1: 0x2000, 0x5b2: 0x2000, 0x5b3: 0x2000, 0x5b4: 0x2000, 0x5b5: 0x2000, + 0x5b6: 0x2000, 0x5b7: 0x2000, 0x5b8: 0x2000, 0x5b9: 0x2000, + // Block 0x17, offset 0x5c0 + 0x5c9: 0x2000, + 0x5d0: 0x200a, 0x5d1: 0x200b, + 0x5d2: 0x200a, 0x5d3: 0x200c, 0x5d4: 0x2000, 0x5d5: 0x2000, 0x5d6: 0x2000, 0x5d7: 0x2000, + 0x5d8: 0x2000, 0x5d9: 0x2000, + 0x5f8: 0x2000, 0x5f9: 0x2000, + // Block 0x18, offset 0x600 + 0x612: 0x2000, 0x614: 0x2000, + 0x627: 0x2000, + // Block 0x19, offset 0x640 + 0x640: 0x2000, 0x642: 0x2000, 0x643: 0x2000, + 0x647: 0x2000, 0x648: 0x2000, 0x64b: 0x2000, + 0x64f: 0x2000, 0x651: 0x2000, + 0x655: 0x2000, + 0x65a: 0x2000, 0x65d: 0x2000, + 0x65e: 0x2000, 0x65f: 0x2000, 0x660: 0x2000, 0x663: 0x2000, + 0x665: 0x2000, 0x667: 0x2000, 0x668: 0x2000, 0x669: 0x2000, + 0x66a: 0x2000, 0x66b: 0x2000, 0x66c: 0x2000, 0x66e: 0x2000, + 0x674: 0x2000, 0x675: 0x2000, + 0x676: 0x2000, 0x677: 0x2000, + 0x67c: 0x2000, 0x67d: 0x2000, + // Block 0x1a, offset 0x680 + 0x688: 0x2000, + 0x68c: 0x2000, + 0x692: 0x2000, + 0x6a0: 0x2000, 0x6a1: 0x2000, + 0x6a4: 0x2000, 0x6a5: 0x2000, 0x6a6: 0x2000, 0x6a7: 0x2000, + 0x6aa: 0x2000, 0x6ab: 0x2000, 0x6ae: 0x2000, 0x6af: 0x2000, + // Block 0x1b, offset 0x6c0 + 0x6c2: 0x2000, 0x6c3: 0x2000, + 0x6c6: 0x2000, 0x6c7: 0x2000, + 0x6d5: 0x2000, + 0x6d9: 0x2000, + 0x6e5: 0x2000, + 0x6ff: 0x2000, + // Block 0x1c, offset 0x700 + 0x712: 0x2000, + 0x71a: 0x4000, 0x71b: 0x4000, + 0x729: 0x4000, + 0x72a: 0x4000, + // Block 0x1d, offset 0x740 + 0x769: 0x4000, + 0x76a: 0x4000, 0x76b: 0x4000, 0x76c: 0x4000, + 0x770: 0x4000, 0x773: 0x4000, + // Block 0x1e, offset 0x780 + 0x7a0: 0x2000, 0x7a1: 0x2000, 0x7a2: 0x2000, 0x7a3: 0x2000, + 0x7a4: 0x2000, 0x7a5: 0x2000, 0x7a6: 0x2000, 0x7a7: 0x2000, 0x7a8: 0x2000, 0x7a9: 0x2000, + 0x7aa: 0x2000, 0x7ab: 0x2000, 0x7ac: 0x2000, 0x7ad: 0x2000, 0x7ae: 0x2000, 0x7af: 0x2000, + 0x7b0: 0x2000, 0x7b1: 0x2000, 0x7b2: 0x2000, 0x7b3: 0x2000, 0x7b4: 0x2000, 0x7b5: 0x2000, + 0x7b6: 0x2000, 0x7b7: 0x2000, 0x7b8: 0x2000, 0x7b9: 0x2000, 0x7ba: 0x2000, 0x7bb: 0x2000, + 0x7bc: 0x2000, 0x7bd: 0x2000, 0x7be: 0x2000, 0x7bf: 0x2000, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x2000, 0x7c1: 0x2000, 0x7c2: 0x2000, 0x7c3: 0x2000, 0x7c4: 0x2000, 0x7c5: 0x2000, + 0x7c6: 0x2000, 0x7c7: 0x2000, 0x7c8: 0x2000, 0x7c9: 0x2000, 0x7ca: 0x2000, 0x7cb: 0x2000, + 0x7cc: 0x2000, 0x7cd: 0x2000, 0x7ce: 0x2000, 0x7cf: 0x2000, 0x7d0: 0x2000, 0x7d1: 0x2000, + 0x7d2: 0x2000, 0x7d3: 0x2000, 0x7d4: 0x2000, 0x7d5: 0x2000, 0x7d6: 0x2000, 0x7d7: 0x2000, + 0x7d8: 0x2000, 0x7d9: 0x2000, 0x7da: 0x2000, 0x7db: 0x2000, 0x7dc: 0x2000, 0x7dd: 0x2000, + 0x7de: 0x2000, 0x7df: 0x2000, 0x7e0: 0x2000, 0x7e1: 0x2000, 0x7e2: 0x2000, 0x7e3: 0x2000, + 0x7e4: 0x2000, 0x7e5: 0x2000, 0x7e6: 0x2000, 0x7e7: 0x2000, 0x7e8: 0x2000, 0x7e9: 0x2000, + 0x7eb: 0x2000, 0x7ec: 0x2000, 0x7ed: 0x2000, 0x7ee: 0x2000, 0x7ef: 0x2000, + 0x7f0: 0x2000, 0x7f1: 0x2000, 0x7f2: 0x2000, 0x7f3: 0x2000, 0x7f4: 0x2000, 0x7f5: 0x2000, + 0x7f6: 0x2000, 0x7f7: 0x2000, 0x7f8: 0x2000, 0x7f9: 0x2000, 0x7fa: 0x2000, 0x7fb: 0x2000, + 0x7fc: 0x2000, 0x7fd: 0x2000, 0x7fe: 0x2000, 0x7ff: 0x2000, + // Block 0x20, offset 0x800 + 0x800: 0x2000, 0x801: 0x2000, 0x802: 0x200d, 0x803: 0x2000, 0x804: 0x2000, 0x805: 0x2000, + 0x806: 0x2000, 0x807: 0x2000, 0x808: 0x2000, 0x809: 0x2000, 0x80a: 0x2000, 0x80b: 0x2000, + 0x80c: 0x2000, 0x80d: 0x2000, 0x80e: 0x2000, 0x80f: 0x2000, 0x810: 0x2000, 0x811: 0x2000, + 0x812: 0x2000, 0x813: 0x2000, 0x814: 0x2000, 0x815: 0x2000, 0x816: 0x2000, 0x817: 0x2000, + 0x818: 0x2000, 0x819: 0x2000, 0x81a: 0x2000, 0x81b: 0x2000, 0x81c: 0x2000, 0x81d: 0x2000, + 0x81e: 0x2000, 0x81f: 0x2000, 0x820: 0x2000, 0x821: 0x2000, 0x822: 0x2000, 0x823: 0x2000, + 0x824: 0x2000, 0x825: 0x2000, 0x826: 0x2000, 0x827: 0x2000, 0x828: 0x2000, 0x829: 0x2000, + 0x82a: 0x2000, 0x82b: 0x2000, 0x82c: 0x2000, 0x82d: 0x2000, 0x82e: 0x2000, 0x82f: 0x2000, + 0x830: 0x2000, 0x831: 0x2000, 0x832: 0x2000, 0x833: 0x2000, 0x834: 0x2000, 0x835: 0x2000, + 0x836: 0x2000, 0x837: 0x2000, 0x838: 0x2000, 0x839: 0x2000, 0x83a: 0x2000, 0x83b: 0x2000, + 0x83c: 0x2000, 0x83d: 0x2000, 0x83e: 0x2000, 0x83f: 0x2000, + // Block 0x21, offset 0x840 + 0x840: 0x2000, 0x841: 0x2000, 0x842: 0x2000, 0x843: 0x2000, 0x844: 0x2000, 0x845: 0x2000, + 0x846: 0x2000, 0x847: 0x2000, 0x848: 0x2000, 0x849: 0x2000, 0x84a: 0x2000, 0x84b: 0x2000, + 0x850: 0x2000, 0x851: 0x2000, + 0x852: 0x2000, 0x853: 0x2000, 0x854: 0x2000, 0x855: 0x2000, 0x856: 0x2000, 0x857: 0x2000, + 0x858: 0x2000, 0x859: 0x2000, 0x85a: 0x2000, 0x85b: 0x2000, 0x85c: 0x2000, 0x85d: 0x2000, + 0x85e: 0x2000, 0x85f: 0x2000, 0x860: 0x2000, 0x861: 0x2000, 0x862: 0x2000, 0x863: 0x2000, + 0x864: 0x2000, 0x865: 0x2000, 0x866: 0x2000, 0x867: 0x2000, 0x868: 0x2000, 0x869: 0x2000, + 0x86a: 0x2000, 0x86b: 0x2000, 0x86c: 0x2000, 0x86d: 0x2000, 0x86e: 0x2000, 0x86f: 0x2000, + 0x870: 0x2000, 0x871: 0x2000, 0x872: 0x2000, 0x873: 0x2000, + // Block 0x22, offset 0x880 + 0x880: 0x2000, 0x881: 0x2000, 0x882: 0x2000, 0x883: 0x2000, 0x884: 0x2000, 0x885: 0x2000, + 0x886: 0x2000, 0x887: 0x2000, 0x888: 0x2000, 0x889: 0x2000, 0x88a: 0x2000, 0x88b: 0x2000, + 0x88c: 0x2000, 0x88d: 0x2000, 0x88e: 0x2000, 0x88f: 0x2000, + 0x892: 0x2000, 0x893: 0x2000, 0x894: 0x2000, 0x895: 0x2000, + 0x8a0: 0x200e, 0x8a1: 0x2000, 0x8a3: 0x2000, + 0x8a4: 0x2000, 0x8a5: 0x2000, 0x8a6: 0x2000, 0x8a7: 0x2000, 0x8a8: 0x2000, 0x8a9: 0x2000, + 0x8b2: 0x2000, 0x8b3: 0x2000, + 0x8b6: 0x2000, 0x8b7: 0x2000, + 0x8bc: 0x2000, 0x8bd: 0x2000, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x2000, 0x8c1: 0x2000, + 0x8c6: 0x2000, 0x8c7: 0x2000, 0x8c8: 0x2000, 0x8cb: 0x200f, + 0x8ce: 0x2000, 0x8cf: 0x2000, 0x8d0: 0x2000, 0x8d1: 0x2000, + 0x8e2: 0x2000, 0x8e3: 0x2000, + 0x8e4: 0x2000, 0x8e5: 0x2000, + 0x8ef: 0x2000, + 0x8fd: 0x4000, 0x8fe: 0x4000, + // Block 0x24, offset 0x900 + 0x905: 0x2000, + 0x906: 0x2000, 0x909: 0x2000, + 0x90e: 0x2000, 0x90f: 0x2000, + 0x914: 0x4000, 0x915: 0x4000, + 0x91c: 0x2000, + 0x91e: 0x2000, + // Block 0x25, offset 0x940 + 0x940: 0x2000, 0x942: 0x2000, + 0x948: 0x4000, 0x949: 0x4000, 0x94a: 0x4000, 0x94b: 0x4000, + 0x94c: 0x4000, 0x94d: 0x4000, 0x94e: 0x4000, 0x94f: 0x4000, 0x950: 0x4000, 0x951: 0x4000, + 0x952: 0x4000, 0x953: 0x4000, + 0x960: 0x2000, 0x961: 0x2000, 0x963: 0x2000, + 0x964: 0x2000, 0x965: 0x2000, 0x967: 0x2000, 0x968: 0x2000, 0x969: 0x2000, + 0x96a: 0x2000, 0x96c: 0x2000, 0x96d: 0x2000, 0x96f: 0x2000, + 0x97f: 0x4000, + // Block 0x26, offset 0x980 + 0x993: 0x4000, + 0x99e: 0x2000, 0x99f: 0x2000, 0x9a1: 0x4000, + 0x9aa: 0x4000, 0x9ab: 0x4000, + 0x9bd: 0x4000, 0x9be: 0x4000, 0x9bf: 0x2000, + // Block 0x27, offset 0x9c0 + 0x9c4: 0x4000, 0x9c5: 0x4000, + 0x9c6: 0x2000, 0x9c7: 0x2000, 0x9c8: 0x2000, 0x9c9: 0x2000, 0x9ca: 0x2000, 0x9cb: 0x2000, + 0x9cc: 0x2000, 0x9cd: 0x2000, 0x9ce: 0x4000, 0x9cf: 0x2000, 0x9d0: 0x2000, 0x9d1: 0x2000, + 0x9d2: 0x2000, 0x9d3: 0x2000, 0x9d4: 0x4000, 0x9d5: 0x2000, 0x9d6: 0x2000, 0x9d7: 0x2000, + 0x9d8: 0x2000, 0x9d9: 0x2000, 0x9da: 0x2000, 0x9db: 0x2000, 0x9dc: 0x2000, 0x9dd: 0x2000, + 0x9de: 0x2000, 0x9df: 0x2000, 0x9e0: 0x2000, 0x9e1: 0x2000, 0x9e3: 0x2000, + 0x9e8: 0x2000, 0x9e9: 0x2000, + 0x9ea: 0x4000, 0x9eb: 0x2000, 0x9ec: 0x2000, 0x9ed: 0x2000, 0x9ee: 0x2000, 0x9ef: 0x2000, + 0x9f0: 0x2000, 0x9f1: 0x2000, 0x9f2: 0x4000, 0x9f3: 0x4000, 0x9f4: 0x2000, 0x9f5: 0x4000, + 0x9f6: 0x2000, 0x9f7: 0x2000, 0x9f8: 0x2000, 0x9f9: 0x2000, 0x9fa: 0x4000, 0x9fb: 0x2000, + 0x9fc: 0x2000, 0x9fd: 0x4000, 0x9fe: 0x2000, 0x9ff: 0x2000, + // Block 0x28, offset 0xa00 + 0xa05: 0x4000, + 0xa0a: 0x4000, 0xa0b: 0x4000, + 0xa28: 0x4000, + 0xa3d: 0x2000, + // Block 0x29, offset 0xa40 + 0xa4c: 0x4000, 0xa4e: 0x4000, + 0xa53: 0x4000, 0xa54: 0x4000, 0xa55: 0x4000, 0xa57: 0x4000, + 0xa76: 0x2000, 0xa77: 0x2000, 0xa78: 0x2000, 0xa79: 0x2000, 0xa7a: 0x2000, 0xa7b: 0x2000, + 0xa7c: 0x2000, 0xa7d: 0x2000, 0xa7e: 0x2000, 0xa7f: 0x2000, + // Block 0x2a, offset 0xa80 + 0xa95: 0x4000, 0xa96: 0x4000, 0xa97: 0x4000, + 0xab0: 0x4000, + 0xabf: 0x4000, + // Block 0x2b, offset 0xac0 + 0xae6: 0x6000, 0xae7: 0x6000, 0xae8: 0x6000, 0xae9: 0x6000, + 0xaea: 0x6000, 0xaeb: 0x6000, 0xaec: 0x6000, 0xaed: 0x6000, + // Block 0x2c, offset 0xb00 + 0xb05: 0x6010, + 0xb06: 0x6011, + // Block 0x2d, offset 0xb40 + 0xb5b: 0x4000, 0xb5c: 0x4000, + // Block 0x2e, offset 0xb80 + 0xb90: 0x4000, + 0xb95: 0x4000, 0xb96: 0x2000, 0xb97: 0x2000, + 0xb98: 0x2000, 0xb99: 0x2000, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x4000, 0xbc1: 0x4000, 0xbc2: 0x4000, 0xbc3: 0x4000, 0xbc4: 0x4000, 0xbc5: 0x4000, + 0xbc6: 0x4000, 0xbc7: 0x4000, 0xbc8: 0x4000, 0xbc9: 0x4000, 0xbca: 0x4000, 0xbcb: 0x4000, + 0xbcc: 0x4000, 0xbcd: 0x4000, 0xbce: 0x4000, 0xbcf: 0x4000, 0xbd0: 0x4000, 0xbd1: 0x4000, + 0xbd2: 0x4000, 0xbd3: 0x4000, 0xbd4: 0x4000, 0xbd5: 0x4000, 0xbd6: 0x4000, 0xbd7: 0x4000, + 0xbd8: 0x4000, 0xbd9: 0x4000, 0xbdb: 0x4000, 0xbdc: 0x4000, 0xbdd: 0x4000, + 0xbde: 0x4000, 0xbdf: 0x4000, 0xbe0: 0x4000, 0xbe1: 0x4000, 0xbe2: 0x4000, 0xbe3: 0x4000, + 0xbe4: 0x4000, 0xbe5: 0x4000, 0xbe6: 0x4000, 0xbe7: 0x4000, 0xbe8: 0x4000, 0xbe9: 0x4000, + 0xbea: 0x4000, 0xbeb: 0x4000, 0xbec: 0x4000, 0xbed: 0x4000, 0xbee: 0x4000, 0xbef: 0x4000, + 0xbf0: 0x4000, 0xbf1: 0x4000, 0xbf2: 0x4000, 0xbf3: 0x4000, 0xbf4: 0x4000, 0xbf5: 0x4000, + 0xbf6: 0x4000, 0xbf7: 0x4000, 0xbf8: 0x4000, 0xbf9: 0x4000, 0xbfa: 0x4000, 0xbfb: 0x4000, + 0xbfc: 0x4000, 0xbfd: 0x4000, 0xbfe: 0x4000, 0xbff: 0x4000, + // Block 0x30, offset 0xc00 + 0xc00: 0x4000, 0xc01: 0x4000, 0xc02: 0x4000, 0xc03: 0x4000, 0xc04: 0x4000, 0xc05: 0x4000, + 0xc06: 0x4000, 0xc07: 0x4000, 0xc08: 0x4000, 0xc09: 0x4000, 0xc0a: 0x4000, 0xc0b: 0x4000, + 0xc0c: 0x4000, 0xc0d: 0x4000, 0xc0e: 0x4000, 0xc0f: 0x4000, 0xc10: 0x4000, 0xc11: 0x4000, + 0xc12: 0x4000, 0xc13: 0x4000, 0xc14: 0x4000, 0xc15: 0x4000, 0xc16: 0x4000, 0xc17: 0x4000, + 0xc18: 0x4000, 0xc19: 0x4000, 0xc1a: 0x4000, 0xc1b: 0x4000, 0xc1c: 0x4000, 0xc1d: 0x4000, + 0xc1e: 0x4000, 0xc1f: 0x4000, 0xc20: 0x4000, 0xc21: 0x4000, 0xc22: 0x4000, 0xc23: 0x4000, + 0xc24: 0x4000, 0xc25: 0x4000, 0xc26: 0x4000, 0xc27: 0x4000, 0xc28: 0x4000, 0xc29: 0x4000, + 0xc2a: 0x4000, 0xc2b: 0x4000, 0xc2c: 0x4000, 0xc2d: 0x4000, 0xc2e: 0x4000, 0xc2f: 0x4000, + 0xc30: 0x4000, 0xc31: 0x4000, 0xc32: 0x4000, 0xc33: 0x4000, + // Block 0x31, offset 0xc40 + 0xc40: 0x4000, 0xc41: 0x4000, 0xc42: 0x4000, 0xc43: 0x4000, 0xc44: 0x4000, 0xc45: 0x4000, + 0xc46: 0x4000, 0xc47: 0x4000, 0xc48: 0x4000, 0xc49: 0x4000, 0xc4a: 0x4000, 0xc4b: 0x4000, + 0xc4c: 0x4000, 0xc4d: 0x4000, 0xc4e: 0x4000, 0xc4f: 0x4000, 0xc50: 0x4000, 0xc51: 0x4000, + 0xc52: 0x4000, 0xc53: 0x4000, 0xc54: 0x4000, 0xc55: 0x4000, + 0xc70: 0x4000, 0xc71: 0x4000, 0xc72: 0x4000, 0xc73: 0x4000, 0xc74: 0x4000, 0xc75: 0x4000, + 0xc76: 0x4000, 0xc77: 0x4000, 0xc78: 0x4000, 0xc79: 0x4000, 0xc7a: 0x4000, 0xc7b: 0x4000, + // Block 0x32, offset 0xc80 + 0xc80: 0x9012, 0xc81: 0x4013, 0xc82: 0x4014, 0xc83: 0x4000, 0xc84: 0x4000, 0xc85: 0x4000, + 0xc86: 0x4000, 0xc87: 0x4000, 0xc88: 0x4000, 0xc89: 0x4000, 0xc8a: 0x4000, 0xc8b: 0x4000, + 0xc8c: 0x4015, 0xc8d: 0x4015, 0xc8e: 0x4000, 0xc8f: 0x4000, 0xc90: 0x4000, 0xc91: 0x4000, + 0xc92: 0x4000, 0xc93: 0x4000, 0xc94: 0x4000, 0xc95: 0x4000, 0xc96: 0x4000, 0xc97: 0x4000, + 0xc98: 0x4000, 0xc99: 0x4000, 0xc9a: 0x4000, 0xc9b: 0x4000, 0xc9c: 0x4000, 0xc9d: 0x4000, + 0xc9e: 0x4000, 0xc9f: 0x4000, 0xca0: 0x4000, 0xca1: 0x4000, 0xca2: 0x4000, 0xca3: 0x4000, + 0xca4: 0x4000, 0xca5: 0x4000, 0xca6: 0x4000, 0xca7: 0x4000, 0xca8: 0x4000, 0xca9: 0x4000, + 0xcaa: 0x4000, 0xcab: 0x4000, 0xcac: 0x4000, 0xcad: 0x4000, 0xcae: 0x4000, 0xcaf: 0x4000, + 0xcb0: 0x4000, 0xcb1: 0x4000, 0xcb2: 0x4000, 0xcb3: 0x4000, 0xcb4: 0x4000, 0xcb5: 0x4000, + 0xcb6: 0x4000, 0xcb7: 0x4000, 0xcb8: 0x4000, 0xcb9: 0x4000, 0xcba: 0x4000, 0xcbb: 0x4000, + 0xcbc: 0x4000, 0xcbd: 0x4000, 0xcbe: 0x4000, + // Block 0x33, offset 0xcc0 + 0xcc1: 0x4000, 0xcc2: 0x4000, 0xcc3: 0x4000, 0xcc4: 0x4000, 0xcc5: 0x4000, + 0xcc6: 0x4000, 0xcc7: 0x4000, 0xcc8: 0x4000, 0xcc9: 0x4000, 0xcca: 0x4000, 0xccb: 0x4000, + 0xccc: 0x4000, 0xccd: 0x4000, 0xcce: 0x4000, 0xccf: 0x4000, 0xcd0: 0x4000, 0xcd1: 0x4000, + 0xcd2: 0x4000, 0xcd3: 0x4000, 0xcd4: 0x4000, 0xcd5: 0x4000, 0xcd6: 0x4000, 0xcd7: 0x4000, + 0xcd8: 0x4000, 0xcd9: 0x4000, 0xcda: 0x4000, 0xcdb: 0x4000, 0xcdc: 0x4000, 0xcdd: 0x4000, + 0xcde: 0x4000, 0xcdf: 0x4000, 0xce0: 0x4000, 0xce1: 0x4000, 0xce2: 0x4000, 0xce3: 0x4000, + 0xce4: 0x4000, 0xce5: 0x4000, 0xce6: 0x4000, 0xce7: 0x4000, 0xce8: 0x4000, 0xce9: 0x4000, + 0xcea: 0x4000, 0xceb: 0x4000, 0xcec: 0x4000, 0xced: 0x4000, 0xcee: 0x4000, 0xcef: 0x4000, + 0xcf0: 0x4000, 0xcf1: 0x4000, 0xcf2: 0x4000, 0xcf3: 0x4000, 0xcf4: 0x4000, 0xcf5: 0x4000, + 0xcf6: 0x4000, 0xcf7: 0x4000, 0xcf8: 0x4000, 0xcf9: 0x4000, 0xcfa: 0x4000, 0xcfb: 0x4000, + 0xcfc: 0x4000, 0xcfd: 0x4000, 0xcfe: 0x4000, 0xcff: 0x4000, + // Block 0x34, offset 0xd00 + 0xd00: 0x4000, 0xd01: 0x4000, 0xd02: 0x4000, 0xd03: 0x4000, 0xd04: 0x4000, 0xd05: 0x4000, + 0xd06: 0x4000, 0xd07: 0x4000, 0xd08: 0x4000, 0xd09: 0x4000, 0xd0a: 0x4000, 0xd0b: 0x4000, + 0xd0c: 0x4000, 0xd0d: 0x4000, 0xd0e: 0x4000, 0xd0f: 0x4000, 0xd10: 0x4000, 0xd11: 0x4000, + 0xd12: 0x4000, 0xd13: 0x4000, 0xd14: 0x4000, 0xd15: 0x4000, 0xd16: 0x4000, + 0xd19: 0x4016, 0xd1a: 0x4017, 0xd1b: 0x4000, 0xd1c: 0x4000, 0xd1d: 0x4000, + 0xd1e: 0x4000, 0xd1f: 0x4000, 0xd20: 0x4000, 0xd21: 0x4018, 0xd22: 0x4019, 0xd23: 0x401a, + 0xd24: 0x401b, 0xd25: 0x401c, 0xd26: 0x401d, 0xd27: 0x401e, 0xd28: 0x401f, 0xd29: 0x4020, + 0xd2a: 0x4021, 0xd2b: 0x4022, 0xd2c: 0x4000, 0xd2d: 0x4010, 0xd2e: 0x4000, 0xd2f: 0x4023, + 0xd30: 0x4000, 0xd31: 0x4024, 0xd32: 0x4000, 0xd33: 0x4025, 0xd34: 0x4000, 0xd35: 0x4026, + 0xd36: 0x4000, 0xd37: 0x401a, 0xd38: 0x4000, 0xd39: 0x4027, 0xd3a: 0x4000, 0xd3b: 0x4028, + 0xd3c: 0x4000, 0xd3d: 0x4020, 0xd3e: 0x4000, 0xd3f: 0x4029, + // Block 0x35, offset 0xd40 + 0xd40: 0x4000, 0xd41: 0x402a, 0xd42: 0x4000, 0xd43: 0x402b, 0xd44: 0x402c, 0xd45: 0x4000, + 0xd46: 0x4017, 0xd47: 0x4000, 0xd48: 0x402d, 0xd49: 0x4000, 0xd4a: 0x402e, 0xd4b: 0x402f, + 0xd4c: 0x4030, 0xd4d: 0x4017, 0xd4e: 0x4016, 0xd4f: 0x4017, 0xd50: 0x4000, 0xd51: 0x4000, + 0xd52: 0x4031, 0xd53: 0x4000, 0xd54: 0x4000, 0xd55: 0x4031, 0xd56: 0x4000, 0xd57: 0x4000, + 0xd58: 0x4032, 0xd59: 0x4000, 0xd5a: 0x4000, 0xd5b: 0x4032, 0xd5c: 0x4000, 0xd5d: 0x4000, + 0xd5e: 0x4033, 0xd5f: 0x402e, 0xd60: 0x4034, 0xd61: 0x4035, 0xd62: 0x4034, 0xd63: 0x4036, + 0xd64: 0x4037, 0xd65: 0x4024, 0xd66: 0x4035, 0xd67: 0x4025, 0xd68: 0x4038, 0xd69: 0x4038, + 0xd6a: 0x4039, 0xd6b: 0x4039, 0xd6c: 0x403a, 0xd6d: 0x403a, 0xd6e: 0x4000, 0xd6f: 0x4035, + 0xd70: 0x4000, 0xd71: 0x4000, 0xd72: 0x403b, 0xd73: 0x403c, 0xd74: 0x4000, 0xd75: 0x4000, + 0xd76: 0x4000, 0xd77: 0x4000, 0xd78: 0x4000, 0xd79: 0x4000, 0xd7a: 0x4000, 0xd7b: 0x403d, + 0xd7c: 0x401c, 0xd7d: 0x4000, 0xd7e: 0x4000, 0xd7f: 0x4000, + // Block 0x36, offset 0xd80 + 0xd85: 0x4000, + 0xd86: 0x4000, 0xd87: 0x4000, 0xd88: 0x4000, 0xd89: 0x4000, 0xd8a: 0x4000, 0xd8b: 0x4000, + 0xd8c: 0x4000, 0xd8d: 0x4000, 0xd8e: 0x4000, 0xd8f: 0x4000, 0xd90: 0x4000, 0xd91: 0x4000, + 0xd92: 0x4000, 0xd93: 0x4000, 0xd94: 0x4000, 0xd95: 0x4000, 0xd96: 0x4000, 0xd97: 0x4000, + 0xd98: 0x4000, 0xd99: 0x4000, 0xd9a: 0x4000, 0xd9b: 0x4000, 0xd9c: 0x4000, 0xd9d: 0x4000, + 0xd9e: 0x4000, 0xd9f: 0x4000, 0xda0: 0x4000, 0xda1: 0x4000, 0xda2: 0x4000, 0xda3: 0x4000, + 0xda4: 0x4000, 0xda5: 0x4000, 0xda6: 0x4000, 0xda7: 0x4000, 0xda8: 0x4000, 0xda9: 0x4000, + 0xdaa: 0x4000, 0xdab: 0x4000, 0xdac: 0x4000, 0xdad: 0x4000, 0xdae: 0x4000, 0xdaf: 0x4000, + 0xdb1: 0x403e, 0xdb2: 0x403e, 0xdb3: 0x403e, 0xdb4: 0x403e, 0xdb5: 0x403e, + 0xdb6: 0x403e, 0xdb7: 0x403e, 0xdb8: 0x403e, 0xdb9: 0x403e, 0xdba: 0x403e, 0xdbb: 0x403e, + 0xdbc: 0x403e, 0xdbd: 0x403e, 0xdbe: 0x403e, 0xdbf: 0x403e, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x4037, 0xdc1: 0x4037, 0xdc2: 0x4037, 0xdc3: 0x4037, 0xdc4: 0x4037, 0xdc5: 0x4037, + 0xdc6: 0x4037, 0xdc7: 0x4037, 0xdc8: 0x4037, 0xdc9: 0x4037, 0xdca: 0x4037, 0xdcb: 0x4037, + 0xdcc: 0x4037, 0xdcd: 0x4037, 0xdce: 0x4037, 0xdcf: 0x400e, 0xdd0: 0x403f, 0xdd1: 0x4040, + 0xdd2: 0x4041, 0xdd3: 0x4040, 0xdd4: 0x403f, 0xdd5: 0x4042, 0xdd6: 0x4043, 0xdd7: 0x4044, + 0xdd8: 0x4040, 0xdd9: 0x4041, 0xdda: 0x4040, 0xddb: 0x4045, 0xddc: 0x4009, 0xddd: 0x4045, + 0xdde: 0x4046, 0xddf: 0x4045, 0xde0: 0x4047, 0xde1: 0x400b, 0xde2: 0x400a, 0xde3: 0x400c, + 0xde4: 0x4048, 0xde5: 0x4000, 0xde6: 0x4000, 0xde7: 0x4000, 0xde8: 0x4000, 0xde9: 0x4000, + 0xdea: 0x4000, 0xdeb: 0x4000, 0xdec: 0x4000, 0xded: 0x4000, 0xdee: 0x4000, 0xdef: 0x4000, + 0xdf0: 0x4000, 0xdf1: 0x4000, 0xdf2: 0x4000, 0xdf3: 0x4000, 0xdf4: 0x4000, 0xdf5: 0x4000, + 0xdf6: 0x4000, 0xdf7: 0x4000, 0xdf8: 0x4000, 0xdf9: 0x4000, 0xdfa: 0x4000, 0xdfb: 0x4000, + 0xdfc: 0x4000, 0xdfd: 0x4000, 0xdfe: 0x4000, 0xdff: 0x4000, + // Block 0x38, offset 0xe00 + 0xe00: 0x4000, 0xe01: 0x4000, 0xe02: 0x4000, 0xe03: 0x4000, 0xe04: 0x4000, 0xe05: 0x4000, + 0xe06: 0x4000, 0xe07: 0x4000, 0xe08: 0x4000, 0xe09: 0x4000, 0xe0a: 0x4000, 0xe0b: 0x4000, + 0xe0c: 0x4000, 0xe0d: 0x4000, 0xe0e: 0x4000, 0xe10: 0x4000, 0xe11: 0x4000, + 0xe12: 0x4000, 0xe13: 0x4000, 0xe14: 0x4000, 0xe15: 0x4000, 0xe16: 0x4000, 0xe17: 0x4000, + 0xe18: 0x4000, 0xe19: 0x4000, 0xe1a: 0x4000, 0xe1b: 0x4000, 0xe1c: 0x4000, 0xe1d: 0x4000, + 0xe1e: 0x4000, 0xe1f: 0x4000, 0xe20: 0x4000, 0xe21: 0x4000, 0xe22: 0x4000, 0xe23: 0x4000, + 0xe24: 0x4000, 0xe25: 0x4000, 0xe26: 0x4000, 0xe27: 0x4000, 0xe28: 0x4000, 0xe29: 0x4000, + 0xe2a: 0x4000, 0xe2b: 0x4000, 0xe2c: 0x4000, 0xe2d: 0x4000, 0xe2e: 0x4000, 0xe2f: 0x4000, + 0xe30: 0x4000, 0xe31: 0x4000, 0xe32: 0x4000, 0xe33: 0x4000, 0xe34: 0x4000, 0xe35: 0x4000, + 0xe36: 0x4000, 0xe37: 0x4000, 0xe38: 0x4000, 0xe39: 0x4000, 0xe3a: 0x4000, + // Block 0x39, offset 0xe40 + 0xe40: 0x4000, 0xe41: 0x4000, 0xe42: 0x4000, 0xe43: 0x4000, 0xe44: 0x4000, 0xe45: 0x4000, + 0xe46: 0x4000, 0xe47: 0x4000, 0xe48: 0x4000, 0xe49: 0x4000, 0xe4a: 0x4000, 0xe4b: 0x4000, + 0xe4c: 0x4000, 0xe4d: 0x4000, 0xe4e: 0x4000, 0xe4f: 0x4000, 0xe50: 0x4000, 0xe51: 0x4000, + 0xe52: 0x4000, 0xe53: 0x4000, 0xe54: 0x4000, 0xe55: 0x4000, 0xe56: 0x4000, 0xe57: 0x4000, + 0xe58: 0x4000, 0xe59: 0x4000, 0xe5a: 0x4000, 0xe5b: 0x4000, 0xe5c: 0x4000, 0xe5d: 0x4000, + 0xe5e: 0x4000, 0xe5f: 0x4000, 0xe60: 0x4000, 0xe61: 0x4000, 0xe62: 0x4000, 0xe63: 0x4000, + 0xe70: 0x4000, 0xe71: 0x4000, 0xe72: 0x4000, 0xe73: 0x4000, 0xe74: 0x4000, 0xe75: 0x4000, + 0xe76: 0x4000, 0xe77: 0x4000, 0xe78: 0x4000, 0xe79: 0x4000, 0xe7a: 0x4000, 0xe7b: 0x4000, + 0xe7c: 0x4000, 0xe7d: 0x4000, 0xe7e: 0x4000, 0xe7f: 0x4000, + // Block 0x3a, offset 0xe80 + 0xe80: 0x4000, 0xe81: 0x4000, 0xe82: 0x4000, 0xe83: 0x4000, 0xe84: 0x4000, 0xe85: 0x4000, + 0xe86: 0x4000, 0xe87: 0x4000, 0xe88: 0x4000, 0xe89: 0x4000, 0xe8a: 0x4000, 0xe8b: 0x4000, + 0xe8c: 0x4000, 0xe8d: 0x4000, 0xe8e: 0x4000, 0xe8f: 0x4000, 0xe90: 0x4000, 0xe91: 0x4000, + 0xe92: 0x4000, 0xe93: 0x4000, 0xe94: 0x4000, 0xe95: 0x4000, 0xe96: 0x4000, 0xe97: 0x4000, + 0xe98: 0x4000, 0xe99: 0x4000, 0xe9a: 0x4000, 0xe9b: 0x4000, 0xe9c: 0x4000, 0xe9d: 0x4000, + 0xe9e: 0x4000, 0xea0: 0x4000, 0xea1: 0x4000, 0xea2: 0x4000, 0xea3: 0x4000, + 0xea4: 0x4000, 0xea5: 0x4000, 0xea6: 0x4000, 0xea7: 0x4000, 0xea8: 0x4000, 0xea9: 0x4000, + 0xeaa: 0x4000, 0xeab: 0x4000, 0xeac: 0x4000, 0xead: 0x4000, 0xeae: 0x4000, 0xeaf: 0x4000, + 0xeb0: 0x4000, 0xeb1: 0x4000, 0xeb2: 0x4000, 0xeb3: 0x4000, 0xeb4: 0x4000, 0xeb5: 0x4000, + 0xeb6: 0x4000, 0xeb7: 0x4000, 0xeb8: 0x4000, 0xeb9: 0x4000, 0xeba: 0x4000, 0xebb: 0x4000, + 0xebc: 0x4000, 0xebd: 0x4000, 0xebe: 0x4000, 0xebf: 0x4000, + // Block 0x3b, offset 0xec0 + 0xec0: 0x4000, 0xec1: 0x4000, 0xec2: 0x4000, 0xec3: 0x4000, 0xec4: 0x4000, 0xec5: 0x4000, + 0xec6: 0x4000, 0xec7: 0x4000, 0xec8: 0x2000, 0xec9: 0x2000, 0xeca: 0x2000, 0xecb: 0x2000, + 0xecc: 0x2000, 0xecd: 0x2000, 0xece: 0x2000, 0xecf: 0x2000, 0xed0: 0x4000, 0xed1: 0x4000, + 0xed2: 0x4000, 0xed3: 0x4000, 0xed4: 0x4000, 0xed5: 0x4000, 0xed6: 0x4000, 0xed7: 0x4000, + 0xed8: 0x4000, 0xed9: 0x4000, 0xeda: 0x4000, 0xedb: 0x4000, 0xedc: 0x4000, 0xedd: 0x4000, + 0xede: 0x4000, 0xedf: 0x4000, 0xee0: 0x4000, 0xee1: 0x4000, 0xee2: 0x4000, 0xee3: 0x4000, + 0xee4: 0x4000, 0xee5: 0x4000, 0xee6: 0x4000, 0xee7: 0x4000, 0xee8: 0x4000, 0xee9: 0x4000, + 0xeea: 0x4000, 0xeeb: 0x4000, 0xeec: 0x4000, 0xeed: 0x4000, 0xeee: 0x4000, 0xeef: 0x4000, + 0xef0: 0x4000, 0xef1: 0x4000, 0xef2: 0x4000, 0xef3: 0x4000, 0xef4: 0x4000, 0xef5: 0x4000, + 0xef6: 0x4000, 0xef7: 0x4000, 0xef8: 0x4000, 0xef9: 0x4000, 0xefa: 0x4000, 0xefb: 0x4000, + 0xefc: 0x4000, 0xefd: 0x4000, 0xefe: 0x4000, 0xeff: 0x4000, + // Block 0x3c, offset 0xf00 + 0xf00: 0x4000, 0xf01: 0x4000, 0xf02: 0x4000, 0xf03: 0x4000, 0xf04: 0x4000, 0xf05: 0x4000, + 0xf06: 0x4000, 0xf07: 0x4000, 0xf08: 0x4000, 0xf09: 0x4000, 0xf0a: 0x4000, 0xf0b: 0x4000, + 0xf0c: 0x4000, 0xf0d: 0x4000, 0xf0e: 0x4000, 0xf0f: 0x4000, 0xf10: 0x4000, 0xf11: 0x4000, + 0xf12: 0x4000, 0xf13: 0x4000, 0xf14: 0x4000, 0xf15: 0x4000, 0xf16: 0x4000, 0xf17: 0x4000, + 0xf18: 0x4000, 0xf19: 0x4000, 0xf1a: 0x4000, 0xf1b: 0x4000, 0xf1c: 0x4000, 0xf1d: 0x4000, + 0xf1e: 0x4000, 0xf1f: 0x4000, 0xf20: 0x4000, 0xf21: 0x4000, 0xf22: 0x4000, 0xf23: 0x4000, + 0xf24: 0x4000, 0xf25: 0x4000, 0xf26: 0x4000, 0xf27: 0x4000, 0xf28: 0x4000, 0xf29: 0x4000, + 0xf2a: 0x4000, 0xf2b: 0x4000, 0xf2c: 0x4000, 0xf2d: 0x4000, 0xf2e: 0x4000, 0xf2f: 0x4000, + 0xf30: 0x4000, 0xf31: 0x4000, 0xf32: 0x4000, 0xf33: 0x4000, 0xf34: 0x4000, 0xf35: 0x4000, + 0xf36: 0x4000, 0xf37: 0x4000, 0xf38: 0x4000, 0xf39: 0x4000, 0xf3a: 0x4000, 0xf3b: 0x4000, + 0xf3c: 0x4000, 0xf3d: 0x4000, 0xf3e: 0x4000, + // Block 0x3d, offset 0xf40 + 0xf40: 0x4000, 0xf41: 0x4000, 0xf42: 0x4000, 0xf43: 0x4000, 0xf44: 0x4000, 0xf45: 0x4000, + 0xf46: 0x4000, 0xf47: 0x4000, 0xf48: 0x4000, 0xf49: 0x4000, 0xf4a: 0x4000, 0xf4b: 0x4000, + 0xf4c: 0x4000, 0xf50: 0x4000, 0xf51: 0x4000, + 0xf52: 0x4000, 0xf53: 0x4000, 0xf54: 0x4000, 0xf55: 0x4000, 0xf56: 0x4000, 0xf57: 0x4000, + 0xf58: 0x4000, 0xf59: 0x4000, 0xf5a: 0x4000, 0xf5b: 0x4000, 0xf5c: 0x4000, 0xf5d: 0x4000, + 0xf5e: 0x4000, 0xf5f: 0x4000, 0xf60: 0x4000, 0xf61: 0x4000, 0xf62: 0x4000, 0xf63: 0x4000, + 0xf64: 0x4000, 0xf65: 0x4000, 0xf66: 0x4000, 0xf67: 0x4000, 0xf68: 0x4000, 0xf69: 0x4000, + 0xf6a: 0x4000, 0xf6b: 0x4000, 0xf6c: 0x4000, 0xf6d: 0x4000, 0xf6e: 0x4000, 0xf6f: 0x4000, + 0xf70: 0x4000, 0xf71: 0x4000, 0xf72: 0x4000, 0xf73: 0x4000, 0xf74: 0x4000, 0xf75: 0x4000, + 0xf76: 0x4000, 0xf77: 0x4000, 0xf78: 0x4000, 0xf79: 0x4000, 0xf7a: 0x4000, 0xf7b: 0x4000, + 0xf7c: 0x4000, 0xf7d: 0x4000, 0xf7e: 0x4000, 0xf7f: 0x4000, + // Block 0x3e, offset 0xf80 + 0xf80: 0x4000, 0xf81: 0x4000, 0xf82: 0x4000, 0xf83: 0x4000, 0xf84: 0x4000, 0xf85: 0x4000, + 0xf86: 0x4000, + // Block 0x3f, offset 0xfc0 + 0xfe0: 0x4000, 0xfe1: 0x4000, 0xfe2: 0x4000, 0xfe3: 0x4000, + 0xfe4: 0x4000, 0xfe5: 0x4000, 0xfe6: 0x4000, 0xfe7: 0x4000, 0xfe8: 0x4000, 0xfe9: 0x4000, + 0xfea: 0x4000, 0xfeb: 0x4000, 0xfec: 0x4000, 0xfed: 0x4000, 0xfee: 0x4000, 0xfef: 0x4000, + 0xff0: 0x4000, 0xff1: 0x4000, 0xff2: 0x4000, 0xff3: 0x4000, 0xff4: 0x4000, 0xff5: 0x4000, + 0xff6: 0x4000, 0xff7: 0x4000, 0xff8: 0x4000, 0xff9: 0x4000, 0xffa: 0x4000, 0xffb: 0x4000, + 0xffc: 0x4000, + // Block 0x40, offset 0x1000 + 0x1000: 0x4000, 0x1001: 0x4000, 0x1002: 0x4000, 0x1003: 0x4000, 0x1004: 0x4000, 0x1005: 0x4000, + 0x1006: 0x4000, 0x1007: 0x4000, 0x1008: 0x4000, 0x1009: 0x4000, 0x100a: 0x4000, 0x100b: 0x4000, + 0x100c: 0x4000, 0x100d: 0x4000, 0x100e: 0x4000, 0x100f: 0x4000, 0x1010: 0x4000, 0x1011: 0x4000, + 0x1012: 0x4000, 0x1013: 0x4000, 0x1014: 0x4000, 0x1015: 0x4000, 0x1016: 0x4000, 0x1017: 0x4000, + 0x1018: 0x4000, 0x1019: 0x4000, 0x101a: 0x4000, 0x101b: 0x4000, 0x101c: 0x4000, 0x101d: 0x4000, + 0x101e: 0x4000, 0x101f: 0x4000, 0x1020: 0x4000, 0x1021: 0x4000, 0x1022: 0x4000, 0x1023: 0x4000, + // Block 0x41, offset 0x1040 + 0x1040: 0x2000, 0x1041: 0x2000, 0x1042: 0x2000, 0x1043: 0x2000, 0x1044: 0x2000, 0x1045: 0x2000, + 0x1046: 0x2000, 0x1047: 0x2000, 0x1048: 0x2000, 0x1049: 0x2000, 0x104a: 0x2000, 0x104b: 0x2000, + 0x104c: 0x2000, 0x104d: 0x2000, 0x104e: 0x2000, 0x104f: 0x2000, 0x1050: 0x4000, 0x1051: 0x4000, + 0x1052: 0x4000, 0x1053: 0x4000, 0x1054: 0x4000, 0x1055: 0x4000, 0x1056: 0x4000, 0x1057: 0x4000, + 0x1058: 0x4000, 0x1059: 0x4000, + 0x1070: 0x4000, 0x1071: 0x4000, 0x1072: 0x4000, 0x1073: 0x4000, 0x1074: 0x4000, 0x1075: 0x4000, + 0x1076: 0x4000, 0x1077: 0x4000, 0x1078: 0x4000, 0x1079: 0x4000, 0x107a: 0x4000, 0x107b: 0x4000, + 0x107c: 0x4000, 0x107d: 0x4000, 0x107e: 0x4000, 0x107f: 0x4000, + // Block 0x42, offset 0x1080 + 0x1080: 0x4000, 0x1081: 0x4000, 0x1082: 0x4000, 0x1083: 0x4000, 0x1084: 0x4000, 0x1085: 0x4000, + 0x1086: 0x4000, 0x1087: 0x4000, 0x1088: 0x4000, 0x1089: 0x4000, 0x108a: 0x4000, 0x108b: 0x4000, + 0x108c: 0x4000, 0x108d: 0x4000, 0x108e: 0x4000, 0x108f: 0x4000, 0x1090: 0x4000, 0x1091: 0x4000, + 0x1092: 0x4000, 0x1094: 0x4000, 0x1095: 0x4000, 0x1096: 0x4000, 0x1097: 0x4000, + 0x1098: 0x4000, 0x1099: 0x4000, 0x109a: 0x4000, 0x109b: 0x4000, 0x109c: 0x4000, 0x109d: 0x4000, + 0x109e: 0x4000, 0x109f: 0x4000, 0x10a0: 0x4000, 0x10a1: 0x4000, 0x10a2: 0x4000, 0x10a3: 0x4000, + 0x10a4: 0x4000, 0x10a5: 0x4000, 0x10a6: 0x4000, 0x10a8: 0x4000, 0x10a9: 0x4000, + 0x10aa: 0x4000, 0x10ab: 0x4000, + // Block 0x43, offset 0x10c0 + 0x10c1: 0x9012, 0x10c2: 0x9012, 0x10c3: 0x9012, 0x10c4: 0x9012, 0x10c5: 0x9012, + 0x10c6: 0x9012, 0x10c7: 0x9012, 0x10c8: 0x9012, 0x10c9: 0x9012, 0x10ca: 0x9012, 0x10cb: 0x9012, + 0x10cc: 0x9012, 0x10cd: 0x9012, 0x10ce: 0x9012, 0x10cf: 0x9012, 0x10d0: 0x9012, 0x10d1: 0x9012, + 0x10d2: 0x9012, 0x10d3: 0x9012, 0x10d4: 0x9012, 0x10d5: 0x9012, 0x10d6: 0x9012, 0x10d7: 0x9012, + 0x10d8: 0x9012, 0x10d9: 0x9012, 0x10da: 0x9012, 0x10db: 0x9012, 0x10dc: 0x9012, 0x10dd: 0x9012, + 0x10de: 0x9012, 0x10df: 0x9012, 0x10e0: 0x9049, 0x10e1: 0x9049, 0x10e2: 0x9049, 0x10e3: 0x9049, + 0x10e4: 0x9049, 0x10e5: 0x9049, 0x10e6: 0x9049, 0x10e7: 0x9049, 0x10e8: 0x9049, 0x10e9: 0x9049, + 0x10ea: 0x9049, 0x10eb: 0x9049, 0x10ec: 0x9049, 0x10ed: 0x9049, 0x10ee: 0x9049, 0x10ef: 0x9049, + 0x10f0: 0x9049, 0x10f1: 0x9049, 0x10f2: 0x9049, 0x10f3: 0x9049, 0x10f4: 0x9049, 0x10f5: 0x9049, + 0x10f6: 0x9049, 0x10f7: 0x9049, 0x10f8: 0x9049, 0x10f9: 0x9049, 0x10fa: 0x9049, 0x10fb: 0x9049, + 0x10fc: 0x9049, 0x10fd: 0x9049, 0x10fe: 0x9049, 0x10ff: 0x9049, + // Block 0x44, offset 0x1100 + 0x1100: 0x9049, 0x1101: 0x9049, 0x1102: 0x9049, 0x1103: 0x9049, 0x1104: 0x9049, 0x1105: 0x9049, + 0x1106: 0x9049, 0x1107: 0x9049, 0x1108: 0x9049, 0x1109: 0x9049, 0x110a: 0x9049, 0x110b: 0x9049, + 0x110c: 0x9049, 0x110d: 0x9049, 0x110e: 0x9049, 0x110f: 0x9049, 0x1110: 0x9049, 0x1111: 0x9049, + 0x1112: 0x9049, 0x1113: 0x9049, 0x1114: 0x9049, 0x1115: 0x9049, 0x1116: 0x9049, 0x1117: 0x9049, + 0x1118: 0x9049, 0x1119: 0x9049, 0x111a: 0x9049, 0x111b: 0x9049, 0x111c: 0x9049, 0x111d: 0x9049, + 0x111e: 0x9049, 0x111f: 0x904a, 0x1120: 0x904b, 0x1121: 0xb04c, 0x1122: 0xb04d, 0x1123: 0xb04d, + 0x1124: 0xb04e, 0x1125: 0xb04f, 0x1126: 0xb050, 0x1127: 0xb051, 0x1128: 0xb052, 0x1129: 0xb053, + 0x112a: 0xb054, 0x112b: 0xb055, 0x112c: 0xb056, 0x112d: 0xb057, 0x112e: 0xb058, 0x112f: 0xb059, + 0x1130: 0xb05a, 0x1131: 0xb05b, 0x1132: 0xb05c, 0x1133: 0xb05d, 0x1134: 0xb05e, 0x1135: 0xb05f, + 0x1136: 0xb060, 0x1137: 0xb061, 0x1138: 0xb062, 0x1139: 0xb063, 0x113a: 0xb064, 0x113b: 0xb065, + 0x113c: 0xb052, 0x113d: 0xb066, 0x113e: 0xb067, 0x113f: 0xb055, + // Block 0x45, offset 0x1140 + 0x1140: 0xb068, 0x1141: 0xb069, 0x1142: 0xb06a, 0x1143: 0xb06b, 0x1144: 0xb05a, 0x1145: 0xb056, + 0x1146: 0xb06c, 0x1147: 0xb06d, 0x1148: 0xb06b, 0x1149: 0xb06e, 0x114a: 0xb06b, 0x114b: 0xb06f, + 0x114c: 0xb06f, 0x114d: 0xb070, 0x114e: 0xb070, 0x114f: 0xb071, 0x1150: 0xb056, 0x1151: 0xb072, + 0x1152: 0xb073, 0x1153: 0xb072, 0x1154: 0xb074, 0x1155: 0xb073, 0x1156: 0xb075, 0x1157: 0xb075, + 0x1158: 0xb076, 0x1159: 0xb076, 0x115a: 0xb077, 0x115b: 0xb077, 0x115c: 0xb073, 0x115d: 0xb078, + 0x115e: 0xb079, 0x115f: 0xb067, 0x1160: 0xb07a, 0x1161: 0xb07b, 0x1162: 0xb07b, 0x1163: 0xb07b, + 0x1164: 0xb07b, 0x1165: 0xb07b, 0x1166: 0xb07b, 0x1167: 0xb07b, 0x1168: 0xb07b, 0x1169: 0xb07b, + 0x116a: 0xb07b, 0x116b: 0xb07b, 0x116c: 0xb07b, 0x116d: 0xb07b, 0x116e: 0xb07b, 0x116f: 0xb07b, + 0x1170: 0xb07c, 0x1171: 0xb07c, 0x1172: 0xb07c, 0x1173: 0xb07c, 0x1174: 0xb07c, 0x1175: 0xb07c, + 0x1176: 0xb07c, 0x1177: 0xb07c, 0x1178: 0xb07c, 0x1179: 0xb07c, 0x117a: 0xb07c, 0x117b: 0xb07c, + 0x117c: 0xb07c, 0x117d: 0xb07c, 0x117e: 0xb07c, + // Block 0x46, offset 0x1180 + 0x1182: 0xb07d, 0x1183: 0xb07e, 0x1184: 0xb07f, 0x1185: 0xb080, + 0x1186: 0xb07f, 0x1187: 0xb07e, 0x118a: 0xb081, 0x118b: 0xb082, + 0x118c: 0xb083, 0x118d: 0xb07f, 0x118e: 0xb080, 0x118f: 0xb07f, + 0x1192: 0xb084, 0x1193: 0xb085, 0x1194: 0xb084, 0x1195: 0xb086, 0x1196: 0xb084, 0x1197: 0xb087, + 0x119a: 0xb088, 0x119b: 0xb089, 0x119c: 0xb08a, + 0x11a0: 0x908b, 0x11a1: 0x908b, 0x11a2: 0x908c, 0x11a3: 0x908d, + 0x11a4: 0x908b, 0x11a5: 0x908e, 0x11a6: 0x908f, 0x11a8: 0xb090, 0x11a9: 0xb091, + 0x11aa: 0xb092, 0x11ab: 0xb091, 0x11ac: 0xb093, 0x11ad: 0xb094, 0x11ae: 0xb095, + 0x11bd: 0x2000, + // Block 0x47, offset 0x11c0 + 0x11e0: 0x4000, 0x11e1: 0x4000, + // Block 0x48, offset 0x1200 + 0x1200: 0x4000, 0x1201: 0x4000, 0x1202: 0x4000, 0x1203: 0x4000, 0x1204: 0x4000, 0x1205: 0x4000, + 0x1206: 0x4000, 0x1207: 0x4000, 0x1208: 0x4000, 0x1209: 0x4000, 0x120a: 0x4000, 0x120b: 0x4000, + 0x120c: 0x4000, 0x120d: 0x4000, 0x120e: 0x4000, 0x120f: 0x4000, 0x1210: 0x4000, 0x1211: 0x4000, + 0x1212: 0x4000, 0x1213: 0x4000, 0x1214: 0x4000, 0x1215: 0x4000, 0x1216: 0x4000, 0x1217: 0x4000, + 0x1218: 0x4000, 0x1219: 0x4000, 0x121a: 0x4000, 0x121b: 0x4000, 0x121c: 0x4000, 0x121d: 0x4000, + 0x121e: 0x4000, 0x121f: 0x4000, 0x1220: 0x4000, 0x1221: 0x4000, 0x1222: 0x4000, 0x1223: 0x4000, + 0x1224: 0x4000, 0x1225: 0x4000, 0x1226: 0x4000, 0x1227: 0x4000, 0x1228: 0x4000, 0x1229: 0x4000, + 0x122a: 0x4000, 0x122b: 0x4000, 0x122c: 0x4000, 0x122d: 0x4000, 0x122e: 0x4000, 0x122f: 0x4000, + 0x1230: 0x4000, 0x1231: 0x4000, + // Block 0x49, offset 0x1240 + 0x1240: 0x4000, 0x1241: 0x4000, 0x1242: 0x4000, 0x1243: 0x4000, 0x1244: 0x4000, 0x1245: 0x4000, + 0x1246: 0x4000, 0x1247: 0x4000, 0x1248: 0x4000, 0x1249: 0x4000, 0x124a: 0x4000, 0x124b: 0x4000, + 0x124c: 0x4000, 0x124d: 0x4000, 0x124e: 0x4000, 0x124f: 0x4000, 0x1250: 0x4000, 0x1251: 0x4000, + 0x1252: 0x4000, 0x1253: 0x4000, 0x1254: 0x4000, 0x1255: 0x4000, 0x1256: 0x4000, 0x1257: 0x4000, + 0x1258: 0x4000, 0x1259: 0x4000, 0x125a: 0x4000, 0x125b: 0x4000, 0x125c: 0x4000, 0x125d: 0x4000, + 0x125e: 0x4000, 0x125f: 0x4000, 0x1260: 0x4000, 0x1261: 0x4000, 0x1262: 0x4000, 0x1263: 0x4000, + 0x1264: 0x4000, 0x1265: 0x4000, 0x1266: 0x4000, 0x1267: 0x4000, 0x1268: 0x4000, 0x1269: 0x4000, + 0x126a: 0x4000, 0x126b: 0x4000, 0x126c: 0x4000, 0x126d: 0x4000, 0x126e: 0x4000, 0x126f: 0x4000, + 0x1270: 0x4000, 0x1271: 0x4000, 0x1272: 0x4000, + // Block 0x4a, offset 0x1280 + 0x1280: 0x4000, 0x1281: 0x4000, 0x1282: 0x4000, 0x1283: 0x4000, 0x1284: 0x4000, 0x1285: 0x4000, + 0x1286: 0x4000, 0x1287: 0x4000, 0x1288: 0x4000, 0x1289: 0x4000, 0x128a: 0x4000, 0x128b: 0x4000, + 0x128c: 0x4000, 0x128d: 0x4000, 0x128e: 0x4000, 0x128f: 0x4000, 0x1290: 0x4000, 0x1291: 0x4000, + 0x1292: 0x4000, 0x1293: 0x4000, 0x1294: 0x4000, 0x1295: 0x4000, 0x1296: 0x4000, 0x1297: 0x4000, + 0x1298: 0x4000, 0x1299: 0x4000, 0x129a: 0x4000, 0x129b: 0x4000, 0x129c: 0x4000, 0x129d: 0x4000, + 0x129e: 0x4000, + // Block 0x4b, offset 0x12c0 + 0x12f0: 0x4000, 0x12f1: 0x4000, 0x12f2: 0x4000, 0x12f3: 0x4000, 0x12f4: 0x4000, 0x12f5: 0x4000, + 0x12f6: 0x4000, 0x12f7: 0x4000, 0x12f8: 0x4000, 0x12f9: 0x4000, 0x12fa: 0x4000, 0x12fb: 0x4000, + 0x12fc: 0x4000, 0x12fd: 0x4000, 0x12fe: 0x4000, 0x12ff: 0x4000, + // Block 0x4c, offset 0x1300 + 0x1300: 0x4000, 0x1301: 0x4000, 0x1302: 0x4000, 0x1303: 0x4000, 0x1304: 0x4000, 0x1305: 0x4000, + 0x1306: 0x4000, 0x1307: 0x4000, 0x1308: 0x4000, 0x1309: 0x4000, 0x130a: 0x4000, 0x130b: 0x4000, + 0x130c: 0x4000, 0x130d: 0x4000, 0x130e: 0x4000, 0x130f: 0x4000, 0x1310: 0x4000, 0x1311: 0x4000, + 0x1312: 0x4000, 0x1313: 0x4000, 0x1314: 0x4000, 0x1315: 0x4000, 0x1316: 0x4000, 0x1317: 0x4000, + 0x1318: 0x4000, 0x1319: 0x4000, 0x131a: 0x4000, 0x131b: 0x4000, 0x131c: 0x4000, 0x131d: 0x4000, + 0x131e: 0x4000, 0x131f: 0x4000, 0x1320: 0x4000, 0x1321: 0x4000, 0x1322: 0x4000, 0x1323: 0x4000, + 0x1324: 0x4000, 0x1325: 0x4000, 0x1326: 0x4000, 0x1327: 0x4000, 0x1328: 0x4000, 0x1329: 0x4000, + 0x132a: 0x4000, 0x132b: 0x4000, 0x132c: 0x4000, 0x132d: 0x4000, 0x132e: 0x4000, 0x132f: 0x4000, + 0x1330: 0x4000, 0x1331: 0x4000, 0x1332: 0x4000, 0x1333: 0x4000, 0x1334: 0x4000, 0x1335: 0x4000, + 0x1336: 0x4000, 0x1337: 0x4000, 0x1338: 0x4000, 0x1339: 0x4000, 0x133a: 0x4000, 0x133b: 0x4000, + // Block 0x4d, offset 0x1340 + 0x1344: 0x4000, + // Block 0x4e, offset 0x1380 + 0x138f: 0x4000, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x2000, 0x13c1: 0x2000, 0x13c2: 0x2000, 0x13c3: 0x2000, 0x13c4: 0x2000, 0x13c5: 0x2000, + 0x13c6: 0x2000, 0x13c7: 0x2000, 0x13c8: 0x2000, 0x13c9: 0x2000, 0x13ca: 0x2000, + 0x13d0: 0x2000, 0x13d1: 0x2000, + 0x13d2: 0x2000, 0x13d3: 0x2000, 0x13d4: 0x2000, 0x13d5: 0x2000, 0x13d6: 0x2000, 0x13d7: 0x2000, + 0x13d8: 0x2000, 0x13d9: 0x2000, 0x13da: 0x2000, 0x13db: 0x2000, 0x13dc: 0x2000, 0x13dd: 0x2000, + 0x13de: 0x2000, 0x13df: 0x2000, 0x13e0: 0x2000, 0x13e1: 0x2000, 0x13e2: 0x2000, 0x13e3: 0x2000, + 0x13e4: 0x2000, 0x13e5: 0x2000, 0x13e6: 0x2000, 0x13e7: 0x2000, 0x13e8: 0x2000, 0x13e9: 0x2000, + 0x13ea: 0x2000, 0x13eb: 0x2000, 0x13ec: 0x2000, 0x13ed: 0x2000, + 0x13f0: 0x2000, 0x13f1: 0x2000, 0x13f2: 0x2000, 0x13f3: 0x2000, 0x13f4: 0x2000, 0x13f5: 0x2000, + 0x13f6: 0x2000, 0x13f7: 0x2000, 0x13f8: 0x2000, 0x13f9: 0x2000, 0x13fa: 0x2000, 0x13fb: 0x2000, + 0x13fc: 0x2000, 0x13fd: 0x2000, 0x13fe: 0x2000, 0x13ff: 0x2000, + // Block 0x50, offset 0x1400 + 0x1400: 0x2000, 0x1401: 0x2000, 0x1402: 0x2000, 0x1403: 0x2000, 0x1404: 0x2000, 0x1405: 0x2000, + 0x1406: 0x2000, 0x1407: 0x2000, 0x1408: 0x2000, 0x1409: 0x2000, 0x140a: 0x2000, 0x140b: 0x2000, + 0x140c: 0x2000, 0x140d: 0x2000, 0x140e: 0x2000, 0x140f: 0x2000, 0x1410: 0x2000, 0x1411: 0x2000, + 0x1412: 0x2000, 0x1413: 0x2000, 0x1414: 0x2000, 0x1415: 0x2000, 0x1416: 0x2000, 0x1417: 0x2000, + 0x1418: 0x2000, 0x1419: 0x2000, 0x141a: 0x2000, 0x141b: 0x2000, 0x141c: 0x2000, 0x141d: 0x2000, + 0x141e: 0x2000, 0x141f: 0x2000, 0x1420: 0x2000, 0x1421: 0x2000, 0x1422: 0x2000, 0x1423: 0x2000, + 0x1424: 0x2000, 0x1425: 0x2000, 0x1426: 0x2000, 0x1427: 0x2000, 0x1428: 0x2000, 0x1429: 0x2000, + 0x1430: 0x2000, 0x1431: 0x2000, 0x1432: 0x2000, 0x1433: 0x2000, 0x1434: 0x2000, 0x1435: 0x2000, + 0x1436: 0x2000, 0x1437: 0x2000, 0x1438: 0x2000, 0x1439: 0x2000, 0x143a: 0x2000, 0x143b: 0x2000, + 0x143c: 0x2000, 0x143d: 0x2000, 0x143e: 0x2000, 0x143f: 0x2000, + // Block 0x51, offset 0x1440 + 0x1440: 0x2000, 0x1441: 0x2000, 0x1442: 0x2000, 0x1443: 0x2000, 0x1444: 0x2000, 0x1445: 0x2000, + 0x1446: 0x2000, 0x1447: 0x2000, 0x1448: 0x2000, 0x1449: 0x2000, 0x144a: 0x2000, 0x144b: 0x2000, + 0x144c: 0x2000, 0x144d: 0x2000, 0x144e: 0x4000, 0x144f: 0x2000, 0x1450: 0x2000, 0x1451: 0x4000, + 0x1452: 0x4000, 0x1453: 0x4000, 0x1454: 0x4000, 0x1455: 0x4000, 0x1456: 0x4000, 0x1457: 0x4000, + 0x1458: 0x4000, 0x1459: 0x4000, 0x145a: 0x4000, 0x145b: 0x2000, 0x145c: 0x2000, 0x145d: 0x2000, + 0x145e: 0x2000, 0x145f: 0x2000, 0x1460: 0x2000, 0x1461: 0x2000, 0x1462: 0x2000, 0x1463: 0x2000, + 0x1464: 0x2000, 0x1465: 0x2000, 0x1466: 0x2000, 0x1467: 0x2000, 0x1468: 0x2000, 0x1469: 0x2000, + 0x146a: 0x2000, 0x146b: 0x2000, 0x146c: 0x2000, + // Block 0x52, offset 0x1480 + 0x1480: 0x4000, 0x1481: 0x4000, 0x1482: 0x4000, + 0x1490: 0x4000, 0x1491: 0x4000, + 0x1492: 0x4000, 0x1493: 0x4000, 0x1494: 0x4000, 0x1495: 0x4000, 0x1496: 0x4000, 0x1497: 0x4000, + 0x1498: 0x4000, 0x1499: 0x4000, 0x149a: 0x4000, 0x149b: 0x4000, 0x149c: 0x4000, 0x149d: 0x4000, + 0x149e: 0x4000, 0x149f: 0x4000, 0x14a0: 0x4000, 0x14a1: 0x4000, 0x14a2: 0x4000, 0x14a3: 0x4000, + 0x14a4: 0x4000, 0x14a5: 0x4000, 0x14a6: 0x4000, 0x14a7: 0x4000, 0x14a8: 0x4000, 0x14a9: 0x4000, + 0x14aa: 0x4000, 0x14ab: 0x4000, 0x14ac: 0x4000, 0x14ad: 0x4000, 0x14ae: 0x4000, 0x14af: 0x4000, + 0x14b0: 0x4000, 0x14b1: 0x4000, 0x14b2: 0x4000, 0x14b3: 0x4000, 0x14b4: 0x4000, 0x14b5: 0x4000, + 0x14b6: 0x4000, 0x14b7: 0x4000, 0x14b8: 0x4000, 0x14b9: 0x4000, 0x14ba: 0x4000, 0x14bb: 0x4000, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x4000, 0x14c1: 0x4000, 0x14c2: 0x4000, 0x14c3: 0x4000, 0x14c4: 0x4000, 0x14c5: 0x4000, + 0x14c6: 0x4000, 0x14c7: 0x4000, 0x14c8: 0x4000, + 0x14d0: 0x4000, 0x14d1: 0x4000, + 0x14e0: 0x4000, 0x14e1: 0x4000, 0x14e2: 0x4000, 0x14e3: 0x4000, + 0x14e4: 0x4000, 0x14e5: 0x4000, + // Block 0x54, offset 0x1500 + 0x1500: 0x4000, 0x1501: 0x4000, 0x1502: 0x4000, 0x1503: 0x4000, 0x1504: 0x4000, 0x1505: 0x4000, + 0x1506: 0x4000, 0x1507: 0x4000, 0x1508: 0x4000, 0x1509: 0x4000, 0x150a: 0x4000, 0x150b: 0x4000, + 0x150c: 0x4000, 0x150d: 0x4000, 0x150e: 0x4000, 0x150f: 0x4000, 0x1510: 0x4000, 0x1511: 0x4000, + 0x1512: 0x4000, 0x1513: 0x4000, 0x1514: 0x4000, 0x1515: 0x4000, 0x1516: 0x4000, 0x1517: 0x4000, + 0x1518: 0x4000, 0x1519: 0x4000, 0x151a: 0x4000, 0x151b: 0x4000, 0x151c: 0x4000, 0x151d: 0x4000, + 0x151e: 0x4000, 0x151f: 0x4000, 0x1520: 0x4000, + 0x152d: 0x4000, 0x152e: 0x4000, 0x152f: 0x4000, + 0x1530: 0x4000, 0x1531: 0x4000, 0x1532: 0x4000, 0x1533: 0x4000, 0x1534: 0x4000, 0x1535: 0x4000, + 0x1537: 0x4000, 0x1538: 0x4000, 0x1539: 0x4000, 0x153a: 0x4000, 0x153b: 0x4000, + 0x153c: 0x4000, 0x153d: 0x4000, 0x153e: 0x4000, 0x153f: 0x4000, + // Block 0x55, offset 0x1540 + 0x1540: 0x4000, 0x1541: 0x4000, 0x1542: 0x4000, 0x1543: 0x4000, 0x1544: 0x4000, 0x1545: 0x4000, + 0x1546: 0x4000, 0x1547: 0x4000, 0x1548: 0x4000, 0x1549: 0x4000, 0x154a: 0x4000, 0x154b: 0x4000, + 0x154c: 0x4000, 0x154d: 0x4000, 0x154e: 0x4000, 0x154f: 0x4000, 0x1550: 0x4000, 0x1551: 0x4000, + 0x1552: 0x4000, 0x1553: 0x4000, 0x1554: 0x4000, 0x1555: 0x4000, 0x1556: 0x4000, 0x1557: 0x4000, + 0x1558: 0x4000, 0x1559: 0x4000, 0x155a: 0x4000, 0x155b: 0x4000, 0x155c: 0x4000, 0x155d: 0x4000, + 0x155e: 0x4000, 0x155f: 0x4000, 0x1560: 0x4000, 0x1561: 0x4000, 0x1562: 0x4000, 0x1563: 0x4000, + 0x1564: 0x4000, 0x1565: 0x4000, 0x1566: 0x4000, 0x1567: 0x4000, 0x1568: 0x4000, 0x1569: 0x4000, + 0x156a: 0x4000, 0x156b: 0x4000, 0x156c: 0x4000, 0x156d: 0x4000, 0x156e: 0x4000, 0x156f: 0x4000, + 0x1570: 0x4000, 0x1571: 0x4000, 0x1572: 0x4000, 0x1573: 0x4000, 0x1574: 0x4000, 0x1575: 0x4000, + 0x1576: 0x4000, 0x1577: 0x4000, 0x1578: 0x4000, 0x1579: 0x4000, 0x157a: 0x4000, 0x157b: 0x4000, + 0x157c: 0x4000, 0x157e: 0x4000, 0x157f: 0x4000, + // Block 0x56, offset 0x1580 + 0x1580: 0x4000, 0x1581: 0x4000, 0x1582: 0x4000, 0x1583: 0x4000, 0x1584: 0x4000, 0x1585: 0x4000, + 0x1586: 0x4000, 0x1587: 0x4000, 0x1588: 0x4000, 0x1589: 0x4000, 0x158a: 0x4000, 0x158b: 0x4000, + 0x158c: 0x4000, 0x158d: 0x4000, 0x158e: 0x4000, 0x158f: 0x4000, 0x1590: 0x4000, 0x1591: 0x4000, + 0x1592: 0x4000, 0x1593: 0x4000, + 0x15a0: 0x4000, 0x15a1: 0x4000, 0x15a2: 0x4000, 0x15a3: 0x4000, + 0x15a4: 0x4000, 0x15a5: 0x4000, 0x15a6: 0x4000, 0x15a7: 0x4000, 0x15a8: 0x4000, 0x15a9: 0x4000, + 0x15aa: 0x4000, 0x15ab: 0x4000, 0x15ac: 0x4000, 0x15ad: 0x4000, 0x15ae: 0x4000, 0x15af: 0x4000, + 0x15b0: 0x4000, 0x15b1: 0x4000, 0x15b2: 0x4000, 0x15b3: 0x4000, 0x15b4: 0x4000, 0x15b5: 0x4000, + 0x15b6: 0x4000, 0x15b7: 0x4000, 0x15b8: 0x4000, 0x15b9: 0x4000, 0x15ba: 0x4000, 0x15bb: 0x4000, + 0x15bc: 0x4000, 0x15bd: 0x4000, 0x15be: 0x4000, 0x15bf: 0x4000, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x4000, 0x15c1: 0x4000, 0x15c2: 0x4000, 0x15c3: 0x4000, 0x15c4: 0x4000, 0x15c5: 0x4000, + 0x15c6: 0x4000, 0x15c7: 0x4000, 0x15c8: 0x4000, 0x15c9: 0x4000, 0x15ca: 0x4000, + 0x15cf: 0x4000, 0x15d0: 0x4000, 0x15d1: 0x4000, + 0x15d2: 0x4000, 0x15d3: 0x4000, + 0x15e0: 0x4000, 0x15e1: 0x4000, 0x15e2: 0x4000, 0x15e3: 0x4000, + 0x15e4: 0x4000, 0x15e5: 0x4000, 0x15e6: 0x4000, 0x15e7: 0x4000, 0x15e8: 0x4000, 0x15e9: 0x4000, + 0x15ea: 0x4000, 0x15eb: 0x4000, 0x15ec: 0x4000, 0x15ed: 0x4000, 0x15ee: 0x4000, 0x15ef: 0x4000, + 0x15f0: 0x4000, 0x15f4: 0x4000, + 0x15f8: 0x4000, 0x15f9: 0x4000, 0x15fa: 0x4000, 0x15fb: 0x4000, + 0x15fc: 0x4000, 0x15fd: 0x4000, 0x15fe: 0x4000, 0x15ff: 0x4000, + // Block 0x58, offset 0x1600 + 0x1600: 0x4000, 0x1602: 0x4000, 0x1603: 0x4000, 0x1604: 0x4000, 0x1605: 0x4000, + 0x1606: 0x4000, 0x1607: 0x4000, 0x1608: 0x4000, 0x1609: 0x4000, 0x160a: 0x4000, 0x160b: 0x4000, + 0x160c: 0x4000, 0x160d: 0x4000, 0x160e: 0x4000, 0x160f: 0x4000, 0x1610: 0x4000, 0x1611: 0x4000, + 0x1612: 0x4000, 0x1613: 0x4000, 0x1614: 0x4000, 0x1615: 0x4000, 0x1616: 0x4000, 0x1617: 0x4000, + 0x1618: 0x4000, 0x1619: 0x4000, 0x161a: 0x4000, 0x161b: 0x4000, 0x161c: 0x4000, 0x161d: 0x4000, + 0x161e: 0x4000, 0x161f: 0x4000, 0x1620: 0x4000, 0x1621: 0x4000, 0x1622: 0x4000, 0x1623: 0x4000, + 0x1624: 0x4000, 0x1625: 0x4000, 0x1626: 0x4000, 0x1627: 0x4000, 0x1628: 0x4000, 0x1629: 0x4000, + 0x162a: 0x4000, 0x162b: 0x4000, 0x162c: 0x4000, 0x162d: 0x4000, 0x162e: 0x4000, 0x162f: 0x4000, + 0x1630: 0x4000, 0x1631: 0x4000, 0x1632: 0x4000, 0x1633: 0x4000, 0x1634: 0x4000, 0x1635: 0x4000, + 0x1636: 0x4000, 0x1637: 0x4000, 0x1638: 0x4000, 0x1639: 0x4000, 0x163a: 0x4000, 0x163b: 0x4000, + 0x163c: 0x4000, 0x163d: 0x4000, 0x163e: 0x4000, 0x163f: 0x4000, + // Block 0x59, offset 0x1640 + 0x1640: 0x4000, 0x1641: 0x4000, 0x1642: 0x4000, 0x1643: 0x4000, 0x1644: 0x4000, 0x1645: 0x4000, + 0x1646: 0x4000, 0x1647: 0x4000, 0x1648: 0x4000, 0x1649: 0x4000, 0x164a: 0x4000, 0x164b: 0x4000, + 0x164c: 0x4000, 0x164d: 0x4000, 0x164e: 0x4000, 0x164f: 0x4000, 0x1650: 0x4000, 0x1651: 0x4000, + 0x1652: 0x4000, 0x1653: 0x4000, 0x1654: 0x4000, 0x1655: 0x4000, 0x1656: 0x4000, 0x1657: 0x4000, + 0x1658: 0x4000, 0x1659: 0x4000, 0x165a: 0x4000, 0x165b: 0x4000, 0x165c: 0x4000, 0x165d: 0x4000, + 0x165e: 0x4000, 0x165f: 0x4000, 0x1660: 0x4000, 0x1661: 0x4000, 0x1662: 0x4000, 0x1663: 0x4000, + 0x1664: 0x4000, 0x1665: 0x4000, 0x1666: 0x4000, 0x1667: 0x4000, 0x1668: 0x4000, 0x1669: 0x4000, + 0x166a: 0x4000, 0x166b: 0x4000, 0x166c: 0x4000, 0x166d: 0x4000, 0x166e: 0x4000, 0x166f: 0x4000, + 0x1670: 0x4000, 0x1671: 0x4000, 0x1672: 0x4000, 0x1673: 0x4000, 0x1674: 0x4000, 0x1675: 0x4000, + 0x1676: 0x4000, 0x1677: 0x4000, 0x1678: 0x4000, 0x1679: 0x4000, 0x167a: 0x4000, 0x167b: 0x4000, + 0x167c: 0x4000, 0x167f: 0x4000, + // Block 0x5a, offset 0x1680 + 0x1680: 0x4000, 0x1681: 0x4000, 0x1682: 0x4000, 0x1683: 0x4000, 0x1684: 0x4000, 0x1685: 0x4000, + 0x1686: 0x4000, 0x1687: 0x4000, 0x1688: 0x4000, 0x1689: 0x4000, 0x168a: 0x4000, 0x168b: 0x4000, + 0x168c: 0x4000, 0x168d: 0x4000, 0x168e: 0x4000, 0x168f: 0x4000, 0x1690: 0x4000, 0x1691: 0x4000, + 0x1692: 0x4000, 0x1693: 0x4000, 0x1694: 0x4000, 0x1695: 0x4000, 0x1696: 0x4000, 0x1697: 0x4000, + 0x1698: 0x4000, 0x1699: 0x4000, 0x169a: 0x4000, 0x169b: 0x4000, 0x169c: 0x4000, 0x169d: 0x4000, + 0x169e: 0x4000, 0x169f: 0x4000, 0x16a0: 0x4000, 0x16a1: 0x4000, 0x16a2: 0x4000, 0x16a3: 0x4000, + 0x16a4: 0x4000, 0x16a5: 0x4000, 0x16a6: 0x4000, 0x16a7: 0x4000, 0x16a8: 0x4000, 0x16a9: 0x4000, + 0x16aa: 0x4000, 0x16ab: 0x4000, 0x16ac: 0x4000, 0x16ad: 0x4000, 0x16ae: 0x4000, 0x16af: 0x4000, + 0x16b0: 0x4000, 0x16b1: 0x4000, 0x16b2: 0x4000, 0x16b3: 0x4000, 0x16b4: 0x4000, 0x16b5: 0x4000, + 0x16b6: 0x4000, 0x16b7: 0x4000, 0x16b8: 0x4000, 0x16b9: 0x4000, 0x16ba: 0x4000, 0x16bb: 0x4000, + 0x16bc: 0x4000, 0x16bd: 0x4000, + // Block 0x5b, offset 0x16c0 + 0x16cb: 0x4000, + 0x16cc: 0x4000, 0x16cd: 0x4000, 0x16ce: 0x4000, 0x16d0: 0x4000, 0x16d1: 0x4000, + 0x16d2: 0x4000, 0x16d3: 0x4000, 0x16d4: 0x4000, 0x16d5: 0x4000, 0x16d6: 0x4000, 0x16d7: 0x4000, + 0x16d8: 0x4000, 0x16d9: 0x4000, 0x16da: 0x4000, 0x16db: 0x4000, 0x16dc: 0x4000, 0x16dd: 0x4000, + 0x16de: 0x4000, 0x16df: 0x4000, 0x16e0: 0x4000, 0x16e1: 0x4000, 0x16e2: 0x4000, 0x16e3: 0x4000, + 0x16e4: 0x4000, 0x16e5: 0x4000, 0x16e6: 0x4000, 0x16e7: 0x4000, + 0x16fa: 0x4000, + // Block 0x5c, offset 0x1700 + 0x1715: 0x4000, 0x1716: 0x4000, + 0x1724: 0x4000, + // Block 0x5d, offset 0x1740 + 0x177b: 0x4000, + 0x177c: 0x4000, 0x177d: 0x4000, 0x177e: 0x4000, 0x177f: 0x4000, + // Block 0x5e, offset 0x1780 + 0x1780: 0x4000, 0x1781: 0x4000, 0x1782: 0x4000, 0x1783: 0x4000, 0x1784: 0x4000, 0x1785: 0x4000, + 0x1786: 0x4000, 0x1787: 0x4000, 0x1788: 0x4000, 0x1789: 0x4000, 0x178a: 0x4000, 0x178b: 0x4000, + 0x178c: 0x4000, 0x178d: 0x4000, 0x178e: 0x4000, 0x178f: 0x4000, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x4000, 0x17c1: 0x4000, 0x17c2: 0x4000, 0x17c3: 0x4000, 0x17c4: 0x4000, 0x17c5: 0x4000, + 0x17cc: 0x4000, 0x17d0: 0x4000, 0x17d1: 0x4000, + 0x17d2: 0x4000, + 0x17eb: 0x4000, 0x17ec: 0x4000, + 0x17f4: 0x4000, 0x17f5: 0x4000, + 0x17f6: 0x4000, 0x17f7: 0x4000, 0x17f8: 0x4000, 0x17f9: 0x4000, + // Block 0x60, offset 0x1800 + 0x1810: 0x4000, 0x1811: 0x4000, + 0x1812: 0x4000, 0x1813: 0x4000, 0x1814: 0x4000, 0x1815: 0x4000, 0x1816: 0x4000, 0x1817: 0x4000, + 0x1818: 0x4000, 0x1819: 0x4000, 0x181a: 0x4000, 0x181b: 0x4000, 0x181c: 0x4000, 0x181d: 0x4000, + 0x181e: 0x4000, 0x181f: 0x4000, 0x1820: 0x4000, 0x1821: 0x4000, 0x1822: 0x4000, 0x1823: 0x4000, + 0x1824: 0x4000, 0x1825: 0x4000, 0x1826: 0x4000, 0x1827: 0x4000, 0x1828: 0x4000, 0x1829: 0x4000, + 0x182a: 0x4000, 0x182b: 0x4000, 0x182c: 0x4000, 0x182d: 0x4000, 0x182e: 0x4000, 0x182f: 0x4000, + 0x1830: 0x4000, 0x1831: 0x4000, 0x1832: 0x4000, 0x1833: 0x4000, 0x1834: 0x4000, 0x1835: 0x4000, + 0x1836: 0x4000, 0x1837: 0x4000, 0x1838: 0x4000, 0x1839: 0x4000, 0x183a: 0x4000, 0x183b: 0x4000, + 0x183c: 0x4000, 0x183d: 0x4000, 0x183e: 0x4000, + // Block 0x61, offset 0x1840 + 0x1840: 0x4000, 0x1841: 0x4000, 0x1842: 0x4000, 0x1843: 0x4000, 0x1844: 0x4000, 0x1845: 0x4000, + 0x1846: 0x4000, 0x1847: 0x4000, 0x1848: 0x4000, 0x1849: 0x4000, 0x184a: 0x4000, 0x184b: 0x4000, + 0x184c: 0x4000, 0x184d: 0x4000, 0x184e: 0x4000, 0x184f: 0x4000, 0x1850: 0x4000, 0x1851: 0x4000, + 0x1852: 0x4000, 0x1853: 0x4000, 0x1854: 0x4000, 0x1855: 0x4000, 0x1856: 0x4000, 0x1857: 0x4000, + 0x1858: 0x4000, 0x1859: 0x4000, 0x185a: 0x4000, 0x185b: 0x4000, 0x185c: 0x4000, 0x185d: 0x4000, + 0x185e: 0x4000, 0x185f: 0x4000, 0x1860: 0x4000, 0x1861: 0x4000, 0x1862: 0x4000, 0x1863: 0x4000, + 0x1864: 0x4000, 0x1865: 0x4000, 0x1866: 0x4000, 0x1867: 0x4000, 0x1868: 0x4000, 0x1869: 0x4000, + 0x186a: 0x4000, 0x186b: 0x4000, 0x186c: 0x4000, 0x186d: 0x4000, 0x186e: 0x4000, 0x186f: 0x4000, + 0x1870: 0x4000, 0x1873: 0x4000, 0x1874: 0x4000, 0x1875: 0x4000, + 0x1876: 0x4000, 0x187a: 0x4000, + 0x187c: 0x4000, 0x187d: 0x4000, 0x187e: 0x4000, 0x187f: 0x4000, + // Block 0x62, offset 0x1880 + 0x1880: 0x4000, 0x1881: 0x4000, 0x1882: 0x4000, 0x1883: 0x4000, 0x1884: 0x4000, 0x1885: 0x4000, + 0x1886: 0x4000, 0x1887: 0x4000, 0x1888: 0x4000, 0x1889: 0x4000, 0x188a: 0x4000, 0x188b: 0x4000, + 0x188c: 0x4000, 0x188d: 0x4000, 0x188e: 0x4000, 0x188f: 0x4000, 0x1890: 0x4000, 0x1891: 0x4000, + 0x1892: 0x4000, 0x1893: 0x4000, 0x1894: 0x4000, 0x1895: 0x4000, 0x1896: 0x4000, 0x1897: 0x4000, + 0x1898: 0x4000, 0x1899: 0x4000, 0x189a: 0x4000, 0x189b: 0x4000, 0x189c: 0x4000, 0x189d: 0x4000, + 0x189e: 0x4000, 0x189f: 0x4000, 0x18a0: 0x4000, 0x18a1: 0x4000, 0x18a2: 0x4000, + 0x18b0: 0x4000, 0x18b1: 0x4000, 0x18b2: 0x4000, 0x18b3: 0x4000, 0x18b4: 0x4000, 0x18b5: 0x4000, + 0x18b6: 0x4000, 0x18b7: 0x4000, 0x18b8: 0x4000, 0x18b9: 0x4000, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x4000, 0x18c1: 0x4000, 0x18c2: 0x4000, + 0x18d0: 0x4000, 0x18d1: 0x4000, + 0x18d2: 0x4000, 0x18d3: 0x4000, 0x18d4: 0x4000, 0x18d5: 0x4000, 0x18d6: 0x4000, 0x18d7: 0x4000, + 0x18d8: 0x4000, 0x18d9: 0x4000, 0x18da: 0x4000, 0x18db: 0x4000, 0x18dc: 0x4000, 0x18dd: 0x4000, + 0x18de: 0x4000, 0x18df: 0x4000, 0x18e0: 0x4000, 0x18e1: 0x4000, 0x18e2: 0x4000, 0x18e3: 0x4000, + 0x18e4: 0x4000, 0x18e5: 0x4000, 0x18e6: 0x4000, 0x18e7: 0x4000, 0x18e8: 0x4000, 0x18e9: 0x4000, + 0x18ea: 0x4000, 0x18eb: 0x4000, 0x18ec: 0x4000, 0x18ed: 0x4000, 0x18ee: 0x4000, 0x18ef: 0x4000, + 0x18f0: 0x4000, 0x18f1: 0x4000, 0x18f2: 0x4000, 0x18f3: 0x4000, 0x18f4: 0x4000, 0x18f5: 0x4000, + 0x18f6: 0x4000, 0x18f7: 0x4000, 0x18f8: 0x4000, 0x18f9: 0x4000, 0x18fa: 0x4000, 0x18fb: 0x4000, + 0x18fc: 0x4000, 0x18fd: 0x4000, 0x18fe: 0x4000, 0x18ff: 0x4000, + // Block 0x64, offset 0x1900 + 0x1900: 0x2000, 0x1901: 0x2000, 0x1902: 0x2000, 0x1903: 0x2000, 0x1904: 0x2000, 0x1905: 0x2000, + 0x1906: 0x2000, 0x1907: 0x2000, 0x1908: 0x2000, 0x1909: 0x2000, 0x190a: 0x2000, 0x190b: 0x2000, + 0x190c: 0x2000, 0x190d: 0x2000, 0x190e: 0x2000, 0x190f: 0x2000, 0x1910: 0x2000, 0x1911: 0x2000, + 0x1912: 0x2000, 0x1913: 0x2000, 0x1914: 0x2000, 0x1915: 0x2000, 0x1916: 0x2000, 0x1917: 0x2000, + 0x1918: 0x2000, 0x1919: 0x2000, 0x191a: 0x2000, 0x191b: 0x2000, 0x191c: 0x2000, 0x191d: 0x2000, + 0x191e: 0x2000, 0x191f: 0x2000, 0x1920: 0x2000, 0x1921: 0x2000, 0x1922: 0x2000, 0x1923: 0x2000, + 0x1924: 0x2000, 0x1925: 0x2000, 0x1926: 0x2000, 0x1927: 0x2000, 0x1928: 0x2000, 0x1929: 0x2000, + 0x192a: 0x2000, 0x192b: 0x2000, 0x192c: 0x2000, 0x192d: 0x2000, 0x192e: 0x2000, 0x192f: 0x2000, + 0x1930: 0x2000, 0x1931: 0x2000, 0x1932: 0x2000, 0x1933: 0x2000, 0x1934: 0x2000, 0x1935: 0x2000, + 0x1936: 0x2000, 0x1937: 0x2000, 0x1938: 0x2000, 0x1939: 0x2000, 0x193a: 0x2000, 0x193b: 0x2000, + 0x193c: 0x2000, 0x193d: 0x2000, +} + +// widthIndex: 22 blocks, 1408 entries, 1408 bytes +// Block 0 is the zero block. +var widthIndex = [1408]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x02, 0xc4: 0x03, 0xc5: 0x04, 0xc7: 0x05, + 0xc9: 0x06, 0xcb: 0x07, 0xcc: 0x08, 0xcd: 0x09, 0xce: 0x0a, 0xcf: 0x0b, + 0xd0: 0x0c, 0xd1: 0x0d, + 0xe1: 0x02, 0xe2: 0x03, 0xe3: 0x04, 0xe4: 0x05, 0xe5: 0x06, 0xe6: 0x06, 0xe7: 0x06, + 0xe8: 0x06, 0xe9: 0x06, 0xea: 0x07, 0xeb: 0x06, 0xec: 0x06, 0xed: 0x08, 0xee: 0x09, 0xef: 0x0a, + 0xf0: 0x0f, 0xf3: 0x12, 0xf4: 0x13, + // Block 0x4, offset 0x100 + 0x104: 0x0e, 0x105: 0x0f, + // Block 0x5, offset 0x140 + 0x140: 0x10, 0x141: 0x11, 0x142: 0x12, 0x144: 0x13, 0x145: 0x14, 0x146: 0x15, 0x147: 0x16, + 0x148: 0x17, 0x149: 0x18, 0x14a: 0x19, 0x14c: 0x1a, 0x14f: 0x1b, + 0x151: 0x1c, 0x152: 0x08, 0x153: 0x1d, 0x154: 0x1e, 0x155: 0x1f, 0x156: 0x20, 0x157: 0x21, + 0x158: 0x22, 0x159: 0x23, 0x15a: 0x24, 0x15b: 0x25, 0x15c: 0x26, 0x15d: 0x27, 0x15e: 0x28, 0x15f: 0x29, + 0x166: 0x2a, + 0x16c: 0x2b, 0x16d: 0x2c, + 0x17a: 0x2d, 0x17b: 0x2e, 0x17c: 0x0e, 0x17d: 0x0e, 0x17e: 0x0e, 0x17f: 0x2f, + // Block 0x6, offset 0x180 + 0x180: 0x30, 0x181: 0x31, 0x182: 0x32, 0x183: 0x33, 0x184: 0x34, 0x185: 0x35, 0x186: 0x36, 0x187: 0x37, + 0x188: 0x38, 0x189: 0x39, 0x18a: 0x0e, 0x18b: 0x3a, 0x18c: 0x0e, 0x18d: 0x0e, 0x18e: 0x0e, 0x18f: 0x0e, + 0x190: 0x0e, 0x191: 0x0e, 0x192: 0x0e, 0x193: 0x0e, 0x194: 0x0e, 0x195: 0x0e, 0x196: 0x0e, 0x197: 0x0e, + 0x198: 0x0e, 0x199: 0x0e, 0x19a: 0x0e, 0x19b: 0x0e, 0x19c: 0x0e, 0x19d: 0x0e, 0x19e: 0x0e, 0x19f: 0x0e, + 0x1a0: 0x0e, 0x1a1: 0x0e, 0x1a2: 0x0e, 0x1a3: 0x0e, 0x1a4: 0x0e, 0x1a5: 0x0e, 0x1a6: 0x0e, 0x1a7: 0x0e, + 0x1a8: 0x0e, 0x1a9: 0x0e, 0x1aa: 0x0e, 0x1ab: 0x0e, 0x1ac: 0x0e, 0x1ad: 0x0e, 0x1ae: 0x0e, 0x1af: 0x0e, + 0x1b0: 0x0e, 0x1b1: 0x0e, 0x1b2: 0x0e, 0x1b3: 0x0e, 0x1b4: 0x0e, 0x1b5: 0x0e, 0x1b6: 0x0e, 0x1b7: 0x0e, + 0x1b8: 0x0e, 0x1b9: 0x0e, 0x1ba: 0x0e, 0x1bb: 0x0e, 0x1bc: 0x0e, 0x1bd: 0x0e, 0x1be: 0x0e, 0x1bf: 0x0e, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x0e, 0x1c1: 0x0e, 0x1c2: 0x0e, 0x1c3: 0x0e, 0x1c4: 0x0e, 0x1c5: 0x0e, 0x1c6: 0x0e, 0x1c7: 0x0e, + 0x1c8: 0x0e, 0x1c9: 0x0e, 0x1ca: 0x0e, 0x1cb: 0x0e, 0x1cc: 0x0e, 0x1cd: 0x0e, 0x1ce: 0x0e, 0x1cf: 0x0e, + 0x1d0: 0x0e, 0x1d1: 0x0e, 0x1d2: 0x0e, 0x1d3: 0x0e, 0x1d4: 0x0e, 0x1d5: 0x0e, 0x1d6: 0x0e, 0x1d7: 0x0e, + 0x1d8: 0x0e, 0x1d9: 0x0e, 0x1da: 0x0e, 0x1db: 0x0e, 0x1dc: 0x0e, 0x1dd: 0x0e, 0x1de: 0x0e, 0x1df: 0x0e, + 0x1e0: 0x0e, 0x1e1: 0x0e, 0x1e2: 0x0e, 0x1e3: 0x0e, 0x1e4: 0x0e, 0x1e5: 0x0e, 0x1e6: 0x0e, 0x1e7: 0x0e, + 0x1e8: 0x0e, 0x1e9: 0x0e, 0x1ea: 0x0e, 0x1eb: 0x0e, 0x1ec: 0x0e, 0x1ed: 0x0e, 0x1ee: 0x0e, 0x1ef: 0x0e, + 0x1f0: 0x0e, 0x1f1: 0x0e, 0x1f2: 0x0e, 0x1f3: 0x0e, 0x1f4: 0x0e, 0x1f5: 0x0e, 0x1f6: 0x0e, + 0x1f8: 0x0e, 0x1f9: 0x0e, 0x1fa: 0x0e, 0x1fb: 0x0e, 0x1fc: 0x0e, 0x1fd: 0x0e, 0x1fe: 0x0e, 0x1ff: 0x0e, + // Block 0x8, offset 0x200 + 0x200: 0x0e, 0x201: 0x0e, 0x202: 0x0e, 0x203: 0x0e, 0x204: 0x0e, 0x205: 0x0e, 0x206: 0x0e, 0x207: 0x0e, + 0x208: 0x0e, 0x209: 0x0e, 0x20a: 0x0e, 0x20b: 0x0e, 0x20c: 0x0e, 0x20d: 0x0e, 0x20e: 0x0e, 0x20f: 0x0e, + 0x210: 0x0e, 0x211: 0x0e, 0x212: 0x0e, 0x213: 0x0e, 0x214: 0x0e, 0x215: 0x0e, 0x216: 0x0e, 0x217: 0x0e, + 0x218: 0x0e, 0x219: 0x0e, 0x21a: 0x0e, 0x21b: 0x0e, 0x21c: 0x0e, 0x21d: 0x0e, 0x21e: 0x0e, 0x21f: 0x0e, + 0x220: 0x0e, 0x221: 0x0e, 0x222: 0x0e, 0x223: 0x0e, 0x224: 0x0e, 0x225: 0x0e, 0x226: 0x0e, 0x227: 0x0e, + 0x228: 0x0e, 0x229: 0x0e, 0x22a: 0x0e, 0x22b: 0x0e, 0x22c: 0x0e, 0x22d: 0x0e, 0x22e: 0x0e, 0x22f: 0x0e, + 0x230: 0x0e, 0x231: 0x0e, 0x232: 0x0e, 0x233: 0x0e, 0x234: 0x0e, 0x235: 0x0e, 0x236: 0x0e, 0x237: 0x0e, + 0x238: 0x0e, 0x239: 0x0e, 0x23a: 0x0e, 0x23b: 0x0e, 0x23c: 0x0e, 0x23d: 0x0e, 0x23e: 0x0e, 0x23f: 0x0e, + // Block 0x9, offset 0x240 + 0x240: 0x0e, 0x241: 0x0e, 0x242: 0x0e, 0x243: 0x0e, 0x244: 0x0e, 0x245: 0x0e, 0x246: 0x0e, 0x247: 0x0e, + 0x248: 0x0e, 0x249: 0x0e, 0x24a: 0x0e, 0x24b: 0x0e, 0x24c: 0x0e, 0x24d: 0x0e, 0x24e: 0x0e, 0x24f: 0x0e, + 0x250: 0x0e, 0x251: 0x0e, 0x252: 0x3b, 0x253: 0x3c, + 0x265: 0x3d, + 0x270: 0x0e, 0x271: 0x0e, 0x272: 0x0e, 0x273: 0x0e, 0x274: 0x0e, 0x275: 0x0e, 0x276: 0x0e, 0x277: 0x0e, + 0x278: 0x0e, 0x279: 0x0e, 0x27a: 0x0e, 0x27b: 0x0e, 0x27c: 0x0e, 0x27d: 0x0e, 0x27e: 0x0e, 0x27f: 0x0e, + // Block 0xa, offset 0x280 + 0x280: 0x0e, 0x281: 0x0e, 0x282: 0x0e, 0x283: 0x0e, 0x284: 0x0e, 0x285: 0x0e, 0x286: 0x0e, 0x287: 0x0e, + 0x288: 0x0e, 0x289: 0x0e, 0x28a: 0x0e, 0x28b: 0x0e, 0x28c: 0x0e, 0x28d: 0x0e, 0x28e: 0x0e, 0x28f: 0x0e, + 0x290: 0x0e, 0x291: 0x0e, 0x292: 0x0e, 0x293: 0x0e, 0x294: 0x0e, 0x295: 0x0e, 0x296: 0x0e, 0x297: 0x0e, + 0x298: 0x0e, 0x299: 0x0e, 0x29a: 0x0e, 0x29b: 0x0e, 0x29c: 0x0e, 0x29d: 0x0e, 0x29e: 0x3e, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x08, 0x2c1: 0x08, 0x2c2: 0x08, 0x2c3: 0x08, 0x2c4: 0x08, 0x2c5: 0x08, 0x2c6: 0x08, 0x2c7: 0x08, + 0x2c8: 0x08, 0x2c9: 0x08, 0x2ca: 0x08, 0x2cb: 0x08, 0x2cc: 0x08, 0x2cd: 0x08, 0x2ce: 0x08, 0x2cf: 0x08, + 0x2d0: 0x08, 0x2d1: 0x08, 0x2d2: 0x08, 0x2d3: 0x08, 0x2d4: 0x08, 0x2d5: 0x08, 0x2d6: 0x08, 0x2d7: 0x08, + 0x2d8: 0x08, 0x2d9: 0x08, 0x2da: 0x08, 0x2db: 0x08, 0x2dc: 0x08, 0x2dd: 0x08, 0x2de: 0x08, 0x2df: 0x08, + 0x2e0: 0x08, 0x2e1: 0x08, 0x2e2: 0x08, 0x2e3: 0x08, 0x2e4: 0x08, 0x2e5: 0x08, 0x2e6: 0x08, 0x2e7: 0x08, + 0x2e8: 0x08, 0x2e9: 0x08, 0x2ea: 0x08, 0x2eb: 0x08, 0x2ec: 0x08, 0x2ed: 0x08, 0x2ee: 0x08, 0x2ef: 0x08, + 0x2f0: 0x08, 0x2f1: 0x08, 0x2f2: 0x08, 0x2f3: 0x08, 0x2f4: 0x08, 0x2f5: 0x08, 0x2f6: 0x08, 0x2f7: 0x08, + 0x2f8: 0x08, 0x2f9: 0x08, 0x2fa: 0x08, 0x2fb: 0x08, 0x2fc: 0x08, 0x2fd: 0x08, 0x2fe: 0x08, 0x2ff: 0x08, + // Block 0xc, offset 0x300 + 0x300: 0x08, 0x301: 0x08, 0x302: 0x08, 0x303: 0x08, 0x304: 0x08, 0x305: 0x08, 0x306: 0x08, 0x307: 0x08, + 0x308: 0x08, 0x309: 0x08, 0x30a: 0x08, 0x30b: 0x08, 0x30c: 0x08, 0x30d: 0x08, 0x30e: 0x08, 0x30f: 0x08, + 0x310: 0x08, 0x311: 0x08, 0x312: 0x08, 0x313: 0x08, 0x314: 0x08, 0x315: 0x08, 0x316: 0x08, 0x317: 0x08, + 0x318: 0x08, 0x319: 0x08, 0x31a: 0x08, 0x31b: 0x08, 0x31c: 0x08, 0x31d: 0x08, 0x31e: 0x08, 0x31f: 0x08, + 0x320: 0x08, 0x321: 0x08, 0x322: 0x08, 0x323: 0x08, 0x324: 0x0e, 0x325: 0x0e, 0x326: 0x0e, 0x327: 0x0e, + 0x328: 0x0e, 0x329: 0x0e, 0x32a: 0x0e, 0x32b: 0x0e, + 0x338: 0x3f, 0x339: 0x40, 0x33c: 0x41, 0x33d: 0x42, 0x33e: 0x43, 0x33f: 0x44, + // Block 0xd, offset 0x340 + 0x37f: 0x45, + // Block 0xe, offset 0x380 + 0x380: 0x0e, 0x381: 0x0e, 0x382: 0x0e, 0x383: 0x0e, 0x384: 0x0e, 0x385: 0x0e, 0x386: 0x0e, 0x387: 0x0e, + 0x388: 0x0e, 0x389: 0x0e, 0x38a: 0x0e, 0x38b: 0x0e, 0x38c: 0x0e, 0x38d: 0x0e, 0x38e: 0x0e, 0x38f: 0x0e, + 0x390: 0x0e, 0x391: 0x0e, 0x392: 0x0e, 0x393: 0x0e, 0x394: 0x0e, 0x395: 0x0e, 0x396: 0x0e, 0x397: 0x0e, + 0x398: 0x0e, 0x399: 0x0e, 0x39a: 0x0e, 0x39b: 0x0e, 0x39c: 0x0e, 0x39d: 0x0e, 0x39e: 0x0e, 0x39f: 0x46, + 0x3a0: 0x0e, 0x3a1: 0x0e, 0x3a2: 0x0e, 0x3a3: 0x0e, 0x3a4: 0x0e, 0x3a5: 0x0e, 0x3a6: 0x0e, 0x3a7: 0x0e, + 0x3a8: 0x0e, 0x3a9: 0x0e, 0x3aa: 0x0e, 0x3ab: 0x47, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x0e, 0x3c1: 0x0e, 0x3c2: 0x0e, 0x3c3: 0x0e, 0x3c4: 0x48, 0x3c5: 0x49, 0x3c6: 0x0e, 0x3c7: 0x0e, + 0x3c8: 0x0e, 0x3c9: 0x0e, 0x3ca: 0x0e, 0x3cb: 0x4a, + // Block 0x10, offset 0x400 + 0x400: 0x4b, 0x403: 0x4c, 0x404: 0x4d, 0x405: 0x4e, 0x406: 0x4f, + 0x408: 0x50, 0x409: 0x51, 0x40c: 0x52, 0x40d: 0x53, 0x40e: 0x54, 0x40f: 0x55, + 0x410: 0x3a, 0x411: 0x56, 0x412: 0x0e, 0x413: 0x57, 0x414: 0x58, 0x415: 0x59, 0x416: 0x5a, 0x417: 0x5b, + 0x418: 0x0e, 0x419: 0x5c, 0x41a: 0x0e, 0x41b: 0x5d, + 0x424: 0x5e, 0x425: 0x5f, 0x426: 0x60, 0x427: 0x61, + // Block 0x11, offset 0x440 + 0x456: 0x0b, 0x457: 0x06, + 0x458: 0x0c, 0x45b: 0x0d, 0x45f: 0x0e, + 0x460: 0x06, 0x461: 0x06, 0x462: 0x06, 0x463: 0x06, 0x464: 0x06, 0x465: 0x06, 0x466: 0x06, 0x467: 0x06, + 0x468: 0x06, 0x469: 0x06, 0x46a: 0x06, 0x46b: 0x06, 0x46c: 0x06, 0x46d: 0x06, 0x46e: 0x06, 0x46f: 0x06, + 0x470: 0x06, 0x471: 0x06, 0x472: 0x06, 0x473: 0x06, 0x474: 0x06, 0x475: 0x06, 0x476: 0x06, 0x477: 0x06, + 0x478: 0x06, 0x479: 0x06, 0x47a: 0x06, 0x47b: 0x06, 0x47c: 0x06, 0x47d: 0x06, 0x47e: 0x06, 0x47f: 0x06, + // Block 0x12, offset 0x480 + 0x484: 0x08, 0x485: 0x08, 0x486: 0x08, 0x487: 0x09, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x08, 0x4c1: 0x08, 0x4c2: 0x08, 0x4c3: 0x08, 0x4c4: 0x08, 0x4c5: 0x08, 0x4c6: 0x08, 0x4c7: 0x08, + 0x4c8: 0x08, 0x4c9: 0x08, 0x4ca: 0x08, 0x4cb: 0x08, 0x4cc: 0x08, 0x4cd: 0x08, 0x4ce: 0x08, 0x4cf: 0x08, + 0x4d0: 0x08, 0x4d1: 0x08, 0x4d2: 0x08, 0x4d3: 0x08, 0x4d4: 0x08, 0x4d5: 0x08, 0x4d6: 0x08, 0x4d7: 0x08, + 0x4d8: 0x08, 0x4d9: 0x08, 0x4da: 0x08, 0x4db: 0x08, 0x4dc: 0x08, 0x4dd: 0x08, 0x4de: 0x08, 0x4df: 0x08, + 0x4e0: 0x08, 0x4e1: 0x08, 0x4e2: 0x08, 0x4e3: 0x08, 0x4e4: 0x08, 0x4e5: 0x08, 0x4e6: 0x08, 0x4e7: 0x08, + 0x4e8: 0x08, 0x4e9: 0x08, 0x4ea: 0x08, 0x4eb: 0x08, 0x4ec: 0x08, 0x4ed: 0x08, 0x4ee: 0x08, 0x4ef: 0x08, + 0x4f0: 0x08, 0x4f1: 0x08, 0x4f2: 0x08, 0x4f3: 0x08, 0x4f4: 0x08, 0x4f5: 0x08, 0x4f6: 0x08, 0x4f7: 0x08, + 0x4f8: 0x08, 0x4f9: 0x08, 0x4fa: 0x08, 0x4fb: 0x08, 0x4fc: 0x08, 0x4fd: 0x08, 0x4fe: 0x08, 0x4ff: 0x62, + // Block 0x14, offset 0x500 + 0x520: 0x10, + 0x530: 0x09, 0x531: 0x09, 0x532: 0x09, 0x533: 0x09, 0x534: 0x09, 0x535: 0x09, 0x536: 0x09, 0x537: 0x09, + 0x538: 0x09, 0x539: 0x09, 0x53a: 0x09, 0x53b: 0x09, 0x53c: 0x09, 0x53d: 0x09, 0x53e: 0x09, 0x53f: 0x11, + // Block 0x15, offset 0x540 + 0x540: 0x09, 0x541: 0x09, 0x542: 0x09, 0x543: 0x09, 0x544: 0x09, 0x545: 0x09, 0x546: 0x09, 0x547: 0x09, + 0x548: 0x09, 0x549: 0x09, 0x54a: 0x09, 0x54b: 0x09, 0x54c: 0x09, 0x54d: 0x09, 0x54e: 0x09, 0x54f: 0x11, +} + +// inverseData contains 4-byte entries of the following format: +// <0 padding> +// The last byte of the UTF-8-encoded rune is xor-ed with the last byte of the +// UTF-8 encoding of the original rune. Mappings often have the following +// pattern: +// A -> A (U+FF21 -> U+0041) +// B -> B (U+FF22 -> U+0042) +// ... +// By xor-ing the last byte the same entry can be shared by many mappings. This +// reduces the total number of distinct entries by about two thirds. +// The resulting entry for the aforementioned mappings is +// { 0x01, 0xE0, 0x00, 0x00 } +// Using this entry to map U+FF21 (UTF-8 [EF BC A1]), we get +// E0 ^ A1 = 41. +// Similarly, for U+FF22 (UTF-8 [EF BC A2]), we get +// E0 ^ A2 = 42. +// Note that because of the xor-ing, the byte sequence stored in the entry is +// not valid UTF-8. +var inverseData = [150][4]byte{ + {0x00, 0x00, 0x00, 0x00}, + {0x03, 0xe3, 0x80, 0xa0}, + {0x03, 0xef, 0xbc, 0xa0}, + {0x03, 0xef, 0xbc, 0xe0}, + {0x03, 0xef, 0xbd, 0xe0}, + {0x03, 0xef, 0xbf, 0x02}, + {0x03, 0xef, 0xbf, 0x00}, + {0x03, 0xef, 0xbf, 0x0e}, + {0x03, 0xef, 0xbf, 0x0c}, + {0x03, 0xef, 0xbf, 0x0f}, + {0x03, 0xef, 0xbf, 0x39}, + {0x03, 0xef, 0xbf, 0x3b}, + {0x03, 0xef, 0xbf, 0x3f}, + {0x03, 0xef, 0xbf, 0x2a}, + {0x03, 0xef, 0xbf, 0x0d}, + {0x03, 0xef, 0xbf, 0x25}, + {0x03, 0xef, 0xbd, 0x1a}, + {0x03, 0xef, 0xbd, 0x26}, + {0x01, 0xa0, 0x00, 0x00}, + {0x03, 0xef, 0xbd, 0x25}, + {0x03, 0xef, 0xbd, 0x23}, + {0x03, 0xef, 0xbd, 0x2e}, + {0x03, 0xef, 0xbe, 0x07}, + {0x03, 0xef, 0xbe, 0x05}, + {0x03, 0xef, 0xbd, 0x06}, + {0x03, 0xef, 0xbd, 0x13}, + {0x03, 0xef, 0xbd, 0x0b}, + {0x03, 0xef, 0xbd, 0x16}, + {0x03, 0xef, 0xbd, 0x0c}, + {0x03, 0xef, 0xbd, 0x15}, + {0x03, 0xef, 0xbd, 0x0d}, + {0x03, 0xef, 0xbd, 0x1c}, + {0x03, 0xef, 0xbd, 0x02}, + {0x03, 0xef, 0xbd, 0x1f}, + {0x03, 0xef, 0xbd, 0x1d}, + {0x03, 0xef, 0xbd, 0x17}, + {0x03, 0xef, 0xbd, 0x08}, + {0x03, 0xef, 0xbd, 0x09}, + {0x03, 0xef, 0xbd, 0x0e}, + {0x03, 0xef, 0xbd, 0x04}, + {0x03, 0xef, 0xbd, 0x05}, + {0x03, 0xef, 0xbe, 0x3f}, + {0x03, 0xef, 0xbe, 0x00}, + {0x03, 0xef, 0xbd, 0x2c}, + {0x03, 0xef, 0xbe, 0x06}, + {0x03, 0xef, 0xbe, 0x0c}, + {0x03, 0xef, 0xbe, 0x0f}, + {0x03, 0xef, 0xbe, 0x0d}, + {0x03, 0xef, 0xbe, 0x0b}, + {0x03, 0xef, 0xbe, 0x19}, + {0x03, 0xef, 0xbe, 0x15}, + {0x03, 0xef, 0xbe, 0x11}, + {0x03, 0xef, 0xbe, 0x31}, + {0x03, 0xef, 0xbe, 0x33}, + {0x03, 0xef, 0xbd, 0x0f}, + {0x03, 0xef, 0xbe, 0x30}, + {0x03, 0xef, 0xbe, 0x3e}, + {0x03, 0xef, 0xbe, 0x32}, + {0x03, 0xef, 0xbe, 0x36}, + {0x03, 0xef, 0xbd, 0x14}, + {0x03, 0xef, 0xbe, 0x2e}, + {0x03, 0xef, 0xbd, 0x1e}, + {0x03, 0xef, 0xbe, 0x10}, + {0x03, 0xef, 0xbf, 0x13}, + {0x03, 0xef, 0xbf, 0x15}, + {0x03, 0xef, 0xbf, 0x17}, + {0x03, 0xef, 0xbf, 0x1f}, + {0x03, 0xef, 0xbf, 0x1d}, + {0x03, 0xef, 0xbf, 0x1b}, + {0x03, 0xef, 0xbf, 0x09}, + {0x03, 0xef, 0xbf, 0x0b}, + {0x03, 0xef, 0xbf, 0x37}, + {0x03, 0xef, 0xbe, 0x04}, + {0x01, 0xe0, 0x00, 0x00}, + {0x03, 0xe2, 0xa6, 0x1a}, + {0x03, 0xe2, 0xa6, 0x26}, + {0x03, 0xe3, 0x80, 0x23}, + {0x03, 0xe3, 0x80, 0x2e}, + {0x03, 0xe3, 0x80, 0x25}, + {0x03, 0xe3, 0x83, 0x1e}, + {0x03, 0xe3, 0x83, 0x14}, + {0x03, 0xe3, 0x82, 0x06}, + {0x03, 0xe3, 0x82, 0x0b}, + {0x03, 0xe3, 0x82, 0x0c}, + {0x03, 0xe3, 0x82, 0x0d}, + {0x03, 0xe3, 0x82, 0x02}, + {0x03, 0xe3, 0x83, 0x0f}, + {0x03, 0xe3, 0x83, 0x08}, + {0x03, 0xe3, 0x83, 0x09}, + {0x03, 0xe3, 0x83, 0x2c}, + {0x03, 0xe3, 0x83, 0x0c}, + {0x03, 0xe3, 0x82, 0x13}, + {0x03, 0xe3, 0x82, 0x16}, + {0x03, 0xe3, 0x82, 0x15}, + {0x03, 0xe3, 0x82, 0x1c}, + {0x03, 0xe3, 0x82, 0x1f}, + {0x03, 0xe3, 0x82, 0x1d}, + {0x03, 0xe3, 0x82, 0x1a}, + {0x03, 0xe3, 0x82, 0x17}, + {0x03, 0xe3, 0x82, 0x08}, + {0x03, 0xe3, 0x82, 0x09}, + {0x03, 0xe3, 0x82, 0x0e}, + {0x03, 0xe3, 0x82, 0x04}, + {0x03, 0xe3, 0x82, 0x05}, + {0x03, 0xe3, 0x82, 0x3f}, + {0x03, 0xe3, 0x83, 0x00}, + {0x03, 0xe3, 0x83, 0x06}, + {0x03, 0xe3, 0x83, 0x05}, + {0x03, 0xe3, 0x83, 0x0d}, + {0x03, 0xe3, 0x83, 0x0b}, + {0x03, 0xe3, 0x83, 0x07}, + {0x03, 0xe3, 0x83, 0x19}, + {0x03, 0xe3, 0x83, 0x15}, + {0x03, 0xe3, 0x83, 0x11}, + {0x03, 0xe3, 0x83, 0x31}, + {0x03, 0xe3, 0x83, 0x33}, + {0x03, 0xe3, 0x83, 0x30}, + {0x03, 0xe3, 0x83, 0x3e}, + {0x03, 0xe3, 0x83, 0x32}, + {0x03, 0xe3, 0x83, 0x36}, + {0x03, 0xe3, 0x83, 0x2e}, + {0x03, 0xe3, 0x82, 0x07}, + {0x03, 0xe3, 0x85, 0x04}, + {0x03, 0xe3, 0x84, 0x10}, + {0x03, 0xe3, 0x85, 0x30}, + {0x03, 0xe3, 0x85, 0x0d}, + {0x03, 0xe3, 0x85, 0x13}, + {0x03, 0xe3, 0x85, 0x15}, + {0x03, 0xe3, 0x85, 0x17}, + {0x03, 0xe3, 0x85, 0x1f}, + {0x03, 0xe3, 0x85, 0x1d}, + {0x03, 0xe3, 0x85, 0x1b}, + {0x03, 0xe3, 0x85, 0x09}, + {0x03, 0xe3, 0x85, 0x0f}, + {0x03, 0xe3, 0x85, 0x0b}, + {0x03, 0xe3, 0x85, 0x37}, + {0x03, 0xe3, 0x85, 0x3b}, + {0x03, 0xe3, 0x85, 0x39}, + {0x03, 0xe3, 0x85, 0x3f}, + {0x02, 0xc2, 0x02, 0x00}, + {0x02, 0xc2, 0x0e, 0x00}, + {0x02, 0xc2, 0x0c, 0x00}, + {0x02, 0xc2, 0x00, 0x00}, + {0x03, 0xe2, 0x82, 0x0f}, + {0x03, 0xe2, 0x94, 0x2a}, + {0x03, 0xe2, 0x86, 0x39}, + {0x03, 0xe2, 0x86, 0x3b}, + {0x03, 0xe2, 0x86, 0x3f}, + {0x03, 0xe2, 0x96, 0x0d}, + {0x03, 0xe2, 0x97, 0x25}, +} + +// Total table size 14936 bytes (14KiB) diff --git a/vendor/golang.org/x/text/width/tables9.0.0.go b/vendor/golang.org/x/text/width/tables9.0.0.go new file mode 100644 index 000000000..7069e2634 --- /dev/null +++ b/vendor/golang.org/x/text/width/tables9.0.0.go @@ -0,0 +1,1286 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build !go1.10 + +package width + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "9.0.0" + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *widthTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return widthValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = widthIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = widthIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = widthIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *widthTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return widthValues[c0] + } + i := widthIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = widthIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = widthIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *widthTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return widthValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = widthIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := widthIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = widthIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = widthIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *widthTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return widthValues[c0] + } + i := widthIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = widthIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = widthIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// widthTrie. Total size: 14080 bytes (13.75 KiB). Checksum: 3b8aeb3dc03667a3. +type widthTrie struct{} + +func newWidthTrie(i int) *widthTrie { + return &widthTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *widthTrie) lookupValue(n uint32, b byte) uint16 { + switch { + default: + return uint16(widthValues[n<<6+uint32(b)]) + } +} + +// widthValues: 99 blocks, 6336 entries, 12672 bytes +// The third block is the zero block. +var widthValues = [6336]uint16{ + // Block 0x0, offset 0x0 + 0x20: 0x6001, 0x21: 0x6002, 0x22: 0x6002, 0x23: 0x6002, + 0x24: 0x6002, 0x25: 0x6002, 0x26: 0x6002, 0x27: 0x6002, 0x28: 0x6002, 0x29: 0x6002, + 0x2a: 0x6002, 0x2b: 0x6002, 0x2c: 0x6002, 0x2d: 0x6002, 0x2e: 0x6002, 0x2f: 0x6002, + 0x30: 0x6002, 0x31: 0x6002, 0x32: 0x6002, 0x33: 0x6002, 0x34: 0x6002, 0x35: 0x6002, + 0x36: 0x6002, 0x37: 0x6002, 0x38: 0x6002, 0x39: 0x6002, 0x3a: 0x6002, 0x3b: 0x6002, + 0x3c: 0x6002, 0x3d: 0x6002, 0x3e: 0x6002, 0x3f: 0x6002, + // Block 0x1, offset 0x40 + 0x40: 0x6003, 0x41: 0x6003, 0x42: 0x6003, 0x43: 0x6003, 0x44: 0x6003, 0x45: 0x6003, + 0x46: 0x6003, 0x47: 0x6003, 0x48: 0x6003, 0x49: 0x6003, 0x4a: 0x6003, 0x4b: 0x6003, + 0x4c: 0x6003, 0x4d: 0x6003, 0x4e: 0x6003, 0x4f: 0x6003, 0x50: 0x6003, 0x51: 0x6003, + 0x52: 0x6003, 0x53: 0x6003, 0x54: 0x6003, 0x55: 0x6003, 0x56: 0x6003, 0x57: 0x6003, + 0x58: 0x6003, 0x59: 0x6003, 0x5a: 0x6003, 0x5b: 0x6003, 0x5c: 0x6003, 0x5d: 0x6003, + 0x5e: 0x6003, 0x5f: 0x6003, 0x60: 0x6004, 0x61: 0x6004, 0x62: 0x6004, 0x63: 0x6004, + 0x64: 0x6004, 0x65: 0x6004, 0x66: 0x6004, 0x67: 0x6004, 0x68: 0x6004, 0x69: 0x6004, + 0x6a: 0x6004, 0x6b: 0x6004, 0x6c: 0x6004, 0x6d: 0x6004, 0x6e: 0x6004, 0x6f: 0x6004, + 0x70: 0x6004, 0x71: 0x6004, 0x72: 0x6004, 0x73: 0x6004, 0x74: 0x6004, 0x75: 0x6004, + 0x76: 0x6004, 0x77: 0x6004, 0x78: 0x6004, 0x79: 0x6004, 0x7a: 0x6004, 0x7b: 0x6004, + 0x7c: 0x6004, 0x7d: 0x6004, 0x7e: 0x6004, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xe1: 0x2000, 0xe2: 0x6005, 0xe3: 0x6005, + 0xe4: 0x2000, 0xe5: 0x6006, 0xe6: 0x6005, 0xe7: 0x2000, 0xe8: 0x2000, + 0xea: 0x2000, 0xec: 0x6007, 0xed: 0x2000, 0xee: 0x2000, 0xef: 0x6008, + 0xf0: 0x2000, 0xf1: 0x2000, 0xf2: 0x2000, 0xf3: 0x2000, 0xf4: 0x2000, + 0xf6: 0x2000, 0xf7: 0x2000, 0xf8: 0x2000, 0xf9: 0x2000, 0xfa: 0x2000, + 0xfc: 0x2000, 0xfd: 0x2000, 0xfe: 0x2000, 0xff: 0x2000, + // Block 0x4, offset 0x100 + 0x106: 0x2000, + 0x110: 0x2000, + 0x117: 0x2000, + 0x118: 0x2000, + 0x11e: 0x2000, 0x11f: 0x2000, 0x120: 0x2000, 0x121: 0x2000, + 0x126: 0x2000, 0x128: 0x2000, 0x129: 0x2000, + 0x12a: 0x2000, 0x12c: 0x2000, 0x12d: 0x2000, + 0x130: 0x2000, 0x132: 0x2000, 0x133: 0x2000, + 0x137: 0x2000, 0x138: 0x2000, 0x139: 0x2000, 0x13a: 0x2000, + 0x13c: 0x2000, 0x13e: 0x2000, + // Block 0x5, offset 0x140 + 0x141: 0x2000, + 0x151: 0x2000, + 0x153: 0x2000, + 0x15b: 0x2000, + 0x166: 0x2000, 0x167: 0x2000, + 0x16b: 0x2000, + 0x171: 0x2000, 0x172: 0x2000, 0x173: 0x2000, + 0x178: 0x2000, + 0x17f: 0x2000, + // Block 0x6, offset 0x180 + 0x180: 0x2000, 0x181: 0x2000, 0x182: 0x2000, 0x184: 0x2000, + 0x188: 0x2000, 0x189: 0x2000, 0x18a: 0x2000, 0x18b: 0x2000, + 0x18d: 0x2000, + 0x192: 0x2000, 0x193: 0x2000, + 0x1a6: 0x2000, 0x1a7: 0x2000, + 0x1ab: 0x2000, + // Block 0x7, offset 0x1c0 + 0x1ce: 0x2000, 0x1d0: 0x2000, + 0x1d2: 0x2000, 0x1d4: 0x2000, 0x1d6: 0x2000, + 0x1d8: 0x2000, 0x1da: 0x2000, 0x1dc: 0x2000, + // Block 0x8, offset 0x200 + 0x211: 0x2000, + 0x221: 0x2000, + // Block 0x9, offset 0x240 + 0x244: 0x2000, + 0x247: 0x2000, 0x249: 0x2000, 0x24a: 0x2000, 0x24b: 0x2000, + 0x24d: 0x2000, 0x250: 0x2000, + 0x258: 0x2000, 0x259: 0x2000, 0x25a: 0x2000, 0x25b: 0x2000, 0x25d: 0x2000, + 0x25f: 0x2000, + // Block 0xa, offset 0x280 + 0x280: 0x2000, 0x281: 0x2000, 0x282: 0x2000, 0x283: 0x2000, 0x284: 0x2000, 0x285: 0x2000, + 0x286: 0x2000, 0x287: 0x2000, 0x288: 0x2000, 0x289: 0x2000, 0x28a: 0x2000, 0x28b: 0x2000, + 0x28c: 0x2000, 0x28d: 0x2000, 0x28e: 0x2000, 0x28f: 0x2000, 0x290: 0x2000, 0x291: 0x2000, + 0x292: 0x2000, 0x293: 0x2000, 0x294: 0x2000, 0x295: 0x2000, 0x296: 0x2000, 0x297: 0x2000, + 0x298: 0x2000, 0x299: 0x2000, 0x29a: 0x2000, 0x29b: 0x2000, 0x29c: 0x2000, 0x29d: 0x2000, + 0x29e: 0x2000, 0x29f: 0x2000, 0x2a0: 0x2000, 0x2a1: 0x2000, 0x2a2: 0x2000, 0x2a3: 0x2000, + 0x2a4: 0x2000, 0x2a5: 0x2000, 0x2a6: 0x2000, 0x2a7: 0x2000, 0x2a8: 0x2000, 0x2a9: 0x2000, + 0x2aa: 0x2000, 0x2ab: 0x2000, 0x2ac: 0x2000, 0x2ad: 0x2000, 0x2ae: 0x2000, 0x2af: 0x2000, + 0x2b0: 0x2000, 0x2b1: 0x2000, 0x2b2: 0x2000, 0x2b3: 0x2000, 0x2b4: 0x2000, 0x2b5: 0x2000, + 0x2b6: 0x2000, 0x2b7: 0x2000, 0x2b8: 0x2000, 0x2b9: 0x2000, 0x2ba: 0x2000, 0x2bb: 0x2000, + 0x2bc: 0x2000, 0x2bd: 0x2000, 0x2be: 0x2000, 0x2bf: 0x2000, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x2000, 0x2c1: 0x2000, 0x2c2: 0x2000, 0x2c3: 0x2000, 0x2c4: 0x2000, 0x2c5: 0x2000, + 0x2c6: 0x2000, 0x2c7: 0x2000, 0x2c8: 0x2000, 0x2c9: 0x2000, 0x2ca: 0x2000, 0x2cb: 0x2000, + 0x2cc: 0x2000, 0x2cd: 0x2000, 0x2ce: 0x2000, 0x2cf: 0x2000, 0x2d0: 0x2000, 0x2d1: 0x2000, + 0x2d2: 0x2000, 0x2d3: 0x2000, 0x2d4: 0x2000, 0x2d5: 0x2000, 0x2d6: 0x2000, 0x2d7: 0x2000, + 0x2d8: 0x2000, 0x2d9: 0x2000, 0x2da: 0x2000, 0x2db: 0x2000, 0x2dc: 0x2000, 0x2dd: 0x2000, + 0x2de: 0x2000, 0x2df: 0x2000, 0x2e0: 0x2000, 0x2e1: 0x2000, 0x2e2: 0x2000, 0x2e3: 0x2000, + 0x2e4: 0x2000, 0x2e5: 0x2000, 0x2e6: 0x2000, 0x2e7: 0x2000, 0x2e8: 0x2000, 0x2e9: 0x2000, + 0x2ea: 0x2000, 0x2eb: 0x2000, 0x2ec: 0x2000, 0x2ed: 0x2000, 0x2ee: 0x2000, 0x2ef: 0x2000, + // Block 0xc, offset 0x300 + 0x311: 0x2000, + 0x312: 0x2000, 0x313: 0x2000, 0x314: 0x2000, 0x315: 0x2000, 0x316: 0x2000, 0x317: 0x2000, + 0x318: 0x2000, 0x319: 0x2000, 0x31a: 0x2000, 0x31b: 0x2000, 0x31c: 0x2000, 0x31d: 0x2000, + 0x31e: 0x2000, 0x31f: 0x2000, 0x320: 0x2000, 0x321: 0x2000, 0x323: 0x2000, + 0x324: 0x2000, 0x325: 0x2000, 0x326: 0x2000, 0x327: 0x2000, 0x328: 0x2000, 0x329: 0x2000, + 0x331: 0x2000, 0x332: 0x2000, 0x333: 0x2000, 0x334: 0x2000, 0x335: 0x2000, + 0x336: 0x2000, 0x337: 0x2000, 0x338: 0x2000, 0x339: 0x2000, 0x33a: 0x2000, 0x33b: 0x2000, + 0x33c: 0x2000, 0x33d: 0x2000, 0x33e: 0x2000, 0x33f: 0x2000, + // Block 0xd, offset 0x340 + 0x340: 0x2000, 0x341: 0x2000, 0x343: 0x2000, 0x344: 0x2000, 0x345: 0x2000, + 0x346: 0x2000, 0x347: 0x2000, 0x348: 0x2000, 0x349: 0x2000, + // Block 0xe, offset 0x380 + 0x381: 0x2000, + 0x390: 0x2000, 0x391: 0x2000, + 0x392: 0x2000, 0x393: 0x2000, 0x394: 0x2000, 0x395: 0x2000, 0x396: 0x2000, 0x397: 0x2000, + 0x398: 0x2000, 0x399: 0x2000, 0x39a: 0x2000, 0x39b: 0x2000, 0x39c: 0x2000, 0x39d: 0x2000, + 0x39e: 0x2000, 0x39f: 0x2000, 0x3a0: 0x2000, 0x3a1: 0x2000, 0x3a2: 0x2000, 0x3a3: 0x2000, + 0x3a4: 0x2000, 0x3a5: 0x2000, 0x3a6: 0x2000, 0x3a7: 0x2000, 0x3a8: 0x2000, 0x3a9: 0x2000, + 0x3aa: 0x2000, 0x3ab: 0x2000, 0x3ac: 0x2000, 0x3ad: 0x2000, 0x3ae: 0x2000, 0x3af: 0x2000, + 0x3b0: 0x2000, 0x3b1: 0x2000, 0x3b2: 0x2000, 0x3b3: 0x2000, 0x3b4: 0x2000, 0x3b5: 0x2000, + 0x3b6: 0x2000, 0x3b7: 0x2000, 0x3b8: 0x2000, 0x3b9: 0x2000, 0x3ba: 0x2000, 0x3bb: 0x2000, + 0x3bc: 0x2000, 0x3bd: 0x2000, 0x3be: 0x2000, 0x3bf: 0x2000, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x2000, 0x3c1: 0x2000, 0x3c2: 0x2000, 0x3c3: 0x2000, 0x3c4: 0x2000, 0x3c5: 0x2000, + 0x3c6: 0x2000, 0x3c7: 0x2000, 0x3c8: 0x2000, 0x3c9: 0x2000, 0x3ca: 0x2000, 0x3cb: 0x2000, + 0x3cc: 0x2000, 0x3cd: 0x2000, 0x3ce: 0x2000, 0x3cf: 0x2000, 0x3d1: 0x2000, + // Block 0x10, offset 0x400 + 0x400: 0x4000, 0x401: 0x4000, 0x402: 0x4000, 0x403: 0x4000, 0x404: 0x4000, 0x405: 0x4000, + 0x406: 0x4000, 0x407: 0x4000, 0x408: 0x4000, 0x409: 0x4000, 0x40a: 0x4000, 0x40b: 0x4000, + 0x40c: 0x4000, 0x40d: 0x4000, 0x40e: 0x4000, 0x40f: 0x4000, 0x410: 0x4000, 0x411: 0x4000, + 0x412: 0x4000, 0x413: 0x4000, 0x414: 0x4000, 0x415: 0x4000, 0x416: 0x4000, 0x417: 0x4000, + 0x418: 0x4000, 0x419: 0x4000, 0x41a: 0x4000, 0x41b: 0x4000, 0x41c: 0x4000, 0x41d: 0x4000, + 0x41e: 0x4000, 0x41f: 0x4000, 0x420: 0x4000, 0x421: 0x4000, 0x422: 0x4000, 0x423: 0x4000, + 0x424: 0x4000, 0x425: 0x4000, 0x426: 0x4000, 0x427: 0x4000, 0x428: 0x4000, 0x429: 0x4000, + 0x42a: 0x4000, 0x42b: 0x4000, 0x42c: 0x4000, 0x42d: 0x4000, 0x42e: 0x4000, 0x42f: 0x4000, + 0x430: 0x4000, 0x431: 0x4000, 0x432: 0x4000, 0x433: 0x4000, 0x434: 0x4000, 0x435: 0x4000, + 0x436: 0x4000, 0x437: 0x4000, 0x438: 0x4000, 0x439: 0x4000, 0x43a: 0x4000, 0x43b: 0x4000, + 0x43c: 0x4000, 0x43d: 0x4000, 0x43e: 0x4000, 0x43f: 0x4000, + // Block 0x11, offset 0x440 + 0x440: 0x4000, 0x441: 0x4000, 0x442: 0x4000, 0x443: 0x4000, 0x444: 0x4000, 0x445: 0x4000, + 0x446: 0x4000, 0x447: 0x4000, 0x448: 0x4000, 0x449: 0x4000, 0x44a: 0x4000, 0x44b: 0x4000, + 0x44c: 0x4000, 0x44d: 0x4000, 0x44e: 0x4000, 0x44f: 0x4000, 0x450: 0x4000, 0x451: 0x4000, + 0x452: 0x4000, 0x453: 0x4000, 0x454: 0x4000, 0x455: 0x4000, 0x456: 0x4000, 0x457: 0x4000, + 0x458: 0x4000, 0x459: 0x4000, 0x45a: 0x4000, 0x45b: 0x4000, 0x45c: 0x4000, 0x45d: 0x4000, + 0x45e: 0x4000, 0x45f: 0x4000, + // Block 0x12, offset 0x480 + 0x490: 0x2000, + 0x493: 0x2000, 0x494: 0x2000, 0x495: 0x2000, 0x496: 0x2000, + 0x498: 0x2000, 0x499: 0x2000, 0x49c: 0x2000, 0x49d: 0x2000, + 0x4a0: 0x2000, 0x4a1: 0x2000, 0x4a2: 0x2000, + 0x4a4: 0x2000, 0x4a5: 0x2000, 0x4a6: 0x2000, 0x4a7: 0x2000, + 0x4b0: 0x2000, 0x4b2: 0x2000, 0x4b3: 0x2000, 0x4b5: 0x2000, + 0x4bb: 0x2000, + 0x4be: 0x2000, + // Block 0x13, offset 0x4c0 + 0x4f4: 0x2000, + 0x4ff: 0x2000, + // Block 0x14, offset 0x500 + 0x501: 0x2000, 0x502: 0x2000, 0x503: 0x2000, 0x504: 0x2000, + 0x529: 0xa009, + 0x52c: 0x2000, + // Block 0x15, offset 0x540 + 0x543: 0x2000, 0x545: 0x2000, + 0x549: 0x2000, + 0x553: 0x2000, 0x556: 0x2000, + 0x561: 0x2000, 0x562: 0x2000, + 0x566: 0x2000, + 0x56b: 0x2000, + // Block 0x16, offset 0x580 + 0x593: 0x2000, 0x594: 0x2000, + 0x59b: 0x2000, 0x59c: 0x2000, 0x59d: 0x2000, + 0x59e: 0x2000, 0x5a0: 0x2000, 0x5a1: 0x2000, 0x5a2: 0x2000, 0x5a3: 0x2000, + 0x5a4: 0x2000, 0x5a5: 0x2000, 0x5a6: 0x2000, 0x5a7: 0x2000, 0x5a8: 0x2000, 0x5a9: 0x2000, + 0x5aa: 0x2000, 0x5ab: 0x2000, + 0x5b0: 0x2000, 0x5b1: 0x2000, 0x5b2: 0x2000, 0x5b3: 0x2000, 0x5b4: 0x2000, 0x5b5: 0x2000, + 0x5b6: 0x2000, 0x5b7: 0x2000, 0x5b8: 0x2000, 0x5b9: 0x2000, + // Block 0x17, offset 0x5c0 + 0x5c9: 0x2000, + 0x5d0: 0x200a, 0x5d1: 0x200b, + 0x5d2: 0x200a, 0x5d3: 0x200c, 0x5d4: 0x2000, 0x5d5: 0x2000, 0x5d6: 0x2000, 0x5d7: 0x2000, + 0x5d8: 0x2000, 0x5d9: 0x2000, + 0x5f8: 0x2000, 0x5f9: 0x2000, + // Block 0x18, offset 0x600 + 0x612: 0x2000, 0x614: 0x2000, + 0x627: 0x2000, + // Block 0x19, offset 0x640 + 0x640: 0x2000, 0x642: 0x2000, 0x643: 0x2000, + 0x647: 0x2000, 0x648: 0x2000, 0x64b: 0x2000, + 0x64f: 0x2000, 0x651: 0x2000, + 0x655: 0x2000, + 0x65a: 0x2000, 0x65d: 0x2000, + 0x65e: 0x2000, 0x65f: 0x2000, 0x660: 0x2000, 0x663: 0x2000, + 0x665: 0x2000, 0x667: 0x2000, 0x668: 0x2000, 0x669: 0x2000, + 0x66a: 0x2000, 0x66b: 0x2000, 0x66c: 0x2000, 0x66e: 0x2000, + 0x674: 0x2000, 0x675: 0x2000, + 0x676: 0x2000, 0x677: 0x2000, + 0x67c: 0x2000, 0x67d: 0x2000, + // Block 0x1a, offset 0x680 + 0x688: 0x2000, + 0x68c: 0x2000, + 0x692: 0x2000, + 0x6a0: 0x2000, 0x6a1: 0x2000, + 0x6a4: 0x2000, 0x6a5: 0x2000, 0x6a6: 0x2000, 0x6a7: 0x2000, + 0x6aa: 0x2000, 0x6ab: 0x2000, 0x6ae: 0x2000, 0x6af: 0x2000, + // Block 0x1b, offset 0x6c0 + 0x6c2: 0x2000, 0x6c3: 0x2000, + 0x6c6: 0x2000, 0x6c7: 0x2000, + 0x6d5: 0x2000, + 0x6d9: 0x2000, + 0x6e5: 0x2000, + 0x6ff: 0x2000, + // Block 0x1c, offset 0x700 + 0x712: 0x2000, + 0x71a: 0x4000, 0x71b: 0x4000, + 0x729: 0x4000, + 0x72a: 0x4000, + // Block 0x1d, offset 0x740 + 0x769: 0x4000, + 0x76a: 0x4000, 0x76b: 0x4000, 0x76c: 0x4000, + 0x770: 0x4000, 0x773: 0x4000, + // Block 0x1e, offset 0x780 + 0x7a0: 0x2000, 0x7a1: 0x2000, 0x7a2: 0x2000, 0x7a3: 0x2000, + 0x7a4: 0x2000, 0x7a5: 0x2000, 0x7a6: 0x2000, 0x7a7: 0x2000, 0x7a8: 0x2000, 0x7a9: 0x2000, + 0x7aa: 0x2000, 0x7ab: 0x2000, 0x7ac: 0x2000, 0x7ad: 0x2000, 0x7ae: 0x2000, 0x7af: 0x2000, + 0x7b0: 0x2000, 0x7b1: 0x2000, 0x7b2: 0x2000, 0x7b3: 0x2000, 0x7b4: 0x2000, 0x7b5: 0x2000, + 0x7b6: 0x2000, 0x7b7: 0x2000, 0x7b8: 0x2000, 0x7b9: 0x2000, 0x7ba: 0x2000, 0x7bb: 0x2000, + 0x7bc: 0x2000, 0x7bd: 0x2000, 0x7be: 0x2000, 0x7bf: 0x2000, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x2000, 0x7c1: 0x2000, 0x7c2: 0x2000, 0x7c3: 0x2000, 0x7c4: 0x2000, 0x7c5: 0x2000, + 0x7c6: 0x2000, 0x7c7: 0x2000, 0x7c8: 0x2000, 0x7c9: 0x2000, 0x7ca: 0x2000, 0x7cb: 0x2000, + 0x7cc: 0x2000, 0x7cd: 0x2000, 0x7ce: 0x2000, 0x7cf: 0x2000, 0x7d0: 0x2000, 0x7d1: 0x2000, + 0x7d2: 0x2000, 0x7d3: 0x2000, 0x7d4: 0x2000, 0x7d5: 0x2000, 0x7d6: 0x2000, 0x7d7: 0x2000, + 0x7d8: 0x2000, 0x7d9: 0x2000, 0x7da: 0x2000, 0x7db: 0x2000, 0x7dc: 0x2000, 0x7dd: 0x2000, + 0x7de: 0x2000, 0x7df: 0x2000, 0x7e0: 0x2000, 0x7e1: 0x2000, 0x7e2: 0x2000, 0x7e3: 0x2000, + 0x7e4: 0x2000, 0x7e5: 0x2000, 0x7e6: 0x2000, 0x7e7: 0x2000, 0x7e8: 0x2000, 0x7e9: 0x2000, + 0x7eb: 0x2000, 0x7ec: 0x2000, 0x7ed: 0x2000, 0x7ee: 0x2000, 0x7ef: 0x2000, + 0x7f0: 0x2000, 0x7f1: 0x2000, 0x7f2: 0x2000, 0x7f3: 0x2000, 0x7f4: 0x2000, 0x7f5: 0x2000, + 0x7f6: 0x2000, 0x7f7: 0x2000, 0x7f8: 0x2000, 0x7f9: 0x2000, 0x7fa: 0x2000, 0x7fb: 0x2000, + 0x7fc: 0x2000, 0x7fd: 0x2000, 0x7fe: 0x2000, 0x7ff: 0x2000, + // Block 0x20, offset 0x800 + 0x800: 0x2000, 0x801: 0x2000, 0x802: 0x200d, 0x803: 0x2000, 0x804: 0x2000, 0x805: 0x2000, + 0x806: 0x2000, 0x807: 0x2000, 0x808: 0x2000, 0x809: 0x2000, 0x80a: 0x2000, 0x80b: 0x2000, + 0x80c: 0x2000, 0x80d: 0x2000, 0x80e: 0x2000, 0x80f: 0x2000, 0x810: 0x2000, 0x811: 0x2000, + 0x812: 0x2000, 0x813: 0x2000, 0x814: 0x2000, 0x815: 0x2000, 0x816: 0x2000, 0x817: 0x2000, + 0x818: 0x2000, 0x819: 0x2000, 0x81a: 0x2000, 0x81b: 0x2000, 0x81c: 0x2000, 0x81d: 0x2000, + 0x81e: 0x2000, 0x81f: 0x2000, 0x820: 0x2000, 0x821: 0x2000, 0x822: 0x2000, 0x823: 0x2000, + 0x824: 0x2000, 0x825: 0x2000, 0x826: 0x2000, 0x827: 0x2000, 0x828: 0x2000, 0x829: 0x2000, + 0x82a: 0x2000, 0x82b: 0x2000, 0x82c: 0x2000, 0x82d: 0x2000, 0x82e: 0x2000, 0x82f: 0x2000, + 0x830: 0x2000, 0x831: 0x2000, 0x832: 0x2000, 0x833: 0x2000, 0x834: 0x2000, 0x835: 0x2000, + 0x836: 0x2000, 0x837: 0x2000, 0x838: 0x2000, 0x839: 0x2000, 0x83a: 0x2000, 0x83b: 0x2000, + 0x83c: 0x2000, 0x83d: 0x2000, 0x83e: 0x2000, 0x83f: 0x2000, + // Block 0x21, offset 0x840 + 0x840: 0x2000, 0x841: 0x2000, 0x842: 0x2000, 0x843: 0x2000, 0x844: 0x2000, 0x845: 0x2000, + 0x846: 0x2000, 0x847: 0x2000, 0x848: 0x2000, 0x849: 0x2000, 0x84a: 0x2000, 0x84b: 0x2000, + 0x850: 0x2000, 0x851: 0x2000, + 0x852: 0x2000, 0x853: 0x2000, 0x854: 0x2000, 0x855: 0x2000, 0x856: 0x2000, 0x857: 0x2000, + 0x858: 0x2000, 0x859: 0x2000, 0x85a: 0x2000, 0x85b: 0x2000, 0x85c: 0x2000, 0x85d: 0x2000, + 0x85e: 0x2000, 0x85f: 0x2000, 0x860: 0x2000, 0x861: 0x2000, 0x862: 0x2000, 0x863: 0x2000, + 0x864: 0x2000, 0x865: 0x2000, 0x866: 0x2000, 0x867: 0x2000, 0x868: 0x2000, 0x869: 0x2000, + 0x86a: 0x2000, 0x86b: 0x2000, 0x86c: 0x2000, 0x86d: 0x2000, 0x86e: 0x2000, 0x86f: 0x2000, + 0x870: 0x2000, 0x871: 0x2000, 0x872: 0x2000, 0x873: 0x2000, + // Block 0x22, offset 0x880 + 0x880: 0x2000, 0x881: 0x2000, 0x882: 0x2000, 0x883: 0x2000, 0x884: 0x2000, 0x885: 0x2000, + 0x886: 0x2000, 0x887: 0x2000, 0x888: 0x2000, 0x889: 0x2000, 0x88a: 0x2000, 0x88b: 0x2000, + 0x88c: 0x2000, 0x88d: 0x2000, 0x88e: 0x2000, 0x88f: 0x2000, + 0x892: 0x2000, 0x893: 0x2000, 0x894: 0x2000, 0x895: 0x2000, + 0x8a0: 0x200e, 0x8a1: 0x2000, 0x8a3: 0x2000, + 0x8a4: 0x2000, 0x8a5: 0x2000, 0x8a6: 0x2000, 0x8a7: 0x2000, 0x8a8: 0x2000, 0x8a9: 0x2000, + 0x8b2: 0x2000, 0x8b3: 0x2000, + 0x8b6: 0x2000, 0x8b7: 0x2000, + 0x8bc: 0x2000, 0x8bd: 0x2000, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x2000, 0x8c1: 0x2000, + 0x8c6: 0x2000, 0x8c7: 0x2000, 0x8c8: 0x2000, 0x8cb: 0x200f, + 0x8ce: 0x2000, 0x8cf: 0x2000, 0x8d0: 0x2000, 0x8d1: 0x2000, + 0x8e2: 0x2000, 0x8e3: 0x2000, + 0x8e4: 0x2000, 0x8e5: 0x2000, + 0x8ef: 0x2000, + 0x8fd: 0x4000, 0x8fe: 0x4000, + // Block 0x24, offset 0x900 + 0x905: 0x2000, + 0x906: 0x2000, 0x909: 0x2000, + 0x90e: 0x2000, 0x90f: 0x2000, + 0x914: 0x4000, 0x915: 0x4000, + 0x91c: 0x2000, + 0x91e: 0x2000, + // Block 0x25, offset 0x940 + 0x940: 0x2000, 0x942: 0x2000, + 0x948: 0x4000, 0x949: 0x4000, 0x94a: 0x4000, 0x94b: 0x4000, + 0x94c: 0x4000, 0x94d: 0x4000, 0x94e: 0x4000, 0x94f: 0x4000, 0x950: 0x4000, 0x951: 0x4000, + 0x952: 0x4000, 0x953: 0x4000, + 0x960: 0x2000, 0x961: 0x2000, 0x963: 0x2000, + 0x964: 0x2000, 0x965: 0x2000, 0x967: 0x2000, 0x968: 0x2000, 0x969: 0x2000, + 0x96a: 0x2000, 0x96c: 0x2000, 0x96d: 0x2000, 0x96f: 0x2000, + 0x97f: 0x4000, + // Block 0x26, offset 0x980 + 0x993: 0x4000, + 0x99e: 0x2000, 0x99f: 0x2000, 0x9a1: 0x4000, + 0x9aa: 0x4000, 0x9ab: 0x4000, + 0x9bd: 0x4000, 0x9be: 0x4000, 0x9bf: 0x2000, + // Block 0x27, offset 0x9c0 + 0x9c4: 0x4000, 0x9c5: 0x4000, + 0x9c6: 0x2000, 0x9c7: 0x2000, 0x9c8: 0x2000, 0x9c9: 0x2000, 0x9ca: 0x2000, 0x9cb: 0x2000, + 0x9cc: 0x2000, 0x9cd: 0x2000, 0x9ce: 0x4000, 0x9cf: 0x2000, 0x9d0: 0x2000, 0x9d1: 0x2000, + 0x9d2: 0x2000, 0x9d3: 0x2000, 0x9d4: 0x4000, 0x9d5: 0x2000, 0x9d6: 0x2000, 0x9d7: 0x2000, + 0x9d8: 0x2000, 0x9d9: 0x2000, 0x9da: 0x2000, 0x9db: 0x2000, 0x9dc: 0x2000, 0x9dd: 0x2000, + 0x9de: 0x2000, 0x9df: 0x2000, 0x9e0: 0x2000, 0x9e1: 0x2000, 0x9e3: 0x2000, + 0x9e8: 0x2000, 0x9e9: 0x2000, + 0x9ea: 0x4000, 0x9eb: 0x2000, 0x9ec: 0x2000, 0x9ed: 0x2000, 0x9ee: 0x2000, 0x9ef: 0x2000, + 0x9f0: 0x2000, 0x9f1: 0x2000, 0x9f2: 0x4000, 0x9f3: 0x4000, 0x9f4: 0x2000, 0x9f5: 0x4000, + 0x9f6: 0x2000, 0x9f7: 0x2000, 0x9f8: 0x2000, 0x9f9: 0x2000, 0x9fa: 0x4000, 0x9fb: 0x2000, + 0x9fc: 0x2000, 0x9fd: 0x4000, 0x9fe: 0x2000, 0x9ff: 0x2000, + // Block 0x28, offset 0xa00 + 0xa05: 0x4000, + 0xa0a: 0x4000, 0xa0b: 0x4000, + 0xa28: 0x4000, + 0xa3d: 0x2000, + // Block 0x29, offset 0xa40 + 0xa4c: 0x4000, 0xa4e: 0x4000, + 0xa53: 0x4000, 0xa54: 0x4000, 0xa55: 0x4000, 0xa57: 0x4000, + 0xa76: 0x2000, 0xa77: 0x2000, 0xa78: 0x2000, 0xa79: 0x2000, 0xa7a: 0x2000, 0xa7b: 0x2000, + 0xa7c: 0x2000, 0xa7d: 0x2000, 0xa7e: 0x2000, 0xa7f: 0x2000, + // Block 0x2a, offset 0xa80 + 0xa95: 0x4000, 0xa96: 0x4000, 0xa97: 0x4000, + 0xab0: 0x4000, + 0xabf: 0x4000, + // Block 0x2b, offset 0xac0 + 0xae6: 0x6000, 0xae7: 0x6000, 0xae8: 0x6000, 0xae9: 0x6000, + 0xaea: 0x6000, 0xaeb: 0x6000, 0xaec: 0x6000, 0xaed: 0x6000, + // Block 0x2c, offset 0xb00 + 0xb05: 0x6010, + 0xb06: 0x6011, + // Block 0x2d, offset 0xb40 + 0xb5b: 0x4000, 0xb5c: 0x4000, + // Block 0x2e, offset 0xb80 + 0xb90: 0x4000, + 0xb95: 0x4000, 0xb96: 0x2000, 0xb97: 0x2000, + 0xb98: 0x2000, 0xb99: 0x2000, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x4000, 0xbc1: 0x4000, 0xbc2: 0x4000, 0xbc3: 0x4000, 0xbc4: 0x4000, 0xbc5: 0x4000, + 0xbc6: 0x4000, 0xbc7: 0x4000, 0xbc8: 0x4000, 0xbc9: 0x4000, 0xbca: 0x4000, 0xbcb: 0x4000, + 0xbcc: 0x4000, 0xbcd: 0x4000, 0xbce: 0x4000, 0xbcf: 0x4000, 0xbd0: 0x4000, 0xbd1: 0x4000, + 0xbd2: 0x4000, 0xbd3: 0x4000, 0xbd4: 0x4000, 0xbd5: 0x4000, 0xbd6: 0x4000, 0xbd7: 0x4000, + 0xbd8: 0x4000, 0xbd9: 0x4000, 0xbdb: 0x4000, 0xbdc: 0x4000, 0xbdd: 0x4000, + 0xbde: 0x4000, 0xbdf: 0x4000, 0xbe0: 0x4000, 0xbe1: 0x4000, 0xbe2: 0x4000, 0xbe3: 0x4000, + 0xbe4: 0x4000, 0xbe5: 0x4000, 0xbe6: 0x4000, 0xbe7: 0x4000, 0xbe8: 0x4000, 0xbe9: 0x4000, + 0xbea: 0x4000, 0xbeb: 0x4000, 0xbec: 0x4000, 0xbed: 0x4000, 0xbee: 0x4000, 0xbef: 0x4000, + 0xbf0: 0x4000, 0xbf1: 0x4000, 0xbf2: 0x4000, 0xbf3: 0x4000, 0xbf4: 0x4000, 0xbf5: 0x4000, + 0xbf6: 0x4000, 0xbf7: 0x4000, 0xbf8: 0x4000, 0xbf9: 0x4000, 0xbfa: 0x4000, 0xbfb: 0x4000, + 0xbfc: 0x4000, 0xbfd: 0x4000, 0xbfe: 0x4000, 0xbff: 0x4000, + // Block 0x30, offset 0xc00 + 0xc00: 0x4000, 0xc01: 0x4000, 0xc02: 0x4000, 0xc03: 0x4000, 0xc04: 0x4000, 0xc05: 0x4000, + 0xc06: 0x4000, 0xc07: 0x4000, 0xc08: 0x4000, 0xc09: 0x4000, 0xc0a: 0x4000, 0xc0b: 0x4000, + 0xc0c: 0x4000, 0xc0d: 0x4000, 0xc0e: 0x4000, 0xc0f: 0x4000, 0xc10: 0x4000, 0xc11: 0x4000, + 0xc12: 0x4000, 0xc13: 0x4000, 0xc14: 0x4000, 0xc15: 0x4000, 0xc16: 0x4000, 0xc17: 0x4000, + 0xc18: 0x4000, 0xc19: 0x4000, 0xc1a: 0x4000, 0xc1b: 0x4000, 0xc1c: 0x4000, 0xc1d: 0x4000, + 0xc1e: 0x4000, 0xc1f: 0x4000, 0xc20: 0x4000, 0xc21: 0x4000, 0xc22: 0x4000, 0xc23: 0x4000, + 0xc24: 0x4000, 0xc25: 0x4000, 0xc26: 0x4000, 0xc27: 0x4000, 0xc28: 0x4000, 0xc29: 0x4000, + 0xc2a: 0x4000, 0xc2b: 0x4000, 0xc2c: 0x4000, 0xc2d: 0x4000, 0xc2e: 0x4000, 0xc2f: 0x4000, + 0xc30: 0x4000, 0xc31: 0x4000, 0xc32: 0x4000, 0xc33: 0x4000, + // Block 0x31, offset 0xc40 + 0xc40: 0x4000, 0xc41: 0x4000, 0xc42: 0x4000, 0xc43: 0x4000, 0xc44: 0x4000, 0xc45: 0x4000, + 0xc46: 0x4000, 0xc47: 0x4000, 0xc48: 0x4000, 0xc49: 0x4000, 0xc4a: 0x4000, 0xc4b: 0x4000, + 0xc4c: 0x4000, 0xc4d: 0x4000, 0xc4e: 0x4000, 0xc4f: 0x4000, 0xc50: 0x4000, 0xc51: 0x4000, + 0xc52: 0x4000, 0xc53: 0x4000, 0xc54: 0x4000, 0xc55: 0x4000, + 0xc70: 0x4000, 0xc71: 0x4000, 0xc72: 0x4000, 0xc73: 0x4000, 0xc74: 0x4000, 0xc75: 0x4000, + 0xc76: 0x4000, 0xc77: 0x4000, 0xc78: 0x4000, 0xc79: 0x4000, 0xc7a: 0x4000, 0xc7b: 0x4000, + // Block 0x32, offset 0xc80 + 0xc80: 0x9012, 0xc81: 0x4013, 0xc82: 0x4014, 0xc83: 0x4000, 0xc84: 0x4000, 0xc85: 0x4000, + 0xc86: 0x4000, 0xc87: 0x4000, 0xc88: 0x4000, 0xc89: 0x4000, 0xc8a: 0x4000, 0xc8b: 0x4000, + 0xc8c: 0x4015, 0xc8d: 0x4015, 0xc8e: 0x4000, 0xc8f: 0x4000, 0xc90: 0x4000, 0xc91: 0x4000, + 0xc92: 0x4000, 0xc93: 0x4000, 0xc94: 0x4000, 0xc95: 0x4000, 0xc96: 0x4000, 0xc97: 0x4000, + 0xc98: 0x4000, 0xc99: 0x4000, 0xc9a: 0x4000, 0xc9b: 0x4000, 0xc9c: 0x4000, 0xc9d: 0x4000, + 0xc9e: 0x4000, 0xc9f: 0x4000, 0xca0: 0x4000, 0xca1: 0x4000, 0xca2: 0x4000, 0xca3: 0x4000, + 0xca4: 0x4000, 0xca5: 0x4000, 0xca6: 0x4000, 0xca7: 0x4000, 0xca8: 0x4000, 0xca9: 0x4000, + 0xcaa: 0x4000, 0xcab: 0x4000, 0xcac: 0x4000, 0xcad: 0x4000, 0xcae: 0x4000, 0xcaf: 0x4000, + 0xcb0: 0x4000, 0xcb1: 0x4000, 0xcb2: 0x4000, 0xcb3: 0x4000, 0xcb4: 0x4000, 0xcb5: 0x4000, + 0xcb6: 0x4000, 0xcb7: 0x4000, 0xcb8: 0x4000, 0xcb9: 0x4000, 0xcba: 0x4000, 0xcbb: 0x4000, + 0xcbc: 0x4000, 0xcbd: 0x4000, 0xcbe: 0x4000, + // Block 0x33, offset 0xcc0 + 0xcc1: 0x4000, 0xcc2: 0x4000, 0xcc3: 0x4000, 0xcc4: 0x4000, 0xcc5: 0x4000, + 0xcc6: 0x4000, 0xcc7: 0x4000, 0xcc8: 0x4000, 0xcc9: 0x4000, 0xcca: 0x4000, 0xccb: 0x4000, + 0xccc: 0x4000, 0xccd: 0x4000, 0xcce: 0x4000, 0xccf: 0x4000, 0xcd0: 0x4000, 0xcd1: 0x4000, + 0xcd2: 0x4000, 0xcd3: 0x4000, 0xcd4: 0x4000, 0xcd5: 0x4000, 0xcd6: 0x4000, 0xcd7: 0x4000, + 0xcd8: 0x4000, 0xcd9: 0x4000, 0xcda: 0x4000, 0xcdb: 0x4000, 0xcdc: 0x4000, 0xcdd: 0x4000, + 0xcde: 0x4000, 0xcdf: 0x4000, 0xce0: 0x4000, 0xce1: 0x4000, 0xce2: 0x4000, 0xce3: 0x4000, + 0xce4: 0x4000, 0xce5: 0x4000, 0xce6: 0x4000, 0xce7: 0x4000, 0xce8: 0x4000, 0xce9: 0x4000, + 0xcea: 0x4000, 0xceb: 0x4000, 0xcec: 0x4000, 0xced: 0x4000, 0xcee: 0x4000, 0xcef: 0x4000, + 0xcf0: 0x4000, 0xcf1: 0x4000, 0xcf2: 0x4000, 0xcf3: 0x4000, 0xcf4: 0x4000, 0xcf5: 0x4000, + 0xcf6: 0x4000, 0xcf7: 0x4000, 0xcf8: 0x4000, 0xcf9: 0x4000, 0xcfa: 0x4000, 0xcfb: 0x4000, + 0xcfc: 0x4000, 0xcfd: 0x4000, 0xcfe: 0x4000, 0xcff: 0x4000, + // Block 0x34, offset 0xd00 + 0xd00: 0x4000, 0xd01: 0x4000, 0xd02: 0x4000, 0xd03: 0x4000, 0xd04: 0x4000, 0xd05: 0x4000, + 0xd06: 0x4000, 0xd07: 0x4000, 0xd08: 0x4000, 0xd09: 0x4000, 0xd0a: 0x4000, 0xd0b: 0x4000, + 0xd0c: 0x4000, 0xd0d: 0x4000, 0xd0e: 0x4000, 0xd0f: 0x4000, 0xd10: 0x4000, 0xd11: 0x4000, + 0xd12: 0x4000, 0xd13: 0x4000, 0xd14: 0x4000, 0xd15: 0x4000, 0xd16: 0x4000, + 0xd19: 0x4016, 0xd1a: 0x4017, 0xd1b: 0x4000, 0xd1c: 0x4000, 0xd1d: 0x4000, + 0xd1e: 0x4000, 0xd1f: 0x4000, 0xd20: 0x4000, 0xd21: 0x4018, 0xd22: 0x4019, 0xd23: 0x401a, + 0xd24: 0x401b, 0xd25: 0x401c, 0xd26: 0x401d, 0xd27: 0x401e, 0xd28: 0x401f, 0xd29: 0x4020, + 0xd2a: 0x4021, 0xd2b: 0x4022, 0xd2c: 0x4000, 0xd2d: 0x4010, 0xd2e: 0x4000, 0xd2f: 0x4023, + 0xd30: 0x4000, 0xd31: 0x4024, 0xd32: 0x4000, 0xd33: 0x4025, 0xd34: 0x4000, 0xd35: 0x4026, + 0xd36: 0x4000, 0xd37: 0x401a, 0xd38: 0x4000, 0xd39: 0x4027, 0xd3a: 0x4000, 0xd3b: 0x4028, + 0xd3c: 0x4000, 0xd3d: 0x4020, 0xd3e: 0x4000, 0xd3f: 0x4029, + // Block 0x35, offset 0xd40 + 0xd40: 0x4000, 0xd41: 0x402a, 0xd42: 0x4000, 0xd43: 0x402b, 0xd44: 0x402c, 0xd45: 0x4000, + 0xd46: 0x4017, 0xd47: 0x4000, 0xd48: 0x402d, 0xd49: 0x4000, 0xd4a: 0x402e, 0xd4b: 0x402f, + 0xd4c: 0x4030, 0xd4d: 0x4017, 0xd4e: 0x4016, 0xd4f: 0x4017, 0xd50: 0x4000, 0xd51: 0x4000, + 0xd52: 0x4031, 0xd53: 0x4000, 0xd54: 0x4000, 0xd55: 0x4031, 0xd56: 0x4000, 0xd57: 0x4000, + 0xd58: 0x4032, 0xd59: 0x4000, 0xd5a: 0x4000, 0xd5b: 0x4032, 0xd5c: 0x4000, 0xd5d: 0x4000, + 0xd5e: 0x4033, 0xd5f: 0x402e, 0xd60: 0x4034, 0xd61: 0x4035, 0xd62: 0x4034, 0xd63: 0x4036, + 0xd64: 0x4037, 0xd65: 0x4024, 0xd66: 0x4035, 0xd67: 0x4025, 0xd68: 0x4038, 0xd69: 0x4038, + 0xd6a: 0x4039, 0xd6b: 0x4039, 0xd6c: 0x403a, 0xd6d: 0x403a, 0xd6e: 0x4000, 0xd6f: 0x4035, + 0xd70: 0x4000, 0xd71: 0x4000, 0xd72: 0x403b, 0xd73: 0x403c, 0xd74: 0x4000, 0xd75: 0x4000, + 0xd76: 0x4000, 0xd77: 0x4000, 0xd78: 0x4000, 0xd79: 0x4000, 0xd7a: 0x4000, 0xd7b: 0x403d, + 0xd7c: 0x401c, 0xd7d: 0x4000, 0xd7e: 0x4000, 0xd7f: 0x4000, + // Block 0x36, offset 0xd80 + 0xd85: 0x4000, + 0xd86: 0x4000, 0xd87: 0x4000, 0xd88: 0x4000, 0xd89: 0x4000, 0xd8a: 0x4000, 0xd8b: 0x4000, + 0xd8c: 0x4000, 0xd8d: 0x4000, 0xd8e: 0x4000, 0xd8f: 0x4000, 0xd90: 0x4000, 0xd91: 0x4000, + 0xd92: 0x4000, 0xd93: 0x4000, 0xd94: 0x4000, 0xd95: 0x4000, 0xd96: 0x4000, 0xd97: 0x4000, + 0xd98: 0x4000, 0xd99: 0x4000, 0xd9a: 0x4000, 0xd9b: 0x4000, 0xd9c: 0x4000, 0xd9d: 0x4000, + 0xd9e: 0x4000, 0xd9f: 0x4000, 0xda0: 0x4000, 0xda1: 0x4000, 0xda2: 0x4000, 0xda3: 0x4000, + 0xda4: 0x4000, 0xda5: 0x4000, 0xda6: 0x4000, 0xda7: 0x4000, 0xda8: 0x4000, 0xda9: 0x4000, + 0xdaa: 0x4000, 0xdab: 0x4000, 0xdac: 0x4000, 0xdad: 0x4000, + 0xdb1: 0x403e, 0xdb2: 0x403e, 0xdb3: 0x403e, 0xdb4: 0x403e, 0xdb5: 0x403e, + 0xdb6: 0x403e, 0xdb7: 0x403e, 0xdb8: 0x403e, 0xdb9: 0x403e, 0xdba: 0x403e, 0xdbb: 0x403e, + 0xdbc: 0x403e, 0xdbd: 0x403e, 0xdbe: 0x403e, 0xdbf: 0x403e, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x4037, 0xdc1: 0x4037, 0xdc2: 0x4037, 0xdc3: 0x4037, 0xdc4: 0x4037, 0xdc5: 0x4037, + 0xdc6: 0x4037, 0xdc7: 0x4037, 0xdc8: 0x4037, 0xdc9: 0x4037, 0xdca: 0x4037, 0xdcb: 0x4037, + 0xdcc: 0x4037, 0xdcd: 0x4037, 0xdce: 0x4037, 0xdcf: 0x400e, 0xdd0: 0x403f, 0xdd1: 0x4040, + 0xdd2: 0x4041, 0xdd3: 0x4040, 0xdd4: 0x403f, 0xdd5: 0x4042, 0xdd6: 0x4043, 0xdd7: 0x4044, + 0xdd8: 0x4040, 0xdd9: 0x4041, 0xdda: 0x4040, 0xddb: 0x4045, 0xddc: 0x4009, 0xddd: 0x4045, + 0xdde: 0x4046, 0xddf: 0x4045, 0xde0: 0x4047, 0xde1: 0x400b, 0xde2: 0x400a, 0xde3: 0x400c, + 0xde4: 0x4048, 0xde5: 0x4000, 0xde6: 0x4000, 0xde7: 0x4000, 0xde8: 0x4000, 0xde9: 0x4000, + 0xdea: 0x4000, 0xdeb: 0x4000, 0xdec: 0x4000, 0xded: 0x4000, 0xdee: 0x4000, 0xdef: 0x4000, + 0xdf0: 0x4000, 0xdf1: 0x4000, 0xdf2: 0x4000, 0xdf3: 0x4000, 0xdf4: 0x4000, 0xdf5: 0x4000, + 0xdf6: 0x4000, 0xdf7: 0x4000, 0xdf8: 0x4000, 0xdf9: 0x4000, 0xdfa: 0x4000, 0xdfb: 0x4000, + 0xdfc: 0x4000, 0xdfd: 0x4000, 0xdfe: 0x4000, 0xdff: 0x4000, + // Block 0x38, offset 0xe00 + 0xe00: 0x4000, 0xe01: 0x4000, 0xe02: 0x4000, 0xe03: 0x4000, 0xe04: 0x4000, 0xe05: 0x4000, + 0xe06: 0x4000, 0xe07: 0x4000, 0xe08: 0x4000, 0xe09: 0x4000, 0xe0a: 0x4000, 0xe0b: 0x4000, + 0xe0c: 0x4000, 0xe0d: 0x4000, 0xe0e: 0x4000, 0xe10: 0x4000, 0xe11: 0x4000, + 0xe12: 0x4000, 0xe13: 0x4000, 0xe14: 0x4000, 0xe15: 0x4000, 0xe16: 0x4000, 0xe17: 0x4000, + 0xe18: 0x4000, 0xe19: 0x4000, 0xe1a: 0x4000, 0xe1b: 0x4000, 0xe1c: 0x4000, 0xe1d: 0x4000, + 0xe1e: 0x4000, 0xe1f: 0x4000, 0xe20: 0x4000, 0xe21: 0x4000, 0xe22: 0x4000, 0xe23: 0x4000, + 0xe24: 0x4000, 0xe25: 0x4000, 0xe26: 0x4000, 0xe27: 0x4000, 0xe28: 0x4000, 0xe29: 0x4000, + 0xe2a: 0x4000, 0xe2b: 0x4000, 0xe2c: 0x4000, 0xe2d: 0x4000, 0xe2e: 0x4000, 0xe2f: 0x4000, + 0xe30: 0x4000, 0xe31: 0x4000, 0xe32: 0x4000, 0xe33: 0x4000, 0xe34: 0x4000, 0xe35: 0x4000, + 0xe36: 0x4000, 0xe37: 0x4000, 0xe38: 0x4000, 0xe39: 0x4000, 0xe3a: 0x4000, + // Block 0x39, offset 0xe40 + 0xe40: 0x4000, 0xe41: 0x4000, 0xe42: 0x4000, 0xe43: 0x4000, 0xe44: 0x4000, 0xe45: 0x4000, + 0xe46: 0x4000, 0xe47: 0x4000, 0xe48: 0x4000, 0xe49: 0x4000, 0xe4a: 0x4000, 0xe4b: 0x4000, + 0xe4c: 0x4000, 0xe4d: 0x4000, 0xe4e: 0x4000, 0xe4f: 0x4000, 0xe50: 0x4000, 0xe51: 0x4000, + 0xe52: 0x4000, 0xe53: 0x4000, 0xe54: 0x4000, 0xe55: 0x4000, 0xe56: 0x4000, 0xe57: 0x4000, + 0xe58: 0x4000, 0xe59: 0x4000, 0xe5a: 0x4000, 0xe5b: 0x4000, 0xe5c: 0x4000, 0xe5d: 0x4000, + 0xe5e: 0x4000, 0xe5f: 0x4000, 0xe60: 0x4000, 0xe61: 0x4000, 0xe62: 0x4000, 0xe63: 0x4000, + 0xe70: 0x4000, 0xe71: 0x4000, 0xe72: 0x4000, 0xe73: 0x4000, 0xe74: 0x4000, 0xe75: 0x4000, + 0xe76: 0x4000, 0xe77: 0x4000, 0xe78: 0x4000, 0xe79: 0x4000, 0xe7a: 0x4000, 0xe7b: 0x4000, + 0xe7c: 0x4000, 0xe7d: 0x4000, 0xe7e: 0x4000, 0xe7f: 0x4000, + // Block 0x3a, offset 0xe80 + 0xe80: 0x4000, 0xe81: 0x4000, 0xe82: 0x4000, 0xe83: 0x4000, 0xe84: 0x4000, 0xe85: 0x4000, + 0xe86: 0x4000, 0xe87: 0x4000, 0xe88: 0x4000, 0xe89: 0x4000, 0xe8a: 0x4000, 0xe8b: 0x4000, + 0xe8c: 0x4000, 0xe8d: 0x4000, 0xe8e: 0x4000, 0xe8f: 0x4000, 0xe90: 0x4000, 0xe91: 0x4000, + 0xe92: 0x4000, 0xe93: 0x4000, 0xe94: 0x4000, 0xe95: 0x4000, 0xe96: 0x4000, 0xe97: 0x4000, + 0xe98: 0x4000, 0xe99: 0x4000, 0xe9a: 0x4000, 0xe9b: 0x4000, 0xe9c: 0x4000, 0xe9d: 0x4000, + 0xe9e: 0x4000, 0xea0: 0x4000, 0xea1: 0x4000, 0xea2: 0x4000, 0xea3: 0x4000, + 0xea4: 0x4000, 0xea5: 0x4000, 0xea6: 0x4000, 0xea7: 0x4000, 0xea8: 0x4000, 0xea9: 0x4000, + 0xeaa: 0x4000, 0xeab: 0x4000, 0xeac: 0x4000, 0xead: 0x4000, 0xeae: 0x4000, 0xeaf: 0x4000, + 0xeb0: 0x4000, 0xeb1: 0x4000, 0xeb2: 0x4000, 0xeb3: 0x4000, 0xeb4: 0x4000, 0xeb5: 0x4000, + 0xeb6: 0x4000, 0xeb7: 0x4000, 0xeb8: 0x4000, 0xeb9: 0x4000, 0xeba: 0x4000, 0xebb: 0x4000, + 0xebc: 0x4000, 0xebd: 0x4000, 0xebe: 0x4000, 0xebf: 0x4000, + // Block 0x3b, offset 0xec0 + 0xec0: 0x4000, 0xec1: 0x4000, 0xec2: 0x4000, 0xec3: 0x4000, 0xec4: 0x4000, 0xec5: 0x4000, + 0xec6: 0x4000, 0xec7: 0x4000, 0xec8: 0x2000, 0xec9: 0x2000, 0xeca: 0x2000, 0xecb: 0x2000, + 0xecc: 0x2000, 0xecd: 0x2000, 0xece: 0x2000, 0xecf: 0x2000, 0xed0: 0x4000, 0xed1: 0x4000, + 0xed2: 0x4000, 0xed3: 0x4000, 0xed4: 0x4000, 0xed5: 0x4000, 0xed6: 0x4000, 0xed7: 0x4000, + 0xed8: 0x4000, 0xed9: 0x4000, 0xeda: 0x4000, 0xedb: 0x4000, 0xedc: 0x4000, 0xedd: 0x4000, + 0xede: 0x4000, 0xedf: 0x4000, 0xee0: 0x4000, 0xee1: 0x4000, 0xee2: 0x4000, 0xee3: 0x4000, + 0xee4: 0x4000, 0xee5: 0x4000, 0xee6: 0x4000, 0xee7: 0x4000, 0xee8: 0x4000, 0xee9: 0x4000, + 0xeea: 0x4000, 0xeeb: 0x4000, 0xeec: 0x4000, 0xeed: 0x4000, 0xeee: 0x4000, 0xeef: 0x4000, + 0xef0: 0x4000, 0xef1: 0x4000, 0xef2: 0x4000, 0xef3: 0x4000, 0xef4: 0x4000, 0xef5: 0x4000, + 0xef6: 0x4000, 0xef7: 0x4000, 0xef8: 0x4000, 0xef9: 0x4000, 0xefa: 0x4000, 0xefb: 0x4000, + 0xefc: 0x4000, 0xefd: 0x4000, 0xefe: 0x4000, 0xeff: 0x4000, + // Block 0x3c, offset 0xf00 + 0xf00: 0x4000, 0xf01: 0x4000, 0xf02: 0x4000, 0xf03: 0x4000, 0xf04: 0x4000, 0xf05: 0x4000, + 0xf06: 0x4000, 0xf07: 0x4000, 0xf08: 0x4000, 0xf09: 0x4000, 0xf0a: 0x4000, 0xf0b: 0x4000, + 0xf0c: 0x4000, 0xf0d: 0x4000, 0xf0e: 0x4000, 0xf0f: 0x4000, 0xf10: 0x4000, 0xf11: 0x4000, + 0xf12: 0x4000, 0xf13: 0x4000, 0xf14: 0x4000, 0xf15: 0x4000, 0xf16: 0x4000, 0xf17: 0x4000, + 0xf18: 0x4000, 0xf19: 0x4000, 0xf1a: 0x4000, 0xf1b: 0x4000, 0xf1c: 0x4000, 0xf1d: 0x4000, + 0xf1e: 0x4000, 0xf1f: 0x4000, 0xf20: 0x4000, 0xf21: 0x4000, 0xf22: 0x4000, 0xf23: 0x4000, + 0xf24: 0x4000, 0xf25: 0x4000, 0xf26: 0x4000, 0xf27: 0x4000, 0xf28: 0x4000, 0xf29: 0x4000, + 0xf2a: 0x4000, 0xf2b: 0x4000, 0xf2c: 0x4000, 0xf2d: 0x4000, 0xf2e: 0x4000, 0xf2f: 0x4000, + 0xf30: 0x4000, 0xf31: 0x4000, 0xf32: 0x4000, 0xf33: 0x4000, 0xf34: 0x4000, 0xf35: 0x4000, + 0xf36: 0x4000, 0xf37: 0x4000, 0xf38: 0x4000, 0xf39: 0x4000, 0xf3a: 0x4000, 0xf3b: 0x4000, + 0xf3c: 0x4000, 0xf3d: 0x4000, 0xf3e: 0x4000, + // Block 0x3d, offset 0xf40 + 0xf40: 0x4000, 0xf41: 0x4000, 0xf42: 0x4000, 0xf43: 0x4000, 0xf44: 0x4000, 0xf45: 0x4000, + 0xf46: 0x4000, 0xf47: 0x4000, 0xf48: 0x4000, 0xf49: 0x4000, 0xf4a: 0x4000, 0xf4b: 0x4000, + 0xf4c: 0x4000, 0xf50: 0x4000, 0xf51: 0x4000, + 0xf52: 0x4000, 0xf53: 0x4000, 0xf54: 0x4000, 0xf55: 0x4000, 0xf56: 0x4000, 0xf57: 0x4000, + 0xf58: 0x4000, 0xf59: 0x4000, 0xf5a: 0x4000, 0xf5b: 0x4000, 0xf5c: 0x4000, 0xf5d: 0x4000, + 0xf5e: 0x4000, 0xf5f: 0x4000, 0xf60: 0x4000, 0xf61: 0x4000, 0xf62: 0x4000, 0xf63: 0x4000, + 0xf64: 0x4000, 0xf65: 0x4000, 0xf66: 0x4000, 0xf67: 0x4000, 0xf68: 0x4000, 0xf69: 0x4000, + 0xf6a: 0x4000, 0xf6b: 0x4000, 0xf6c: 0x4000, 0xf6d: 0x4000, 0xf6e: 0x4000, 0xf6f: 0x4000, + 0xf70: 0x4000, 0xf71: 0x4000, 0xf72: 0x4000, 0xf73: 0x4000, 0xf74: 0x4000, 0xf75: 0x4000, + 0xf76: 0x4000, 0xf77: 0x4000, 0xf78: 0x4000, 0xf79: 0x4000, 0xf7a: 0x4000, 0xf7b: 0x4000, + 0xf7c: 0x4000, 0xf7d: 0x4000, 0xf7e: 0x4000, 0xf7f: 0x4000, + // Block 0x3e, offset 0xf80 + 0xf80: 0x4000, 0xf81: 0x4000, 0xf82: 0x4000, 0xf83: 0x4000, 0xf84: 0x4000, 0xf85: 0x4000, + 0xf86: 0x4000, + // Block 0x3f, offset 0xfc0 + 0xfe0: 0x4000, 0xfe1: 0x4000, 0xfe2: 0x4000, 0xfe3: 0x4000, + 0xfe4: 0x4000, 0xfe5: 0x4000, 0xfe6: 0x4000, 0xfe7: 0x4000, 0xfe8: 0x4000, 0xfe9: 0x4000, + 0xfea: 0x4000, 0xfeb: 0x4000, 0xfec: 0x4000, 0xfed: 0x4000, 0xfee: 0x4000, 0xfef: 0x4000, + 0xff0: 0x4000, 0xff1: 0x4000, 0xff2: 0x4000, 0xff3: 0x4000, 0xff4: 0x4000, 0xff5: 0x4000, + 0xff6: 0x4000, 0xff7: 0x4000, 0xff8: 0x4000, 0xff9: 0x4000, 0xffa: 0x4000, 0xffb: 0x4000, + 0xffc: 0x4000, + // Block 0x40, offset 0x1000 + 0x1000: 0x4000, 0x1001: 0x4000, 0x1002: 0x4000, 0x1003: 0x4000, 0x1004: 0x4000, 0x1005: 0x4000, + 0x1006: 0x4000, 0x1007: 0x4000, 0x1008: 0x4000, 0x1009: 0x4000, 0x100a: 0x4000, 0x100b: 0x4000, + 0x100c: 0x4000, 0x100d: 0x4000, 0x100e: 0x4000, 0x100f: 0x4000, 0x1010: 0x4000, 0x1011: 0x4000, + 0x1012: 0x4000, 0x1013: 0x4000, 0x1014: 0x4000, 0x1015: 0x4000, 0x1016: 0x4000, 0x1017: 0x4000, + 0x1018: 0x4000, 0x1019: 0x4000, 0x101a: 0x4000, 0x101b: 0x4000, 0x101c: 0x4000, 0x101d: 0x4000, + 0x101e: 0x4000, 0x101f: 0x4000, 0x1020: 0x4000, 0x1021: 0x4000, 0x1022: 0x4000, 0x1023: 0x4000, + // Block 0x41, offset 0x1040 + 0x1040: 0x2000, 0x1041: 0x2000, 0x1042: 0x2000, 0x1043: 0x2000, 0x1044: 0x2000, 0x1045: 0x2000, + 0x1046: 0x2000, 0x1047: 0x2000, 0x1048: 0x2000, 0x1049: 0x2000, 0x104a: 0x2000, 0x104b: 0x2000, + 0x104c: 0x2000, 0x104d: 0x2000, 0x104e: 0x2000, 0x104f: 0x2000, 0x1050: 0x4000, 0x1051: 0x4000, + 0x1052: 0x4000, 0x1053: 0x4000, 0x1054: 0x4000, 0x1055: 0x4000, 0x1056: 0x4000, 0x1057: 0x4000, + 0x1058: 0x4000, 0x1059: 0x4000, + 0x1070: 0x4000, 0x1071: 0x4000, 0x1072: 0x4000, 0x1073: 0x4000, 0x1074: 0x4000, 0x1075: 0x4000, + 0x1076: 0x4000, 0x1077: 0x4000, 0x1078: 0x4000, 0x1079: 0x4000, 0x107a: 0x4000, 0x107b: 0x4000, + 0x107c: 0x4000, 0x107d: 0x4000, 0x107e: 0x4000, 0x107f: 0x4000, + // Block 0x42, offset 0x1080 + 0x1080: 0x4000, 0x1081: 0x4000, 0x1082: 0x4000, 0x1083: 0x4000, 0x1084: 0x4000, 0x1085: 0x4000, + 0x1086: 0x4000, 0x1087: 0x4000, 0x1088: 0x4000, 0x1089: 0x4000, 0x108a: 0x4000, 0x108b: 0x4000, + 0x108c: 0x4000, 0x108d: 0x4000, 0x108e: 0x4000, 0x108f: 0x4000, 0x1090: 0x4000, 0x1091: 0x4000, + 0x1092: 0x4000, 0x1094: 0x4000, 0x1095: 0x4000, 0x1096: 0x4000, 0x1097: 0x4000, + 0x1098: 0x4000, 0x1099: 0x4000, 0x109a: 0x4000, 0x109b: 0x4000, 0x109c: 0x4000, 0x109d: 0x4000, + 0x109e: 0x4000, 0x109f: 0x4000, 0x10a0: 0x4000, 0x10a1: 0x4000, 0x10a2: 0x4000, 0x10a3: 0x4000, + 0x10a4: 0x4000, 0x10a5: 0x4000, 0x10a6: 0x4000, 0x10a8: 0x4000, 0x10a9: 0x4000, + 0x10aa: 0x4000, 0x10ab: 0x4000, + // Block 0x43, offset 0x10c0 + 0x10c1: 0x9012, 0x10c2: 0x9012, 0x10c3: 0x9012, 0x10c4: 0x9012, 0x10c5: 0x9012, + 0x10c6: 0x9012, 0x10c7: 0x9012, 0x10c8: 0x9012, 0x10c9: 0x9012, 0x10ca: 0x9012, 0x10cb: 0x9012, + 0x10cc: 0x9012, 0x10cd: 0x9012, 0x10ce: 0x9012, 0x10cf: 0x9012, 0x10d0: 0x9012, 0x10d1: 0x9012, + 0x10d2: 0x9012, 0x10d3: 0x9012, 0x10d4: 0x9012, 0x10d5: 0x9012, 0x10d6: 0x9012, 0x10d7: 0x9012, + 0x10d8: 0x9012, 0x10d9: 0x9012, 0x10da: 0x9012, 0x10db: 0x9012, 0x10dc: 0x9012, 0x10dd: 0x9012, + 0x10de: 0x9012, 0x10df: 0x9012, 0x10e0: 0x9049, 0x10e1: 0x9049, 0x10e2: 0x9049, 0x10e3: 0x9049, + 0x10e4: 0x9049, 0x10e5: 0x9049, 0x10e6: 0x9049, 0x10e7: 0x9049, 0x10e8: 0x9049, 0x10e9: 0x9049, + 0x10ea: 0x9049, 0x10eb: 0x9049, 0x10ec: 0x9049, 0x10ed: 0x9049, 0x10ee: 0x9049, 0x10ef: 0x9049, + 0x10f0: 0x9049, 0x10f1: 0x9049, 0x10f2: 0x9049, 0x10f3: 0x9049, 0x10f4: 0x9049, 0x10f5: 0x9049, + 0x10f6: 0x9049, 0x10f7: 0x9049, 0x10f8: 0x9049, 0x10f9: 0x9049, 0x10fa: 0x9049, 0x10fb: 0x9049, + 0x10fc: 0x9049, 0x10fd: 0x9049, 0x10fe: 0x9049, 0x10ff: 0x9049, + // Block 0x44, offset 0x1100 + 0x1100: 0x9049, 0x1101: 0x9049, 0x1102: 0x9049, 0x1103: 0x9049, 0x1104: 0x9049, 0x1105: 0x9049, + 0x1106: 0x9049, 0x1107: 0x9049, 0x1108: 0x9049, 0x1109: 0x9049, 0x110a: 0x9049, 0x110b: 0x9049, + 0x110c: 0x9049, 0x110d: 0x9049, 0x110e: 0x9049, 0x110f: 0x9049, 0x1110: 0x9049, 0x1111: 0x9049, + 0x1112: 0x9049, 0x1113: 0x9049, 0x1114: 0x9049, 0x1115: 0x9049, 0x1116: 0x9049, 0x1117: 0x9049, + 0x1118: 0x9049, 0x1119: 0x9049, 0x111a: 0x9049, 0x111b: 0x9049, 0x111c: 0x9049, 0x111d: 0x9049, + 0x111e: 0x9049, 0x111f: 0x904a, 0x1120: 0x904b, 0x1121: 0xb04c, 0x1122: 0xb04d, 0x1123: 0xb04d, + 0x1124: 0xb04e, 0x1125: 0xb04f, 0x1126: 0xb050, 0x1127: 0xb051, 0x1128: 0xb052, 0x1129: 0xb053, + 0x112a: 0xb054, 0x112b: 0xb055, 0x112c: 0xb056, 0x112d: 0xb057, 0x112e: 0xb058, 0x112f: 0xb059, + 0x1130: 0xb05a, 0x1131: 0xb05b, 0x1132: 0xb05c, 0x1133: 0xb05d, 0x1134: 0xb05e, 0x1135: 0xb05f, + 0x1136: 0xb060, 0x1137: 0xb061, 0x1138: 0xb062, 0x1139: 0xb063, 0x113a: 0xb064, 0x113b: 0xb065, + 0x113c: 0xb052, 0x113d: 0xb066, 0x113e: 0xb067, 0x113f: 0xb055, + // Block 0x45, offset 0x1140 + 0x1140: 0xb068, 0x1141: 0xb069, 0x1142: 0xb06a, 0x1143: 0xb06b, 0x1144: 0xb05a, 0x1145: 0xb056, + 0x1146: 0xb06c, 0x1147: 0xb06d, 0x1148: 0xb06b, 0x1149: 0xb06e, 0x114a: 0xb06b, 0x114b: 0xb06f, + 0x114c: 0xb06f, 0x114d: 0xb070, 0x114e: 0xb070, 0x114f: 0xb071, 0x1150: 0xb056, 0x1151: 0xb072, + 0x1152: 0xb073, 0x1153: 0xb072, 0x1154: 0xb074, 0x1155: 0xb073, 0x1156: 0xb075, 0x1157: 0xb075, + 0x1158: 0xb076, 0x1159: 0xb076, 0x115a: 0xb077, 0x115b: 0xb077, 0x115c: 0xb073, 0x115d: 0xb078, + 0x115e: 0xb079, 0x115f: 0xb067, 0x1160: 0xb07a, 0x1161: 0xb07b, 0x1162: 0xb07b, 0x1163: 0xb07b, + 0x1164: 0xb07b, 0x1165: 0xb07b, 0x1166: 0xb07b, 0x1167: 0xb07b, 0x1168: 0xb07b, 0x1169: 0xb07b, + 0x116a: 0xb07b, 0x116b: 0xb07b, 0x116c: 0xb07b, 0x116d: 0xb07b, 0x116e: 0xb07b, 0x116f: 0xb07b, + 0x1170: 0xb07c, 0x1171: 0xb07c, 0x1172: 0xb07c, 0x1173: 0xb07c, 0x1174: 0xb07c, 0x1175: 0xb07c, + 0x1176: 0xb07c, 0x1177: 0xb07c, 0x1178: 0xb07c, 0x1179: 0xb07c, 0x117a: 0xb07c, 0x117b: 0xb07c, + 0x117c: 0xb07c, 0x117d: 0xb07c, 0x117e: 0xb07c, + // Block 0x46, offset 0x1180 + 0x1182: 0xb07d, 0x1183: 0xb07e, 0x1184: 0xb07f, 0x1185: 0xb080, + 0x1186: 0xb07f, 0x1187: 0xb07e, 0x118a: 0xb081, 0x118b: 0xb082, + 0x118c: 0xb083, 0x118d: 0xb07f, 0x118e: 0xb080, 0x118f: 0xb07f, + 0x1192: 0xb084, 0x1193: 0xb085, 0x1194: 0xb084, 0x1195: 0xb086, 0x1196: 0xb084, 0x1197: 0xb087, + 0x119a: 0xb088, 0x119b: 0xb089, 0x119c: 0xb08a, + 0x11a0: 0x908b, 0x11a1: 0x908b, 0x11a2: 0x908c, 0x11a3: 0x908d, + 0x11a4: 0x908b, 0x11a5: 0x908e, 0x11a6: 0x908f, 0x11a8: 0xb090, 0x11a9: 0xb091, + 0x11aa: 0xb092, 0x11ab: 0xb091, 0x11ac: 0xb093, 0x11ad: 0xb094, 0x11ae: 0xb095, + 0x11bd: 0x2000, + // Block 0x47, offset 0x11c0 + 0x11e0: 0x4000, + // Block 0x48, offset 0x1200 + 0x1200: 0x4000, 0x1201: 0x4000, 0x1202: 0x4000, 0x1203: 0x4000, 0x1204: 0x4000, 0x1205: 0x4000, + 0x1206: 0x4000, 0x1207: 0x4000, 0x1208: 0x4000, 0x1209: 0x4000, 0x120a: 0x4000, 0x120b: 0x4000, + 0x120c: 0x4000, 0x120d: 0x4000, 0x120e: 0x4000, 0x120f: 0x4000, 0x1210: 0x4000, 0x1211: 0x4000, + 0x1212: 0x4000, 0x1213: 0x4000, 0x1214: 0x4000, 0x1215: 0x4000, 0x1216: 0x4000, 0x1217: 0x4000, + 0x1218: 0x4000, 0x1219: 0x4000, 0x121a: 0x4000, 0x121b: 0x4000, 0x121c: 0x4000, 0x121d: 0x4000, + 0x121e: 0x4000, 0x121f: 0x4000, 0x1220: 0x4000, 0x1221: 0x4000, 0x1222: 0x4000, 0x1223: 0x4000, + 0x1224: 0x4000, 0x1225: 0x4000, 0x1226: 0x4000, 0x1227: 0x4000, 0x1228: 0x4000, 0x1229: 0x4000, + 0x122a: 0x4000, 0x122b: 0x4000, 0x122c: 0x4000, + // Block 0x49, offset 0x1240 + 0x1240: 0x4000, 0x1241: 0x4000, 0x1242: 0x4000, 0x1243: 0x4000, 0x1244: 0x4000, 0x1245: 0x4000, + 0x1246: 0x4000, 0x1247: 0x4000, 0x1248: 0x4000, 0x1249: 0x4000, 0x124a: 0x4000, 0x124b: 0x4000, + 0x124c: 0x4000, 0x124d: 0x4000, 0x124e: 0x4000, 0x124f: 0x4000, 0x1250: 0x4000, 0x1251: 0x4000, + 0x1252: 0x4000, 0x1253: 0x4000, 0x1254: 0x4000, 0x1255: 0x4000, 0x1256: 0x4000, 0x1257: 0x4000, + 0x1258: 0x4000, 0x1259: 0x4000, 0x125a: 0x4000, 0x125b: 0x4000, 0x125c: 0x4000, 0x125d: 0x4000, + 0x125e: 0x4000, 0x125f: 0x4000, 0x1260: 0x4000, 0x1261: 0x4000, 0x1262: 0x4000, 0x1263: 0x4000, + 0x1264: 0x4000, 0x1265: 0x4000, 0x1266: 0x4000, 0x1267: 0x4000, 0x1268: 0x4000, 0x1269: 0x4000, + 0x126a: 0x4000, 0x126b: 0x4000, 0x126c: 0x4000, 0x126d: 0x4000, 0x126e: 0x4000, 0x126f: 0x4000, + 0x1270: 0x4000, 0x1271: 0x4000, 0x1272: 0x4000, + // Block 0x4a, offset 0x1280 + 0x1280: 0x4000, 0x1281: 0x4000, + // Block 0x4b, offset 0x12c0 + 0x12c4: 0x4000, + // Block 0x4c, offset 0x1300 + 0x130f: 0x4000, + // Block 0x4d, offset 0x1340 + 0x1340: 0x2000, 0x1341: 0x2000, 0x1342: 0x2000, 0x1343: 0x2000, 0x1344: 0x2000, 0x1345: 0x2000, + 0x1346: 0x2000, 0x1347: 0x2000, 0x1348: 0x2000, 0x1349: 0x2000, 0x134a: 0x2000, + 0x1350: 0x2000, 0x1351: 0x2000, + 0x1352: 0x2000, 0x1353: 0x2000, 0x1354: 0x2000, 0x1355: 0x2000, 0x1356: 0x2000, 0x1357: 0x2000, + 0x1358: 0x2000, 0x1359: 0x2000, 0x135a: 0x2000, 0x135b: 0x2000, 0x135c: 0x2000, 0x135d: 0x2000, + 0x135e: 0x2000, 0x135f: 0x2000, 0x1360: 0x2000, 0x1361: 0x2000, 0x1362: 0x2000, 0x1363: 0x2000, + 0x1364: 0x2000, 0x1365: 0x2000, 0x1366: 0x2000, 0x1367: 0x2000, 0x1368: 0x2000, 0x1369: 0x2000, + 0x136a: 0x2000, 0x136b: 0x2000, 0x136c: 0x2000, 0x136d: 0x2000, + 0x1370: 0x2000, 0x1371: 0x2000, 0x1372: 0x2000, 0x1373: 0x2000, 0x1374: 0x2000, 0x1375: 0x2000, + 0x1376: 0x2000, 0x1377: 0x2000, 0x1378: 0x2000, 0x1379: 0x2000, 0x137a: 0x2000, 0x137b: 0x2000, + 0x137c: 0x2000, 0x137d: 0x2000, 0x137e: 0x2000, 0x137f: 0x2000, + // Block 0x4e, offset 0x1380 + 0x1380: 0x2000, 0x1381: 0x2000, 0x1382: 0x2000, 0x1383: 0x2000, 0x1384: 0x2000, 0x1385: 0x2000, + 0x1386: 0x2000, 0x1387: 0x2000, 0x1388: 0x2000, 0x1389: 0x2000, 0x138a: 0x2000, 0x138b: 0x2000, + 0x138c: 0x2000, 0x138d: 0x2000, 0x138e: 0x2000, 0x138f: 0x2000, 0x1390: 0x2000, 0x1391: 0x2000, + 0x1392: 0x2000, 0x1393: 0x2000, 0x1394: 0x2000, 0x1395: 0x2000, 0x1396: 0x2000, 0x1397: 0x2000, + 0x1398: 0x2000, 0x1399: 0x2000, 0x139a: 0x2000, 0x139b: 0x2000, 0x139c: 0x2000, 0x139d: 0x2000, + 0x139e: 0x2000, 0x139f: 0x2000, 0x13a0: 0x2000, 0x13a1: 0x2000, 0x13a2: 0x2000, 0x13a3: 0x2000, + 0x13a4: 0x2000, 0x13a5: 0x2000, 0x13a6: 0x2000, 0x13a7: 0x2000, 0x13a8: 0x2000, 0x13a9: 0x2000, + 0x13b0: 0x2000, 0x13b1: 0x2000, 0x13b2: 0x2000, 0x13b3: 0x2000, 0x13b4: 0x2000, 0x13b5: 0x2000, + 0x13b6: 0x2000, 0x13b7: 0x2000, 0x13b8: 0x2000, 0x13b9: 0x2000, 0x13ba: 0x2000, 0x13bb: 0x2000, + 0x13bc: 0x2000, 0x13bd: 0x2000, 0x13be: 0x2000, 0x13bf: 0x2000, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x2000, 0x13c1: 0x2000, 0x13c2: 0x2000, 0x13c3: 0x2000, 0x13c4: 0x2000, 0x13c5: 0x2000, + 0x13c6: 0x2000, 0x13c7: 0x2000, 0x13c8: 0x2000, 0x13c9: 0x2000, 0x13ca: 0x2000, 0x13cb: 0x2000, + 0x13cc: 0x2000, 0x13cd: 0x2000, 0x13ce: 0x4000, 0x13cf: 0x2000, 0x13d0: 0x2000, 0x13d1: 0x4000, + 0x13d2: 0x4000, 0x13d3: 0x4000, 0x13d4: 0x4000, 0x13d5: 0x4000, 0x13d6: 0x4000, 0x13d7: 0x4000, + 0x13d8: 0x4000, 0x13d9: 0x4000, 0x13da: 0x4000, 0x13db: 0x2000, 0x13dc: 0x2000, 0x13dd: 0x2000, + 0x13de: 0x2000, 0x13df: 0x2000, 0x13e0: 0x2000, 0x13e1: 0x2000, 0x13e2: 0x2000, 0x13e3: 0x2000, + 0x13e4: 0x2000, 0x13e5: 0x2000, 0x13e6: 0x2000, 0x13e7: 0x2000, 0x13e8: 0x2000, 0x13e9: 0x2000, + 0x13ea: 0x2000, 0x13eb: 0x2000, 0x13ec: 0x2000, + // Block 0x50, offset 0x1400 + 0x1400: 0x4000, 0x1401: 0x4000, 0x1402: 0x4000, + 0x1410: 0x4000, 0x1411: 0x4000, + 0x1412: 0x4000, 0x1413: 0x4000, 0x1414: 0x4000, 0x1415: 0x4000, 0x1416: 0x4000, 0x1417: 0x4000, + 0x1418: 0x4000, 0x1419: 0x4000, 0x141a: 0x4000, 0x141b: 0x4000, 0x141c: 0x4000, 0x141d: 0x4000, + 0x141e: 0x4000, 0x141f: 0x4000, 0x1420: 0x4000, 0x1421: 0x4000, 0x1422: 0x4000, 0x1423: 0x4000, + 0x1424: 0x4000, 0x1425: 0x4000, 0x1426: 0x4000, 0x1427: 0x4000, 0x1428: 0x4000, 0x1429: 0x4000, + 0x142a: 0x4000, 0x142b: 0x4000, 0x142c: 0x4000, 0x142d: 0x4000, 0x142e: 0x4000, 0x142f: 0x4000, + 0x1430: 0x4000, 0x1431: 0x4000, 0x1432: 0x4000, 0x1433: 0x4000, 0x1434: 0x4000, 0x1435: 0x4000, + 0x1436: 0x4000, 0x1437: 0x4000, 0x1438: 0x4000, 0x1439: 0x4000, 0x143a: 0x4000, 0x143b: 0x4000, + // Block 0x51, offset 0x1440 + 0x1440: 0x4000, 0x1441: 0x4000, 0x1442: 0x4000, 0x1443: 0x4000, 0x1444: 0x4000, 0x1445: 0x4000, + 0x1446: 0x4000, 0x1447: 0x4000, 0x1448: 0x4000, + 0x1450: 0x4000, 0x1451: 0x4000, + // Block 0x52, offset 0x1480 + 0x1480: 0x4000, 0x1481: 0x4000, 0x1482: 0x4000, 0x1483: 0x4000, 0x1484: 0x4000, 0x1485: 0x4000, + 0x1486: 0x4000, 0x1487: 0x4000, 0x1488: 0x4000, 0x1489: 0x4000, 0x148a: 0x4000, 0x148b: 0x4000, + 0x148c: 0x4000, 0x148d: 0x4000, 0x148e: 0x4000, 0x148f: 0x4000, 0x1490: 0x4000, 0x1491: 0x4000, + 0x1492: 0x4000, 0x1493: 0x4000, 0x1494: 0x4000, 0x1495: 0x4000, 0x1496: 0x4000, 0x1497: 0x4000, + 0x1498: 0x4000, 0x1499: 0x4000, 0x149a: 0x4000, 0x149b: 0x4000, 0x149c: 0x4000, 0x149d: 0x4000, + 0x149e: 0x4000, 0x149f: 0x4000, 0x14a0: 0x4000, + 0x14ad: 0x4000, 0x14ae: 0x4000, 0x14af: 0x4000, + 0x14b0: 0x4000, 0x14b1: 0x4000, 0x14b2: 0x4000, 0x14b3: 0x4000, 0x14b4: 0x4000, 0x14b5: 0x4000, + 0x14b7: 0x4000, 0x14b8: 0x4000, 0x14b9: 0x4000, 0x14ba: 0x4000, 0x14bb: 0x4000, + 0x14bc: 0x4000, 0x14bd: 0x4000, 0x14be: 0x4000, 0x14bf: 0x4000, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x4000, 0x14c1: 0x4000, 0x14c2: 0x4000, 0x14c3: 0x4000, 0x14c4: 0x4000, 0x14c5: 0x4000, + 0x14c6: 0x4000, 0x14c7: 0x4000, 0x14c8: 0x4000, 0x14c9: 0x4000, 0x14ca: 0x4000, 0x14cb: 0x4000, + 0x14cc: 0x4000, 0x14cd: 0x4000, 0x14ce: 0x4000, 0x14cf: 0x4000, 0x14d0: 0x4000, 0x14d1: 0x4000, + 0x14d2: 0x4000, 0x14d3: 0x4000, 0x14d4: 0x4000, 0x14d5: 0x4000, 0x14d6: 0x4000, 0x14d7: 0x4000, + 0x14d8: 0x4000, 0x14d9: 0x4000, 0x14da: 0x4000, 0x14db: 0x4000, 0x14dc: 0x4000, 0x14dd: 0x4000, + 0x14de: 0x4000, 0x14df: 0x4000, 0x14e0: 0x4000, 0x14e1: 0x4000, 0x14e2: 0x4000, 0x14e3: 0x4000, + 0x14e4: 0x4000, 0x14e5: 0x4000, 0x14e6: 0x4000, 0x14e7: 0x4000, 0x14e8: 0x4000, 0x14e9: 0x4000, + 0x14ea: 0x4000, 0x14eb: 0x4000, 0x14ec: 0x4000, 0x14ed: 0x4000, 0x14ee: 0x4000, 0x14ef: 0x4000, + 0x14f0: 0x4000, 0x14f1: 0x4000, 0x14f2: 0x4000, 0x14f3: 0x4000, 0x14f4: 0x4000, 0x14f5: 0x4000, + 0x14f6: 0x4000, 0x14f7: 0x4000, 0x14f8: 0x4000, 0x14f9: 0x4000, 0x14fa: 0x4000, 0x14fb: 0x4000, + 0x14fc: 0x4000, 0x14fe: 0x4000, 0x14ff: 0x4000, + // Block 0x54, offset 0x1500 + 0x1500: 0x4000, 0x1501: 0x4000, 0x1502: 0x4000, 0x1503: 0x4000, 0x1504: 0x4000, 0x1505: 0x4000, + 0x1506: 0x4000, 0x1507: 0x4000, 0x1508: 0x4000, 0x1509: 0x4000, 0x150a: 0x4000, 0x150b: 0x4000, + 0x150c: 0x4000, 0x150d: 0x4000, 0x150e: 0x4000, 0x150f: 0x4000, 0x1510: 0x4000, 0x1511: 0x4000, + 0x1512: 0x4000, 0x1513: 0x4000, + 0x1520: 0x4000, 0x1521: 0x4000, 0x1522: 0x4000, 0x1523: 0x4000, + 0x1524: 0x4000, 0x1525: 0x4000, 0x1526: 0x4000, 0x1527: 0x4000, 0x1528: 0x4000, 0x1529: 0x4000, + 0x152a: 0x4000, 0x152b: 0x4000, 0x152c: 0x4000, 0x152d: 0x4000, 0x152e: 0x4000, 0x152f: 0x4000, + 0x1530: 0x4000, 0x1531: 0x4000, 0x1532: 0x4000, 0x1533: 0x4000, 0x1534: 0x4000, 0x1535: 0x4000, + 0x1536: 0x4000, 0x1537: 0x4000, 0x1538: 0x4000, 0x1539: 0x4000, 0x153a: 0x4000, 0x153b: 0x4000, + 0x153c: 0x4000, 0x153d: 0x4000, 0x153e: 0x4000, 0x153f: 0x4000, + // Block 0x55, offset 0x1540 + 0x1540: 0x4000, 0x1541: 0x4000, 0x1542: 0x4000, 0x1543: 0x4000, 0x1544: 0x4000, 0x1545: 0x4000, + 0x1546: 0x4000, 0x1547: 0x4000, 0x1548: 0x4000, 0x1549: 0x4000, 0x154a: 0x4000, + 0x154f: 0x4000, 0x1550: 0x4000, 0x1551: 0x4000, + 0x1552: 0x4000, 0x1553: 0x4000, + 0x1560: 0x4000, 0x1561: 0x4000, 0x1562: 0x4000, 0x1563: 0x4000, + 0x1564: 0x4000, 0x1565: 0x4000, 0x1566: 0x4000, 0x1567: 0x4000, 0x1568: 0x4000, 0x1569: 0x4000, + 0x156a: 0x4000, 0x156b: 0x4000, 0x156c: 0x4000, 0x156d: 0x4000, 0x156e: 0x4000, 0x156f: 0x4000, + 0x1570: 0x4000, 0x1574: 0x4000, + 0x1578: 0x4000, 0x1579: 0x4000, 0x157a: 0x4000, 0x157b: 0x4000, + 0x157c: 0x4000, 0x157d: 0x4000, 0x157e: 0x4000, 0x157f: 0x4000, + // Block 0x56, offset 0x1580 + 0x1580: 0x4000, 0x1582: 0x4000, 0x1583: 0x4000, 0x1584: 0x4000, 0x1585: 0x4000, + 0x1586: 0x4000, 0x1587: 0x4000, 0x1588: 0x4000, 0x1589: 0x4000, 0x158a: 0x4000, 0x158b: 0x4000, + 0x158c: 0x4000, 0x158d: 0x4000, 0x158e: 0x4000, 0x158f: 0x4000, 0x1590: 0x4000, 0x1591: 0x4000, + 0x1592: 0x4000, 0x1593: 0x4000, 0x1594: 0x4000, 0x1595: 0x4000, 0x1596: 0x4000, 0x1597: 0x4000, + 0x1598: 0x4000, 0x1599: 0x4000, 0x159a: 0x4000, 0x159b: 0x4000, 0x159c: 0x4000, 0x159d: 0x4000, + 0x159e: 0x4000, 0x159f: 0x4000, 0x15a0: 0x4000, 0x15a1: 0x4000, 0x15a2: 0x4000, 0x15a3: 0x4000, + 0x15a4: 0x4000, 0x15a5: 0x4000, 0x15a6: 0x4000, 0x15a7: 0x4000, 0x15a8: 0x4000, 0x15a9: 0x4000, + 0x15aa: 0x4000, 0x15ab: 0x4000, 0x15ac: 0x4000, 0x15ad: 0x4000, 0x15ae: 0x4000, 0x15af: 0x4000, + 0x15b0: 0x4000, 0x15b1: 0x4000, 0x15b2: 0x4000, 0x15b3: 0x4000, 0x15b4: 0x4000, 0x15b5: 0x4000, + 0x15b6: 0x4000, 0x15b7: 0x4000, 0x15b8: 0x4000, 0x15b9: 0x4000, 0x15ba: 0x4000, 0x15bb: 0x4000, + 0x15bc: 0x4000, 0x15bd: 0x4000, 0x15be: 0x4000, 0x15bf: 0x4000, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x4000, 0x15c1: 0x4000, 0x15c2: 0x4000, 0x15c3: 0x4000, 0x15c4: 0x4000, 0x15c5: 0x4000, + 0x15c6: 0x4000, 0x15c7: 0x4000, 0x15c8: 0x4000, 0x15c9: 0x4000, 0x15ca: 0x4000, 0x15cb: 0x4000, + 0x15cc: 0x4000, 0x15cd: 0x4000, 0x15ce: 0x4000, 0x15cf: 0x4000, 0x15d0: 0x4000, 0x15d1: 0x4000, + 0x15d2: 0x4000, 0x15d3: 0x4000, 0x15d4: 0x4000, 0x15d5: 0x4000, 0x15d6: 0x4000, 0x15d7: 0x4000, + 0x15d8: 0x4000, 0x15d9: 0x4000, 0x15da: 0x4000, 0x15db: 0x4000, 0x15dc: 0x4000, 0x15dd: 0x4000, + 0x15de: 0x4000, 0x15df: 0x4000, 0x15e0: 0x4000, 0x15e1: 0x4000, 0x15e2: 0x4000, 0x15e3: 0x4000, + 0x15e4: 0x4000, 0x15e5: 0x4000, 0x15e6: 0x4000, 0x15e7: 0x4000, 0x15e8: 0x4000, 0x15e9: 0x4000, + 0x15ea: 0x4000, 0x15eb: 0x4000, 0x15ec: 0x4000, 0x15ed: 0x4000, 0x15ee: 0x4000, 0x15ef: 0x4000, + 0x15f0: 0x4000, 0x15f1: 0x4000, 0x15f2: 0x4000, 0x15f3: 0x4000, 0x15f4: 0x4000, 0x15f5: 0x4000, + 0x15f6: 0x4000, 0x15f7: 0x4000, 0x15f8: 0x4000, 0x15f9: 0x4000, 0x15fa: 0x4000, 0x15fb: 0x4000, + 0x15fc: 0x4000, 0x15ff: 0x4000, + // Block 0x58, offset 0x1600 + 0x1600: 0x4000, 0x1601: 0x4000, 0x1602: 0x4000, 0x1603: 0x4000, 0x1604: 0x4000, 0x1605: 0x4000, + 0x1606: 0x4000, 0x1607: 0x4000, 0x1608: 0x4000, 0x1609: 0x4000, 0x160a: 0x4000, 0x160b: 0x4000, + 0x160c: 0x4000, 0x160d: 0x4000, 0x160e: 0x4000, 0x160f: 0x4000, 0x1610: 0x4000, 0x1611: 0x4000, + 0x1612: 0x4000, 0x1613: 0x4000, 0x1614: 0x4000, 0x1615: 0x4000, 0x1616: 0x4000, 0x1617: 0x4000, + 0x1618: 0x4000, 0x1619: 0x4000, 0x161a: 0x4000, 0x161b: 0x4000, 0x161c: 0x4000, 0x161d: 0x4000, + 0x161e: 0x4000, 0x161f: 0x4000, 0x1620: 0x4000, 0x1621: 0x4000, 0x1622: 0x4000, 0x1623: 0x4000, + 0x1624: 0x4000, 0x1625: 0x4000, 0x1626: 0x4000, 0x1627: 0x4000, 0x1628: 0x4000, 0x1629: 0x4000, + 0x162a: 0x4000, 0x162b: 0x4000, 0x162c: 0x4000, 0x162d: 0x4000, 0x162e: 0x4000, 0x162f: 0x4000, + 0x1630: 0x4000, 0x1631: 0x4000, 0x1632: 0x4000, 0x1633: 0x4000, 0x1634: 0x4000, 0x1635: 0x4000, + 0x1636: 0x4000, 0x1637: 0x4000, 0x1638: 0x4000, 0x1639: 0x4000, 0x163a: 0x4000, 0x163b: 0x4000, + 0x163c: 0x4000, 0x163d: 0x4000, + // Block 0x59, offset 0x1640 + 0x164b: 0x4000, + 0x164c: 0x4000, 0x164d: 0x4000, 0x164e: 0x4000, 0x1650: 0x4000, 0x1651: 0x4000, + 0x1652: 0x4000, 0x1653: 0x4000, 0x1654: 0x4000, 0x1655: 0x4000, 0x1656: 0x4000, 0x1657: 0x4000, + 0x1658: 0x4000, 0x1659: 0x4000, 0x165a: 0x4000, 0x165b: 0x4000, 0x165c: 0x4000, 0x165d: 0x4000, + 0x165e: 0x4000, 0x165f: 0x4000, 0x1660: 0x4000, 0x1661: 0x4000, 0x1662: 0x4000, 0x1663: 0x4000, + 0x1664: 0x4000, 0x1665: 0x4000, 0x1666: 0x4000, 0x1667: 0x4000, + 0x167a: 0x4000, + // Block 0x5a, offset 0x1680 + 0x1695: 0x4000, 0x1696: 0x4000, + 0x16a4: 0x4000, + // Block 0x5b, offset 0x16c0 + 0x16fb: 0x4000, + 0x16fc: 0x4000, 0x16fd: 0x4000, 0x16fe: 0x4000, 0x16ff: 0x4000, + // Block 0x5c, offset 0x1700 + 0x1700: 0x4000, 0x1701: 0x4000, 0x1702: 0x4000, 0x1703: 0x4000, 0x1704: 0x4000, 0x1705: 0x4000, + 0x1706: 0x4000, 0x1707: 0x4000, 0x1708: 0x4000, 0x1709: 0x4000, 0x170a: 0x4000, 0x170b: 0x4000, + 0x170c: 0x4000, 0x170d: 0x4000, 0x170e: 0x4000, 0x170f: 0x4000, + // Block 0x5d, offset 0x1740 + 0x1740: 0x4000, 0x1741: 0x4000, 0x1742: 0x4000, 0x1743: 0x4000, 0x1744: 0x4000, 0x1745: 0x4000, + 0x174c: 0x4000, 0x1750: 0x4000, 0x1751: 0x4000, + 0x1752: 0x4000, + 0x176b: 0x4000, 0x176c: 0x4000, + 0x1774: 0x4000, 0x1775: 0x4000, + 0x1776: 0x4000, + // Block 0x5e, offset 0x1780 + 0x1790: 0x4000, 0x1791: 0x4000, + 0x1792: 0x4000, 0x1793: 0x4000, 0x1794: 0x4000, 0x1795: 0x4000, 0x1796: 0x4000, 0x1797: 0x4000, + 0x1798: 0x4000, 0x1799: 0x4000, 0x179a: 0x4000, 0x179b: 0x4000, 0x179c: 0x4000, 0x179d: 0x4000, + 0x179e: 0x4000, 0x17a0: 0x4000, 0x17a1: 0x4000, 0x17a2: 0x4000, 0x17a3: 0x4000, + 0x17a4: 0x4000, 0x17a5: 0x4000, 0x17a6: 0x4000, 0x17a7: 0x4000, + 0x17b0: 0x4000, 0x17b3: 0x4000, 0x17b4: 0x4000, 0x17b5: 0x4000, + 0x17b6: 0x4000, 0x17b7: 0x4000, 0x17b8: 0x4000, 0x17b9: 0x4000, 0x17ba: 0x4000, 0x17bb: 0x4000, + 0x17bc: 0x4000, 0x17bd: 0x4000, 0x17be: 0x4000, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x4000, 0x17c1: 0x4000, 0x17c2: 0x4000, 0x17c3: 0x4000, 0x17c4: 0x4000, 0x17c5: 0x4000, + 0x17c6: 0x4000, 0x17c7: 0x4000, 0x17c8: 0x4000, 0x17c9: 0x4000, 0x17ca: 0x4000, 0x17cb: 0x4000, + 0x17d0: 0x4000, 0x17d1: 0x4000, + 0x17d2: 0x4000, 0x17d3: 0x4000, 0x17d4: 0x4000, 0x17d5: 0x4000, 0x17d6: 0x4000, 0x17d7: 0x4000, + 0x17d8: 0x4000, 0x17d9: 0x4000, 0x17da: 0x4000, 0x17db: 0x4000, 0x17dc: 0x4000, 0x17dd: 0x4000, + 0x17de: 0x4000, + // Block 0x60, offset 0x1800 + 0x1800: 0x4000, 0x1801: 0x4000, 0x1802: 0x4000, 0x1803: 0x4000, 0x1804: 0x4000, 0x1805: 0x4000, + 0x1806: 0x4000, 0x1807: 0x4000, 0x1808: 0x4000, 0x1809: 0x4000, 0x180a: 0x4000, 0x180b: 0x4000, + 0x180c: 0x4000, 0x180d: 0x4000, 0x180e: 0x4000, 0x180f: 0x4000, 0x1810: 0x4000, 0x1811: 0x4000, + // Block 0x61, offset 0x1840 + 0x1840: 0x4000, + // Block 0x62, offset 0x1880 + 0x1880: 0x2000, 0x1881: 0x2000, 0x1882: 0x2000, 0x1883: 0x2000, 0x1884: 0x2000, 0x1885: 0x2000, + 0x1886: 0x2000, 0x1887: 0x2000, 0x1888: 0x2000, 0x1889: 0x2000, 0x188a: 0x2000, 0x188b: 0x2000, + 0x188c: 0x2000, 0x188d: 0x2000, 0x188e: 0x2000, 0x188f: 0x2000, 0x1890: 0x2000, 0x1891: 0x2000, + 0x1892: 0x2000, 0x1893: 0x2000, 0x1894: 0x2000, 0x1895: 0x2000, 0x1896: 0x2000, 0x1897: 0x2000, + 0x1898: 0x2000, 0x1899: 0x2000, 0x189a: 0x2000, 0x189b: 0x2000, 0x189c: 0x2000, 0x189d: 0x2000, + 0x189e: 0x2000, 0x189f: 0x2000, 0x18a0: 0x2000, 0x18a1: 0x2000, 0x18a2: 0x2000, 0x18a3: 0x2000, + 0x18a4: 0x2000, 0x18a5: 0x2000, 0x18a6: 0x2000, 0x18a7: 0x2000, 0x18a8: 0x2000, 0x18a9: 0x2000, + 0x18aa: 0x2000, 0x18ab: 0x2000, 0x18ac: 0x2000, 0x18ad: 0x2000, 0x18ae: 0x2000, 0x18af: 0x2000, + 0x18b0: 0x2000, 0x18b1: 0x2000, 0x18b2: 0x2000, 0x18b3: 0x2000, 0x18b4: 0x2000, 0x18b5: 0x2000, + 0x18b6: 0x2000, 0x18b7: 0x2000, 0x18b8: 0x2000, 0x18b9: 0x2000, 0x18ba: 0x2000, 0x18bb: 0x2000, + 0x18bc: 0x2000, 0x18bd: 0x2000, +} + +// widthIndex: 22 blocks, 1408 entries, 1408 bytes +// Block 0 is the zero block. +var widthIndex = [1408]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x02, 0xc4: 0x03, 0xc5: 0x04, 0xc7: 0x05, + 0xc9: 0x06, 0xcb: 0x07, 0xcc: 0x08, 0xcd: 0x09, 0xce: 0x0a, 0xcf: 0x0b, + 0xd0: 0x0c, 0xd1: 0x0d, + 0xe1: 0x02, 0xe2: 0x03, 0xe3: 0x04, 0xe4: 0x05, 0xe5: 0x06, 0xe6: 0x06, 0xe7: 0x06, + 0xe8: 0x06, 0xe9: 0x06, 0xea: 0x07, 0xeb: 0x06, 0xec: 0x06, 0xed: 0x08, 0xee: 0x09, 0xef: 0x0a, + 0xf0: 0x0f, 0xf3: 0x12, 0xf4: 0x13, + // Block 0x4, offset 0x100 + 0x104: 0x0e, 0x105: 0x0f, + // Block 0x5, offset 0x140 + 0x140: 0x10, 0x141: 0x11, 0x142: 0x12, 0x144: 0x13, 0x145: 0x14, 0x146: 0x15, 0x147: 0x16, + 0x148: 0x17, 0x149: 0x18, 0x14a: 0x19, 0x14c: 0x1a, 0x14f: 0x1b, + 0x151: 0x1c, 0x152: 0x08, 0x153: 0x1d, 0x154: 0x1e, 0x155: 0x1f, 0x156: 0x20, 0x157: 0x21, + 0x158: 0x22, 0x159: 0x23, 0x15a: 0x24, 0x15b: 0x25, 0x15c: 0x26, 0x15d: 0x27, 0x15e: 0x28, 0x15f: 0x29, + 0x166: 0x2a, + 0x16c: 0x2b, 0x16d: 0x2c, + 0x17a: 0x2d, 0x17b: 0x2e, 0x17c: 0x0e, 0x17d: 0x0e, 0x17e: 0x0e, 0x17f: 0x2f, + // Block 0x6, offset 0x180 + 0x180: 0x30, 0x181: 0x31, 0x182: 0x32, 0x183: 0x33, 0x184: 0x34, 0x185: 0x35, 0x186: 0x36, 0x187: 0x37, + 0x188: 0x38, 0x189: 0x39, 0x18a: 0x0e, 0x18b: 0x3a, 0x18c: 0x0e, 0x18d: 0x0e, 0x18e: 0x0e, 0x18f: 0x0e, + 0x190: 0x0e, 0x191: 0x0e, 0x192: 0x0e, 0x193: 0x0e, 0x194: 0x0e, 0x195: 0x0e, 0x196: 0x0e, 0x197: 0x0e, + 0x198: 0x0e, 0x199: 0x0e, 0x19a: 0x0e, 0x19b: 0x0e, 0x19c: 0x0e, 0x19d: 0x0e, 0x19e: 0x0e, 0x19f: 0x0e, + 0x1a0: 0x0e, 0x1a1: 0x0e, 0x1a2: 0x0e, 0x1a3: 0x0e, 0x1a4: 0x0e, 0x1a5: 0x0e, 0x1a6: 0x0e, 0x1a7: 0x0e, + 0x1a8: 0x0e, 0x1a9: 0x0e, 0x1aa: 0x0e, 0x1ab: 0x0e, 0x1ac: 0x0e, 0x1ad: 0x0e, 0x1ae: 0x0e, 0x1af: 0x0e, + 0x1b0: 0x0e, 0x1b1: 0x0e, 0x1b2: 0x0e, 0x1b3: 0x0e, 0x1b4: 0x0e, 0x1b5: 0x0e, 0x1b6: 0x0e, 0x1b7: 0x0e, + 0x1b8: 0x0e, 0x1b9: 0x0e, 0x1ba: 0x0e, 0x1bb: 0x0e, 0x1bc: 0x0e, 0x1bd: 0x0e, 0x1be: 0x0e, 0x1bf: 0x0e, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x0e, 0x1c1: 0x0e, 0x1c2: 0x0e, 0x1c3: 0x0e, 0x1c4: 0x0e, 0x1c5: 0x0e, 0x1c6: 0x0e, 0x1c7: 0x0e, + 0x1c8: 0x0e, 0x1c9: 0x0e, 0x1ca: 0x0e, 0x1cb: 0x0e, 0x1cc: 0x0e, 0x1cd: 0x0e, 0x1ce: 0x0e, 0x1cf: 0x0e, + 0x1d0: 0x0e, 0x1d1: 0x0e, 0x1d2: 0x0e, 0x1d3: 0x0e, 0x1d4: 0x0e, 0x1d5: 0x0e, 0x1d6: 0x0e, 0x1d7: 0x0e, + 0x1d8: 0x0e, 0x1d9: 0x0e, 0x1da: 0x0e, 0x1db: 0x0e, 0x1dc: 0x0e, 0x1dd: 0x0e, 0x1de: 0x0e, 0x1df: 0x0e, + 0x1e0: 0x0e, 0x1e1: 0x0e, 0x1e2: 0x0e, 0x1e3: 0x0e, 0x1e4: 0x0e, 0x1e5: 0x0e, 0x1e6: 0x0e, 0x1e7: 0x0e, + 0x1e8: 0x0e, 0x1e9: 0x0e, 0x1ea: 0x0e, 0x1eb: 0x0e, 0x1ec: 0x0e, 0x1ed: 0x0e, 0x1ee: 0x0e, 0x1ef: 0x0e, + 0x1f0: 0x0e, 0x1f1: 0x0e, 0x1f2: 0x0e, 0x1f3: 0x0e, 0x1f4: 0x0e, 0x1f5: 0x0e, 0x1f6: 0x0e, + 0x1f8: 0x0e, 0x1f9: 0x0e, 0x1fa: 0x0e, 0x1fb: 0x0e, 0x1fc: 0x0e, 0x1fd: 0x0e, 0x1fe: 0x0e, 0x1ff: 0x0e, + // Block 0x8, offset 0x200 + 0x200: 0x0e, 0x201: 0x0e, 0x202: 0x0e, 0x203: 0x0e, 0x204: 0x0e, 0x205: 0x0e, 0x206: 0x0e, 0x207: 0x0e, + 0x208: 0x0e, 0x209: 0x0e, 0x20a: 0x0e, 0x20b: 0x0e, 0x20c: 0x0e, 0x20d: 0x0e, 0x20e: 0x0e, 0x20f: 0x0e, + 0x210: 0x0e, 0x211: 0x0e, 0x212: 0x0e, 0x213: 0x0e, 0x214: 0x0e, 0x215: 0x0e, 0x216: 0x0e, 0x217: 0x0e, + 0x218: 0x0e, 0x219: 0x0e, 0x21a: 0x0e, 0x21b: 0x0e, 0x21c: 0x0e, 0x21d: 0x0e, 0x21e: 0x0e, 0x21f: 0x0e, + 0x220: 0x0e, 0x221: 0x0e, 0x222: 0x0e, 0x223: 0x0e, 0x224: 0x0e, 0x225: 0x0e, 0x226: 0x0e, 0x227: 0x0e, + 0x228: 0x0e, 0x229: 0x0e, 0x22a: 0x0e, 0x22b: 0x0e, 0x22c: 0x0e, 0x22d: 0x0e, 0x22e: 0x0e, 0x22f: 0x0e, + 0x230: 0x0e, 0x231: 0x0e, 0x232: 0x0e, 0x233: 0x0e, 0x234: 0x0e, 0x235: 0x0e, 0x236: 0x0e, 0x237: 0x0e, + 0x238: 0x0e, 0x239: 0x0e, 0x23a: 0x0e, 0x23b: 0x0e, 0x23c: 0x0e, 0x23d: 0x0e, 0x23e: 0x0e, 0x23f: 0x0e, + // Block 0x9, offset 0x240 + 0x240: 0x0e, 0x241: 0x0e, 0x242: 0x0e, 0x243: 0x0e, 0x244: 0x0e, 0x245: 0x0e, 0x246: 0x0e, 0x247: 0x0e, + 0x248: 0x0e, 0x249: 0x0e, 0x24a: 0x0e, 0x24b: 0x0e, 0x24c: 0x0e, 0x24d: 0x0e, 0x24e: 0x0e, 0x24f: 0x0e, + 0x250: 0x0e, 0x251: 0x0e, 0x252: 0x3b, 0x253: 0x3c, + 0x265: 0x3d, + 0x270: 0x0e, 0x271: 0x0e, 0x272: 0x0e, 0x273: 0x0e, 0x274: 0x0e, 0x275: 0x0e, 0x276: 0x0e, 0x277: 0x0e, + 0x278: 0x0e, 0x279: 0x0e, 0x27a: 0x0e, 0x27b: 0x0e, 0x27c: 0x0e, 0x27d: 0x0e, 0x27e: 0x0e, 0x27f: 0x0e, + // Block 0xa, offset 0x280 + 0x280: 0x0e, 0x281: 0x0e, 0x282: 0x0e, 0x283: 0x0e, 0x284: 0x0e, 0x285: 0x0e, 0x286: 0x0e, 0x287: 0x0e, + 0x288: 0x0e, 0x289: 0x0e, 0x28a: 0x0e, 0x28b: 0x0e, 0x28c: 0x0e, 0x28d: 0x0e, 0x28e: 0x0e, 0x28f: 0x0e, + 0x290: 0x0e, 0x291: 0x0e, 0x292: 0x0e, 0x293: 0x0e, 0x294: 0x0e, 0x295: 0x0e, 0x296: 0x0e, 0x297: 0x0e, + 0x298: 0x0e, 0x299: 0x0e, 0x29a: 0x0e, 0x29b: 0x0e, 0x29c: 0x0e, 0x29d: 0x0e, 0x29e: 0x3e, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x08, 0x2c1: 0x08, 0x2c2: 0x08, 0x2c3: 0x08, 0x2c4: 0x08, 0x2c5: 0x08, 0x2c6: 0x08, 0x2c7: 0x08, + 0x2c8: 0x08, 0x2c9: 0x08, 0x2ca: 0x08, 0x2cb: 0x08, 0x2cc: 0x08, 0x2cd: 0x08, 0x2ce: 0x08, 0x2cf: 0x08, + 0x2d0: 0x08, 0x2d1: 0x08, 0x2d2: 0x08, 0x2d3: 0x08, 0x2d4: 0x08, 0x2d5: 0x08, 0x2d6: 0x08, 0x2d7: 0x08, + 0x2d8: 0x08, 0x2d9: 0x08, 0x2da: 0x08, 0x2db: 0x08, 0x2dc: 0x08, 0x2dd: 0x08, 0x2de: 0x08, 0x2df: 0x08, + 0x2e0: 0x08, 0x2e1: 0x08, 0x2e2: 0x08, 0x2e3: 0x08, 0x2e4: 0x08, 0x2e5: 0x08, 0x2e6: 0x08, 0x2e7: 0x08, + 0x2e8: 0x08, 0x2e9: 0x08, 0x2ea: 0x08, 0x2eb: 0x08, 0x2ec: 0x08, 0x2ed: 0x08, 0x2ee: 0x08, 0x2ef: 0x08, + 0x2f0: 0x08, 0x2f1: 0x08, 0x2f2: 0x08, 0x2f3: 0x08, 0x2f4: 0x08, 0x2f5: 0x08, 0x2f6: 0x08, 0x2f7: 0x08, + 0x2f8: 0x08, 0x2f9: 0x08, 0x2fa: 0x08, 0x2fb: 0x08, 0x2fc: 0x08, 0x2fd: 0x08, 0x2fe: 0x08, 0x2ff: 0x08, + // Block 0xc, offset 0x300 + 0x300: 0x08, 0x301: 0x08, 0x302: 0x08, 0x303: 0x08, 0x304: 0x08, 0x305: 0x08, 0x306: 0x08, 0x307: 0x08, + 0x308: 0x08, 0x309: 0x08, 0x30a: 0x08, 0x30b: 0x08, 0x30c: 0x08, 0x30d: 0x08, 0x30e: 0x08, 0x30f: 0x08, + 0x310: 0x08, 0x311: 0x08, 0x312: 0x08, 0x313: 0x08, 0x314: 0x08, 0x315: 0x08, 0x316: 0x08, 0x317: 0x08, + 0x318: 0x08, 0x319: 0x08, 0x31a: 0x08, 0x31b: 0x08, 0x31c: 0x08, 0x31d: 0x08, 0x31e: 0x08, 0x31f: 0x08, + 0x320: 0x08, 0x321: 0x08, 0x322: 0x08, 0x323: 0x08, 0x324: 0x0e, 0x325: 0x0e, 0x326: 0x0e, 0x327: 0x0e, + 0x328: 0x0e, 0x329: 0x0e, 0x32a: 0x0e, 0x32b: 0x0e, + 0x338: 0x3f, 0x339: 0x40, 0x33c: 0x41, 0x33d: 0x42, 0x33e: 0x43, 0x33f: 0x44, + // Block 0xd, offset 0x340 + 0x37f: 0x45, + // Block 0xe, offset 0x380 + 0x380: 0x0e, 0x381: 0x0e, 0x382: 0x0e, 0x383: 0x0e, 0x384: 0x0e, 0x385: 0x0e, 0x386: 0x0e, 0x387: 0x0e, + 0x388: 0x0e, 0x389: 0x0e, 0x38a: 0x0e, 0x38b: 0x0e, 0x38c: 0x0e, 0x38d: 0x0e, 0x38e: 0x0e, 0x38f: 0x0e, + 0x390: 0x0e, 0x391: 0x0e, 0x392: 0x0e, 0x393: 0x0e, 0x394: 0x0e, 0x395: 0x0e, 0x396: 0x0e, 0x397: 0x0e, + 0x398: 0x0e, 0x399: 0x0e, 0x39a: 0x0e, 0x39b: 0x0e, 0x39c: 0x0e, 0x39d: 0x0e, 0x39e: 0x0e, 0x39f: 0x46, + 0x3a0: 0x0e, 0x3a1: 0x0e, 0x3a2: 0x0e, 0x3a3: 0x0e, 0x3a4: 0x0e, 0x3a5: 0x0e, 0x3a6: 0x0e, 0x3a7: 0x0e, + 0x3a8: 0x0e, 0x3a9: 0x0e, 0x3aa: 0x0e, 0x3ab: 0x47, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x48, + // Block 0x10, offset 0x400 + 0x400: 0x49, 0x403: 0x4a, 0x404: 0x4b, 0x405: 0x4c, 0x406: 0x4d, + 0x408: 0x4e, 0x409: 0x4f, 0x40c: 0x50, 0x40d: 0x51, 0x40e: 0x52, 0x40f: 0x53, + 0x410: 0x3a, 0x411: 0x54, 0x412: 0x0e, 0x413: 0x55, 0x414: 0x56, 0x415: 0x57, 0x416: 0x58, 0x417: 0x59, + 0x418: 0x0e, 0x419: 0x5a, 0x41a: 0x0e, 0x41b: 0x5b, + 0x424: 0x5c, 0x425: 0x5d, 0x426: 0x5e, 0x427: 0x5f, + // Block 0x11, offset 0x440 + 0x456: 0x0b, 0x457: 0x06, + 0x458: 0x0c, 0x45b: 0x0d, 0x45f: 0x0e, + 0x460: 0x06, 0x461: 0x06, 0x462: 0x06, 0x463: 0x06, 0x464: 0x06, 0x465: 0x06, 0x466: 0x06, 0x467: 0x06, + 0x468: 0x06, 0x469: 0x06, 0x46a: 0x06, 0x46b: 0x06, 0x46c: 0x06, 0x46d: 0x06, 0x46e: 0x06, 0x46f: 0x06, + 0x470: 0x06, 0x471: 0x06, 0x472: 0x06, 0x473: 0x06, 0x474: 0x06, 0x475: 0x06, 0x476: 0x06, 0x477: 0x06, + 0x478: 0x06, 0x479: 0x06, 0x47a: 0x06, 0x47b: 0x06, 0x47c: 0x06, 0x47d: 0x06, 0x47e: 0x06, 0x47f: 0x06, + // Block 0x12, offset 0x480 + 0x484: 0x08, 0x485: 0x08, 0x486: 0x08, 0x487: 0x09, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x08, 0x4c1: 0x08, 0x4c2: 0x08, 0x4c3: 0x08, 0x4c4: 0x08, 0x4c5: 0x08, 0x4c6: 0x08, 0x4c7: 0x08, + 0x4c8: 0x08, 0x4c9: 0x08, 0x4ca: 0x08, 0x4cb: 0x08, 0x4cc: 0x08, 0x4cd: 0x08, 0x4ce: 0x08, 0x4cf: 0x08, + 0x4d0: 0x08, 0x4d1: 0x08, 0x4d2: 0x08, 0x4d3: 0x08, 0x4d4: 0x08, 0x4d5: 0x08, 0x4d6: 0x08, 0x4d7: 0x08, + 0x4d8: 0x08, 0x4d9: 0x08, 0x4da: 0x08, 0x4db: 0x08, 0x4dc: 0x08, 0x4dd: 0x08, 0x4de: 0x08, 0x4df: 0x08, + 0x4e0: 0x08, 0x4e1: 0x08, 0x4e2: 0x08, 0x4e3: 0x08, 0x4e4: 0x08, 0x4e5: 0x08, 0x4e6: 0x08, 0x4e7: 0x08, + 0x4e8: 0x08, 0x4e9: 0x08, 0x4ea: 0x08, 0x4eb: 0x08, 0x4ec: 0x08, 0x4ed: 0x08, 0x4ee: 0x08, 0x4ef: 0x08, + 0x4f0: 0x08, 0x4f1: 0x08, 0x4f2: 0x08, 0x4f3: 0x08, 0x4f4: 0x08, 0x4f5: 0x08, 0x4f6: 0x08, 0x4f7: 0x08, + 0x4f8: 0x08, 0x4f9: 0x08, 0x4fa: 0x08, 0x4fb: 0x08, 0x4fc: 0x08, 0x4fd: 0x08, 0x4fe: 0x08, 0x4ff: 0x60, + // Block 0x14, offset 0x500 + 0x520: 0x10, + 0x530: 0x09, 0x531: 0x09, 0x532: 0x09, 0x533: 0x09, 0x534: 0x09, 0x535: 0x09, 0x536: 0x09, 0x537: 0x09, + 0x538: 0x09, 0x539: 0x09, 0x53a: 0x09, 0x53b: 0x09, 0x53c: 0x09, 0x53d: 0x09, 0x53e: 0x09, 0x53f: 0x11, + // Block 0x15, offset 0x540 + 0x540: 0x09, 0x541: 0x09, 0x542: 0x09, 0x543: 0x09, 0x544: 0x09, 0x545: 0x09, 0x546: 0x09, 0x547: 0x09, + 0x548: 0x09, 0x549: 0x09, 0x54a: 0x09, 0x54b: 0x09, 0x54c: 0x09, 0x54d: 0x09, 0x54e: 0x09, 0x54f: 0x11, +} + +// inverseData contains 4-byte entries of the following format: +// <0 padding> +// The last byte of the UTF-8-encoded rune is xor-ed with the last byte of the +// UTF-8 encoding of the original rune. Mappings often have the following +// pattern: +// A -> A (U+FF21 -> U+0041) +// B -> B (U+FF22 -> U+0042) +// ... +// By xor-ing the last byte the same entry can be shared by many mappings. This +// reduces the total number of distinct entries by about two thirds. +// The resulting entry for the aforementioned mappings is +// { 0x01, 0xE0, 0x00, 0x00 } +// Using this entry to map U+FF21 (UTF-8 [EF BC A1]), we get +// E0 ^ A1 = 41. +// Similarly, for U+FF22 (UTF-8 [EF BC A2]), we get +// E0 ^ A2 = 42. +// Note that because of the xor-ing, the byte sequence stored in the entry is +// not valid UTF-8. +var inverseData = [150][4]byte{ + {0x00, 0x00, 0x00, 0x00}, + {0x03, 0xe3, 0x80, 0xa0}, + {0x03, 0xef, 0xbc, 0xa0}, + {0x03, 0xef, 0xbc, 0xe0}, + {0x03, 0xef, 0xbd, 0xe0}, + {0x03, 0xef, 0xbf, 0x02}, + {0x03, 0xef, 0xbf, 0x00}, + {0x03, 0xef, 0xbf, 0x0e}, + {0x03, 0xef, 0xbf, 0x0c}, + {0x03, 0xef, 0xbf, 0x0f}, + {0x03, 0xef, 0xbf, 0x39}, + {0x03, 0xef, 0xbf, 0x3b}, + {0x03, 0xef, 0xbf, 0x3f}, + {0x03, 0xef, 0xbf, 0x2a}, + {0x03, 0xef, 0xbf, 0x0d}, + {0x03, 0xef, 0xbf, 0x25}, + {0x03, 0xef, 0xbd, 0x1a}, + {0x03, 0xef, 0xbd, 0x26}, + {0x01, 0xa0, 0x00, 0x00}, + {0x03, 0xef, 0xbd, 0x25}, + {0x03, 0xef, 0xbd, 0x23}, + {0x03, 0xef, 0xbd, 0x2e}, + {0x03, 0xef, 0xbe, 0x07}, + {0x03, 0xef, 0xbe, 0x05}, + {0x03, 0xef, 0xbd, 0x06}, + {0x03, 0xef, 0xbd, 0x13}, + {0x03, 0xef, 0xbd, 0x0b}, + {0x03, 0xef, 0xbd, 0x16}, + {0x03, 0xef, 0xbd, 0x0c}, + {0x03, 0xef, 0xbd, 0x15}, + {0x03, 0xef, 0xbd, 0x0d}, + {0x03, 0xef, 0xbd, 0x1c}, + {0x03, 0xef, 0xbd, 0x02}, + {0x03, 0xef, 0xbd, 0x1f}, + {0x03, 0xef, 0xbd, 0x1d}, + {0x03, 0xef, 0xbd, 0x17}, + {0x03, 0xef, 0xbd, 0x08}, + {0x03, 0xef, 0xbd, 0x09}, + {0x03, 0xef, 0xbd, 0x0e}, + {0x03, 0xef, 0xbd, 0x04}, + {0x03, 0xef, 0xbd, 0x05}, + {0x03, 0xef, 0xbe, 0x3f}, + {0x03, 0xef, 0xbe, 0x00}, + {0x03, 0xef, 0xbd, 0x2c}, + {0x03, 0xef, 0xbe, 0x06}, + {0x03, 0xef, 0xbe, 0x0c}, + {0x03, 0xef, 0xbe, 0x0f}, + {0x03, 0xef, 0xbe, 0x0d}, + {0x03, 0xef, 0xbe, 0x0b}, + {0x03, 0xef, 0xbe, 0x19}, + {0x03, 0xef, 0xbe, 0x15}, + {0x03, 0xef, 0xbe, 0x11}, + {0x03, 0xef, 0xbe, 0x31}, + {0x03, 0xef, 0xbe, 0x33}, + {0x03, 0xef, 0xbd, 0x0f}, + {0x03, 0xef, 0xbe, 0x30}, + {0x03, 0xef, 0xbe, 0x3e}, + {0x03, 0xef, 0xbe, 0x32}, + {0x03, 0xef, 0xbe, 0x36}, + {0x03, 0xef, 0xbd, 0x14}, + {0x03, 0xef, 0xbe, 0x2e}, + {0x03, 0xef, 0xbd, 0x1e}, + {0x03, 0xef, 0xbe, 0x10}, + {0x03, 0xef, 0xbf, 0x13}, + {0x03, 0xef, 0xbf, 0x15}, + {0x03, 0xef, 0xbf, 0x17}, + {0x03, 0xef, 0xbf, 0x1f}, + {0x03, 0xef, 0xbf, 0x1d}, + {0x03, 0xef, 0xbf, 0x1b}, + {0x03, 0xef, 0xbf, 0x09}, + {0x03, 0xef, 0xbf, 0x0b}, + {0x03, 0xef, 0xbf, 0x37}, + {0x03, 0xef, 0xbe, 0x04}, + {0x01, 0xe0, 0x00, 0x00}, + {0x03, 0xe2, 0xa6, 0x1a}, + {0x03, 0xe2, 0xa6, 0x26}, + {0x03, 0xe3, 0x80, 0x23}, + {0x03, 0xe3, 0x80, 0x2e}, + {0x03, 0xe3, 0x80, 0x25}, + {0x03, 0xe3, 0x83, 0x1e}, + {0x03, 0xe3, 0x83, 0x14}, + {0x03, 0xe3, 0x82, 0x06}, + {0x03, 0xe3, 0x82, 0x0b}, + {0x03, 0xe3, 0x82, 0x0c}, + {0x03, 0xe3, 0x82, 0x0d}, + {0x03, 0xe3, 0x82, 0x02}, + {0x03, 0xe3, 0x83, 0x0f}, + {0x03, 0xe3, 0x83, 0x08}, + {0x03, 0xe3, 0x83, 0x09}, + {0x03, 0xe3, 0x83, 0x2c}, + {0x03, 0xe3, 0x83, 0x0c}, + {0x03, 0xe3, 0x82, 0x13}, + {0x03, 0xe3, 0x82, 0x16}, + {0x03, 0xe3, 0x82, 0x15}, + {0x03, 0xe3, 0x82, 0x1c}, + {0x03, 0xe3, 0x82, 0x1f}, + {0x03, 0xe3, 0x82, 0x1d}, + {0x03, 0xe3, 0x82, 0x1a}, + {0x03, 0xe3, 0x82, 0x17}, + {0x03, 0xe3, 0x82, 0x08}, + {0x03, 0xe3, 0x82, 0x09}, + {0x03, 0xe3, 0x82, 0x0e}, + {0x03, 0xe3, 0x82, 0x04}, + {0x03, 0xe3, 0x82, 0x05}, + {0x03, 0xe3, 0x82, 0x3f}, + {0x03, 0xe3, 0x83, 0x00}, + {0x03, 0xe3, 0x83, 0x06}, + {0x03, 0xe3, 0x83, 0x05}, + {0x03, 0xe3, 0x83, 0x0d}, + {0x03, 0xe3, 0x83, 0x0b}, + {0x03, 0xe3, 0x83, 0x07}, + {0x03, 0xe3, 0x83, 0x19}, + {0x03, 0xe3, 0x83, 0x15}, + {0x03, 0xe3, 0x83, 0x11}, + {0x03, 0xe3, 0x83, 0x31}, + {0x03, 0xe3, 0x83, 0x33}, + {0x03, 0xe3, 0x83, 0x30}, + {0x03, 0xe3, 0x83, 0x3e}, + {0x03, 0xe3, 0x83, 0x32}, + {0x03, 0xe3, 0x83, 0x36}, + {0x03, 0xe3, 0x83, 0x2e}, + {0x03, 0xe3, 0x82, 0x07}, + {0x03, 0xe3, 0x85, 0x04}, + {0x03, 0xe3, 0x84, 0x10}, + {0x03, 0xe3, 0x85, 0x30}, + {0x03, 0xe3, 0x85, 0x0d}, + {0x03, 0xe3, 0x85, 0x13}, + {0x03, 0xe3, 0x85, 0x15}, + {0x03, 0xe3, 0x85, 0x17}, + {0x03, 0xe3, 0x85, 0x1f}, + {0x03, 0xe3, 0x85, 0x1d}, + {0x03, 0xe3, 0x85, 0x1b}, + {0x03, 0xe3, 0x85, 0x09}, + {0x03, 0xe3, 0x85, 0x0f}, + {0x03, 0xe3, 0x85, 0x0b}, + {0x03, 0xe3, 0x85, 0x37}, + {0x03, 0xe3, 0x85, 0x3b}, + {0x03, 0xe3, 0x85, 0x39}, + {0x03, 0xe3, 0x85, 0x3f}, + {0x02, 0xc2, 0x02, 0x00}, + {0x02, 0xc2, 0x0e, 0x00}, + {0x02, 0xc2, 0x0c, 0x00}, + {0x02, 0xc2, 0x00, 0x00}, + {0x03, 0xe2, 0x82, 0x0f}, + {0x03, 0xe2, 0x94, 0x2a}, + {0x03, 0xe2, 0x86, 0x39}, + {0x03, 0xe2, 0x86, 0x3b}, + {0x03, 0xe2, 0x86, 0x3f}, + {0x03, 0xe2, 0x96, 0x0d}, + {0x03, 0xe2, 0x97, 0x25}, +} + +// Total table size 14680 bytes (14KiB) diff --git a/vendor/golang.org/x/text/width/transform.go b/vendor/golang.org/x/text/width/transform.go new file mode 100644 index 000000000..0049f700a --- /dev/null +++ b/vendor/golang.org/x/text/width/transform.go @@ -0,0 +1,239 @@ +// Copyright 2015 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 width + +import ( + "unicode/utf8" + + "golang.org/x/text/transform" +) + +type foldTransform struct { + transform.NopResetter +} + +func (foldTransform) Span(src []byte, atEOF bool) (n int, err error) { + for n < len(src) { + if src[n] < utf8.RuneSelf { + // ASCII fast path. + for n++; n < len(src) && src[n] < utf8.RuneSelf; n++ { + } + continue + } + v, size := trie.lookup(src[n:]) + if size == 0 { // incomplete UTF-8 encoding + if !atEOF { + err = transform.ErrShortSrc + } else { + n = len(src) + } + break + } + if elem(v)&tagNeedsFold != 0 { + err = transform.ErrEndOfSpan + break + } + n += size + } + return n, err +} + +func (foldTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { + for nSrc < len(src) { + if src[nSrc] < utf8.RuneSelf { + // ASCII fast path. + start, end := nSrc, len(src) + if d := len(dst) - nDst; d < end-start { + end = nSrc + d + } + for nSrc++; nSrc < end && src[nSrc] < utf8.RuneSelf; nSrc++ { + } + n := copy(dst[nDst:], src[start:nSrc]) + if nDst += n; nDst == len(dst) { + nSrc = start + n + if nSrc == len(src) { + return nDst, nSrc, nil + } + if src[nSrc] < utf8.RuneSelf { + return nDst, nSrc, transform.ErrShortDst + } + } + continue + } + v, size := trie.lookup(src[nSrc:]) + if size == 0 { // incomplete UTF-8 encoding + if !atEOF { + return nDst, nSrc, transform.ErrShortSrc + } + size = 1 // gobble 1 byte + } + if elem(v)&tagNeedsFold == 0 { + if size != copy(dst[nDst:], src[nSrc:nSrc+size]) { + return nDst, nSrc, transform.ErrShortDst + } + nDst += size + } else { + data := inverseData[byte(v)] + if len(dst)-nDst < int(data[0]) { + return nDst, nSrc, transform.ErrShortDst + } + i := 1 + for end := int(data[0]); i < end; i++ { + dst[nDst] = data[i] + nDst++ + } + dst[nDst] = data[i] ^ src[nSrc+size-1] + nDst++ + } + nSrc += size + } + return nDst, nSrc, nil +} + +type narrowTransform struct { + transform.NopResetter +} + +func (narrowTransform) Span(src []byte, atEOF bool) (n int, err error) { + for n < len(src) { + if src[n] < utf8.RuneSelf { + // ASCII fast path. + for n++; n < len(src) && src[n] < utf8.RuneSelf; n++ { + } + continue + } + v, size := trie.lookup(src[n:]) + if size == 0 { // incomplete UTF-8 encoding + if !atEOF { + err = transform.ErrShortSrc + } else { + n = len(src) + } + break + } + if k := elem(v).kind(); byte(v) == 0 || k != EastAsianFullwidth && k != EastAsianWide && k != EastAsianAmbiguous { + } else { + err = transform.ErrEndOfSpan + break + } + n += size + } + return n, err +} + +func (narrowTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { + for nSrc < len(src) { + if src[nSrc] < utf8.RuneSelf { + // ASCII fast path. + start, end := nSrc, len(src) + if d := len(dst) - nDst; d < end-start { + end = nSrc + d + } + for nSrc++; nSrc < end && src[nSrc] < utf8.RuneSelf; nSrc++ { + } + n := copy(dst[nDst:], src[start:nSrc]) + if nDst += n; nDst == len(dst) { + nSrc = start + n + if nSrc == len(src) { + return nDst, nSrc, nil + } + if src[nSrc] < utf8.RuneSelf { + return nDst, nSrc, transform.ErrShortDst + } + } + continue + } + v, size := trie.lookup(src[nSrc:]) + if size == 0 { // incomplete UTF-8 encoding + if !atEOF { + return nDst, nSrc, transform.ErrShortSrc + } + size = 1 // gobble 1 byte + } + if k := elem(v).kind(); byte(v) == 0 || k != EastAsianFullwidth && k != EastAsianWide && k != EastAsianAmbiguous { + if size != copy(dst[nDst:], src[nSrc:nSrc+size]) { + return nDst, nSrc, transform.ErrShortDst + } + nDst += size + } else { + data := inverseData[byte(v)] + if len(dst)-nDst < int(data[0]) { + return nDst, nSrc, transform.ErrShortDst + } + i := 1 + for end := int(data[0]); i < end; i++ { + dst[nDst] = data[i] + nDst++ + } + dst[nDst] = data[i] ^ src[nSrc+size-1] + nDst++ + } + nSrc += size + } + return nDst, nSrc, nil +} + +type wideTransform struct { + transform.NopResetter +} + +func (wideTransform) Span(src []byte, atEOF bool) (n int, err error) { + for n < len(src) { + // TODO: Consider ASCII fast path. Special-casing ASCII handling can + // reduce the ns/op of BenchmarkWideASCII by about 30%. This is probably + // not enough to warrant the extra code and complexity. + v, size := trie.lookup(src[n:]) + if size == 0 { // incomplete UTF-8 encoding + if !atEOF { + err = transform.ErrShortSrc + } else { + n = len(src) + } + break + } + if k := elem(v).kind(); byte(v) == 0 || k != EastAsianHalfwidth && k != EastAsianNarrow { + } else { + err = transform.ErrEndOfSpan + break + } + n += size + } + return n, err +} + +func (wideTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { + for nSrc < len(src) { + // TODO: Consider ASCII fast path. Special-casing ASCII handling can + // reduce the ns/op of BenchmarkWideASCII by about 30%. This is probably + // not enough to warrant the extra code and complexity. + v, size := trie.lookup(src[nSrc:]) + if size == 0 { // incomplete UTF-8 encoding + if !atEOF { + return nDst, nSrc, transform.ErrShortSrc + } + size = 1 // gobble 1 byte + } + if k := elem(v).kind(); byte(v) == 0 || k != EastAsianHalfwidth && k != EastAsianNarrow { + if size != copy(dst[nDst:], src[nSrc:nSrc+size]) { + return nDst, nSrc, transform.ErrShortDst + } + nDst += size + } else { + data := inverseData[byte(v)] + if len(dst)-nDst < int(data[0]) { + return nDst, nSrc, transform.ErrShortDst + } + i := 1 + for end := int(data[0]); i < end; i++ { + dst[nDst] = data[i] + nDst++ + } + dst[nDst] = data[i] ^ src[nSrc+size-1] + nDst++ + } + nSrc += size + } + return nDst, nSrc, nil +} diff --git a/vendor/golang.org/x/text/width/trieval.go b/vendor/golang.org/x/text/width/trieval.go new file mode 100644 index 000000000..ca8e45fd1 --- /dev/null +++ b/vendor/golang.org/x/text/width/trieval.go @@ -0,0 +1,30 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package width + +// elem is an entry of the width trie. The high byte is used to encode the type +// of the rune. The low byte is used to store the index to a mapping entry in +// the inverseData array. +type elem uint16 + +const ( + tagNeutral elem = iota << typeShift + tagAmbiguous + tagWide + tagNarrow + tagFullwidth + tagHalfwidth +) + +const ( + numTypeBits = 3 + typeShift = 16 - numTypeBits + + // tagNeedsFold is true for all fullwidth and halfwidth runes except for + // the Won sign U+20A9. + tagNeedsFold = 0x1000 + + // The Korean Won sign is halfwidth, but SHOULD NOT be mapped to a wide + // variant. + wonSign rune = 0x20A9 +) diff --git a/vendor/golang.org/x/text/width/width.go b/vendor/golang.org/x/text/width/width.go new file mode 100644 index 000000000..29c7509be --- /dev/null +++ b/vendor/golang.org/x/text/width/width.go @@ -0,0 +1,206 @@ +// Copyright 2015 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. + +//go:generate stringer -type=Kind +//go:generate go run gen.go gen_common.go gen_trieval.go + +// Package width provides functionality for handling different widths in text. +// +// Wide characters behave like ideographs; they tend to allow line breaks after +// each character and remain upright in vertical text layout. Narrow characters +// are kept together in words or runs that are rotated sideways in vertical text +// layout. +// +// For more information, see https://unicode.org/reports/tr11/. +package width // import "golang.org/x/text/width" + +import ( + "unicode/utf8" + + "golang.org/x/text/transform" +) + +// TODO +// 1) Reduce table size by compressing blocks. +// 2) API proposition for computing display length +// (approximation, fixed pitch only). +// 3) Implement display length. + +// Kind indicates the type of width property as defined in https://unicode.org/reports/tr11/. +type Kind int + +const ( + // Neutral characters do not occur in legacy East Asian character sets. + Neutral Kind = iota + + // EastAsianAmbiguous characters that can be sometimes wide and sometimes + // narrow and require additional information not contained in the character + // code to further resolve their width. + EastAsianAmbiguous + + // EastAsianWide characters are wide in its usual form. They occur only in + // the context of East Asian typography. These runes may have explicit + // halfwidth counterparts. + EastAsianWide + + // EastAsianNarrow characters are narrow in its usual form. They often have + // fullwidth counterparts. + EastAsianNarrow + + // Note: there exist Narrow runes that do not have fullwidth or wide + // counterparts, despite what the definition says (e.g. U+27E6). + + // EastAsianFullwidth characters have a compatibility decompositions of type + // wide that map to a narrow counterpart. + EastAsianFullwidth + + // EastAsianHalfwidth characters have a compatibility decomposition of type + // narrow that map to a wide or ambiguous counterpart, plus U+20A9 ₩ WON + // SIGN. + EastAsianHalfwidth + + // Note: there exist runes that have a halfwidth counterparts but that are + // classified as Ambiguous, rather than wide (e.g. U+2190). +) + +// TODO: the generated tries need to return size 1 for invalid runes for the +// width to be computed correctly (each byte should render width 1) + +var trie = newWidthTrie(0) + +// Lookup reports the Properties of the first rune in b and the number of bytes +// of its UTF-8 encoding. +func Lookup(b []byte) (p Properties, size int) { + v, sz := trie.lookup(b) + return Properties{elem(v), b[sz-1]}, sz +} + +// LookupString reports the Properties of the first rune in s and the number of +// bytes of its UTF-8 encoding. +func LookupString(s string) (p Properties, size int) { + v, sz := trie.lookupString(s) + return Properties{elem(v), s[sz-1]}, sz +} + +// LookupRune reports the Properties of rune r. +func LookupRune(r rune) Properties { + var buf [4]byte + n := utf8.EncodeRune(buf[:], r) + v, _ := trie.lookup(buf[:n]) + last := byte(r) + if r >= utf8.RuneSelf { + last = 0x80 + byte(r&0x3f) + } + return Properties{elem(v), last} +} + +// Properties provides access to width properties of a rune. +type Properties struct { + elem elem + last byte +} + +func (e elem) kind() Kind { + return Kind(e >> typeShift) +} + +// Kind returns the Kind of a rune as defined in Unicode TR #11. +// See https://unicode.org/reports/tr11/ for more details. +func (p Properties) Kind() Kind { + return p.elem.kind() +} + +// Folded returns the folded variant of a rune or 0 if the rune is canonical. +func (p Properties) Folded() rune { + if p.elem&tagNeedsFold != 0 { + buf := inverseData[byte(p.elem)] + buf[buf[0]] ^= p.last + r, _ := utf8.DecodeRune(buf[1 : 1+buf[0]]) + return r + } + return 0 +} + +// Narrow returns the narrow variant of a rune or 0 if the rune is already +// narrow or doesn't have a narrow variant. +func (p Properties) Narrow() rune { + if k := p.elem.kind(); byte(p.elem) != 0 && (k == EastAsianFullwidth || k == EastAsianWide || k == EastAsianAmbiguous) { + buf := inverseData[byte(p.elem)] + buf[buf[0]] ^= p.last + r, _ := utf8.DecodeRune(buf[1 : 1+buf[0]]) + return r + } + return 0 +} + +// Wide returns the wide variant of a rune or 0 if the rune is already +// wide or doesn't have a wide variant. +func (p Properties) Wide() rune { + if k := p.elem.kind(); byte(p.elem) != 0 && (k == EastAsianHalfwidth || k == EastAsianNarrow) { + buf := inverseData[byte(p.elem)] + buf[buf[0]] ^= p.last + r, _ := utf8.DecodeRune(buf[1 : 1+buf[0]]) + return r + } + return 0 +} + +// TODO for Properties: +// - Add Fullwidth/Halfwidth or Inverted methods for computing variants +// mapping. +// - Add width information (including information on non-spacing runes). + +// Transformer implements the transform.Transformer interface. +type Transformer struct { + t transform.SpanningTransformer +} + +// Reset implements the transform.Transformer interface. +func (t Transformer) Reset() { t.t.Reset() } + +// Transform implements the transform.Transformer interface. +func (t Transformer) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { + return t.t.Transform(dst, src, atEOF) +} + +// Span implements the transform.SpanningTransformer interface. +func (t Transformer) Span(src []byte, atEOF bool) (n int, err error) { + return t.t.Span(src, atEOF) +} + +// Bytes returns a new byte slice with the result of applying t to b. +func (t Transformer) Bytes(b []byte) []byte { + b, _, _ = transform.Bytes(t, b) + return b +} + +// String returns a string with the result of applying t to s. +func (t Transformer) String(s string) string { + s, _, _ = transform.String(t, s) + return s +} + +var ( + // Fold is a transform that maps all runes to their canonical width. + // + // Note that the NFKC and NFKD transforms in golang.org/x/text/unicode/norm + // provide a more generic folding mechanism. + Fold Transformer = Transformer{foldTransform{}} + + // Widen is a transform that maps runes to their wide variant, if + // available. + Widen Transformer = Transformer{wideTransform{}} + + // Narrow is a transform that maps runes to their narrow variant, if + // available. + Narrow Transformer = Transformer{narrowTransform{}} +) + +// TODO: Consider the following options: +// - Treat Ambiguous runes that have a halfwidth counterpart as wide, or some +// generalized variant of this. +// - Consider a wide Won character to be the default width (or some generalized +// variant of this). +// - Filter the set of characters that gets converted (the preferred approach is +// to allow applying filters to transforms). diff --git a/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/cel_service.pb.go b/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/cel_service.pb.go new file mode 100644 index 000000000..5e66fac60 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/cel_service.pb.go @@ -0,0 +1,195 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/api/expr/v1alpha1/cel_service.proto + +package expr // import "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// CelServiceClient is the client API for CelService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type CelServiceClient interface { + // Transforms CEL source text into a parsed representation. + Parse(ctx context.Context, in *ParseRequest, opts ...grpc.CallOption) (*ParseResponse, error) + // Runs static checks on a parsed CEL representation and return + // an annotated representation, or a set of issues. + Check(ctx context.Context, in *CheckRequest, opts ...grpc.CallOption) (*CheckResponse, error) + // Evaluates a parsed or annotation CEL representation given + // values of external bindings. + Eval(ctx context.Context, in *EvalRequest, opts ...grpc.CallOption) (*EvalResponse, error) +} + +type celServiceClient struct { + cc *grpc.ClientConn +} + +func NewCelServiceClient(cc *grpc.ClientConn) CelServiceClient { + return &celServiceClient{cc} +} + +func (c *celServiceClient) Parse(ctx context.Context, in *ParseRequest, opts ...grpc.CallOption) (*ParseResponse, error) { + out := new(ParseResponse) + err := c.cc.Invoke(ctx, "/google.api.expr.v1alpha1.CelService/Parse", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *celServiceClient) Check(ctx context.Context, in *CheckRequest, opts ...grpc.CallOption) (*CheckResponse, error) { + out := new(CheckResponse) + err := c.cc.Invoke(ctx, "/google.api.expr.v1alpha1.CelService/Check", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *celServiceClient) Eval(ctx context.Context, in *EvalRequest, opts ...grpc.CallOption) (*EvalResponse, error) { + out := new(EvalResponse) + err := c.cc.Invoke(ctx, "/google.api.expr.v1alpha1.CelService/Eval", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// CelServiceServer is the server API for CelService service. +type CelServiceServer interface { + // Transforms CEL source text into a parsed representation. + Parse(context.Context, *ParseRequest) (*ParseResponse, error) + // Runs static checks on a parsed CEL representation and return + // an annotated representation, or a set of issues. + Check(context.Context, *CheckRequest) (*CheckResponse, error) + // Evaluates a parsed or annotation CEL representation given + // values of external bindings. + Eval(context.Context, *EvalRequest) (*EvalResponse, error) +} + +func RegisterCelServiceServer(s *grpc.Server, srv CelServiceServer) { + s.RegisterService(&_CelService_serviceDesc, srv) +} + +func _CelService_Parse_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ParseRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CelServiceServer).Parse(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.api.expr.v1alpha1.CelService/Parse", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CelServiceServer).Parse(ctx, req.(*ParseRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CelService_Check_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CheckRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CelServiceServer).Check(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.api.expr.v1alpha1.CelService/Check", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CelServiceServer).Check(ctx, req.(*CheckRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CelService_Eval_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EvalRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CelServiceServer).Eval(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.api.expr.v1alpha1.CelService/Eval", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CelServiceServer).Eval(ctx, req.(*EvalRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _CelService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "google.api.expr.v1alpha1.CelService", + HandlerType: (*CelServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Parse", + Handler: _CelService_Parse_Handler, + }, + { + MethodName: "Check", + Handler: _CelService_Check_Handler, + }, + { + MethodName: "Eval", + Handler: _CelService_Eval_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "google/api/expr/v1alpha1/cel_service.proto", +} + +func init() { + proto.RegisterFile("google/api/expr/v1alpha1/cel_service.proto", fileDescriptor_cel_service_082dfec354944354) +} + +var fileDescriptor_cel_service_082dfec354944354 = []byte{ + // 240 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0xd1, 0x31, 0x4b, 0xc4, 0x30, + 0x14, 0xc0, 0x71, 0x2b, 0xea, 0x90, 0x45, 0xc8, 0x24, 0x87, 0x93, 0xe0, 0x09, 0x0e, 0x09, 0x77, + 0x8e, 0x3a, 0xdd, 0xe1, 0x5e, 0x74, 0x10, 0x6e, 0x91, 0x67, 0x78, 0xe6, 0x82, 0x69, 0x5e, 0x4c, + 0x6a, 0xf1, 0xcb, 0xf8, 0x3d, 0x1d, 0x25, 0x69, 0xab, 0x88, 0xc4, 0xde, 0xd8, 0xbe, 0x5f, 0xfe, + 0x81, 0x17, 0x76, 0xa9, 0x89, 0xb4, 0x45, 0x09, 0xde, 0x48, 0x7c, 0xf7, 0x41, 0x76, 0x0b, 0xb0, + 0x7e, 0x0b, 0x0b, 0xa9, 0xd0, 0x3e, 0x46, 0x0c, 0x9d, 0x51, 0x28, 0x7c, 0xa0, 0x96, 0xf8, 0x49, + 0x6f, 0x05, 0x78, 0x23, 0x92, 0x15, 0xa3, 0x9d, 0x2d, 0xcb, 0x15, 0x72, 0xcf, 0x14, 0x1a, 0x70, + 0x0a, 0x7f, 0xd7, 0x96, 0x1f, 0xfb, 0x8c, 0xad, 0xd1, 0xde, 0xf7, 0x3f, 0xf9, 0x86, 0x1d, 0xd6, + 0x10, 0x22, 0xf2, 0xb9, 0x28, 0x5d, 0x23, 0x32, 0xb8, 0xc3, 0xd7, 0x37, 0x8c, 0xed, 0xec, 0x62, + 0xd2, 0x45, 0x4f, 0x2e, 0xe2, 0xd9, 0x5e, 0x6a, 0xaf, 0xb7, 0xa8, 0x5e, 0xfe, 0x6b, 0x67, 0xb0, + 0x43, 0x7b, 0x70, 0xdf, 0xed, 0x07, 0x76, 0x70, 0xdb, 0x81, 0xe5, 0xe7, 0xe5, 0x23, 0x69, 0x3e, + 0x96, 0xe7, 0x53, 0x6c, 0x0c, 0xaf, 0x02, 0x3b, 0x55, 0xd4, 0x14, 0xf9, 0xea, 0xf8, 0x67, 0x79, + 0x75, 0x5a, 0x68, 0x5d, 0x6d, 0x6e, 0x06, 0xac, 0xc9, 0x82, 0xd3, 0x82, 0x82, 0x96, 0x1a, 0x5d, + 0x5e, 0xb7, 0xec, 0x47, 0xe0, 0x4d, 0xfc, 0xfb, 0x4a, 0xd7, 0xe9, 0xeb, 0xb3, 0xaa, 0x9e, 0x8e, + 0xb2, 0xbd, 0xfa, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x3e, 0x97, 0x50, 0xb8, 0x16, 0x02, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/checked.pb.go b/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/checked.pb.go new file mode 100644 index 000000000..867074459 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/checked.pb.go @@ -0,0 +1,1428 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/api/expr/v1alpha1/checked.proto + +package expr // import "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import empty "github.com/golang/protobuf/ptypes/empty" +import _struct "github.com/golang/protobuf/ptypes/struct" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// CEL primitive types. +type Type_PrimitiveType int32 + +const ( + // Unspecified type. + Type_PRIMITIVE_TYPE_UNSPECIFIED Type_PrimitiveType = 0 + // Boolean type. + Type_BOOL Type_PrimitiveType = 1 + // Int64 type. + // + // Proto-based integer values are widened to int64. + Type_INT64 Type_PrimitiveType = 2 + // Uint64 type. + // + // Proto-based unsigned integer values are widened to uint64. + Type_UINT64 Type_PrimitiveType = 3 + // Double type. + // + // Proto-based float values are widened to double values. + Type_DOUBLE Type_PrimitiveType = 4 + // String type. + Type_STRING Type_PrimitiveType = 5 + // Bytes type. + Type_BYTES Type_PrimitiveType = 6 +) + +var Type_PrimitiveType_name = map[int32]string{ + 0: "PRIMITIVE_TYPE_UNSPECIFIED", + 1: "BOOL", + 2: "INT64", + 3: "UINT64", + 4: "DOUBLE", + 5: "STRING", + 6: "BYTES", +} +var Type_PrimitiveType_value = map[string]int32{ + "PRIMITIVE_TYPE_UNSPECIFIED": 0, + "BOOL": 1, + "INT64": 2, + "UINT64": 3, + "DOUBLE": 4, + "STRING": 5, + "BYTES": 6, +} + +func (x Type_PrimitiveType) String() string { + return proto.EnumName(Type_PrimitiveType_name, int32(x)) +} +func (Type_PrimitiveType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_checked_2fc1f80fa2b6cdfd, []int{1, 0} +} + +// Well-known protobuf types treated with first-class support in CEL. +type Type_WellKnownType int32 + +const ( + // Unspecified type. + Type_WELL_KNOWN_TYPE_UNSPECIFIED Type_WellKnownType = 0 + // Well-known protobuf.Any type. + // + // Any types are a polymorphic message type. During type-checking they are + // treated like `DYN` types, but at runtime they are resolved to a specific + // message type specified at evaluation time. + Type_ANY Type_WellKnownType = 1 + // Well-known protobuf.Timestamp type, internally referenced as `timestamp`. + Type_TIMESTAMP Type_WellKnownType = 2 + // Well-known protobuf.Duration type, internally referenced as `duration`. + Type_DURATION Type_WellKnownType = 3 +) + +var Type_WellKnownType_name = map[int32]string{ + 0: "WELL_KNOWN_TYPE_UNSPECIFIED", + 1: "ANY", + 2: "TIMESTAMP", + 3: "DURATION", +} +var Type_WellKnownType_value = map[string]int32{ + "WELL_KNOWN_TYPE_UNSPECIFIED": 0, + "ANY": 1, + "TIMESTAMP": 2, + "DURATION": 3, +} + +func (x Type_WellKnownType) String() string { + return proto.EnumName(Type_WellKnownType_name, int32(x)) +} +func (Type_WellKnownType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_checked_2fc1f80fa2b6cdfd, []int{1, 1} +} + +// A CEL expression which has been successfully type checked. +type CheckedExpr struct { + // A map from expression ids to resolved references. + // + // The following entries are in this table: + // + // - An Ident or Select expression is represented here if it resolves to a + // declaration. For instance, if `a.b.c` is represented by + // `select(select(id(a), b), c)`, and `a.b` resolves to a declaration, + // while `c` is a field selection, then the reference is attached to the + // nested select expression (but not to the id or or the outer select). + // In turn, if `a` resolves to a declaration and `b.c` are field selections, + // the reference is attached to the ident expression. + // - Every Call expression has an entry here, identifying the function being + // called. + // - Every CreateStruct expression for a message has an entry, identifying + // the message. + ReferenceMap map[int64]*Reference `protobuf:"bytes,2,rep,name=reference_map,json=referenceMap,proto3" json:"reference_map,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // A map from expression ids to types. + // + // Every expression node which has a type different than DYN has a mapping + // here. If an expression has type DYN, it is omitted from this map to save + // space. + TypeMap map[int64]*Type `protobuf:"bytes,3,rep,name=type_map,json=typeMap,proto3" json:"type_map,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // The source info derived from input that generated the parsed `expr` and + // any optimizations made during the type-checking pass. + SourceInfo *SourceInfo `protobuf:"bytes,5,opt,name=source_info,json=sourceInfo,proto3" json:"source_info,omitempty"` + // The checked expression. Semantically equivalent to the parsed `expr`, but + // may have structural differences. + Expr *Expr `protobuf:"bytes,4,opt,name=expr,proto3" json:"expr,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CheckedExpr) Reset() { *m = CheckedExpr{} } +func (m *CheckedExpr) String() string { return proto.CompactTextString(m) } +func (*CheckedExpr) ProtoMessage() {} +func (*CheckedExpr) Descriptor() ([]byte, []int) { + return fileDescriptor_checked_2fc1f80fa2b6cdfd, []int{0} +} +func (m *CheckedExpr) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CheckedExpr.Unmarshal(m, b) +} +func (m *CheckedExpr) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CheckedExpr.Marshal(b, m, deterministic) +} +func (dst *CheckedExpr) XXX_Merge(src proto.Message) { + xxx_messageInfo_CheckedExpr.Merge(dst, src) +} +func (m *CheckedExpr) XXX_Size() int { + return xxx_messageInfo_CheckedExpr.Size(m) +} +func (m *CheckedExpr) XXX_DiscardUnknown() { + xxx_messageInfo_CheckedExpr.DiscardUnknown(m) +} + +var xxx_messageInfo_CheckedExpr proto.InternalMessageInfo + +func (m *CheckedExpr) GetReferenceMap() map[int64]*Reference { + if m != nil { + return m.ReferenceMap + } + return nil +} + +func (m *CheckedExpr) GetTypeMap() map[int64]*Type { + if m != nil { + return m.TypeMap + } + return nil +} + +func (m *CheckedExpr) GetSourceInfo() *SourceInfo { + if m != nil { + return m.SourceInfo + } + return nil +} + +func (m *CheckedExpr) GetExpr() *Expr { + if m != nil { + return m.Expr + } + return nil +} + +// Represents a CEL type. +type Type struct { + // The kind of type. + // + // Types that are valid to be assigned to TypeKind: + // *Type_Dyn + // *Type_Null + // *Type_Primitive + // *Type_Wrapper + // *Type_WellKnown + // *Type_ListType_ + // *Type_MapType_ + // *Type_Function + // *Type_MessageType + // *Type_TypeParam + // *Type_Type + // *Type_Error + // *Type_AbstractType_ + TypeKind isType_TypeKind `protobuf_oneof:"type_kind"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Type) Reset() { *m = Type{} } +func (m *Type) String() string { return proto.CompactTextString(m) } +func (*Type) ProtoMessage() {} +func (*Type) Descriptor() ([]byte, []int) { + return fileDescriptor_checked_2fc1f80fa2b6cdfd, []int{1} +} +func (m *Type) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Type.Unmarshal(m, b) +} +func (m *Type) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Type.Marshal(b, m, deterministic) +} +func (dst *Type) XXX_Merge(src proto.Message) { + xxx_messageInfo_Type.Merge(dst, src) +} +func (m *Type) XXX_Size() int { + return xxx_messageInfo_Type.Size(m) +} +func (m *Type) XXX_DiscardUnknown() { + xxx_messageInfo_Type.DiscardUnknown(m) +} + +var xxx_messageInfo_Type proto.InternalMessageInfo + +type isType_TypeKind interface { + isType_TypeKind() +} + +type Type_Dyn struct { + Dyn *empty.Empty `protobuf:"bytes,1,opt,name=dyn,proto3,oneof"` +} + +type Type_Null struct { + Null _struct.NullValue `protobuf:"varint,2,opt,name=null,proto3,enum=google.protobuf.NullValue,oneof"` +} + +type Type_Primitive struct { + Primitive Type_PrimitiveType `protobuf:"varint,3,opt,name=primitive,proto3,enum=google.api.expr.v1alpha1.Type_PrimitiveType,oneof"` +} + +type Type_Wrapper struct { + Wrapper Type_PrimitiveType `protobuf:"varint,4,opt,name=wrapper,proto3,enum=google.api.expr.v1alpha1.Type_PrimitiveType,oneof"` +} + +type Type_WellKnown struct { + WellKnown Type_WellKnownType `protobuf:"varint,5,opt,name=well_known,json=wellKnown,proto3,enum=google.api.expr.v1alpha1.Type_WellKnownType,oneof"` +} + +type Type_ListType_ struct { + ListType *Type_ListType `protobuf:"bytes,6,opt,name=list_type,json=listType,proto3,oneof"` +} + +type Type_MapType_ struct { + MapType *Type_MapType `protobuf:"bytes,7,opt,name=map_type,json=mapType,proto3,oneof"` +} + +type Type_Function struct { + Function *Type_FunctionType `protobuf:"bytes,8,opt,name=function,proto3,oneof"` +} + +type Type_MessageType struct { + MessageType string `protobuf:"bytes,9,opt,name=message_type,json=messageType,proto3,oneof"` +} + +type Type_TypeParam struct { + TypeParam string `protobuf:"bytes,10,opt,name=type_param,json=typeParam,proto3,oneof"` +} + +type Type_Type struct { + Type *Type `protobuf:"bytes,11,opt,name=type,proto3,oneof"` +} + +type Type_Error struct { + Error *empty.Empty `protobuf:"bytes,12,opt,name=error,proto3,oneof"` +} + +type Type_AbstractType_ struct { + AbstractType *Type_AbstractType `protobuf:"bytes,14,opt,name=abstract_type,json=abstractType,proto3,oneof"` +} + +func (*Type_Dyn) isType_TypeKind() {} + +func (*Type_Null) isType_TypeKind() {} + +func (*Type_Primitive) isType_TypeKind() {} + +func (*Type_Wrapper) isType_TypeKind() {} + +func (*Type_WellKnown) isType_TypeKind() {} + +func (*Type_ListType_) isType_TypeKind() {} + +func (*Type_MapType_) isType_TypeKind() {} + +func (*Type_Function) isType_TypeKind() {} + +func (*Type_MessageType) isType_TypeKind() {} + +func (*Type_TypeParam) isType_TypeKind() {} + +func (*Type_Type) isType_TypeKind() {} + +func (*Type_Error) isType_TypeKind() {} + +func (*Type_AbstractType_) isType_TypeKind() {} + +func (m *Type) GetTypeKind() isType_TypeKind { + if m != nil { + return m.TypeKind + } + return nil +} + +func (m *Type) GetDyn() *empty.Empty { + if x, ok := m.GetTypeKind().(*Type_Dyn); ok { + return x.Dyn + } + return nil +} + +func (m *Type) GetNull() _struct.NullValue { + if x, ok := m.GetTypeKind().(*Type_Null); ok { + return x.Null + } + return _struct.NullValue_NULL_VALUE +} + +func (m *Type) GetPrimitive() Type_PrimitiveType { + if x, ok := m.GetTypeKind().(*Type_Primitive); ok { + return x.Primitive + } + return Type_PRIMITIVE_TYPE_UNSPECIFIED +} + +func (m *Type) GetWrapper() Type_PrimitiveType { + if x, ok := m.GetTypeKind().(*Type_Wrapper); ok { + return x.Wrapper + } + return Type_PRIMITIVE_TYPE_UNSPECIFIED +} + +func (m *Type) GetWellKnown() Type_WellKnownType { + if x, ok := m.GetTypeKind().(*Type_WellKnown); ok { + return x.WellKnown + } + return Type_WELL_KNOWN_TYPE_UNSPECIFIED +} + +func (m *Type) GetListType() *Type_ListType { + if x, ok := m.GetTypeKind().(*Type_ListType_); ok { + return x.ListType + } + return nil +} + +func (m *Type) GetMapType() *Type_MapType { + if x, ok := m.GetTypeKind().(*Type_MapType_); ok { + return x.MapType + } + return nil +} + +func (m *Type) GetFunction() *Type_FunctionType { + if x, ok := m.GetTypeKind().(*Type_Function); ok { + return x.Function + } + return nil +} + +func (m *Type) GetMessageType() string { + if x, ok := m.GetTypeKind().(*Type_MessageType); ok { + return x.MessageType + } + return "" +} + +func (m *Type) GetTypeParam() string { + if x, ok := m.GetTypeKind().(*Type_TypeParam); ok { + return x.TypeParam + } + return "" +} + +func (m *Type) GetType() *Type { + if x, ok := m.GetTypeKind().(*Type_Type); ok { + return x.Type + } + return nil +} + +func (m *Type) GetError() *empty.Empty { + if x, ok := m.GetTypeKind().(*Type_Error); ok { + return x.Error + } + return nil +} + +func (m *Type) GetAbstractType() *Type_AbstractType { + if x, ok := m.GetTypeKind().(*Type_AbstractType_); ok { + return x.AbstractType + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*Type) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _Type_OneofMarshaler, _Type_OneofUnmarshaler, _Type_OneofSizer, []interface{}{ + (*Type_Dyn)(nil), + (*Type_Null)(nil), + (*Type_Primitive)(nil), + (*Type_Wrapper)(nil), + (*Type_WellKnown)(nil), + (*Type_ListType_)(nil), + (*Type_MapType_)(nil), + (*Type_Function)(nil), + (*Type_MessageType)(nil), + (*Type_TypeParam)(nil), + (*Type_Type)(nil), + (*Type_Error)(nil), + (*Type_AbstractType_)(nil), + } +} + +func _Type_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*Type) + // type_kind + switch x := m.TypeKind.(type) { + case *Type_Dyn: + b.EncodeVarint(1<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Dyn); err != nil { + return err + } + case *Type_Null: + b.EncodeVarint(2<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.Null)) + case *Type_Primitive: + b.EncodeVarint(3<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.Primitive)) + case *Type_Wrapper: + b.EncodeVarint(4<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.Wrapper)) + case *Type_WellKnown: + b.EncodeVarint(5<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.WellKnown)) + case *Type_ListType_: + b.EncodeVarint(6<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.ListType); err != nil { + return err + } + case *Type_MapType_: + b.EncodeVarint(7<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.MapType); err != nil { + return err + } + case *Type_Function: + b.EncodeVarint(8<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Function); err != nil { + return err + } + case *Type_MessageType: + b.EncodeVarint(9<<3 | proto.WireBytes) + b.EncodeStringBytes(x.MessageType) + case *Type_TypeParam: + b.EncodeVarint(10<<3 | proto.WireBytes) + b.EncodeStringBytes(x.TypeParam) + case *Type_Type: + b.EncodeVarint(11<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Type); err != nil { + return err + } + case *Type_Error: + b.EncodeVarint(12<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Error); err != nil { + return err + } + case *Type_AbstractType_: + b.EncodeVarint(14<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.AbstractType); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("Type.TypeKind has unexpected type %T", x) + } + return nil +} + +func _Type_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*Type) + switch tag { + case 1: // type_kind.dyn + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(empty.Empty) + err := b.DecodeMessage(msg) + m.TypeKind = &Type_Dyn{msg} + return true, err + case 2: // type_kind.null + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.TypeKind = &Type_Null{_struct.NullValue(x)} + return true, err + case 3: // type_kind.primitive + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.TypeKind = &Type_Primitive{Type_PrimitiveType(x)} + return true, err + case 4: // type_kind.wrapper + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.TypeKind = &Type_Wrapper{Type_PrimitiveType(x)} + return true, err + case 5: // type_kind.well_known + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.TypeKind = &Type_WellKnown{Type_WellKnownType(x)} + return true, err + case 6: // type_kind.list_type + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Type_ListType) + err := b.DecodeMessage(msg) + m.TypeKind = &Type_ListType_{msg} + return true, err + case 7: // type_kind.map_type + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Type_MapType) + err := b.DecodeMessage(msg) + m.TypeKind = &Type_MapType_{msg} + return true, err + case 8: // type_kind.function + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Type_FunctionType) + err := b.DecodeMessage(msg) + m.TypeKind = &Type_Function{msg} + return true, err + case 9: // type_kind.message_type + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.TypeKind = &Type_MessageType{x} + return true, err + case 10: // type_kind.type_param + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.TypeKind = &Type_TypeParam{x} + return true, err + case 11: // type_kind.type + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Type) + err := b.DecodeMessage(msg) + m.TypeKind = &Type_Type{msg} + return true, err + case 12: // type_kind.error + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(empty.Empty) + err := b.DecodeMessage(msg) + m.TypeKind = &Type_Error{msg} + return true, err + case 14: // type_kind.abstract_type + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Type_AbstractType) + err := b.DecodeMessage(msg) + m.TypeKind = &Type_AbstractType_{msg} + return true, err + default: + return false, nil + } +} + +func _Type_OneofSizer(msg proto.Message) (n int) { + m := msg.(*Type) + // type_kind + switch x := m.TypeKind.(type) { + case *Type_Dyn: + s := proto.Size(x.Dyn) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Type_Null: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(x.Null)) + case *Type_Primitive: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(x.Primitive)) + case *Type_Wrapper: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(x.Wrapper)) + case *Type_WellKnown: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(x.WellKnown)) + case *Type_ListType_: + s := proto.Size(x.ListType) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Type_MapType_: + s := proto.Size(x.MapType) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Type_Function: + s := proto.Size(x.Function) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Type_MessageType: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(len(x.MessageType))) + n += len(x.MessageType) + case *Type_TypeParam: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(len(x.TypeParam))) + n += len(x.TypeParam) + case *Type_Type: + s := proto.Size(x.Type) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Type_Error: + s := proto.Size(x.Error) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Type_AbstractType_: + s := proto.Size(x.AbstractType) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +// List type with typed elements, e.g. `list`. +type Type_ListType struct { + // The element type. + ElemType *Type `protobuf:"bytes,1,opt,name=elem_type,json=elemType,proto3" json:"elem_type,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Type_ListType) Reset() { *m = Type_ListType{} } +func (m *Type_ListType) String() string { return proto.CompactTextString(m) } +func (*Type_ListType) ProtoMessage() {} +func (*Type_ListType) Descriptor() ([]byte, []int) { + return fileDescriptor_checked_2fc1f80fa2b6cdfd, []int{1, 0} +} +func (m *Type_ListType) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Type_ListType.Unmarshal(m, b) +} +func (m *Type_ListType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Type_ListType.Marshal(b, m, deterministic) +} +func (dst *Type_ListType) XXX_Merge(src proto.Message) { + xxx_messageInfo_Type_ListType.Merge(dst, src) +} +func (m *Type_ListType) XXX_Size() int { + return xxx_messageInfo_Type_ListType.Size(m) +} +func (m *Type_ListType) XXX_DiscardUnknown() { + xxx_messageInfo_Type_ListType.DiscardUnknown(m) +} + +var xxx_messageInfo_Type_ListType proto.InternalMessageInfo + +func (m *Type_ListType) GetElemType() *Type { + if m != nil { + return m.ElemType + } + return nil +} + +// Map type with parameterized key and value types, e.g. `map`. +type Type_MapType struct { + // The type of the key. + KeyType *Type `protobuf:"bytes,1,opt,name=key_type,json=keyType,proto3" json:"key_type,omitempty"` + // The type of the value. + ValueType *Type `protobuf:"bytes,2,opt,name=value_type,json=valueType,proto3" json:"value_type,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Type_MapType) Reset() { *m = Type_MapType{} } +func (m *Type_MapType) String() string { return proto.CompactTextString(m) } +func (*Type_MapType) ProtoMessage() {} +func (*Type_MapType) Descriptor() ([]byte, []int) { + return fileDescriptor_checked_2fc1f80fa2b6cdfd, []int{1, 1} +} +func (m *Type_MapType) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Type_MapType.Unmarshal(m, b) +} +func (m *Type_MapType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Type_MapType.Marshal(b, m, deterministic) +} +func (dst *Type_MapType) XXX_Merge(src proto.Message) { + xxx_messageInfo_Type_MapType.Merge(dst, src) +} +func (m *Type_MapType) XXX_Size() int { + return xxx_messageInfo_Type_MapType.Size(m) +} +func (m *Type_MapType) XXX_DiscardUnknown() { + xxx_messageInfo_Type_MapType.DiscardUnknown(m) +} + +var xxx_messageInfo_Type_MapType proto.InternalMessageInfo + +func (m *Type_MapType) GetKeyType() *Type { + if m != nil { + return m.KeyType + } + return nil +} + +func (m *Type_MapType) GetValueType() *Type { + if m != nil { + return m.ValueType + } + return nil +} + +// Function type with result and arg types. +type Type_FunctionType struct { + // Result type of the function. + ResultType *Type `protobuf:"bytes,1,opt,name=result_type,json=resultType,proto3" json:"result_type,omitempty"` + // Argument types of the function. + ArgTypes []*Type `protobuf:"bytes,2,rep,name=arg_types,json=argTypes,proto3" json:"arg_types,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Type_FunctionType) Reset() { *m = Type_FunctionType{} } +func (m *Type_FunctionType) String() string { return proto.CompactTextString(m) } +func (*Type_FunctionType) ProtoMessage() {} +func (*Type_FunctionType) Descriptor() ([]byte, []int) { + return fileDescriptor_checked_2fc1f80fa2b6cdfd, []int{1, 2} +} +func (m *Type_FunctionType) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Type_FunctionType.Unmarshal(m, b) +} +func (m *Type_FunctionType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Type_FunctionType.Marshal(b, m, deterministic) +} +func (dst *Type_FunctionType) XXX_Merge(src proto.Message) { + xxx_messageInfo_Type_FunctionType.Merge(dst, src) +} +func (m *Type_FunctionType) XXX_Size() int { + return xxx_messageInfo_Type_FunctionType.Size(m) +} +func (m *Type_FunctionType) XXX_DiscardUnknown() { + xxx_messageInfo_Type_FunctionType.DiscardUnknown(m) +} + +var xxx_messageInfo_Type_FunctionType proto.InternalMessageInfo + +func (m *Type_FunctionType) GetResultType() *Type { + if m != nil { + return m.ResultType + } + return nil +} + +func (m *Type_FunctionType) GetArgTypes() []*Type { + if m != nil { + return m.ArgTypes + } + return nil +} + +// Application defined abstract type. +type Type_AbstractType struct { + // The fully qualified name of this abstract type. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Parameter types for this abstract type. + ParameterTypes []*Type `protobuf:"bytes,2,rep,name=parameter_types,json=parameterTypes,proto3" json:"parameter_types,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Type_AbstractType) Reset() { *m = Type_AbstractType{} } +func (m *Type_AbstractType) String() string { return proto.CompactTextString(m) } +func (*Type_AbstractType) ProtoMessage() {} +func (*Type_AbstractType) Descriptor() ([]byte, []int) { + return fileDescriptor_checked_2fc1f80fa2b6cdfd, []int{1, 3} +} +func (m *Type_AbstractType) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Type_AbstractType.Unmarshal(m, b) +} +func (m *Type_AbstractType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Type_AbstractType.Marshal(b, m, deterministic) +} +func (dst *Type_AbstractType) XXX_Merge(src proto.Message) { + xxx_messageInfo_Type_AbstractType.Merge(dst, src) +} +func (m *Type_AbstractType) XXX_Size() int { + return xxx_messageInfo_Type_AbstractType.Size(m) +} +func (m *Type_AbstractType) XXX_DiscardUnknown() { + xxx_messageInfo_Type_AbstractType.DiscardUnknown(m) +} + +var xxx_messageInfo_Type_AbstractType proto.InternalMessageInfo + +func (m *Type_AbstractType) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Type_AbstractType) GetParameterTypes() []*Type { + if m != nil { + return m.ParameterTypes + } + return nil +} + +// Represents a declaration of a named value or function. +// +// A declaration is part of the contract between the expression, the agent +// evaluating that expression, and the caller requesting evaluation. +type Decl struct { + // The fully qualified name of the declaration. + // + // Declarations are organized in containers and this represents the full path + // to the declaration in its container, as in `google.api.expr.Decl`. + // + // Declarations used as + // [FunctionDecl.Overload][google.api.expr.v1alpha1.Decl.FunctionDecl.Overload] + // parameters may or may not have a name depending on whether the overload is + // function declaration or a function definition containing a result + // [Expr][google.api.expr.v1alpha1.Expr]. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Required. The declaration kind. + // + // Types that are valid to be assigned to DeclKind: + // *Decl_Ident + // *Decl_Function + DeclKind isDecl_DeclKind `protobuf_oneof:"decl_kind"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Decl) Reset() { *m = Decl{} } +func (m *Decl) String() string { return proto.CompactTextString(m) } +func (*Decl) ProtoMessage() {} +func (*Decl) Descriptor() ([]byte, []int) { + return fileDescriptor_checked_2fc1f80fa2b6cdfd, []int{2} +} +func (m *Decl) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Decl.Unmarshal(m, b) +} +func (m *Decl) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Decl.Marshal(b, m, deterministic) +} +func (dst *Decl) XXX_Merge(src proto.Message) { + xxx_messageInfo_Decl.Merge(dst, src) +} +func (m *Decl) XXX_Size() int { + return xxx_messageInfo_Decl.Size(m) +} +func (m *Decl) XXX_DiscardUnknown() { + xxx_messageInfo_Decl.DiscardUnknown(m) +} + +var xxx_messageInfo_Decl proto.InternalMessageInfo + +func (m *Decl) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +type isDecl_DeclKind interface { + isDecl_DeclKind() +} + +type Decl_Ident struct { + Ident *Decl_IdentDecl `protobuf:"bytes,2,opt,name=ident,proto3,oneof"` +} + +type Decl_Function struct { + Function *Decl_FunctionDecl `protobuf:"bytes,3,opt,name=function,proto3,oneof"` +} + +func (*Decl_Ident) isDecl_DeclKind() {} + +func (*Decl_Function) isDecl_DeclKind() {} + +func (m *Decl) GetDeclKind() isDecl_DeclKind { + if m != nil { + return m.DeclKind + } + return nil +} + +func (m *Decl) GetIdent() *Decl_IdentDecl { + if x, ok := m.GetDeclKind().(*Decl_Ident); ok { + return x.Ident + } + return nil +} + +func (m *Decl) GetFunction() *Decl_FunctionDecl { + if x, ok := m.GetDeclKind().(*Decl_Function); ok { + return x.Function + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*Decl) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _Decl_OneofMarshaler, _Decl_OneofUnmarshaler, _Decl_OneofSizer, []interface{}{ + (*Decl_Ident)(nil), + (*Decl_Function)(nil), + } +} + +func _Decl_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*Decl) + // decl_kind + switch x := m.DeclKind.(type) { + case *Decl_Ident: + b.EncodeVarint(2<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Ident); err != nil { + return err + } + case *Decl_Function: + b.EncodeVarint(3<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Function); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("Decl.DeclKind has unexpected type %T", x) + } + return nil +} + +func _Decl_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*Decl) + switch tag { + case 2: // decl_kind.ident + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Decl_IdentDecl) + err := b.DecodeMessage(msg) + m.DeclKind = &Decl_Ident{msg} + return true, err + case 3: // decl_kind.function + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Decl_FunctionDecl) + err := b.DecodeMessage(msg) + m.DeclKind = &Decl_Function{msg} + return true, err + default: + return false, nil + } +} + +func _Decl_OneofSizer(msg proto.Message) (n int) { + m := msg.(*Decl) + // decl_kind + switch x := m.DeclKind.(type) { + case *Decl_Ident: + s := proto.Size(x.Ident) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Decl_Function: + s := proto.Size(x.Function) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +// Identifier declaration which specifies its type and optional `Expr` value. +// +// An identifier without a value is a declaration that must be provided at +// evaluation time. An identifier with a value should resolve to a constant, +// but may be used in conjunction with other identifiers bound at evaluation +// time. +type Decl_IdentDecl struct { + // Required. The type of the identifier. + Type *Type `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + // The constant value of the identifier. If not specified, the identifier + // must be supplied at evaluation time. + Value *Constant `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + // Documentation string for the identifier. + Doc string `protobuf:"bytes,3,opt,name=doc,proto3" json:"doc,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Decl_IdentDecl) Reset() { *m = Decl_IdentDecl{} } +func (m *Decl_IdentDecl) String() string { return proto.CompactTextString(m) } +func (*Decl_IdentDecl) ProtoMessage() {} +func (*Decl_IdentDecl) Descriptor() ([]byte, []int) { + return fileDescriptor_checked_2fc1f80fa2b6cdfd, []int{2, 0} +} +func (m *Decl_IdentDecl) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Decl_IdentDecl.Unmarshal(m, b) +} +func (m *Decl_IdentDecl) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Decl_IdentDecl.Marshal(b, m, deterministic) +} +func (dst *Decl_IdentDecl) XXX_Merge(src proto.Message) { + xxx_messageInfo_Decl_IdentDecl.Merge(dst, src) +} +func (m *Decl_IdentDecl) XXX_Size() int { + return xxx_messageInfo_Decl_IdentDecl.Size(m) +} +func (m *Decl_IdentDecl) XXX_DiscardUnknown() { + xxx_messageInfo_Decl_IdentDecl.DiscardUnknown(m) +} + +var xxx_messageInfo_Decl_IdentDecl proto.InternalMessageInfo + +func (m *Decl_IdentDecl) GetType() *Type { + if m != nil { + return m.Type + } + return nil +} + +func (m *Decl_IdentDecl) GetValue() *Constant { + if m != nil { + return m.Value + } + return nil +} + +func (m *Decl_IdentDecl) GetDoc() string { + if m != nil { + return m.Doc + } + return "" +} + +// Function declaration specifies one or more overloads which indicate the +// function's parameter types and return type, and may optionally specify a +// function definition in terms of CEL expressions. +// +// Functions have no observable side-effects (there may be side-effects like +// logging which are not observable from CEL). +type Decl_FunctionDecl struct { + // Required. List of function overloads, must contain at least one overload. + Overloads []*Decl_FunctionDecl_Overload `protobuf:"bytes,1,rep,name=overloads,proto3" json:"overloads,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Decl_FunctionDecl) Reset() { *m = Decl_FunctionDecl{} } +func (m *Decl_FunctionDecl) String() string { return proto.CompactTextString(m) } +func (*Decl_FunctionDecl) ProtoMessage() {} +func (*Decl_FunctionDecl) Descriptor() ([]byte, []int) { + return fileDescriptor_checked_2fc1f80fa2b6cdfd, []int{2, 1} +} +func (m *Decl_FunctionDecl) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Decl_FunctionDecl.Unmarshal(m, b) +} +func (m *Decl_FunctionDecl) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Decl_FunctionDecl.Marshal(b, m, deterministic) +} +func (dst *Decl_FunctionDecl) XXX_Merge(src proto.Message) { + xxx_messageInfo_Decl_FunctionDecl.Merge(dst, src) +} +func (m *Decl_FunctionDecl) XXX_Size() int { + return xxx_messageInfo_Decl_FunctionDecl.Size(m) +} +func (m *Decl_FunctionDecl) XXX_DiscardUnknown() { + xxx_messageInfo_Decl_FunctionDecl.DiscardUnknown(m) +} + +var xxx_messageInfo_Decl_FunctionDecl proto.InternalMessageInfo + +func (m *Decl_FunctionDecl) GetOverloads() []*Decl_FunctionDecl_Overload { + if m != nil { + return m.Overloads + } + return nil +} + +// An overload indicates a function's parameter types and return type, and +// may optionally include a function body described in terms of +// [Expr][google.api.expr.v1alpha1.Expr] values. +// +// Functions overloads are declared in either a function or method +// call-style. For methods, the `params[0]` is the expected type of the +// target receiver. +// +// Overloads must have non-overlapping argument types after erasure of all +// parameterized type variables (similar as type erasure in Java). +type Decl_FunctionDecl_Overload struct { + // Required. Globally unique overload name of the function which reflects + // the function name and argument types. + // + // This will be used by a [Reference][google.api.expr.v1alpha1.Reference] + // to indicate the `overload_id` that was resolved for the function + // `name`. + OverloadId string `protobuf:"bytes,1,opt,name=overload_id,json=overloadId,proto3" json:"overload_id,omitempty"` + // List of function parameter [Type][google.api.expr.v1alpha1.Type] + // values. + // + // Param types are disjoint after generic type parameters have been + // replaced with the type `DYN`. Since the `DYN` type is compatible with + // any other type, this means that if `A` is a type parameter, the + // function types `int` and `int` are not disjoint. Likewise, + // `map` is not disjoint from `map`. + // + // When the `result_type` of a function is a generic type param, the + // type param name also appears as the `type` of on at least one params. + Params []*Type `protobuf:"bytes,2,rep,name=params,proto3" json:"params,omitempty"` + // The type param names associated with the function declaration. + // + // For example, `function ex(K key, map map) : V` would yield + // the type params of `K, V`. + TypeParams []string `protobuf:"bytes,3,rep,name=type_params,json=typeParams,proto3" json:"type_params,omitempty"` + // Required. The result type of the function. For example, the operator + // `string.isEmpty()` would have `result_type` of `kind: BOOL`. + ResultType *Type `protobuf:"bytes,4,opt,name=result_type,json=resultType,proto3" json:"result_type,omitempty"` + // Whether the function is to be used in a method call-style `x.f(...)` + // of a function call-style `f(x, ...)`. + // + // For methods, the first parameter declaration, `params[0]` is the + // expected type of the target receiver. + IsInstanceFunction bool `protobuf:"varint,5,opt,name=is_instance_function,json=isInstanceFunction,proto3" json:"is_instance_function,omitempty"` + // Documentation string for the overload. + Doc string `protobuf:"bytes,6,opt,name=doc,proto3" json:"doc,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Decl_FunctionDecl_Overload) Reset() { *m = Decl_FunctionDecl_Overload{} } +func (m *Decl_FunctionDecl_Overload) String() string { return proto.CompactTextString(m) } +func (*Decl_FunctionDecl_Overload) ProtoMessage() {} +func (*Decl_FunctionDecl_Overload) Descriptor() ([]byte, []int) { + return fileDescriptor_checked_2fc1f80fa2b6cdfd, []int{2, 1, 0} +} +func (m *Decl_FunctionDecl_Overload) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Decl_FunctionDecl_Overload.Unmarshal(m, b) +} +func (m *Decl_FunctionDecl_Overload) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Decl_FunctionDecl_Overload.Marshal(b, m, deterministic) +} +func (dst *Decl_FunctionDecl_Overload) XXX_Merge(src proto.Message) { + xxx_messageInfo_Decl_FunctionDecl_Overload.Merge(dst, src) +} +func (m *Decl_FunctionDecl_Overload) XXX_Size() int { + return xxx_messageInfo_Decl_FunctionDecl_Overload.Size(m) +} +func (m *Decl_FunctionDecl_Overload) XXX_DiscardUnknown() { + xxx_messageInfo_Decl_FunctionDecl_Overload.DiscardUnknown(m) +} + +var xxx_messageInfo_Decl_FunctionDecl_Overload proto.InternalMessageInfo + +func (m *Decl_FunctionDecl_Overload) GetOverloadId() string { + if m != nil { + return m.OverloadId + } + return "" +} + +func (m *Decl_FunctionDecl_Overload) GetParams() []*Type { + if m != nil { + return m.Params + } + return nil +} + +func (m *Decl_FunctionDecl_Overload) GetTypeParams() []string { + if m != nil { + return m.TypeParams + } + return nil +} + +func (m *Decl_FunctionDecl_Overload) GetResultType() *Type { + if m != nil { + return m.ResultType + } + return nil +} + +func (m *Decl_FunctionDecl_Overload) GetIsInstanceFunction() bool { + if m != nil { + return m.IsInstanceFunction + } + return false +} + +func (m *Decl_FunctionDecl_Overload) GetDoc() string { + if m != nil { + return m.Doc + } + return "" +} + +// Describes a resolved reference to a declaration. +type Reference struct { + // The fully qualified name of the declaration. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // For references to functions, this is a list of `Overload.overload_id` + // values which match according to typing rules. + // + // If the list has more than one element, overload resolution among the + // presented candidates must happen at runtime because of dynamic types. The + // type checker attempts to narrow down this list as much as possible. + // + // Empty if this is not a reference to a + // [Decl.FunctionDecl][google.api.expr.v1alpha1.Decl.FunctionDecl]. + OverloadId []string `protobuf:"bytes,3,rep,name=overload_id,json=overloadId,proto3" json:"overload_id,omitempty"` + // For references to constants, this may contain the value of the + // constant if known at compile time. + Value *Constant `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Reference) Reset() { *m = Reference{} } +func (m *Reference) String() string { return proto.CompactTextString(m) } +func (*Reference) ProtoMessage() {} +func (*Reference) Descriptor() ([]byte, []int) { + return fileDescriptor_checked_2fc1f80fa2b6cdfd, []int{3} +} +func (m *Reference) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Reference.Unmarshal(m, b) +} +func (m *Reference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Reference.Marshal(b, m, deterministic) +} +func (dst *Reference) XXX_Merge(src proto.Message) { + xxx_messageInfo_Reference.Merge(dst, src) +} +func (m *Reference) XXX_Size() int { + return xxx_messageInfo_Reference.Size(m) +} +func (m *Reference) XXX_DiscardUnknown() { + xxx_messageInfo_Reference.DiscardUnknown(m) +} + +var xxx_messageInfo_Reference proto.InternalMessageInfo + +func (m *Reference) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Reference) GetOverloadId() []string { + if m != nil { + return m.OverloadId + } + return nil +} + +func (m *Reference) GetValue() *Constant { + if m != nil { + return m.Value + } + return nil +} + +func init() { + proto.RegisterType((*CheckedExpr)(nil), "google.api.expr.v1alpha1.CheckedExpr") + proto.RegisterMapType((map[int64]*Reference)(nil), "google.api.expr.v1alpha1.CheckedExpr.ReferenceMapEntry") + proto.RegisterMapType((map[int64]*Type)(nil), "google.api.expr.v1alpha1.CheckedExpr.TypeMapEntry") + proto.RegisterType((*Type)(nil), "google.api.expr.v1alpha1.Type") + proto.RegisterType((*Type_ListType)(nil), "google.api.expr.v1alpha1.Type.ListType") + proto.RegisterType((*Type_MapType)(nil), "google.api.expr.v1alpha1.Type.MapType") + proto.RegisterType((*Type_FunctionType)(nil), "google.api.expr.v1alpha1.Type.FunctionType") + proto.RegisterType((*Type_AbstractType)(nil), "google.api.expr.v1alpha1.Type.AbstractType") + proto.RegisterType((*Decl)(nil), "google.api.expr.v1alpha1.Decl") + proto.RegisterType((*Decl_IdentDecl)(nil), "google.api.expr.v1alpha1.Decl.IdentDecl") + proto.RegisterType((*Decl_FunctionDecl)(nil), "google.api.expr.v1alpha1.Decl.FunctionDecl") + proto.RegisterType((*Decl_FunctionDecl_Overload)(nil), "google.api.expr.v1alpha1.Decl.FunctionDecl.Overload") + proto.RegisterType((*Reference)(nil), "google.api.expr.v1alpha1.Reference") + proto.RegisterEnum("google.api.expr.v1alpha1.Type_PrimitiveType", Type_PrimitiveType_name, Type_PrimitiveType_value) + proto.RegisterEnum("google.api.expr.v1alpha1.Type_WellKnownType", Type_WellKnownType_name, Type_WellKnownType_value) +} + +func init() { + proto.RegisterFile("google/api/expr/v1alpha1/checked.proto", fileDescriptor_checked_2fc1f80fa2b6cdfd) +} + +var fileDescriptor_checked_2fc1f80fa2b6cdfd = []byte{ + // 1144 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0x5f, 0x6f, 0xdb, 0xb6, + 0x17, 0x8d, 0x6c, 0xd9, 0x96, 0xae, 0x9c, 0xfe, 0xfc, 0x23, 0x86, 0x41, 0x50, 0x8b, 0x36, 0x70, + 0xb7, 0x2e, 0xd8, 0x06, 0xb9, 0xf5, 0x82, 0xae, 0x5d, 0x37, 0x6c, 0x71, 0xa2, 0x24, 0x42, 0xfd, + 0x0f, 0x8a, 0x93, 0x20, 0xc5, 0x00, 0x81, 0x91, 0x19, 0x57, 0xb0, 0x2c, 0x09, 0x94, 0x9c, 0xc4, + 0x7b, 0xdd, 0xd3, 0xb0, 0x7d, 0x9b, 0x7d, 0x89, 0x7d, 0x9a, 0xbd, 0x6e, 0x8f, 0x03, 0x29, 0xc9, + 0x71, 0xfe, 0x38, 0xb6, 0xdf, 0xae, 0xc8, 0x73, 0x0e, 0x2f, 0x2f, 0xcf, 0x25, 0x05, 0x2f, 0x06, + 0x41, 0x30, 0xf0, 0x48, 0x0d, 0x87, 0x6e, 0x8d, 0x5c, 0x85, 0xb4, 0x76, 0xf1, 0x0a, 0x7b, 0xe1, + 0x47, 0xfc, 0xaa, 0xe6, 0x7c, 0x24, 0xce, 0x90, 0xf4, 0xf5, 0x90, 0x06, 0x71, 0x80, 0xd4, 0x04, + 0xa7, 0xe3, 0xd0, 0xd5, 0x19, 0x4e, 0xcf, 0x70, 0xda, 0xe7, 0x73, 0x15, 0xa2, 0x89, 0x1f, 0xe3, + 0xab, 0x44, 0x40, 0x7b, 0x9c, 0xc2, 0xf8, 0xd7, 0xd9, 0xf8, 0xbc, 0x46, 0x46, 0x61, 0x3c, 0x49, + 0x27, 0x9f, 0xdc, 0x9e, 0x8c, 0x62, 0x3a, 0x76, 0xe2, 0x64, 0xb6, 0xfa, 0x4f, 0x1e, 0x94, 0x9d, + 0x24, 0x1b, 0xe3, 0x2a, 0xa4, 0xe8, 0x67, 0x58, 0xa7, 0xe4, 0x9c, 0x50, 0xe2, 0x3b, 0xc4, 0x1e, + 0xe1, 0x50, 0xcd, 0x6d, 0xe4, 0x37, 0x95, 0xfa, 0xb7, 0xfa, 0xbc, 0x1c, 0xf5, 0x19, 0xb6, 0x6e, + 0x65, 0xd4, 0x16, 0x0e, 0x0d, 0x3f, 0xa6, 0x13, 0xab, 0x4c, 0x67, 0x86, 0x50, 0x0b, 0xa4, 0x78, + 0x12, 0x26, 0xc2, 0x79, 0x2e, 0x5c, 0x5f, 0x4e, 0xb8, 0x37, 0x09, 0xaf, 0x35, 0x4b, 0x71, 0xf2, + 0x85, 0x0c, 0x50, 0xa2, 0x60, 0x4c, 0x1d, 0x62, 0xbb, 0xfe, 0x79, 0xa0, 0x16, 0x36, 0x84, 0x4d, + 0xa5, 0xfe, 0xd9, 0x7c, 0xc5, 0x43, 0x0e, 0x36, 0xfd, 0xf3, 0xc0, 0x82, 0x68, 0x1a, 0xa3, 0x3a, + 0x88, 0x0c, 0xa7, 0x8a, 0x9c, 0xff, 0x74, 0x3e, 0x9f, 0xa5, 0x62, 0x71, 0xac, 0xd6, 0x87, 0xff, + 0xdf, 0xd9, 0x2c, 0xaa, 0x40, 0x7e, 0x48, 0x26, 0xaa, 0xb0, 0x21, 0x6c, 0xe6, 0x2d, 0x16, 0xa2, + 0xb7, 0x50, 0xb8, 0xc0, 0xde, 0x98, 0xa8, 0x39, 0xae, 0xfd, 0x7c, 0xbe, 0xf6, 0x54, 0xcd, 0x4a, + 0x18, 0xdf, 0xe5, 0xde, 0x08, 0xda, 0x07, 0x28, 0xcf, 0xee, 0xfc, 0x9e, 0x05, 0xb6, 0x6e, 0x2e, + 0xf0, 0x40, 0xf2, 0x4c, 0x68, 0x46, 0xbb, 0xfa, 0x97, 0x02, 0x22, 0x1b, 0x43, 0x5f, 0x42, 0xbe, + 0x3f, 0xf1, 0xb9, 0xa8, 0x52, 0xff, 0x34, 0x13, 0xc8, 0xec, 0xa2, 0x1b, 0xcc, 0x4b, 0x07, 0x6b, + 0x16, 0x03, 0xa1, 0x97, 0x20, 0xfa, 0x63, 0xcf, 0xe3, 0xab, 0x3d, 0xaa, 0x6b, 0x77, 0xc0, 0xed, + 0xb1, 0xe7, 0x1d, 0xb3, 0x25, 0x0e, 0xd6, 0x2c, 0x8e, 0x44, 0x4d, 0x90, 0x43, 0xea, 0x8e, 0xdc, + 0xd8, 0xbd, 0x20, 0x6a, 0x9e, 0xd3, 0xbe, 0x7e, 0x38, 0x49, 0xbd, 0x9b, 0xe1, 0xd9, 0xd7, 0xc1, + 0x9a, 0x75, 0x2d, 0x80, 0x0e, 0xa0, 0x74, 0x49, 0x71, 0x18, 0x92, 0xe4, 0xb4, 0x56, 0xd7, 0xca, + 0xe8, 0xa8, 0x05, 0x70, 0x49, 0x3c, 0xcf, 0x1e, 0xfa, 0xc1, 0xa5, 0xcf, 0xad, 0xb3, 0x58, 0xec, + 0x84, 0x78, 0xde, 0x7b, 0x86, 0xcf, 0x12, 0xbb, 0xcc, 0x06, 0xd0, 0x1e, 0xc8, 0x9e, 0x1b, 0xc5, + 0x36, 0xb3, 0xa6, 0x5a, 0xe4, 0xa5, 0xfc, 0x62, 0x81, 0x5a, 0xd3, 0x8d, 0xe2, 0x54, 0x48, 0xf2, + 0xd2, 0x18, 0xed, 0x80, 0x34, 0xc2, 0x61, 0x22, 0x53, 0xe2, 0x32, 0x2f, 0x16, 0xc8, 0xb4, 0x70, + 0x98, 0xed, 0x6d, 0x94, 0x84, 0xc8, 0x04, 0xe9, 0x7c, 0xec, 0x3b, 0xb1, 0x1b, 0xf8, 0xaa, 0xc4, + 0x45, 0xbe, 0x5a, 0x20, 0xb2, 0x97, 0xc2, 0xb3, 0x7c, 0x32, 0x3a, 0x7a, 0x0e, 0xe5, 0x11, 0x89, + 0x22, 0x3c, 0x20, 0x49, 0x4e, 0xf2, 0x86, 0xb0, 0x29, 0x1f, 0xac, 0x59, 0x4a, 0x3a, 0xca, 0xd7, + 0x7b, 0x06, 0xc0, 0xdb, 0x3a, 0xc4, 0x14, 0x8f, 0x54, 0x48, 0x21, 0x32, 0x1b, 0xeb, 0xb2, 0x21, + 0xb4, 0x05, 0x22, 0x67, 0x2b, 0xcb, 0x98, 0x94, 0x59, 0x87, 0xa1, 0x91, 0x0e, 0x05, 0x42, 0x69, + 0x40, 0xd5, 0xf2, 0x02, 0x6b, 0x26, 0x30, 0x64, 0xc1, 0x3a, 0x3e, 0x8b, 0x62, 0x8a, 0x9d, 0xf4, + 0x1c, 0x1e, 0x2d, 0xb5, 0xf7, 0xed, 0x94, 0x93, 0xae, 0x5d, 0xc6, 0x33, 0xdf, 0xda, 0x3e, 0x48, + 0xd9, 0x39, 0xa1, 0x77, 0x20, 0x13, 0x8f, 0x8c, 0x12, 0x6d, 0x61, 0xa9, 0x7e, 0x93, 0x18, 0x81, + 0x0b, 0xfd, 0x2a, 0x40, 0x29, 0x3d, 0x2a, 0xf4, 0x16, 0xa4, 0x21, 0x99, 0xac, 0xa2, 0x53, 0x1a, + 0x92, 0x09, 0xa7, 0xfe, 0x00, 0xc0, 0x5b, 0x38, 0x21, 0x2f, 0xd7, 0xf4, 0x32, 0x67, 0xf0, 0x2c, + 0xfe, 0x10, 0xa0, 0x3c, 0x7b, 0xd6, 0xe8, 0x47, 0x50, 0x28, 0x89, 0xc6, 0x5e, 0xbc, 0x4a, 0x36, + 0x90, 0x50, 0xb2, 0xa2, 0x60, 0x3a, 0xe0, 0xec, 0x28, 0x7d, 0x2c, 0x16, 0x16, 0x05, 0xd3, 0x01, + 0x0b, 0x22, 0x6d, 0x08, 0xe5, 0xd9, 0xea, 0x23, 0x04, 0xa2, 0x8f, 0x47, 0x49, 0x1a, 0xb2, 0xc5, + 0x63, 0xb4, 0x0f, 0xff, 0xe3, 0xbe, 0x22, 0x31, 0xa1, 0x2b, 0x2d, 0xf3, 0x68, 0x4a, 0xe3, 0x8b, + 0x55, 0x23, 0x58, 0xbf, 0x71, 0x1b, 0xa0, 0xa7, 0xa0, 0x75, 0x2d, 0xb3, 0x65, 0xf6, 0xcc, 0x63, + 0xc3, 0xee, 0x9d, 0x76, 0x0d, 0xfb, 0xa8, 0x7d, 0xd8, 0x35, 0x76, 0xcc, 0x3d, 0xd3, 0xd8, 0xad, + 0xac, 0x21, 0x09, 0xc4, 0x46, 0xa7, 0xd3, 0xac, 0x08, 0x48, 0x86, 0x82, 0xd9, 0xee, 0xbd, 0xde, + 0xaa, 0xe4, 0x10, 0x40, 0xf1, 0x28, 0x89, 0xf3, 0x2c, 0xde, 0xed, 0x1c, 0x35, 0x9a, 0x46, 0x45, + 0x64, 0xf1, 0x61, 0xcf, 0x32, 0xdb, 0xfb, 0x95, 0x02, 0x83, 0x37, 0x4e, 0x7b, 0xc6, 0x61, 0xa5, + 0x58, 0x3d, 0x86, 0xf5, 0x1b, 0xb7, 0x06, 0x7a, 0x06, 0x8f, 0x4f, 0x8c, 0x66, 0xd3, 0x7e, 0xdf, + 0xee, 0x9c, 0xb4, 0xef, 0x5b, 0xb5, 0x04, 0xf9, 0xed, 0xf6, 0x69, 0x45, 0x40, 0xeb, 0x20, 0xf7, + 0xcc, 0x96, 0x71, 0xd8, 0xdb, 0x6e, 0x75, 0x2b, 0x39, 0x54, 0x06, 0x69, 0xf7, 0xc8, 0xda, 0xee, + 0x99, 0x9d, 0x76, 0x25, 0xdf, 0x50, 0x80, 0xb7, 0x97, 0x3d, 0x74, 0xfd, 0x7e, 0xf5, 0xcf, 0x02, + 0x88, 0xbb, 0xc4, 0xf1, 0xee, 0xad, 0xdf, 0x4f, 0x50, 0x70, 0xfb, 0xc4, 0x8f, 0x53, 0xb3, 0x6c, + 0xce, 0xaf, 0x1a, 0x93, 0xd0, 0x4d, 0x86, 0x65, 0x11, 0xeb, 0x2b, 0x4e, 0xbc, 0x71, 0x9d, 0xe4, + 0x17, 0xb5, 0x14, 0x17, 0xc9, 0x2c, 0x96, 0xea, 0x4c, 0xe9, 0xda, 0xef, 0x02, 0xc8, 0xd3, 0x15, + 0xd8, 0xc3, 0xbb, 0x82, 0xeb, 0x92, 0x4b, 0xe1, 0xcd, 0xcd, 0x07, 0xaf, 0xfa, 0xc0, 0xff, 0x43, + 0xe0, 0x47, 0x31, 0xf6, 0xe3, 0xf4, 0xd1, 0x63, 0x8f, 0x67, 0x3f, 0x70, 0xf8, 0x0e, 0x64, 0x8b, + 0x85, 0xda, 0xdf, 0xb9, 0xeb, 0x6e, 0xe0, 0x09, 0x59, 0x20, 0x07, 0x17, 0x84, 0x7a, 0x01, 0xee, + 0x47, 0xaa, 0xc0, 0x5d, 0xb6, 0xb5, 0xc2, 0x56, 0xf5, 0x4e, 0x4a, 0xb6, 0xae, 0x65, 0xb4, 0xdf, + 0x72, 0x20, 0x65, 0xe3, 0xe8, 0x19, 0x28, 0xd9, 0x8c, 0xed, 0xf6, 0xd3, 0x73, 0x82, 0x6c, 0xc8, + 0xec, 0xa3, 0xd7, 0x50, 0xe4, 0xb6, 0x5d, 0xd6, 0xe4, 0x29, 0x9a, 0x09, 0x5f, 0x5f, 0xc1, 0x11, + 0xff, 0xb9, 0x92, 0x2d, 0x98, 0xde, 0xc0, 0xd1, 0xed, 0x46, 0x17, 0x57, 0x6e, 0xf4, 0x97, 0xf0, + 0x89, 0x1b, 0xd9, 0x2e, 0xaf, 0xa9, 0x43, 0xec, 0xa9, 0x23, 0xd8, 0xd3, 0x29, 0x59, 0xc8, 0x8d, + 0xcc, 0x74, 0x2a, 0xab, 0x48, 0x56, 0xf0, 0xe2, 0xb4, 0xe0, 0xcc, 0xb5, 0x7d, 0xe2, 0x78, 0x89, + 0x6b, 0x7f, 0x01, 0x79, 0xfa, 0xd3, 0x73, 0xaf, 0x73, 0x6f, 0x15, 0x2b, 0xdd, 0xd3, 0x4c, 0xb1, + 0xa6, 0x5e, 0x10, 0x57, 0xf4, 0x42, 0xc3, 0x83, 0x27, 0x4e, 0x30, 0x9a, 0x8b, 0x6f, 0xc8, 0xec, + 0x38, 0xbb, 0xec, 0x9d, 0xe9, 0x0a, 0x1f, 0xbe, 0x4f, 0x61, 0x83, 0xc0, 0xc3, 0xfe, 0x40, 0x0f, + 0xe8, 0xa0, 0x36, 0x20, 0x3e, 0x7f, 0x85, 0x6a, 0xc9, 0x14, 0x0e, 0xdd, 0xe8, 0xee, 0x4f, 0xfa, + 0x3b, 0xf6, 0xf5, 0xaf, 0x20, 0x9c, 0x15, 0x39, 0xf6, 0x9b, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, + 0xee, 0x02, 0xe6, 0x8f, 0x11, 0x0c, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/conformance_service.pb.go b/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/conformance_service.pb.go new file mode 100644 index 000000000..0b1b4e2a8 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/conformance_service.pb.go @@ -0,0 +1,799 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/api/expr/v1alpha1/conformance_service.proto + +package expr // import "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import status "google.golang.org/genproto/googleapis/rpc/status" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// Severities of issues. +type IssueDetails_Severity int32 + +const ( + // An unspecified severity. + IssueDetails_SEVERITY_UNSPECIFIED IssueDetails_Severity = 0 + // Deprecation issue for statements and method that may no longer be + // supported or maintained. + IssueDetails_DEPRECATION IssueDetails_Severity = 1 + // Warnings such as: unused variables. + IssueDetails_WARNING IssueDetails_Severity = 2 + // Errors such as: unmatched curly braces or variable redefinition. + IssueDetails_ERROR IssueDetails_Severity = 3 +) + +var IssueDetails_Severity_name = map[int32]string{ + 0: "SEVERITY_UNSPECIFIED", + 1: "DEPRECATION", + 2: "WARNING", + 3: "ERROR", +} +var IssueDetails_Severity_value = map[string]int32{ + "SEVERITY_UNSPECIFIED": 0, + "DEPRECATION": 1, + "WARNING": 2, + "ERROR": 3, +} + +func (x IssueDetails_Severity) String() string { + return proto.EnumName(IssueDetails_Severity_name, int32(x)) +} +func (IssueDetails_Severity) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_conformance_service_61e1e6f4037f9b36, []int{6, 0} +} + +// Request message for the Parse method. +type ParseRequest struct { + // Required. Source text in CEL syntax. + CelSource string `protobuf:"bytes,1,opt,name=cel_source,json=celSource,proto3" json:"cel_source,omitempty"` + // Tag for version of CEL syntax, for future use. + SyntaxVersion string `protobuf:"bytes,2,opt,name=syntax_version,json=syntaxVersion,proto3" json:"syntax_version,omitempty"` + // File or resource for source text, used in + // [SourceInfo][google.api.expr.v1alpha1.SourceInfo]. + SourceLocation string `protobuf:"bytes,3,opt,name=source_location,json=sourceLocation,proto3" json:"source_location,omitempty"` + // Prevent macro expansion. See "Macros" in Language Defiinition. + DisableMacros bool `protobuf:"varint,4,opt,name=disable_macros,json=disableMacros,proto3" json:"disable_macros,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ParseRequest) Reset() { *m = ParseRequest{} } +func (m *ParseRequest) String() string { return proto.CompactTextString(m) } +func (*ParseRequest) ProtoMessage() {} +func (*ParseRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_conformance_service_61e1e6f4037f9b36, []int{0} +} +func (m *ParseRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ParseRequest.Unmarshal(m, b) +} +func (m *ParseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ParseRequest.Marshal(b, m, deterministic) +} +func (dst *ParseRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ParseRequest.Merge(dst, src) +} +func (m *ParseRequest) XXX_Size() int { + return xxx_messageInfo_ParseRequest.Size(m) +} +func (m *ParseRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ParseRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ParseRequest proto.InternalMessageInfo + +func (m *ParseRequest) GetCelSource() string { + if m != nil { + return m.CelSource + } + return "" +} + +func (m *ParseRequest) GetSyntaxVersion() string { + if m != nil { + return m.SyntaxVersion + } + return "" +} + +func (m *ParseRequest) GetSourceLocation() string { + if m != nil { + return m.SourceLocation + } + return "" +} + +func (m *ParseRequest) GetDisableMacros() bool { + if m != nil { + return m.DisableMacros + } + return false +} + +// Response message for the Parse method. +type ParseResponse struct { + // The parsed representation, or unset if parsing failed. + ParsedExpr *ParsedExpr `protobuf:"bytes,1,opt,name=parsed_expr,json=parsedExpr,proto3" json:"parsed_expr,omitempty"` + // Any number of issues with [StatusDetails][] as the details. + Issues []*status.Status `protobuf:"bytes,2,rep,name=issues,proto3" json:"issues,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ParseResponse) Reset() { *m = ParseResponse{} } +func (m *ParseResponse) String() string { return proto.CompactTextString(m) } +func (*ParseResponse) ProtoMessage() {} +func (*ParseResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_conformance_service_61e1e6f4037f9b36, []int{1} +} +func (m *ParseResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ParseResponse.Unmarshal(m, b) +} +func (m *ParseResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ParseResponse.Marshal(b, m, deterministic) +} +func (dst *ParseResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ParseResponse.Merge(dst, src) +} +func (m *ParseResponse) XXX_Size() int { + return xxx_messageInfo_ParseResponse.Size(m) +} +func (m *ParseResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ParseResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ParseResponse proto.InternalMessageInfo + +func (m *ParseResponse) GetParsedExpr() *ParsedExpr { + if m != nil { + return m.ParsedExpr + } + return nil +} + +func (m *ParseResponse) GetIssues() []*status.Status { + if m != nil { + return m.Issues + } + return nil +} + +// Request message for the Check method. +type CheckRequest struct { + // Required. The parsed representation of the CEL program. + ParsedExpr *ParsedExpr `protobuf:"bytes,1,opt,name=parsed_expr,json=parsedExpr,proto3" json:"parsed_expr,omitempty"` + // Declarations of types for external variables and functions. + // Required if program uses external variables or functions + // not in the default environment. + TypeEnv []*Decl `protobuf:"bytes,2,rep,name=type_env,json=typeEnv,proto3" json:"type_env,omitempty"` + // The protocol buffer context. See "Name Resolution" in the + // Language Definition. + Container string `protobuf:"bytes,3,opt,name=container,proto3" json:"container,omitempty"` + // If true, use only the declarations in + // [type_env][google.api.expr.v1alpha1.CheckRequest.type_env]. If false + // (default), add declarations for the standard definitions to the type + // environment. See "Standard Definitions" in the Language Definition. + NoStdEnv bool `protobuf:"varint,4,opt,name=no_std_env,json=noStdEnv,proto3" json:"no_std_env,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CheckRequest) Reset() { *m = CheckRequest{} } +func (m *CheckRequest) String() string { return proto.CompactTextString(m) } +func (*CheckRequest) ProtoMessage() {} +func (*CheckRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_conformance_service_61e1e6f4037f9b36, []int{2} +} +func (m *CheckRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CheckRequest.Unmarshal(m, b) +} +func (m *CheckRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CheckRequest.Marshal(b, m, deterministic) +} +func (dst *CheckRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CheckRequest.Merge(dst, src) +} +func (m *CheckRequest) XXX_Size() int { + return xxx_messageInfo_CheckRequest.Size(m) +} +func (m *CheckRequest) XXX_DiscardUnknown() { + xxx_messageInfo_CheckRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_CheckRequest proto.InternalMessageInfo + +func (m *CheckRequest) GetParsedExpr() *ParsedExpr { + if m != nil { + return m.ParsedExpr + } + return nil +} + +func (m *CheckRequest) GetTypeEnv() []*Decl { + if m != nil { + return m.TypeEnv + } + return nil +} + +func (m *CheckRequest) GetContainer() string { + if m != nil { + return m.Container + } + return "" +} + +func (m *CheckRequest) GetNoStdEnv() bool { + if m != nil { + return m.NoStdEnv + } + return false +} + +// Response message for the Check method. +type CheckResponse struct { + // The annotated representation, or unset if checking failed. + CheckedExpr *CheckedExpr `protobuf:"bytes,1,opt,name=checked_expr,json=checkedExpr,proto3" json:"checked_expr,omitempty"` + // Any number of issues with [StatusDetails][] as the details. + Issues []*status.Status `protobuf:"bytes,2,rep,name=issues,proto3" json:"issues,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CheckResponse) Reset() { *m = CheckResponse{} } +func (m *CheckResponse) String() string { return proto.CompactTextString(m) } +func (*CheckResponse) ProtoMessage() {} +func (*CheckResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_conformance_service_61e1e6f4037f9b36, []int{3} +} +func (m *CheckResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CheckResponse.Unmarshal(m, b) +} +func (m *CheckResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CheckResponse.Marshal(b, m, deterministic) +} +func (dst *CheckResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CheckResponse.Merge(dst, src) +} +func (m *CheckResponse) XXX_Size() int { + return xxx_messageInfo_CheckResponse.Size(m) +} +func (m *CheckResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CheckResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CheckResponse proto.InternalMessageInfo + +func (m *CheckResponse) GetCheckedExpr() *CheckedExpr { + if m != nil { + return m.CheckedExpr + } + return nil +} + +func (m *CheckResponse) GetIssues() []*status.Status { + if m != nil { + return m.Issues + } + return nil +} + +// Request message for the Eval method. +type EvalRequest struct { + // Required. Either the parsed or annotated representation of the CEL program. + // + // Types that are valid to be assigned to ExprKind: + // *EvalRequest_ParsedExpr + // *EvalRequest_CheckedExpr + ExprKind isEvalRequest_ExprKind `protobuf_oneof:"expr_kind"` + // Bindings for the external variables. The types SHOULD be compatible + // with the type environment in + // [CheckRequest][google.api.expr.v1alpha1.CheckRequest], if checked. + Bindings map[string]*ExprValue `protobuf:"bytes,3,rep,name=bindings,proto3" json:"bindings,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // SHOULD be the same container as used in + // [CheckRequest][google.api.expr.v1alpha1.CheckRequest], if checked. + Container string `protobuf:"bytes,4,opt,name=container,proto3" json:"container,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EvalRequest) Reset() { *m = EvalRequest{} } +func (m *EvalRequest) String() string { return proto.CompactTextString(m) } +func (*EvalRequest) ProtoMessage() {} +func (*EvalRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_conformance_service_61e1e6f4037f9b36, []int{4} +} +func (m *EvalRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EvalRequest.Unmarshal(m, b) +} +func (m *EvalRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EvalRequest.Marshal(b, m, deterministic) +} +func (dst *EvalRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_EvalRequest.Merge(dst, src) +} +func (m *EvalRequest) XXX_Size() int { + return xxx_messageInfo_EvalRequest.Size(m) +} +func (m *EvalRequest) XXX_DiscardUnknown() { + xxx_messageInfo_EvalRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_EvalRequest proto.InternalMessageInfo + +type isEvalRequest_ExprKind interface { + isEvalRequest_ExprKind() +} + +type EvalRequest_ParsedExpr struct { + ParsedExpr *ParsedExpr `protobuf:"bytes,1,opt,name=parsed_expr,json=parsedExpr,proto3,oneof"` +} + +type EvalRequest_CheckedExpr struct { + CheckedExpr *CheckedExpr `protobuf:"bytes,2,opt,name=checked_expr,json=checkedExpr,proto3,oneof"` +} + +func (*EvalRequest_ParsedExpr) isEvalRequest_ExprKind() {} + +func (*EvalRequest_CheckedExpr) isEvalRequest_ExprKind() {} + +func (m *EvalRequest) GetExprKind() isEvalRequest_ExprKind { + if m != nil { + return m.ExprKind + } + return nil +} + +func (m *EvalRequest) GetParsedExpr() *ParsedExpr { + if x, ok := m.GetExprKind().(*EvalRequest_ParsedExpr); ok { + return x.ParsedExpr + } + return nil +} + +func (m *EvalRequest) GetCheckedExpr() *CheckedExpr { + if x, ok := m.GetExprKind().(*EvalRequest_CheckedExpr); ok { + return x.CheckedExpr + } + return nil +} + +func (m *EvalRequest) GetBindings() map[string]*ExprValue { + if m != nil { + return m.Bindings + } + return nil +} + +func (m *EvalRequest) GetContainer() string { + if m != nil { + return m.Container + } + return "" +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*EvalRequest) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _EvalRequest_OneofMarshaler, _EvalRequest_OneofUnmarshaler, _EvalRequest_OneofSizer, []interface{}{ + (*EvalRequest_ParsedExpr)(nil), + (*EvalRequest_CheckedExpr)(nil), + } +} + +func _EvalRequest_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*EvalRequest) + // expr_kind + switch x := m.ExprKind.(type) { + case *EvalRequest_ParsedExpr: + b.EncodeVarint(1<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.ParsedExpr); err != nil { + return err + } + case *EvalRequest_CheckedExpr: + b.EncodeVarint(2<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.CheckedExpr); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("EvalRequest.ExprKind has unexpected type %T", x) + } + return nil +} + +func _EvalRequest_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*EvalRequest) + switch tag { + case 1: // expr_kind.parsed_expr + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(ParsedExpr) + err := b.DecodeMessage(msg) + m.ExprKind = &EvalRequest_ParsedExpr{msg} + return true, err + case 2: // expr_kind.checked_expr + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(CheckedExpr) + err := b.DecodeMessage(msg) + m.ExprKind = &EvalRequest_CheckedExpr{msg} + return true, err + default: + return false, nil + } +} + +func _EvalRequest_OneofSizer(msg proto.Message) (n int) { + m := msg.(*EvalRequest) + // expr_kind + switch x := m.ExprKind.(type) { + case *EvalRequest_ParsedExpr: + s := proto.Size(x.ParsedExpr) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *EvalRequest_CheckedExpr: + s := proto.Size(x.CheckedExpr) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +// Response message for the Eval method. +type EvalResponse struct { + // The execution result, or unset if execution couldn't start. + Result *ExprValue `protobuf:"bytes,1,opt,name=result,proto3" json:"result,omitempty"` + // Any number of issues with [StatusDetails][] as the details. + // Note that CEL execution errors are reified into + // [ExprValue][google.api.expr.v1alpha1.ExprValue]. Nevertheless, we'll allow + // out-of-band issues to be raised, which also makes the replies more regular. + Issues []*status.Status `protobuf:"bytes,2,rep,name=issues,proto3" json:"issues,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EvalResponse) Reset() { *m = EvalResponse{} } +func (m *EvalResponse) String() string { return proto.CompactTextString(m) } +func (*EvalResponse) ProtoMessage() {} +func (*EvalResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_conformance_service_61e1e6f4037f9b36, []int{5} +} +func (m *EvalResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EvalResponse.Unmarshal(m, b) +} +func (m *EvalResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EvalResponse.Marshal(b, m, deterministic) +} +func (dst *EvalResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_EvalResponse.Merge(dst, src) +} +func (m *EvalResponse) XXX_Size() int { + return xxx_messageInfo_EvalResponse.Size(m) +} +func (m *EvalResponse) XXX_DiscardUnknown() { + xxx_messageInfo_EvalResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_EvalResponse proto.InternalMessageInfo + +func (m *EvalResponse) GetResult() *ExprValue { + if m != nil { + return m.Result + } + return nil +} + +func (m *EvalResponse) GetIssues() []*status.Status { + if m != nil { + return m.Issues + } + return nil +} + +// Warnings or errors in service execution are represented by +// [google.rpc.Status][google.rpc.Status] messages, with the following message +// in the details field. +type IssueDetails struct { + // The severity of the issue. + Severity IssueDetails_Severity `protobuf:"varint,1,opt,name=severity,proto3,enum=google.api.expr.v1alpha1.IssueDetails_Severity" json:"severity,omitempty"` + // Position in the source, if known. + Position *SourcePosition `protobuf:"bytes,2,opt,name=position,proto3" json:"position,omitempty"` + // Expression ID from [Expr][google.api.expr.v1alpha1.Expr], 0 if unknown. + Id int64 `protobuf:"varint,3,opt,name=id,proto3" json:"id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IssueDetails) Reset() { *m = IssueDetails{} } +func (m *IssueDetails) String() string { return proto.CompactTextString(m) } +func (*IssueDetails) ProtoMessage() {} +func (*IssueDetails) Descriptor() ([]byte, []int) { + return fileDescriptor_conformance_service_61e1e6f4037f9b36, []int{6} +} +func (m *IssueDetails) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_IssueDetails.Unmarshal(m, b) +} +func (m *IssueDetails) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_IssueDetails.Marshal(b, m, deterministic) +} +func (dst *IssueDetails) XXX_Merge(src proto.Message) { + xxx_messageInfo_IssueDetails.Merge(dst, src) +} +func (m *IssueDetails) XXX_Size() int { + return xxx_messageInfo_IssueDetails.Size(m) +} +func (m *IssueDetails) XXX_DiscardUnknown() { + xxx_messageInfo_IssueDetails.DiscardUnknown(m) +} + +var xxx_messageInfo_IssueDetails proto.InternalMessageInfo + +func (m *IssueDetails) GetSeverity() IssueDetails_Severity { + if m != nil { + return m.Severity + } + return IssueDetails_SEVERITY_UNSPECIFIED +} + +func (m *IssueDetails) GetPosition() *SourcePosition { + if m != nil { + return m.Position + } + return nil +} + +func (m *IssueDetails) GetId() int64 { + if m != nil { + return m.Id + } + return 0 +} + +func init() { + proto.RegisterType((*ParseRequest)(nil), "google.api.expr.v1alpha1.ParseRequest") + proto.RegisterType((*ParseResponse)(nil), "google.api.expr.v1alpha1.ParseResponse") + proto.RegisterType((*CheckRequest)(nil), "google.api.expr.v1alpha1.CheckRequest") + proto.RegisterType((*CheckResponse)(nil), "google.api.expr.v1alpha1.CheckResponse") + proto.RegisterType((*EvalRequest)(nil), "google.api.expr.v1alpha1.EvalRequest") + proto.RegisterMapType((map[string]*ExprValue)(nil), "google.api.expr.v1alpha1.EvalRequest.BindingsEntry") + proto.RegisterType((*EvalResponse)(nil), "google.api.expr.v1alpha1.EvalResponse") + proto.RegisterType((*IssueDetails)(nil), "google.api.expr.v1alpha1.IssueDetails") + proto.RegisterEnum("google.api.expr.v1alpha1.IssueDetails_Severity", IssueDetails_Severity_name, IssueDetails_Severity_value) +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// ConformanceServiceClient is the client API for ConformanceService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type ConformanceServiceClient interface { + // Transforms CEL source text into a parsed representation. + Parse(ctx context.Context, in *ParseRequest, opts ...grpc.CallOption) (*ParseResponse, error) + // Runs static checks on a parsed CEL representation and return + // an annotated representation, or a set of issues. + Check(ctx context.Context, in *CheckRequest, opts ...grpc.CallOption) (*CheckResponse, error) + // Evaluates a parsed or annotation CEL representation given + // values of external bindings. + Eval(ctx context.Context, in *EvalRequest, opts ...grpc.CallOption) (*EvalResponse, error) +} + +type conformanceServiceClient struct { + cc *grpc.ClientConn +} + +func NewConformanceServiceClient(cc *grpc.ClientConn) ConformanceServiceClient { + return &conformanceServiceClient{cc} +} + +func (c *conformanceServiceClient) Parse(ctx context.Context, in *ParseRequest, opts ...grpc.CallOption) (*ParseResponse, error) { + out := new(ParseResponse) + err := c.cc.Invoke(ctx, "/google.api.expr.v1alpha1.ConformanceService/Parse", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *conformanceServiceClient) Check(ctx context.Context, in *CheckRequest, opts ...grpc.CallOption) (*CheckResponse, error) { + out := new(CheckResponse) + err := c.cc.Invoke(ctx, "/google.api.expr.v1alpha1.ConformanceService/Check", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *conformanceServiceClient) Eval(ctx context.Context, in *EvalRequest, opts ...grpc.CallOption) (*EvalResponse, error) { + out := new(EvalResponse) + err := c.cc.Invoke(ctx, "/google.api.expr.v1alpha1.ConformanceService/Eval", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ConformanceServiceServer is the server API for ConformanceService service. +type ConformanceServiceServer interface { + // Transforms CEL source text into a parsed representation. + Parse(context.Context, *ParseRequest) (*ParseResponse, error) + // Runs static checks on a parsed CEL representation and return + // an annotated representation, or a set of issues. + Check(context.Context, *CheckRequest) (*CheckResponse, error) + // Evaluates a parsed or annotation CEL representation given + // values of external bindings. + Eval(context.Context, *EvalRequest) (*EvalResponse, error) +} + +func RegisterConformanceServiceServer(s *grpc.Server, srv ConformanceServiceServer) { + s.RegisterService(&_ConformanceService_serviceDesc, srv) +} + +func _ConformanceService_Parse_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ParseRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ConformanceServiceServer).Parse(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.api.expr.v1alpha1.ConformanceService/Parse", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ConformanceServiceServer).Parse(ctx, req.(*ParseRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ConformanceService_Check_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CheckRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ConformanceServiceServer).Check(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.api.expr.v1alpha1.ConformanceService/Check", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ConformanceServiceServer).Check(ctx, req.(*CheckRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ConformanceService_Eval_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EvalRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ConformanceServiceServer).Eval(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.api.expr.v1alpha1.ConformanceService/Eval", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ConformanceServiceServer).Eval(ctx, req.(*EvalRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _ConformanceService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "google.api.expr.v1alpha1.ConformanceService", + HandlerType: (*ConformanceServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Parse", + Handler: _ConformanceService_Parse_Handler, + }, + { + MethodName: "Check", + Handler: _ConformanceService_Check_Handler, + }, + { + MethodName: "Eval", + Handler: _ConformanceService_Eval_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "google/api/expr/v1alpha1/conformance_service.proto", +} + +func init() { + proto.RegisterFile("google/api/expr/v1alpha1/conformance_service.proto", fileDescriptor_conformance_service_61e1e6f4037f9b36) +} + +var fileDescriptor_conformance_service_61e1e6f4037f9b36 = []byte{ + // 807 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x41, 0x6f, 0xdb, 0x36, + 0x18, 0xb5, 0xe4, 0x24, 0xb5, 0x3f, 0xd9, 0xa9, 0x41, 0x0c, 0xa8, 0x61, 0x64, 0x43, 0xa0, 0x2e, + 0x69, 0xb0, 0x83, 0x84, 0xba, 0x97, 0x75, 0xdd, 0xa5, 0xb1, 0xb5, 0xc6, 0xdb, 0x9a, 0x18, 0x74, + 0x97, 0x62, 0xbd, 0x68, 0x8c, 0xc4, 0xb9, 0x44, 0x14, 0x52, 0x23, 0x65, 0xcd, 0xde, 0x69, 0x18, + 0xb0, 0x7f, 0xb2, 0xfd, 0x9b, 0xfd, 0xa0, 0x1d, 0x07, 0x89, 0xb4, 0x63, 0xb7, 0x50, 0xd2, 0x0c, + 0xbd, 0x49, 0x9f, 0xde, 0x7b, 0xfa, 0xde, 0xe3, 0x47, 0x12, 0xfa, 0x53, 0x21, 0xa6, 0x09, 0xf5, + 0x49, 0xca, 0x7c, 0x3a, 0x4f, 0xa5, 0x9f, 0x3f, 0x26, 0x49, 0xfa, 0x96, 0x3c, 0xf6, 0x23, 0xc1, + 0x7f, 0x16, 0xf2, 0x8a, 0xf0, 0x88, 0x86, 0x8a, 0xca, 0x9c, 0x45, 0xd4, 0x4b, 0xa5, 0xc8, 0x04, + 0xea, 0x6a, 0x8e, 0x47, 0x52, 0xe6, 0x15, 0x1c, 0x6f, 0xc9, 0xe9, 0x1d, 0x56, 0xab, 0xbd, 0xa5, + 0xd1, 0x25, 0x8d, 0xb5, 0x42, 0xef, 0x61, 0x25, 0x8e, 0xe6, 0x24, 0x31, 0xa0, 0x83, 0x4a, 0x90, + 0x5a, 0xf0, 0x8c, 0xcc, 0x0d, 0xec, 0x81, 0x81, 0xc9, 0x34, 0xf2, 0x55, 0x46, 0xb2, 0x99, 0xd2, + 0x1f, 0xdc, 0xbf, 0x2c, 0x68, 0x8d, 0x89, 0x54, 0x14, 0xd3, 0x5f, 0x66, 0x54, 0x65, 0xe8, 0x53, + 0x80, 0x88, 0x26, 0xa1, 0x12, 0x33, 0x19, 0xd1, 0xae, 0xb5, 0x6f, 0x1d, 0x35, 0x71, 0x33, 0xa2, + 0xc9, 0xa4, 0x2c, 0xa0, 0x03, 0xd8, 0xd5, 0xc2, 0x61, 0x4e, 0xa5, 0x62, 0x82, 0x77, 0xed, 0x12, + 0xd2, 0xd6, 0xd5, 0x73, 0x5d, 0x44, 0x8f, 0xe0, 0xbe, 0x56, 0x08, 0x13, 0x11, 0x91, 0xac, 0xc0, + 0xd5, 0x4b, 0xdc, 0xae, 0x2e, 0x7f, 0x6f, 0xaa, 0x85, 0x5e, 0xcc, 0x14, 0xb9, 0x48, 0x68, 0x78, + 0x45, 0x22, 0x29, 0x54, 0x77, 0x6b, 0xdf, 0x3a, 0x6a, 0xe0, 0xb6, 0xa9, 0xbe, 0x2c, 0x8b, 0xee, + 0x1f, 0x16, 0xb4, 0x4d, 0x9b, 0x2a, 0x15, 0x5c, 0x51, 0x14, 0x80, 0x93, 0x16, 0x85, 0x38, 0x2c, + 0x6c, 0x97, 0x8d, 0x3a, 0xfd, 0xcf, 0xbd, 0xaa, 0xd4, 0xbd, 0x92, 0x1d, 0x07, 0xf3, 0x54, 0x62, + 0x48, 0x57, 0xcf, 0xe8, 0x0b, 0xd8, 0x61, 0x4a, 0xcd, 0xa8, 0xea, 0xda, 0xfb, 0xf5, 0x23, 0xa7, + 0x8f, 0x96, 0x0a, 0x32, 0x8d, 0xbc, 0x49, 0x99, 0x14, 0x36, 0x08, 0xf7, 0x1f, 0x0b, 0x5a, 0x83, + 0x62, 0x89, 0x96, 0x59, 0x7d, 0xa4, 0x1e, 0x9e, 0x42, 0x23, 0x5b, 0xa4, 0x34, 0xa4, 0x3c, 0x37, + 0x5d, 0x7c, 0x56, 0xad, 0x31, 0xa4, 0x51, 0x82, 0xef, 0x15, 0xf8, 0x80, 0xe7, 0x68, 0x0f, 0x9a, + 0x91, 0xe0, 0x19, 0x61, 0x9c, 0x4a, 0x93, 0xf0, 0x75, 0x01, 0xed, 0x01, 0x70, 0x11, 0xaa, 0x2c, + 0x2e, 0xa5, 0x75, 0xb0, 0x0d, 0x2e, 0x26, 0x59, 0x1c, 0xf0, 0xdc, 0xfd, 0xd3, 0x82, 0xb6, 0xb1, + 0x63, 0x32, 0x3d, 0x81, 0x96, 0x19, 0xc1, 0x75, 0x43, 0x07, 0xd5, 0xcd, 0x0c, 0x34, 0xba, 0x74, + 0xe4, 0x44, 0xd7, 0x2f, 0x77, 0x8a, 0xf5, 0xf7, 0x3a, 0x38, 0x41, 0x4e, 0x92, 0x65, 0xaa, 0x2f, + 0xfe, 0x77, 0xaa, 0x27, 0xb5, 0x8d, 0x5c, 0xbf, 0x7d, 0xc7, 0x8e, 0x7d, 0x07, 0x3b, 0x27, 0xb5, + 0x4d, 0x43, 0x67, 0xd0, 0xb8, 0x60, 0x3c, 0x66, 0x7c, 0xaa, 0xba, 0xf5, 0xd2, 0xd2, 0x93, 0x6a, + 0x9d, 0x35, 0x37, 0xde, 0xb1, 0x61, 0x05, 0x3c, 0x93, 0x0b, 0xbc, 0x12, 0xd9, 0x5c, 0xb9, 0xad, + 0x77, 0x56, 0xae, 0xf7, 0x13, 0xb4, 0x37, 0x88, 0xa8, 0x03, 0xf5, 0x4b, 0xba, 0x30, 0xfb, 0xb1, + 0x78, 0x44, 0x4f, 0x61, 0x3b, 0x27, 0xc9, 0x8c, 0x1a, 0x5b, 0x0f, 0x6f, 0x68, 0x67, 0x9e, 0xca, + 0xf3, 0x02, 0x8a, 0x35, 0xe3, 0x2b, 0xfb, 0x4b, 0xeb, 0xd8, 0x81, 0x66, 0x81, 0x0a, 0x2f, 0x19, + 0x8f, 0xdd, 0x5f, 0xa1, 0xa5, 0x7b, 0x36, 0x83, 0xf0, 0x0c, 0x76, 0x24, 0x55, 0xb3, 0x24, 0x33, + 0xe9, 0x7f, 0x90, 0xb8, 0xa1, 0xdc, 0x6d, 0xed, 0x6d, 0x68, 0x8d, 0x8a, 0xc7, 0x21, 0xcd, 0x08, + 0x4b, 0x14, 0xfa, 0x0e, 0x1a, 0x8a, 0xe6, 0x54, 0xb2, 0x4c, 0x9b, 0xdd, 0xed, 0xfb, 0xd5, 0xff, + 0x5e, 0x67, 0x7a, 0x13, 0x43, 0xc3, 0x2b, 0x01, 0x34, 0x84, 0x46, 0x2a, 0x14, 0xcb, 0x96, 0xc7, + 0x94, 0xd3, 0x3f, 0xaa, 0x16, 0xd3, 0x07, 0xdc, 0xd8, 0xe0, 0xf1, 0x8a, 0x89, 0x76, 0xc1, 0x66, + 0x71, 0xb9, 0xb9, 0xea, 0xd8, 0x66, 0xb1, 0xfb, 0x12, 0x1a, 0xcb, 0x7f, 0xa1, 0x2e, 0x7c, 0x32, + 0x09, 0xce, 0x03, 0x3c, 0x7a, 0xf5, 0x63, 0xf8, 0xc3, 0xe9, 0x64, 0x1c, 0x0c, 0x46, 0xdf, 0x8c, + 0x82, 0x61, 0xa7, 0x86, 0xee, 0x83, 0x33, 0x0c, 0xc6, 0x38, 0x18, 0x3c, 0x7f, 0x35, 0x3a, 0x3b, + 0xed, 0x58, 0xc8, 0x81, 0x7b, 0xaf, 0x9f, 0xe3, 0xd3, 0xd1, 0xe9, 0x8b, 0x8e, 0x8d, 0x9a, 0xb0, + 0x1d, 0x60, 0x7c, 0x86, 0x3b, 0xf5, 0xfe, 0xdf, 0x36, 0xa0, 0xc1, 0xf5, 0x35, 0x32, 0xd1, 0xb7, + 0x08, 0x7a, 0x03, 0xdb, 0xe5, 0x60, 0xa3, 0xc3, 0x5b, 0x26, 0xdf, 0x0c, 0x5a, 0xef, 0xd1, 0xad, + 0x38, 0xbd, 0xb8, 0x6e, 0xad, 0xd0, 0x2e, 0x47, 0xfd, 0x26, 0xed, 0xf5, 0x83, 0xee, 0x26, 0xed, + 0x8d, 0x13, 0xc4, 0xad, 0xa1, 0xd7, 0xb0, 0x55, 0x8c, 0x12, 0x3a, 0xf8, 0xa0, 0xed, 0xd1, 0x3b, + 0xbc, 0x0d, 0xb6, 0x14, 0x3e, 0xfe, 0x0d, 0xf6, 0x22, 0x71, 0x55, 0x09, 0x3f, 0x7e, 0xf0, 0x7e, + 0x88, 0xe3, 0xe2, 0x8a, 0x1b, 0x5b, 0x6f, 0xbe, 0x36, 0xa4, 0xa9, 0x48, 0x08, 0x9f, 0x7a, 0x42, + 0x4e, 0xfd, 0x29, 0xe5, 0xe5, 0x05, 0xe8, 0xeb, 0x4f, 0x24, 0x65, 0xea, 0xfd, 0x3b, 0xf4, 0x59, + 0xf1, 0xf6, 0xaf, 0x65, 0x5d, 0xec, 0x94, 0xd8, 0x27, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0xf9, + 0x66, 0xbb, 0xae, 0x09, 0x08, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/eval.pb.go b/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/eval.pb.go new file mode 100644 index 000000000..4cbcba717 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/eval.pb.go @@ -0,0 +1,427 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/api/expr/v1alpha1/eval.proto + +package expr // import "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import status "google.golang.org/genproto/googleapis/rpc/status" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// The state of an evaluation. +// +// Can represent an inital, partial, or completed state of evaluation. +type EvalState struct { + // The unique values referenced in this message. + Values []*ExprValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` + // An ordered list of results. + // + // Tracks the flow of evaluation through the expression. + // May be sparse. + Results []*EvalState_Result `protobuf:"bytes,3,rep,name=results,proto3" json:"results,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EvalState) Reset() { *m = EvalState{} } +func (m *EvalState) String() string { return proto.CompactTextString(m) } +func (*EvalState) ProtoMessage() {} +func (*EvalState) Descriptor() ([]byte, []int) { + return fileDescriptor_eval_bc3ea778c40b9368, []int{0} +} +func (m *EvalState) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EvalState.Unmarshal(m, b) +} +func (m *EvalState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EvalState.Marshal(b, m, deterministic) +} +func (dst *EvalState) XXX_Merge(src proto.Message) { + xxx_messageInfo_EvalState.Merge(dst, src) +} +func (m *EvalState) XXX_Size() int { + return xxx_messageInfo_EvalState.Size(m) +} +func (m *EvalState) XXX_DiscardUnknown() { + xxx_messageInfo_EvalState.DiscardUnknown(m) +} + +var xxx_messageInfo_EvalState proto.InternalMessageInfo + +func (m *EvalState) GetValues() []*ExprValue { + if m != nil { + return m.Values + } + return nil +} + +func (m *EvalState) GetResults() []*EvalState_Result { + if m != nil { + return m.Results + } + return nil +} + +// A single evalution result. +type EvalState_Result struct { + // The id of the expression this result if for. + Expr int64 `protobuf:"varint,1,opt,name=expr,proto3" json:"expr,omitempty"` + // The index in `values` of the resulting value. + Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EvalState_Result) Reset() { *m = EvalState_Result{} } +func (m *EvalState_Result) String() string { return proto.CompactTextString(m) } +func (*EvalState_Result) ProtoMessage() {} +func (*EvalState_Result) Descriptor() ([]byte, []int) { + return fileDescriptor_eval_bc3ea778c40b9368, []int{0, 0} +} +func (m *EvalState_Result) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EvalState_Result.Unmarshal(m, b) +} +func (m *EvalState_Result) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EvalState_Result.Marshal(b, m, deterministic) +} +func (dst *EvalState_Result) XXX_Merge(src proto.Message) { + xxx_messageInfo_EvalState_Result.Merge(dst, src) +} +func (m *EvalState_Result) XXX_Size() int { + return xxx_messageInfo_EvalState_Result.Size(m) +} +func (m *EvalState_Result) XXX_DiscardUnknown() { + xxx_messageInfo_EvalState_Result.DiscardUnknown(m) +} + +var xxx_messageInfo_EvalState_Result proto.InternalMessageInfo + +func (m *EvalState_Result) GetExpr() int64 { + if m != nil { + return m.Expr + } + return 0 +} + +func (m *EvalState_Result) GetValue() int64 { + if m != nil { + return m.Value + } + return 0 +} + +// The value of an evaluated expression. +type ExprValue struct { + // An expression can resolve to a value, error or unknown. + // + // Types that are valid to be assigned to Kind: + // *ExprValue_Value + // *ExprValue_Error + // *ExprValue_Unknown + Kind isExprValue_Kind `protobuf_oneof:"kind"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ExprValue) Reset() { *m = ExprValue{} } +func (m *ExprValue) String() string { return proto.CompactTextString(m) } +func (*ExprValue) ProtoMessage() {} +func (*ExprValue) Descriptor() ([]byte, []int) { + return fileDescriptor_eval_bc3ea778c40b9368, []int{1} +} +func (m *ExprValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ExprValue.Unmarshal(m, b) +} +func (m *ExprValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ExprValue.Marshal(b, m, deterministic) +} +func (dst *ExprValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExprValue.Merge(dst, src) +} +func (m *ExprValue) XXX_Size() int { + return xxx_messageInfo_ExprValue.Size(m) +} +func (m *ExprValue) XXX_DiscardUnknown() { + xxx_messageInfo_ExprValue.DiscardUnknown(m) +} + +var xxx_messageInfo_ExprValue proto.InternalMessageInfo + +type isExprValue_Kind interface { + isExprValue_Kind() +} + +type ExprValue_Value struct { + Value *Value `protobuf:"bytes,1,opt,name=value,proto3,oneof"` +} + +type ExprValue_Error struct { + Error *ErrorSet `protobuf:"bytes,2,opt,name=error,proto3,oneof"` +} + +type ExprValue_Unknown struct { + Unknown *UnknownSet `protobuf:"bytes,3,opt,name=unknown,proto3,oneof"` +} + +func (*ExprValue_Value) isExprValue_Kind() {} + +func (*ExprValue_Error) isExprValue_Kind() {} + +func (*ExprValue_Unknown) isExprValue_Kind() {} + +func (m *ExprValue) GetKind() isExprValue_Kind { + if m != nil { + return m.Kind + } + return nil +} + +func (m *ExprValue) GetValue() *Value { + if x, ok := m.GetKind().(*ExprValue_Value); ok { + return x.Value + } + return nil +} + +func (m *ExprValue) GetError() *ErrorSet { + if x, ok := m.GetKind().(*ExprValue_Error); ok { + return x.Error + } + return nil +} + +func (m *ExprValue) GetUnknown() *UnknownSet { + if x, ok := m.GetKind().(*ExprValue_Unknown); ok { + return x.Unknown + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*ExprValue) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _ExprValue_OneofMarshaler, _ExprValue_OneofUnmarshaler, _ExprValue_OneofSizer, []interface{}{ + (*ExprValue_Value)(nil), + (*ExprValue_Error)(nil), + (*ExprValue_Unknown)(nil), + } +} + +func _ExprValue_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*ExprValue) + // kind + switch x := m.Kind.(type) { + case *ExprValue_Value: + b.EncodeVarint(1<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Value); err != nil { + return err + } + case *ExprValue_Error: + b.EncodeVarint(2<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Error); err != nil { + return err + } + case *ExprValue_Unknown: + b.EncodeVarint(3<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Unknown); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("ExprValue.Kind has unexpected type %T", x) + } + return nil +} + +func _ExprValue_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*ExprValue) + switch tag { + case 1: // kind.value + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Value) + err := b.DecodeMessage(msg) + m.Kind = &ExprValue_Value{msg} + return true, err + case 2: // kind.error + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(ErrorSet) + err := b.DecodeMessage(msg) + m.Kind = &ExprValue_Error{msg} + return true, err + case 3: // kind.unknown + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(UnknownSet) + err := b.DecodeMessage(msg) + m.Kind = &ExprValue_Unknown{msg} + return true, err + default: + return false, nil + } +} + +func _ExprValue_OneofSizer(msg proto.Message) (n int) { + m := msg.(*ExprValue) + // kind + switch x := m.Kind.(type) { + case *ExprValue_Value: + s := proto.Size(x.Value) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *ExprValue_Error: + s := proto.Size(x.Error) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *ExprValue_Unknown: + s := proto.Size(x.Unknown) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +// A set of errors. +// +// The errors included depend on the context. See `ExprValue.error`. +type ErrorSet struct { + // The errors in the set. + Errors []*status.Status `protobuf:"bytes,1,rep,name=errors,proto3" json:"errors,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ErrorSet) Reset() { *m = ErrorSet{} } +func (m *ErrorSet) String() string { return proto.CompactTextString(m) } +func (*ErrorSet) ProtoMessage() {} +func (*ErrorSet) Descriptor() ([]byte, []int) { + return fileDescriptor_eval_bc3ea778c40b9368, []int{2} +} +func (m *ErrorSet) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ErrorSet.Unmarshal(m, b) +} +func (m *ErrorSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ErrorSet.Marshal(b, m, deterministic) +} +func (dst *ErrorSet) XXX_Merge(src proto.Message) { + xxx_messageInfo_ErrorSet.Merge(dst, src) +} +func (m *ErrorSet) XXX_Size() int { + return xxx_messageInfo_ErrorSet.Size(m) +} +func (m *ErrorSet) XXX_DiscardUnknown() { + xxx_messageInfo_ErrorSet.DiscardUnknown(m) +} + +var xxx_messageInfo_ErrorSet proto.InternalMessageInfo + +func (m *ErrorSet) GetErrors() []*status.Status { + if m != nil { + return m.Errors + } + return nil +} + +// A set of expressions for which the value is unknown. +// +// The unknowns included depend on the context. See `ExprValue.unknown`. +type UnknownSet struct { + // The ids of the expressions with unknown values. + Exprs []int64 `protobuf:"varint,1,rep,packed,name=exprs,proto3" json:"exprs,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UnknownSet) Reset() { *m = UnknownSet{} } +func (m *UnknownSet) String() string { return proto.CompactTextString(m) } +func (*UnknownSet) ProtoMessage() {} +func (*UnknownSet) Descriptor() ([]byte, []int) { + return fileDescriptor_eval_bc3ea778c40b9368, []int{3} +} +func (m *UnknownSet) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UnknownSet.Unmarshal(m, b) +} +func (m *UnknownSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UnknownSet.Marshal(b, m, deterministic) +} +func (dst *UnknownSet) XXX_Merge(src proto.Message) { + xxx_messageInfo_UnknownSet.Merge(dst, src) +} +func (m *UnknownSet) XXX_Size() int { + return xxx_messageInfo_UnknownSet.Size(m) +} +func (m *UnknownSet) XXX_DiscardUnknown() { + xxx_messageInfo_UnknownSet.DiscardUnknown(m) +} + +var xxx_messageInfo_UnknownSet proto.InternalMessageInfo + +func (m *UnknownSet) GetExprs() []int64 { + if m != nil { + return m.Exprs + } + return nil +} + +func init() { + proto.RegisterType((*EvalState)(nil), "google.api.expr.v1alpha1.EvalState") + proto.RegisterType((*EvalState_Result)(nil), "google.api.expr.v1alpha1.EvalState.Result") + proto.RegisterType((*ExprValue)(nil), "google.api.expr.v1alpha1.ExprValue") + proto.RegisterType((*ErrorSet)(nil), "google.api.expr.v1alpha1.ErrorSet") + proto.RegisterType((*UnknownSet)(nil), "google.api.expr.v1alpha1.UnknownSet") +} + +func init() { + proto.RegisterFile("google/api/expr/v1alpha1/eval.proto", fileDescriptor_eval_bc3ea778c40b9368) +} + +var fileDescriptor_eval_bc3ea778c40b9368 = []byte{ + // 367 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0xcf, 0x4b, 0xeb, 0x40, + 0x10, 0xc7, 0x5f, 0x5e, 0xda, 0xf4, 0xbd, 0xe9, 0x6d, 0x11, 0x0c, 0x45, 0xb0, 0xa4, 0x3d, 0x94, + 0x1e, 0x36, 0x34, 0x82, 0x82, 0xf5, 0x20, 0xc5, 0x82, 0xc7, 0x92, 0xa2, 0x07, 0x6f, 0x6b, 0x5d, + 0x62, 0xe8, 0x9a, 0x5d, 0x36, 0x3f, 0xec, 0xdf, 0xe7, 0xd1, 0xbf, 0xc8, 0xa3, 0xec, 0x6c, 0x16, + 0x0f, 0x92, 0xde, 0x3a, 0xbb, 0x9f, 0xcf, 0x77, 0xa6, 0xd9, 0x81, 0x49, 0x26, 0x65, 0x26, 0x78, + 0xcc, 0x54, 0x1e, 0xf3, 0x83, 0xd2, 0x71, 0xb3, 0x60, 0x42, 0xbd, 0xb2, 0x45, 0xcc, 0x1b, 0x26, + 0xa8, 0xd2, 0xb2, 0x92, 0x24, 0xb4, 0x10, 0x65, 0x2a, 0xa7, 0x06, 0xa2, 0x0e, 0x1a, 0x4d, 0x3b, + 0xf5, 0x86, 0x89, 0x9a, 0x5b, 0x7f, 0x74, 0xda, 0x52, 0x5a, 0xed, 0xe2, 0xb2, 0x62, 0x55, 0x5d, + 0xda, 0x8b, 0xe8, 0xc3, 0x83, 0xff, 0xeb, 0x86, 0x89, 0x6d, 0xc5, 0x2a, 0x4e, 0x96, 0x10, 0xa0, + 0x55, 0x86, 0xde, 0xd8, 0x9f, 0x0d, 0x93, 0x09, 0xed, 0xea, 0x4b, 0xd7, 0x07, 0xa5, 0x1f, 0x0d, + 0x9b, 0xb6, 0x0a, 0xb9, 0x83, 0x81, 0xe6, 0x65, 0x2d, 0xaa, 0x32, 0xf4, 0xd1, 0x9e, 0x1f, 0xb1, + 0x5d, 0x4b, 0x9a, 0xa2, 0x92, 0x3a, 0x75, 0x94, 0x40, 0x60, 0x8f, 0x08, 0x81, 0x9e, 0x91, 0x42, + 0x6f, 0xec, 0xcd, 0xfc, 0x14, 0x7f, 0x93, 0x13, 0xe8, 0x63, 0xb7, 0xf0, 0x2f, 0x1e, 0xda, 0x22, + 0xfa, 0x34, 0x7f, 0xc2, 0xcd, 0x43, 0xae, 0x1c, 0x63, 0xc4, 0x61, 0x72, 0xde, 0x3d, 0x05, 0xf2, + 0xf7, 0x7f, 0xda, 0x18, 0x72, 0x0d, 0x7d, 0xae, 0xb5, 0xd4, 0x18, 0x3e, 0x4c, 0xa2, 0x23, 0xe3, + 0x1b, 0x6c, 0xcb, 0x2b, 0xe3, 0xa2, 0x42, 0x6e, 0x61, 0x50, 0x17, 0xfb, 0x42, 0xbe, 0x17, 0xa1, + 0x8f, 0xf6, 0xb4, 0xdb, 0x7e, 0xb0, 0xa0, 0xf5, 0x9d, 0xb6, 0x0a, 0xa0, 0xb7, 0xcf, 0x8b, 0x97, + 0xe8, 0x12, 0xfe, 0xb9, 0x78, 0x32, 0x87, 0x00, 0xe3, 0xdd, 0x7b, 0x10, 0x17, 0xaa, 0xd5, 0x8e, + 0x6e, 0xf1, 0x1d, 0xd3, 0x96, 0x88, 0x22, 0x80, 0x9f, 0x60, 0xf3, 0xa1, 0x4c, 0x53, 0x2b, 0xfa, + 0xa9, 0x2d, 0x56, 0x02, 0xce, 0x76, 0xf2, 0xad, 0x73, 0xb2, 0x15, 0xae, 0xc2, 0xc6, 0x2c, 0xc6, + 0xc6, 0x7b, 0xba, 0x69, 0xb1, 0x4c, 0x0a, 0x56, 0x64, 0x54, 0xea, 0x2c, 0xce, 0x78, 0x81, 0x6b, + 0x13, 0xdb, 0x2b, 0xa6, 0xf2, 0xf2, 0xf7, 0xe2, 0x2d, 0x4d, 0xf5, 0xe5, 0x79, 0xcf, 0x01, 0xb2, + 0x17, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x9d, 0x62, 0xde, 0x1d, 0xe2, 0x02, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/explain.pb.go b/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/explain.pb.go new file mode 100644 index 000000000..6b1f8f636 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/explain.pb.go @@ -0,0 +1,157 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/api/expr/v1alpha1/explain.proto + +package expr // import "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// Values of intermediate expressions produced when evaluating expression. +// Deprecated, use `EvalState` instead. +// +// Deprecated: Do not use. +type Explain struct { + // All of the observed values. + // + // The field value_index is an index in the values list. + // Separating values from steps is needed to remove redundant values. + Values []*Value `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` + // List of steps. + // + // Repeated evaluations of the same expression generate new ExprStep + // instances. The order of such ExprStep instances matches the order of + // elements returned by Comprehension.iter_range. + ExprSteps []*Explain_ExprStep `protobuf:"bytes,2,rep,name=expr_steps,json=exprSteps,proto3" json:"expr_steps,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Explain) Reset() { *m = Explain{} } +func (m *Explain) String() string { return proto.CompactTextString(m) } +func (*Explain) ProtoMessage() {} +func (*Explain) Descriptor() ([]byte, []int) { + return fileDescriptor_explain_fcb87931845c5427, []int{0} +} +func (m *Explain) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Explain.Unmarshal(m, b) +} +func (m *Explain) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Explain.Marshal(b, m, deterministic) +} +func (dst *Explain) XXX_Merge(src proto.Message) { + xxx_messageInfo_Explain.Merge(dst, src) +} +func (m *Explain) XXX_Size() int { + return xxx_messageInfo_Explain.Size(m) +} +func (m *Explain) XXX_DiscardUnknown() { + xxx_messageInfo_Explain.DiscardUnknown(m) +} + +var xxx_messageInfo_Explain proto.InternalMessageInfo + +func (m *Explain) GetValues() []*Value { + if m != nil { + return m.Values + } + return nil +} + +func (m *Explain) GetExprSteps() []*Explain_ExprStep { + if m != nil { + return m.ExprSteps + } + return nil +} + +// ID and value index of one step. +type Explain_ExprStep struct { + // ID of corresponding Expr node. + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // Index of the value in the values list. + ValueIndex int32 `protobuf:"varint,2,opt,name=value_index,json=valueIndex,proto3" json:"value_index,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Explain_ExprStep) Reset() { *m = Explain_ExprStep{} } +func (m *Explain_ExprStep) String() string { return proto.CompactTextString(m) } +func (*Explain_ExprStep) ProtoMessage() {} +func (*Explain_ExprStep) Descriptor() ([]byte, []int) { + return fileDescriptor_explain_fcb87931845c5427, []int{0, 0} +} +func (m *Explain_ExprStep) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Explain_ExprStep.Unmarshal(m, b) +} +func (m *Explain_ExprStep) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Explain_ExprStep.Marshal(b, m, deterministic) +} +func (dst *Explain_ExprStep) XXX_Merge(src proto.Message) { + xxx_messageInfo_Explain_ExprStep.Merge(dst, src) +} +func (m *Explain_ExprStep) XXX_Size() int { + return xxx_messageInfo_Explain_ExprStep.Size(m) +} +func (m *Explain_ExprStep) XXX_DiscardUnknown() { + xxx_messageInfo_Explain_ExprStep.DiscardUnknown(m) +} + +var xxx_messageInfo_Explain_ExprStep proto.InternalMessageInfo + +func (m *Explain_ExprStep) GetId() int64 { + if m != nil { + return m.Id + } + return 0 +} + +func (m *Explain_ExprStep) GetValueIndex() int32 { + if m != nil { + return m.ValueIndex + } + return 0 +} + +func init() { + proto.RegisterType((*Explain)(nil), "google.api.expr.v1alpha1.Explain") + proto.RegisterType((*Explain_ExprStep)(nil), "google.api.expr.v1alpha1.Explain.ExprStep") +} + +func init() { + proto.RegisterFile("google/api/expr/v1alpha1/explain.proto", fileDescriptor_explain_fcb87931845c5427) +} + +var fileDescriptor_explain_fcb87931845c5427 = []byte{ + // 261 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x90, 0xb1, 0x4b, 0x03, 0x31, + 0x14, 0xc6, 0x79, 0x29, 0x56, 0x7d, 0x15, 0x87, 0x4c, 0xa1, 0x08, 0x3d, 0x44, 0xe4, 0x70, 0x48, + 0xa8, 0x0e, 0x82, 0x75, 0x2a, 0x38, 0x74, 0x2b, 0x27, 0x38, 0xb8, 0x94, 0xe8, 0x85, 0x18, 0x88, + 0x97, 0x70, 0x39, 0x4b, 0xff, 0x4a, 0xff, 0x1e, 0x47, 0x49, 0x2e, 0x37, 0x95, 0x9b, 0xee, 0xde, + 0xfb, 0x7e, 0xdf, 0xf7, 0x91, 0x87, 0xb7, 0xda, 0x39, 0x6d, 0x95, 0x90, 0xde, 0x08, 0x75, 0xf0, + 0xad, 0xd8, 0x2f, 0xa5, 0xf5, 0x5f, 0x72, 0x19, 0x27, 0x2b, 0x4d, 0xc3, 0x7d, 0xeb, 0x3a, 0x47, + 0x59, 0xcf, 0x71, 0xe9, 0x0d, 0x8f, 0x1c, 0x1f, 0xb8, 0xf9, 0xcd, 0x68, 0xc2, 0x5e, 0xda, 0x1f, + 0xd5, 0xfb, 0xaf, 0x7f, 0x01, 0x4f, 0x5f, 0xfa, 0x44, 0xfa, 0x88, 0xd3, 0x24, 0x05, 0x06, 0xc5, + 0xa4, 0x9c, 0xdd, 0x2f, 0xf8, 0x58, 0x38, 0x7f, 0x8b, 0x5c, 0x95, 0x71, 0xba, 0x41, 0x8c, 0xf2, + 0x2e, 0x74, 0xca, 0x07, 0x46, 0x92, 0xf9, 0x6e, 0xdc, 0x9c, 0xfb, 0xe2, 0xb7, 0x7d, 0xed, 0x94, + 0xaf, 0xce, 0x55, 0xfe, 0x0b, 0xf3, 0x15, 0x9e, 0x0d, 0x6b, 0x7a, 0x89, 0xc4, 0xd4, 0x0c, 0x0a, + 0x28, 0x27, 0x15, 0x31, 0x35, 0x5d, 0xe0, 0x2c, 0x15, 0xee, 0x4c, 0x53, 0xab, 0x03, 0x23, 0x05, + 0x94, 0x27, 0x15, 0xa6, 0xd5, 0x26, 0x6e, 0x9e, 0x08, 0x83, 0xb5, 0xc3, 0xab, 0x4f, 0xf7, 0x3d, + 0x5a, 0xbe, 0xbe, 0xc8, 0xed, 0xdb, 0xf8, 0xfc, 0x2d, 0xbc, 0x3f, 0x67, 0x52, 0x3b, 0x2b, 0x1b, + 0xcd, 0x5d, 0xab, 0x85, 0x56, 0x4d, 0x3a, 0x8e, 0xe8, 0x25, 0xe9, 0x4d, 0x38, 0xbe, 0xe2, 0x2a, + 0x4e, 0x7f, 0x00, 0x1f, 0xd3, 0xc4, 0x3e, 0xfc, 0x07, 0x00, 0x00, 0xff, 0xff, 0x34, 0xf2, 0xb9, + 0x9e, 0xb2, 0x01, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/syntax.pb.go b/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/syntax.pb.go new file mode 100644 index 000000000..0cb02f44e --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/syntax.pb.go @@ -0,0 +1,1572 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/api/expr/v1alpha1/syntax.proto + +package expr // import "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import duration "github.com/golang/protobuf/ptypes/duration" +import _struct "github.com/golang/protobuf/ptypes/struct" +import timestamp "github.com/golang/protobuf/ptypes/timestamp" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// An expression together with source information as returned by the parser. +type ParsedExpr struct { + // The parsed expression. + Expr *Expr `protobuf:"bytes,2,opt,name=expr,proto3" json:"expr,omitempty"` + // The source info derived from input that generated the parsed `expr`. + SourceInfo *SourceInfo `protobuf:"bytes,3,opt,name=source_info,json=sourceInfo,proto3" json:"source_info,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ParsedExpr) Reset() { *m = ParsedExpr{} } +func (m *ParsedExpr) String() string { return proto.CompactTextString(m) } +func (*ParsedExpr) ProtoMessage() {} +func (*ParsedExpr) Descriptor() ([]byte, []int) { + return fileDescriptor_syntax_c21dd3f8bb00852d, []int{0} +} +func (m *ParsedExpr) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ParsedExpr.Unmarshal(m, b) +} +func (m *ParsedExpr) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ParsedExpr.Marshal(b, m, deterministic) +} +func (dst *ParsedExpr) XXX_Merge(src proto.Message) { + xxx_messageInfo_ParsedExpr.Merge(dst, src) +} +func (m *ParsedExpr) XXX_Size() int { + return xxx_messageInfo_ParsedExpr.Size(m) +} +func (m *ParsedExpr) XXX_DiscardUnknown() { + xxx_messageInfo_ParsedExpr.DiscardUnknown(m) +} + +var xxx_messageInfo_ParsedExpr proto.InternalMessageInfo + +func (m *ParsedExpr) GetExpr() *Expr { + if m != nil { + return m.Expr + } + return nil +} + +func (m *ParsedExpr) GetSourceInfo() *SourceInfo { + if m != nil { + return m.SourceInfo + } + return nil +} + +// An abstract representation of a common expression. +// +// Expressions are abstractly represented as a collection of identifiers, +// select statements, function calls, literals, and comprehensions. All +// operators with the exception of the '.' operator are modelled as function +// calls. This makes it easy to represent new operators into the existing AST. +// +// All references within expressions must resolve to a +// [Decl][google.api.expr.v1alpha1.Decl] provided at type-check for an +// expression to be valid. A reference may either be a bare identifier `name` or +// a qualified identifier `google.api.name`. References may either refer to a +// value or a function declaration. +// +// For example, the expression `google.api.name.startsWith('expr')` references +// the declaration `google.api.name` within a +// [Expr.Select][google.api.expr.v1alpha1.Expr.Select] expression, and the +// function declaration `startsWith`. +type Expr struct { + // Required. An id assigned to this node by the parser which is unique in a + // given expression tree. This is used to associate type information and other + // attributes to a node in the parse tree. + Id int64 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` + // Required. Variants of expressions. + // + // Types that are valid to be assigned to ExprKind: + // *Expr_ConstExpr + // *Expr_IdentExpr + // *Expr_SelectExpr + // *Expr_CallExpr + // *Expr_ListExpr + // *Expr_StructExpr + // *Expr_ComprehensionExpr + ExprKind isExpr_ExprKind `protobuf_oneof:"expr_kind"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Expr) Reset() { *m = Expr{} } +func (m *Expr) String() string { return proto.CompactTextString(m) } +func (*Expr) ProtoMessage() {} +func (*Expr) Descriptor() ([]byte, []int) { + return fileDescriptor_syntax_c21dd3f8bb00852d, []int{1} +} +func (m *Expr) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Expr.Unmarshal(m, b) +} +func (m *Expr) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Expr.Marshal(b, m, deterministic) +} +func (dst *Expr) XXX_Merge(src proto.Message) { + xxx_messageInfo_Expr.Merge(dst, src) +} +func (m *Expr) XXX_Size() int { + return xxx_messageInfo_Expr.Size(m) +} +func (m *Expr) XXX_DiscardUnknown() { + xxx_messageInfo_Expr.DiscardUnknown(m) +} + +var xxx_messageInfo_Expr proto.InternalMessageInfo + +func (m *Expr) GetId() int64 { + if m != nil { + return m.Id + } + return 0 +} + +type isExpr_ExprKind interface { + isExpr_ExprKind() +} + +type Expr_ConstExpr struct { + ConstExpr *Constant `protobuf:"bytes,3,opt,name=const_expr,json=constExpr,proto3,oneof"` +} + +type Expr_IdentExpr struct { + IdentExpr *Expr_Ident `protobuf:"bytes,4,opt,name=ident_expr,json=identExpr,proto3,oneof"` +} + +type Expr_SelectExpr struct { + SelectExpr *Expr_Select `protobuf:"bytes,5,opt,name=select_expr,json=selectExpr,proto3,oneof"` +} + +type Expr_CallExpr struct { + CallExpr *Expr_Call `protobuf:"bytes,6,opt,name=call_expr,json=callExpr,proto3,oneof"` +} + +type Expr_ListExpr struct { + ListExpr *Expr_CreateList `protobuf:"bytes,7,opt,name=list_expr,json=listExpr,proto3,oneof"` +} + +type Expr_StructExpr struct { + StructExpr *Expr_CreateStruct `protobuf:"bytes,8,opt,name=struct_expr,json=structExpr,proto3,oneof"` +} + +type Expr_ComprehensionExpr struct { + ComprehensionExpr *Expr_Comprehension `protobuf:"bytes,9,opt,name=comprehension_expr,json=comprehensionExpr,proto3,oneof"` +} + +func (*Expr_ConstExpr) isExpr_ExprKind() {} + +func (*Expr_IdentExpr) isExpr_ExprKind() {} + +func (*Expr_SelectExpr) isExpr_ExprKind() {} + +func (*Expr_CallExpr) isExpr_ExprKind() {} + +func (*Expr_ListExpr) isExpr_ExprKind() {} + +func (*Expr_StructExpr) isExpr_ExprKind() {} + +func (*Expr_ComprehensionExpr) isExpr_ExprKind() {} + +func (m *Expr) GetExprKind() isExpr_ExprKind { + if m != nil { + return m.ExprKind + } + return nil +} + +func (m *Expr) GetConstExpr() *Constant { + if x, ok := m.GetExprKind().(*Expr_ConstExpr); ok { + return x.ConstExpr + } + return nil +} + +func (m *Expr) GetIdentExpr() *Expr_Ident { + if x, ok := m.GetExprKind().(*Expr_IdentExpr); ok { + return x.IdentExpr + } + return nil +} + +func (m *Expr) GetSelectExpr() *Expr_Select { + if x, ok := m.GetExprKind().(*Expr_SelectExpr); ok { + return x.SelectExpr + } + return nil +} + +func (m *Expr) GetCallExpr() *Expr_Call { + if x, ok := m.GetExprKind().(*Expr_CallExpr); ok { + return x.CallExpr + } + return nil +} + +func (m *Expr) GetListExpr() *Expr_CreateList { + if x, ok := m.GetExprKind().(*Expr_ListExpr); ok { + return x.ListExpr + } + return nil +} + +func (m *Expr) GetStructExpr() *Expr_CreateStruct { + if x, ok := m.GetExprKind().(*Expr_StructExpr); ok { + return x.StructExpr + } + return nil +} + +func (m *Expr) GetComprehensionExpr() *Expr_Comprehension { + if x, ok := m.GetExprKind().(*Expr_ComprehensionExpr); ok { + return x.ComprehensionExpr + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*Expr) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _Expr_OneofMarshaler, _Expr_OneofUnmarshaler, _Expr_OneofSizer, []interface{}{ + (*Expr_ConstExpr)(nil), + (*Expr_IdentExpr)(nil), + (*Expr_SelectExpr)(nil), + (*Expr_CallExpr)(nil), + (*Expr_ListExpr)(nil), + (*Expr_StructExpr)(nil), + (*Expr_ComprehensionExpr)(nil), + } +} + +func _Expr_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*Expr) + // expr_kind + switch x := m.ExprKind.(type) { + case *Expr_ConstExpr: + b.EncodeVarint(3<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.ConstExpr); err != nil { + return err + } + case *Expr_IdentExpr: + b.EncodeVarint(4<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.IdentExpr); err != nil { + return err + } + case *Expr_SelectExpr: + b.EncodeVarint(5<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.SelectExpr); err != nil { + return err + } + case *Expr_CallExpr: + b.EncodeVarint(6<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.CallExpr); err != nil { + return err + } + case *Expr_ListExpr: + b.EncodeVarint(7<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.ListExpr); err != nil { + return err + } + case *Expr_StructExpr: + b.EncodeVarint(8<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.StructExpr); err != nil { + return err + } + case *Expr_ComprehensionExpr: + b.EncodeVarint(9<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.ComprehensionExpr); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("Expr.ExprKind has unexpected type %T", x) + } + return nil +} + +func _Expr_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*Expr) + switch tag { + case 3: // expr_kind.const_expr + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Constant) + err := b.DecodeMessage(msg) + m.ExprKind = &Expr_ConstExpr{msg} + return true, err + case 4: // expr_kind.ident_expr + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Expr_Ident) + err := b.DecodeMessage(msg) + m.ExprKind = &Expr_IdentExpr{msg} + return true, err + case 5: // expr_kind.select_expr + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Expr_Select) + err := b.DecodeMessage(msg) + m.ExprKind = &Expr_SelectExpr{msg} + return true, err + case 6: // expr_kind.call_expr + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Expr_Call) + err := b.DecodeMessage(msg) + m.ExprKind = &Expr_CallExpr{msg} + return true, err + case 7: // expr_kind.list_expr + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Expr_CreateList) + err := b.DecodeMessage(msg) + m.ExprKind = &Expr_ListExpr{msg} + return true, err + case 8: // expr_kind.struct_expr + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Expr_CreateStruct) + err := b.DecodeMessage(msg) + m.ExprKind = &Expr_StructExpr{msg} + return true, err + case 9: // expr_kind.comprehension_expr + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Expr_Comprehension) + err := b.DecodeMessage(msg) + m.ExprKind = &Expr_ComprehensionExpr{msg} + return true, err + default: + return false, nil + } +} + +func _Expr_OneofSizer(msg proto.Message) (n int) { + m := msg.(*Expr) + // expr_kind + switch x := m.ExprKind.(type) { + case *Expr_ConstExpr: + s := proto.Size(x.ConstExpr) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Expr_IdentExpr: + s := proto.Size(x.IdentExpr) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Expr_SelectExpr: + s := proto.Size(x.SelectExpr) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Expr_CallExpr: + s := proto.Size(x.CallExpr) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Expr_ListExpr: + s := proto.Size(x.ListExpr) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Expr_StructExpr: + s := proto.Size(x.StructExpr) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Expr_ComprehensionExpr: + s := proto.Size(x.ComprehensionExpr) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +// An identifier expression. e.g. `request`. +type Expr_Ident struct { + // Required. Holds a single, unqualified identifier, possibly preceded by a + // '.'. + // + // Qualified names are represented by the + // [Expr.Select][google.api.expr.v1alpha1.Expr.Select] expression. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Expr_Ident) Reset() { *m = Expr_Ident{} } +func (m *Expr_Ident) String() string { return proto.CompactTextString(m) } +func (*Expr_Ident) ProtoMessage() {} +func (*Expr_Ident) Descriptor() ([]byte, []int) { + return fileDescriptor_syntax_c21dd3f8bb00852d, []int{1, 0} +} +func (m *Expr_Ident) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Expr_Ident.Unmarshal(m, b) +} +func (m *Expr_Ident) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Expr_Ident.Marshal(b, m, deterministic) +} +func (dst *Expr_Ident) XXX_Merge(src proto.Message) { + xxx_messageInfo_Expr_Ident.Merge(dst, src) +} +func (m *Expr_Ident) XXX_Size() int { + return xxx_messageInfo_Expr_Ident.Size(m) +} +func (m *Expr_Ident) XXX_DiscardUnknown() { + xxx_messageInfo_Expr_Ident.DiscardUnknown(m) +} + +var xxx_messageInfo_Expr_Ident proto.InternalMessageInfo + +func (m *Expr_Ident) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +// A field selection expression. e.g. `request.auth`. +type Expr_Select struct { + // Required. The target of the selection expression. + // + // For example, in the select expression `request.auth`, the `request` + // portion of the expression is the `operand`. + Operand *Expr `protobuf:"bytes,1,opt,name=operand,proto3" json:"operand,omitempty"` + // Required. The name of the field to select. + // + // For example, in the select expression `request.auth`, the `auth` portion + // of the expression would be the `field`. + Field string `protobuf:"bytes,2,opt,name=field,proto3" json:"field,omitempty"` + // Whether the select is to be interpreted as a field presence test. + // + // This results from the macro `has(request.auth)`. + TestOnly bool `protobuf:"varint,3,opt,name=test_only,json=testOnly,proto3" json:"test_only,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Expr_Select) Reset() { *m = Expr_Select{} } +func (m *Expr_Select) String() string { return proto.CompactTextString(m) } +func (*Expr_Select) ProtoMessage() {} +func (*Expr_Select) Descriptor() ([]byte, []int) { + return fileDescriptor_syntax_c21dd3f8bb00852d, []int{1, 1} +} +func (m *Expr_Select) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Expr_Select.Unmarshal(m, b) +} +func (m *Expr_Select) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Expr_Select.Marshal(b, m, deterministic) +} +func (dst *Expr_Select) XXX_Merge(src proto.Message) { + xxx_messageInfo_Expr_Select.Merge(dst, src) +} +func (m *Expr_Select) XXX_Size() int { + return xxx_messageInfo_Expr_Select.Size(m) +} +func (m *Expr_Select) XXX_DiscardUnknown() { + xxx_messageInfo_Expr_Select.DiscardUnknown(m) +} + +var xxx_messageInfo_Expr_Select proto.InternalMessageInfo + +func (m *Expr_Select) GetOperand() *Expr { + if m != nil { + return m.Operand + } + return nil +} + +func (m *Expr_Select) GetField() string { + if m != nil { + return m.Field + } + return "" +} + +func (m *Expr_Select) GetTestOnly() bool { + if m != nil { + return m.TestOnly + } + return false +} + +// A call expression, including calls to predefined functions and operators. +// +// For example, `value == 10`, `size(map_value)`. +type Expr_Call struct { + // The target of an method call-style expression. For example, `x` in + // `x.f()`. + Target *Expr `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"` + // Required. The name of the function or method being called. + Function string `protobuf:"bytes,2,opt,name=function,proto3" json:"function,omitempty"` + // The arguments. + Args []*Expr `protobuf:"bytes,3,rep,name=args,proto3" json:"args,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Expr_Call) Reset() { *m = Expr_Call{} } +func (m *Expr_Call) String() string { return proto.CompactTextString(m) } +func (*Expr_Call) ProtoMessage() {} +func (*Expr_Call) Descriptor() ([]byte, []int) { + return fileDescriptor_syntax_c21dd3f8bb00852d, []int{1, 2} +} +func (m *Expr_Call) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Expr_Call.Unmarshal(m, b) +} +func (m *Expr_Call) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Expr_Call.Marshal(b, m, deterministic) +} +func (dst *Expr_Call) XXX_Merge(src proto.Message) { + xxx_messageInfo_Expr_Call.Merge(dst, src) +} +func (m *Expr_Call) XXX_Size() int { + return xxx_messageInfo_Expr_Call.Size(m) +} +func (m *Expr_Call) XXX_DiscardUnknown() { + xxx_messageInfo_Expr_Call.DiscardUnknown(m) +} + +var xxx_messageInfo_Expr_Call proto.InternalMessageInfo + +func (m *Expr_Call) GetTarget() *Expr { + if m != nil { + return m.Target + } + return nil +} + +func (m *Expr_Call) GetFunction() string { + if m != nil { + return m.Function + } + return "" +} + +func (m *Expr_Call) GetArgs() []*Expr { + if m != nil { + return m.Args + } + return nil +} + +// A list creation expression. +// +// Lists may either be homogenous, e.g. `[1, 2, 3]`, or heterogenous, e.g. +// `dyn([1, 'hello', 2.0])` +type Expr_CreateList struct { + // The elements part of the list. + Elements []*Expr `protobuf:"bytes,1,rep,name=elements,proto3" json:"elements,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Expr_CreateList) Reset() { *m = Expr_CreateList{} } +func (m *Expr_CreateList) String() string { return proto.CompactTextString(m) } +func (*Expr_CreateList) ProtoMessage() {} +func (*Expr_CreateList) Descriptor() ([]byte, []int) { + return fileDescriptor_syntax_c21dd3f8bb00852d, []int{1, 3} +} +func (m *Expr_CreateList) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Expr_CreateList.Unmarshal(m, b) +} +func (m *Expr_CreateList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Expr_CreateList.Marshal(b, m, deterministic) +} +func (dst *Expr_CreateList) XXX_Merge(src proto.Message) { + xxx_messageInfo_Expr_CreateList.Merge(dst, src) +} +func (m *Expr_CreateList) XXX_Size() int { + return xxx_messageInfo_Expr_CreateList.Size(m) +} +func (m *Expr_CreateList) XXX_DiscardUnknown() { + xxx_messageInfo_Expr_CreateList.DiscardUnknown(m) +} + +var xxx_messageInfo_Expr_CreateList proto.InternalMessageInfo + +func (m *Expr_CreateList) GetElements() []*Expr { + if m != nil { + return m.Elements + } + return nil +} + +// A map or message creation expression. +// +// Maps are constructed as `{'key_name': 'value'}`. Message construction is +// similar, but prefixed with a type name and composed of field ids: +// `types.MyType{field_id: 'value'}`. +type Expr_CreateStruct struct { + // The type name of the message to be created, empty when creating map + // literals. + MessageName string `protobuf:"bytes,1,opt,name=message_name,json=messageName,proto3" json:"message_name,omitempty"` + // The entries in the creation expression. + Entries []*Expr_CreateStruct_Entry `protobuf:"bytes,2,rep,name=entries,proto3" json:"entries,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Expr_CreateStruct) Reset() { *m = Expr_CreateStruct{} } +func (m *Expr_CreateStruct) String() string { return proto.CompactTextString(m) } +func (*Expr_CreateStruct) ProtoMessage() {} +func (*Expr_CreateStruct) Descriptor() ([]byte, []int) { + return fileDescriptor_syntax_c21dd3f8bb00852d, []int{1, 4} +} +func (m *Expr_CreateStruct) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Expr_CreateStruct.Unmarshal(m, b) +} +func (m *Expr_CreateStruct) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Expr_CreateStruct.Marshal(b, m, deterministic) +} +func (dst *Expr_CreateStruct) XXX_Merge(src proto.Message) { + xxx_messageInfo_Expr_CreateStruct.Merge(dst, src) +} +func (m *Expr_CreateStruct) XXX_Size() int { + return xxx_messageInfo_Expr_CreateStruct.Size(m) +} +func (m *Expr_CreateStruct) XXX_DiscardUnknown() { + xxx_messageInfo_Expr_CreateStruct.DiscardUnknown(m) +} + +var xxx_messageInfo_Expr_CreateStruct proto.InternalMessageInfo + +func (m *Expr_CreateStruct) GetMessageName() string { + if m != nil { + return m.MessageName + } + return "" +} + +func (m *Expr_CreateStruct) GetEntries() []*Expr_CreateStruct_Entry { + if m != nil { + return m.Entries + } + return nil +} + +// Represents an entry. +type Expr_CreateStruct_Entry struct { + // Required. An id assigned to this node by the parser which is unique + // in a given expression tree. This is used to associate type + // information and other attributes to the node. + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // The `Entry` key kinds. + // + // Types that are valid to be assigned to KeyKind: + // *Expr_CreateStruct_Entry_FieldKey + // *Expr_CreateStruct_Entry_MapKey + KeyKind isExpr_CreateStruct_Entry_KeyKind `protobuf_oneof:"key_kind"` + // Required. The value assigned to the key. + Value *Expr `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Expr_CreateStruct_Entry) Reset() { *m = Expr_CreateStruct_Entry{} } +func (m *Expr_CreateStruct_Entry) String() string { return proto.CompactTextString(m) } +func (*Expr_CreateStruct_Entry) ProtoMessage() {} +func (*Expr_CreateStruct_Entry) Descriptor() ([]byte, []int) { + return fileDescriptor_syntax_c21dd3f8bb00852d, []int{1, 4, 0} +} +func (m *Expr_CreateStruct_Entry) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Expr_CreateStruct_Entry.Unmarshal(m, b) +} +func (m *Expr_CreateStruct_Entry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Expr_CreateStruct_Entry.Marshal(b, m, deterministic) +} +func (dst *Expr_CreateStruct_Entry) XXX_Merge(src proto.Message) { + xxx_messageInfo_Expr_CreateStruct_Entry.Merge(dst, src) +} +func (m *Expr_CreateStruct_Entry) XXX_Size() int { + return xxx_messageInfo_Expr_CreateStruct_Entry.Size(m) +} +func (m *Expr_CreateStruct_Entry) XXX_DiscardUnknown() { + xxx_messageInfo_Expr_CreateStruct_Entry.DiscardUnknown(m) +} + +var xxx_messageInfo_Expr_CreateStruct_Entry proto.InternalMessageInfo + +func (m *Expr_CreateStruct_Entry) GetId() int64 { + if m != nil { + return m.Id + } + return 0 +} + +type isExpr_CreateStruct_Entry_KeyKind interface { + isExpr_CreateStruct_Entry_KeyKind() +} + +type Expr_CreateStruct_Entry_FieldKey struct { + FieldKey string `protobuf:"bytes,2,opt,name=field_key,json=fieldKey,proto3,oneof"` +} + +type Expr_CreateStruct_Entry_MapKey struct { + MapKey *Expr `protobuf:"bytes,3,opt,name=map_key,json=mapKey,proto3,oneof"` +} + +func (*Expr_CreateStruct_Entry_FieldKey) isExpr_CreateStruct_Entry_KeyKind() {} + +func (*Expr_CreateStruct_Entry_MapKey) isExpr_CreateStruct_Entry_KeyKind() {} + +func (m *Expr_CreateStruct_Entry) GetKeyKind() isExpr_CreateStruct_Entry_KeyKind { + if m != nil { + return m.KeyKind + } + return nil +} + +func (m *Expr_CreateStruct_Entry) GetFieldKey() string { + if x, ok := m.GetKeyKind().(*Expr_CreateStruct_Entry_FieldKey); ok { + return x.FieldKey + } + return "" +} + +func (m *Expr_CreateStruct_Entry) GetMapKey() *Expr { + if x, ok := m.GetKeyKind().(*Expr_CreateStruct_Entry_MapKey); ok { + return x.MapKey + } + return nil +} + +func (m *Expr_CreateStruct_Entry) GetValue() *Expr { + if m != nil { + return m.Value + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*Expr_CreateStruct_Entry) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _Expr_CreateStruct_Entry_OneofMarshaler, _Expr_CreateStruct_Entry_OneofUnmarshaler, _Expr_CreateStruct_Entry_OneofSizer, []interface{}{ + (*Expr_CreateStruct_Entry_FieldKey)(nil), + (*Expr_CreateStruct_Entry_MapKey)(nil), + } +} + +func _Expr_CreateStruct_Entry_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*Expr_CreateStruct_Entry) + // key_kind + switch x := m.KeyKind.(type) { + case *Expr_CreateStruct_Entry_FieldKey: + b.EncodeVarint(2<<3 | proto.WireBytes) + b.EncodeStringBytes(x.FieldKey) + case *Expr_CreateStruct_Entry_MapKey: + b.EncodeVarint(3<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.MapKey); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("Expr_CreateStruct_Entry.KeyKind has unexpected type %T", x) + } + return nil +} + +func _Expr_CreateStruct_Entry_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*Expr_CreateStruct_Entry) + switch tag { + case 2: // key_kind.field_key + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.KeyKind = &Expr_CreateStruct_Entry_FieldKey{x} + return true, err + case 3: // key_kind.map_key + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Expr) + err := b.DecodeMessage(msg) + m.KeyKind = &Expr_CreateStruct_Entry_MapKey{msg} + return true, err + default: + return false, nil + } +} + +func _Expr_CreateStruct_Entry_OneofSizer(msg proto.Message) (n int) { + m := msg.(*Expr_CreateStruct_Entry) + // key_kind + switch x := m.KeyKind.(type) { + case *Expr_CreateStruct_Entry_FieldKey: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(len(x.FieldKey))) + n += len(x.FieldKey) + case *Expr_CreateStruct_Entry_MapKey: + s := proto.Size(x.MapKey) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +// A comprehension expression applied to a list or map. +// +// Comprehensions are not part of the core syntax, but enabled with macros. +// A macro matches a specific call signature within a parsed AST and replaces +// the call with an alternate AST block. Macro expansion happens at parse +// time. +// +// The following macros are supported within CEL: +// +// Aggregate type macros may be applied to all elements in a list or all keys +// in a map: +// +// * `all`, `exists`, `exists_one` - test a predicate expression against +// the inputs and return `true` if the predicate is satisfied for all, +// any, or only one value `list.all(x, x < 10)`. +// * `filter` - test a predicate expression against the inputs and return +// the subset of elements which satisfy the predicate: +// `payments.filter(p, p > 1000)`. +// * `map` - apply an expression to all elements in the input and return the +// output aggregate type: `[1, 2, 3].map(i, i * i)`. +// +// The `has(m.x)` macro tests whether the property `x` is present in struct +// `m`. The semantics of this macro depend on the type of `m`. For proto2 +// messages `has(m.x)` is defined as 'defined, but not set`. For proto3, the +// macro tests whether the property is set to its default. For map and struct +// types, the macro tests whether the property `x` is defined on `m`. +type Expr_Comprehension struct { + // The name of the iteration variable. + IterVar string `protobuf:"bytes,1,opt,name=iter_var,json=iterVar,proto3" json:"iter_var,omitempty"` + // The range over which var iterates. + IterRange *Expr `protobuf:"bytes,2,opt,name=iter_range,json=iterRange,proto3" json:"iter_range,omitempty"` + // The name of the variable used for accumulation of the result. + AccuVar string `protobuf:"bytes,3,opt,name=accu_var,json=accuVar,proto3" json:"accu_var,omitempty"` + // The initial value of the accumulator. + AccuInit *Expr `protobuf:"bytes,4,opt,name=accu_init,json=accuInit,proto3" json:"accu_init,omitempty"` + // An expression which can contain iter_var and accu_var. + // + // Returns false when the result has been computed and may be used as + // a hint to short-circuit the remainder of the comprehension. + LoopCondition *Expr `protobuf:"bytes,5,opt,name=loop_condition,json=loopCondition,proto3" json:"loop_condition,omitempty"` + // An expression which can contain iter_var and accu_var. + // + // Computes the next value of accu_var. + LoopStep *Expr `protobuf:"bytes,6,opt,name=loop_step,json=loopStep,proto3" json:"loop_step,omitempty"` + // An expression which can contain accu_var. + // + // Computes the result. + Result *Expr `protobuf:"bytes,7,opt,name=result,proto3" json:"result,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Expr_Comprehension) Reset() { *m = Expr_Comprehension{} } +func (m *Expr_Comprehension) String() string { return proto.CompactTextString(m) } +func (*Expr_Comprehension) ProtoMessage() {} +func (*Expr_Comprehension) Descriptor() ([]byte, []int) { + return fileDescriptor_syntax_c21dd3f8bb00852d, []int{1, 5} +} +func (m *Expr_Comprehension) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Expr_Comprehension.Unmarshal(m, b) +} +func (m *Expr_Comprehension) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Expr_Comprehension.Marshal(b, m, deterministic) +} +func (dst *Expr_Comprehension) XXX_Merge(src proto.Message) { + xxx_messageInfo_Expr_Comprehension.Merge(dst, src) +} +func (m *Expr_Comprehension) XXX_Size() int { + return xxx_messageInfo_Expr_Comprehension.Size(m) +} +func (m *Expr_Comprehension) XXX_DiscardUnknown() { + xxx_messageInfo_Expr_Comprehension.DiscardUnknown(m) +} + +var xxx_messageInfo_Expr_Comprehension proto.InternalMessageInfo + +func (m *Expr_Comprehension) GetIterVar() string { + if m != nil { + return m.IterVar + } + return "" +} + +func (m *Expr_Comprehension) GetIterRange() *Expr { + if m != nil { + return m.IterRange + } + return nil +} + +func (m *Expr_Comprehension) GetAccuVar() string { + if m != nil { + return m.AccuVar + } + return "" +} + +func (m *Expr_Comprehension) GetAccuInit() *Expr { + if m != nil { + return m.AccuInit + } + return nil +} + +func (m *Expr_Comprehension) GetLoopCondition() *Expr { + if m != nil { + return m.LoopCondition + } + return nil +} + +func (m *Expr_Comprehension) GetLoopStep() *Expr { + if m != nil { + return m.LoopStep + } + return nil +} + +func (m *Expr_Comprehension) GetResult() *Expr { + if m != nil { + return m.Result + } + return nil +} + +// Represents a primitive literal. +// +// Named 'Constant' here for backwards compatibility. +// +// This is similar as the primitives supported in the well-known type +// `google.protobuf.Value`, but richer so it can represent CEL's full range of +// primitives. +// +// Lists and structs are not included as constants as these aggregate types may +// contain [Expr][google.api.expr.v1alpha1.Expr] elements which require +// evaluation and are thus not constant. +// +// Examples of literals include: `"hello"`, `b'bytes'`, `1u`, `4.2`, `-2`, +// `true`, `null`. +type Constant struct { + // Required. The valid constant kinds. + // + // Types that are valid to be assigned to ConstantKind: + // *Constant_NullValue + // *Constant_BoolValue + // *Constant_Int64Value + // *Constant_Uint64Value + // *Constant_DoubleValue + // *Constant_StringValue + // *Constant_BytesValue + // *Constant_DurationValue + // *Constant_TimestampValue + ConstantKind isConstant_ConstantKind `protobuf_oneof:"constant_kind"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Constant) Reset() { *m = Constant{} } +func (m *Constant) String() string { return proto.CompactTextString(m) } +func (*Constant) ProtoMessage() {} +func (*Constant) Descriptor() ([]byte, []int) { + return fileDescriptor_syntax_c21dd3f8bb00852d, []int{2} +} +func (m *Constant) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Constant.Unmarshal(m, b) +} +func (m *Constant) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Constant.Marshal(b, m, deterministic) +} +func (dst *Constant) XXX_Merge(src proto.Message) { + xxx_messageInfo_Constant.Merge(dst, src) +} +func (m *Constant) XXX_Size() int { + return xxx_messageInfo_Constant.Size(m) +} +func (m *Constant) XXX_DiscardUnknown() { + xxx_messageInfo_Constant.DiscardUnknown(m) +} + +var xxx_messageInfo_Constant proto.InternalMessageInfo + +type isConstant_ConstantKind interface { + isConstant_ConstantKind() +} + +type Constant_NullValue struct { + NullValue _struct.NullValue `protobuf:"varint,1,opt,name=null_value,json=nullValue,proto3,enum=google.protobuf.NullValue,oneof"` +} + +type Constant_BoolValue struct { + BoolValue bool `protobuf:"varint,2,opt,name=bool_value,json=boolValue,proto3,oneof"` +} + +type Constant_Int64Value struct { + Int64Value int64 `protobuf:"varint,3,opt,name=int64_value,json=int64Value,proto3,oneof"` +} + +type Constant_Uint64Value struct { + Uint64Value uint64 `protobuf:"varint,4,opt,name=uint64_value,json=uint64Value,proto3,oneof"` +} + +type Constant_DoubleValue struct { + DoubleValue float64 `protobuf:"fixed64,5,opt,name=double_value,json=doubleValue,proto3,oneof"` +} + +type Constant_StringValue struct { + StringValue string `protobuf:"bytes,6,opt,name=string_value,json=stringValue,proto3,oneof"` +} + +type Constant_BytesValue struct { + BytesValue []byte `protobuf:"bytes,7,opt,name=bytes_value,json=bytesValue,proto3,oneof"` +} + +type Constant_DurationValue struct { + DurationValue *duration.Duration `protobuf:"bytes,8,opt,name=duration_value,json=durationValue,proto3,oneof"` +} + +type Constant_TimestampValue struct { + TimestampValue *timestamp.Timestamp `protobuf:"bytes,9,opt,name=timestamp_value,json=timestampValue,proto3,oneof"` +} + +func (*Constant_NullValue) isConstant_ConstantKind() {} + +func (*Constant_BoolValue) isConstant_ConstantKind() {} + +func (*Constant_Int64Value) isConstant_ConstantKind() {} + +func (*Constant_Uint64Value) isConstant_ConstantKind() {} + +func (*Constant_DoubleValue) isConstant_ConstantKind() {} + +func (*Constant_StringValue) isConstant_ConstantKind() {} + +func (*Constant_BytesValue) isConstant_ConstantKind() {} + +func (*Constant_DurationValue) isConstant_ConstantKind() {} + +func (*Constant_TimestampValue) isConstant_ConstantKind() {} + +func (m *Constant) GetConstantKind() isConstant_ConstantKind { + if m != nil { + return m.ConstantKind + } + return nil +} + +func (m *Constant) GetNullValue() _struct.NullValue { + if x, ok := m.GetConstantKind().(*Constant_NullValue); ok { + return x.NullValue + } + return _struct.NullValue_NULL_VALUE +} + +func (m *Constant) GetBoolValue() bool { + if x, ok := m.GetConstantKind().(*Constant_BoolValue); ok { + return x.BoolValue + } + return false +} + +func (m *Constant) GetInt64Value() int64 { + if x, ok := m.GetConstantKind().(*Constant_Int64Value); ok { + return x.Int64Value + } + return 0 +} + +func (m *Constant) GetUint64Value() uint64 { + if x, ok := m.GetConstantKind().(*Constant_Uint64Value); ok { + return x.Uint64Value + } + return 0 +} + +func (m *Constant) GetDoubleValue() float64 { + if x, ok := m.GetConstantKind().(*Constant_DoubleValue); ok { + return x.DoubleValue + } + return 0 +} + +func (m *Constant) GetStringValue() string { + if x, ok := m.GetConstantKind().(*Constant_StringValue); ok { + return x.StringValue + } + return "" +} + +func (m *Constant) GetBytesValue() []byte { + if x, ok := m.GetConstantKind().(*Constant_BytesValue); ok { + return x.BytesValue + } + return nil +} + +func (m *Constant) GetDurationValue() *duration.Duration { + if x, ok := m.GetConstantKind().(*Constant_DurationValue); ok { + return x.DurationValue + } + return nil +} + +func (m *Constant) GetTimestampValue() *timestamp.Timestamp { + if x, ok := m.GetConstantKind().(*Constant_TimestampValue); ok { + return x.TimestampValue + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*Constant) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _Constant_OneofMarshaler, _Constant_OneofUnmarshaler, _Constant_OneofSizer, []interface{}{ + (*Constant_NullValue)(nil), + (*Constant_BoolValue)(nil), + (*Constant_Int64Value)(nil), + (*Constant_Uint64Value)(nil), + (*Constant_DoubleValue)(nil), + (*Constant_StringValue)(nil), + (*Constant_BytesValue)(nil), + (*Constant_DurationValue)(nil), + (*Constant_TimestampValue)(nil), + } +} + +func _Constant_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*Constant) + // constant_kind + switch x := m.ConstantKind.(type) { + case *Constant_NullValue: + b.EncodeVarint(1<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.NullValue)) + case *Constant_BoolValue: + t := uint64(0) + if x.BoolValue { + t = 1 + } + b.EncodeVarint(2<<3 | proto.WireVarint) + b.EncodeVarint(t) + case *Constant_Int64Value: + b.EncodeVarint(3<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.Int64Value)) + case *Constant_Uint64Value: + b.EncodeVarint(4<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.Uint64Value)) + case *Constant_DoubleValue: + b.EncodeVarint(5<<3 | proto.WireFixed64) + b.EncodeFixed64(math.Float64bits(x.DoubleValue)) + case *Constant_StringValue: + b.EncodeVarint(6<<3 | proto.WireBytes) + b.EncodeStringBytes(x.StringValue) + case *Constant_BytesValue: + b.EncodeVarint(7<<3 | proto.WireBytes) + b.EncodeRawBytes(x.BytesValue) + case *Constant_DurationValue: + b.EncodeVarint(8<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.DurationValue); err != nil { + return err + } + case *Constant_TimestampValue: + b.EncodeVarint(9<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.TimestampValue); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("Constant.ConstantKind has unexpected type %T", x) + } + return nil +} + +func _Constant_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*Constant) + switch tag { + case 1: // constant_kind.null_value + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.ConstantKind = &Constant_NullValue{_struct.NullValue(x)} + return true, err + case 2: // constant_kind.bool_value + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.ConstantKind = &Constant_BoolValue{x != 0} + return true, err + case 3: // constant_kind.int64_value + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.ConstantKind = &Constant_Int64Value{int64(x)} + return true, err + case 4: // constant_kind.uint64_value + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.ConstantKind = &Constant_Uint64Value{x} + return true, err + case 5: // constant_kind.double_value + if wire != proto.WireFixed64 { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeFixed64() + m.ConstantKind = &Constant_DoubleValue{math.Float64frombits(x)} + return true, err + case 6: // constant_kind.string_value + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.ConstantKind = &Constant_StringValue{x} + return true, err + case 7: // constant_kind.bytes_value + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeRawBytes(true) + m.ConstantKind = &Constant_BytesValue{x} + return true, err + case 8: // constant_kind.duration_value + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(duration.Duration) + err := b.DecodeMessage(msg) + m.ConstantKind = &Constant_DurationValue{msg} + return true, err + case 9: // constant_kind.timestamp_value + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(timestamp.Timestamp) + err := b.DecodeMessage(msg) + m.ConstantKind = &Constant_TimestampValue{msg} + return true, err + default: + return false, nil + } +} + +func _Constant_OneofSizer(msg proto.Message) (n int) { + m := msg.(*Constant) + // constant_kind + switch x := m.ConstantKind.(type) { + case *Constant_NullValue: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(x.NullValue)) + case *Constant_BoolValue: + n += 1 // tag and wire + n += 1 + case *Constant_Int64Value: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(x.Int64Value)) + case *Constant_Uint64Value: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(x.Uint64Value)) + case *Constant_DoubleValue: + n += 1 // tag and wire + n += 8 + case *Constant_StringValue: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(len(x.StringValue))) + n += len(x.StringValue) + case *Constant_BytesValue: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(len(x.BytesValue))) + n += len(x.BytesValue) + case *Constant_DurationValue: + s := proto.Size(x.DurationValue) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Constant_TimestampValue: + s := proto.Size(x.TimestampValue) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +// Source information collected at parse time. +type SourceInfo struct { + // The syntax version of the source, e.g. `cel1`. + SyntaxVersion string `protobuf:"bytes,1,opt,name=syntax_version,json=syntaxVersion,proto3" json:"syntax_version,omitempty"` + // The location name. All position information attached to an expression is + // relative to this location. + // + // The location could be a file, UI element, or similar. For example, + // `acme/app/AnvilPolicy.cel`. + Location string `protobuf:"bytes,2,opt,name=location,proto3" json:"location,omitempty"` + // Monotonically increasing list of character offsets where newlines appear. + // + // The line number of a given position is the index `i` where for a given + // `id` the `line_offsets[i] < id_positions[id] < line_offsets[i+1]`. The + // column may be derivd from `id_positions[id] - line_offsets[i]`. + LineOffsets []int32 `protobuf:"varint,3,rep,packed,name=line_offsets,json=lineOffsets,proto3" json:"line_offsets,omitempty"` + // A map from the parse node id (e.g. `Expr.id`) to the character offset + // within source. + Positions map[int64]int32 `protobuf:"bytes,4,rep,name=positions,proto3" json:"positions,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SourceInfo) Reset() { *m = SourceInfo{} } +func (m *SourceInfo) String() string { return proto.CompactTextString(m) } +func (*SourceInfo) ProtoMessage() {} +func (*SourceInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_syntax_c21dd3f8bb00852d, []int{3} +} +func (m *SourceInfo) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SourceInfo.Unmarshal(m, b) +} +func (m *SourceInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SourceInfo.Marshal(b, m, deterministic) +} +func (dst *SourceInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_SourceInfo.Merge(dst, src) +} +func (m *SourceInfo) XXX_Size() int { + return xxx_messageInfo_SourceInfo.Size(m) +} +func (m *SourceInfo) XXX_DiscardUnknown() { + xxx_messageInfo_SourceInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_SourceInfo proto.InternalMessageInfo + +func (m *SourceInfo) GetSyntaxVersion() string { + if m != nil { + return m.SyntaxVersion + } + return "" +} + +func (m *SourceInfo) GetLocation() string { + if m != nil { + return m.Location + } + return "" +} + +func (m *SourceInfo) GetLineOffsets() []int32 { + if m != nil { + return m.LineOffsets + } + return nil +} + +func (m *SourceInfo) GetPositions() map[int64]int32 { + if m != nil { + return m.Positions + } + return nil +} + +// A specific position in source. +type SourcePosition struct { + // The soucre location name (e.g. file name). + Location string `protobuf:"bytes,1,opt,name=location,proto3" json:"location,omitempty"` + // The character offset. + Offset int32 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset,omitempty"` + // The 1-based index of the starting line in the source text + // where the issue occurs, or 0 if unknown. + Line int32 `protobuf:"varint,3,opt,name=line,proto3" json:"line,omitempty"` + // The 0-based index of the starting position within the line of source text + // where the issue occurs. Only meaningful if line is nonzero. + Column int32 `protobuf:"varint,4,opt,name=column,proto3" json:"column,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SourcePosition) Reset() { *m = SourcePosition{} } +func (m *SourcePosition) String() string { return proto.CompactTextString(m) } +func (*SourcePosition) ProtoMessage() {} +func (*SourcePosition) Descriptor() ([]byte, []int) { + return fileDescriptor_syntax_c21dd3f8bb00852d, []int{4} +} +func (m *SourcePosition) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SourcePosition.Unmarshal(m, b) +} +func (m *SourcePosition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SourcePosition.Marshal(b, m, deterministic) +} +func (dst *SourcePosition) XXX_Merge(src proto.Message) { + xxx_messageInfo_SourcePosition.Merge(dst, src) +} +func (m *SourcePosition) XXX_Size() int { + return xxx_messageInfo_SourcePosition.Size(m) +} +func (m *SourcePosition) XXX_DiscardUnknown() { + xxx_messageInfo_SourcePosition.DiscardUnknown(m) +} + +var xxx_messageInfo_SourcePosition proto.InternalMessageInfo + +func (m *SourcePosition) GetLocation() string { + if m != nil { + return m.Location + } + return "" +} + +func (m *SourcePosition) GetOffset() int32 { + if m != nil { + return m.Offset + } + return 0 +} + +func (m *SourcePosition) GetLine() int32 { + if m != nil { + return m.Line + } + return 0 +} + +func (m *SourcePosition) GetColumn() int32 { + if m != nil { + return m.Column + } + return 0 +} + +func init() { + proto.RegisterType((*ParsedExpr)(nil), "google.api.expr.v1alpha1.ParsedExpr") + proto.RegisterType((*Expr)(nil), "google.api.expr.v1alpha1.Expr") + proto.RegisterType((*Expr_Ident)(nil), "google.api.expr.v1alpha1.Expr.Ident") + proto.RegisterType((*Expr_Select)(nil), "google.api.expr.v1alpha1.Expr.Select") + proto.RegisterType((*Expr_Call)(nil), "google.api.expr.v1alpha1.Expr.Call") + proto.RegisterType((*Expr_CreateList)(nil), "google.api.expr.v1alpha1.Expr.CreateList") + proto.RegisterType((*Expr_CreateStruct)(nil), "google.api.expr.v1alpha1.Expr.CreateStruct") + proto.RegisterType((*Expr_CreateStruct_Entry)(nil), "google.api.expr.v1alpha1.Expr.CreateStruct.Entry") + proto.RegisterType((*Expr_Comprehension)(nil), "google.api.expr.v1alpha1.Expr.Comprehension") + proto.RegisterType((*Constant)(nil), "google.api.expr.v1alpha1.Constant") + proto.RegisterType((*SourceInfo)(nil), "google.api.expr.v1alpha1.SourceInfo") + proto.RegisterMapType((map[int64]int32)(nil), "google.api.expr.v1alpha1.SourceInfo.PositionsEntry") + proto.RegisterType((*SourcePosition)(nil), "google.api.expr.v1alpha1.SourcePosition") +} + +func init() { + proto.RegisterFile("google/api/expr/v1alpha1/syntax.proto", fileDescriptor_syntax_c21dd3f8bb00852d) +} + +var fileDescriptor_syntax_c21dd3f8bb00852d = []byte{ + // 1134 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xcf, 0x6e, 0x1b, 0xb7, + 0x13, 0xd6, 0xea, 0x9f, 0xb5, 0x23, 0x5b, 0xf9, 0xfd, 0x88, 0xa2, 0x50, 0x36, 0x69, 0xe2, 0x38, + 0x35, 0x90, 0xa2, 0x85, 0x04, 0x3b, 0x41, 0x90, 0xc6, 0xe9, 0x45, 0xae, 0x0b, 0x19, 0x29, 0x1c, + 0x77, 0x5d, 0xf8, 0x50, 0xa0, 0x10, 0xe8, 0x15, 0xa5, 0x2c, 0x4c, 0x91, 0x8b, 0x25, 0xd7, 0xb0, + 0xce, 0x3d, 0xf4, 0xd6, 0x97, 0x69, 0x5f, 0xa0, 0xef, 0xd1, 0x07, 0xe9, 0xa5, 0x40, 0x31, 0x43, + 0xae, 0xfc, 0x0f, 0x86, 0xd4, 0x1b, 0x39, 0xfc, 0xbe, 0x8f, 0xc3, 0x99, 0xe1, 0x90, 0xb0, 0x3d, + 0xd5, 0x7a, 0x2a, 0x45, 0x9f, 0x67, 0x69, 0x5f, 0x5c, 0x66, 0x79, 0xff, 0x62, 0x87, 0xcb, 0xec, + 0x23, 0xdf, 0xe9, 0x9b, 0xb9, 0xb2, 0xfc, 0xb2, 0x97, 0xe5, 0xda, 0x6a, 0xd6, 0x75, 0xb0, 0x1e, + 0xcf, 0xd2, 0x1e, 0xc2, 0x7a, 0x25, 0x2c, 0x7a, 0xe2, 0x05, 0x08, 0x77, 0x56, 0x4c, 0xfa, 0xe3, + 0x22, 0xe7, 0x36, 0xd5, 0xca, 0x31, 0xa3, 0xc7, 0xb7, 0xd7, 0x8d, 0xcd, 0x8b, 0xc4, 0xfa, 0xd5, + 0xa7, 0xb7, 0x57, 0x6d, 0x3a, 0x13, 0xc6, 0xf2, 0x59, 0xe6, 0x00, 0x5b, 0xbf, 0x06, 0x00, 0xc7, + 0x3c, 0x37, 0x62, 0x7c, 0x70, 0x99, 0xe5, 0x6c, 0x17, 0xea, 0xb8, 0x7d, 0xb7, 0xba, 0x19, 0xbc, + 0x68, 0xef, 0x3e, 0xe9, 0xdd, 0xe7, 0x56, 0x0f, 0xd1, 0x31, 0x61, 0xd9, 0x01, 0xb4, 0x8d, 0x2e, + 0xf2, 0x44, 0x8c, 0x52, 0x35, 0xd1, 0xdd, 0x1a, 0x51, 0x3f, 0xbf, 0x9f, 0x7a, 0x42, 0xe0, 0x43, + 0x35, 0xd1, 0x31, 0x98, 0xc5, 0x78, 0xeb, 0xaf, 0x75, 0xa8, 0x93, 0x0f, 0x1d, 0xa8, 0xa6, 0x63, + 0xf2, 0xa0, 0x16, 0x57, 0xd3, 0x31, 0xdb, 0x07, 0x48, 0xb4, 0x32, 0x76, 0x44, 0x9e, 0x39, 0xf9, + 0xad, 0xfb, 0xe5, 0xf7, 0x11, 0xcb, 0x95, 0x1d, 0x56, 0xe2, 0x90, 0x78, 0x07, 0xce, 0x49, 0x48, + 0xc7, 0x42, 0x79, 0x91, 0xfa, 0x32, 0x1f, 0x91, 0xd3, 0x3b, 0x44, 0x02, 0xca, 0x10, 0x93, 0x64, + 0x86, 0xd0, 0x36, 0x42, 0x8a, 0xc4, 0xeb, 0x34, 0x48, 0x67, 0x7b, 0x89, 0xce, 0x09, 0x31, 0x86, + 0x95, 0x18, 0x1c, 0x97, 0x94, 0x06, 0x10, 0x26, 0x5c, 0x4a, 0xa7, 0xd3, 0x24, 0x9d, 0xe7, 0x4b, + 0x74, 0xf6, 0xb9, 0x94, 0xc3, 0x4a, 0xdc, 0x42, 0x9e, 0xf7, 0x26, 0x94, 0x69, 0x19, 0x98, 0x35, + 0xd2, 0xf8, 0x62, 0x99, 0x46, 0x2e, 0xb8, 0x15, 0xdf, 0xa7, 0x06, 0xfd, 0x69, 0x21, 0x9b, 0x94, + 0x8e, 0xa0, 0xed, 0xea, 0xc6, 0x69, 0xb5, 0x48, 0xeb, 0xcb, 0x95, 0xb4, 0x4e, 0x88, 0x47, 0xa7, + 0xa3, 0x11, 0xe9, 0xfd, 0x0c, 0x2c, 0xd1, 0xb3, 0x2c, 0x17, 0x1f, 0x85, 0x32, 0xa9, 0x56, 0x4e, + 0x36, 0x24, 0xd9, 0xaf, 0x96, 0xc9, 0x5e, 0x27, 0x0e, 0x2b, 0xf1, 0xff, 0x6f, 0x28, 0x21, 0x24, + 0x7a, 0x04, 0x0d, 0x4a, 0x0e, 0x63, 0x50, 0x57, 0x7c, 0x26, 0xba, 0xc1, 0x66, 0xf0, 0x22, 0x8c, + 0x69, 0x1c, 0x15, 0xd0, 0x74, 0x11, 0x67, 0x6f, 0x60, 0x4d, 0x67, 0x22, 0xe7, 0x6a, 0x4c, 0x80, + 0xe5, 0x05, 0x5d, 0xc2, 0xd9, 0x27, 0xd0, 0x98, 0xa4, 0x42, 0xba, 0x32, 0x0c, 0x63, 0x37, 0x61, + 0x8f, 0x20, 0xb4, 0xc2, 0xd8, 0x91, 0x56, 0x72, 0x4e, 0x85, 0xd8, 0x8a, 0x5b, 0x68, 0xf8, 0xa0, + 0xe4, 0x3c, 0xfa, 0x2d, 0x80, 0x3a, 0x66, 0x88, 0xbd, 0x86, 0xa6, 0xe5, 0xf9, 0x54, 0xd8, 0x15, + 0x37, 0xf5, 0x68, 0x16, 0x41, 0x6b, 0x52, 0xa8, 0x04, 0xef, 0xb6, 0xdf, 0x76, 0x31, 0xc7, 0x7b, + 0xc9, 0xf3, 0xa9, 0xe9, 0xd6, 0x36, 0x6b, 0xab, 0xdc, 0x4b, 0xc4, 0x46, 0x43, 0x80, 0xab, 0x6c, + 0xb3, 0xb7, 0xd0, 0x12, 0x52, 0xcc, 0x84, 0xb2, 0xa6, 0x1b, 0xac, 0xa4, 0xb2, 0xc0, 0x47, 0x7f, + 0x54, 0x61, 0xfd, 0x7a, 0xb2, 0xd9, 0x33, 0x58, 0x9f, 0x09, 0x63, 0xf8, 0x54, 0x8c, 0xae, 0x85, + 0xbf, 0xed, 0x6d, 0x47, 0x7c, 0x26, 0xd8, 0x7b, 0x58, 0x13, 0xca, 0xe6, 0xa9, 0x30, 0xdd, 0x2a, + 0x6d, 0xb7, 0xf3, 0x1f, 0xaa, 0xa9, 0x77, 0xa0, 0x6c, 0x3e, 0x8f, 0x4b, 0x85, 0xe8, 0xf7, 0x00, + 0x1a, 0x64, 0xf2, 0xcd, 0x21, 0x58, 0x34, 0x87, 0xcf, 0x20, 0xa4, 0xdc, 0x8c, 0xce, 0xc5, 0xdc, + 0x45, 0x0d, 0xeb, 0x9a, 0x4c, 0xef, 0xc5, 0x9c, 0x7d, 0x0d, 0x6b, 0x33, 0x9e, 0xd1, 0x62, 0x6d, + 0x95, 0x64, 0x0c, 0x2b, 0x71, 0x73, 0xc6, 0x33, 0xa4, 0xbe, 0x82, 0xc6, 0x05, 0x97, 0x85, 0xf0, + 0xcd, 0x62, 0x59, 0xb4, 0x1c, 0x78, 0x00, 0xd0, 0x3a, 0x17, 0xf3, 0xd1, 0x79, 0xaa, 0xc6, 0xd1, + 0x3f, 0x55, 0xd8, 0xb8, 0x51, 0xcc, 0xec, 0x21, 0xb4, 0x52, 0x2b, 0xf2, 0xd1, 0x05, 0xcf, 0x7d, + 0xcc, 0xd6, 0x70, 0x7e, 0xca, 0x73, 0xf6, 0x0d, 0x00, 0x2d, 0xe5, 0x5c, 0x4d, 0xc5, 0x8a, 0xfd, + 0x37, 0x44, 0x46, 0x8c, 0x04, 0x54, 0xe6, 0x49, 0x52, 0x90, 0x72, 0xcd, 0x29, 0xe3, 0x1c, 0x95, + 0xf7, 0x20, 0xa4, 0xa5, 0x54, 0xa5, 0x76, 0xc5, 0xc3, 0x90, 0xd6, 0xa1, 0x4a, 0x2d, 0x3b, 0x80, + 0x8e, 0xd4, 0x3a, 0x1b, 0x25, 0x5a, 0x8d, 0x53, 0x2a, 0xcd, 0xc6, 0x4a, 0x0a, 0x1b, 0xc8, 0xda, + 0x2f, 0x49, 0xe8, 0x03, 0xc9, 0x18, 0x2b, 0x32, 0xdf, 0xed, 0x96, 0xfa, 0x80, 0x84, 0x13, 0x2b, + 0x32, 0xbc, 0x50, 0xb9, 0x30, 0x85, 0xb4, 0xbe, 0xc7, 0x2d, 0xbd, 0x50, 0x0e, 0x3d, 0x68, 0x43, + 0x88, 0xab, 0x94, 0x8c, 0xad, 0x3f, 0x6b, 0xd0, 0x2a, 0x9f, 0x06, 0xb6, 0x07, 0xa0, 0x0a, 0x29, + 0x47, 0x2e, 0xc1, 0x98, 0x89, 0xce, 0x6e, 0x54, 0xaa, 0x96, 0x6f, 0x65, 0xef, 0xa8, 0x90, 0xf2, + 0x14, 0x11, 0xf8, 0x06, 0xa8, 0x72, 0xc2, 0x9e, 0x02, 0x9c, 0x69, 0x5d, 0x92, 0x31, 0x53, 0x2d, + 0x04, 0xa0, 0xcd, 0x01, 0x9e, 0x41, 0x3b, 0x55, 0xf6, 0xf5, 0x2b, 0x8f, 0xc0, 0x74, 0xd4, 0xb0, + 0x3f, 0x92, 0xd1, 0x41, 0x9e, 0xc3, 0x7a, 0x71, 0x1d, 0x83, 0x69, 0xa9, 0x0f, 0x2b, 0x71, 0xbb, + 0xb8, 0x09, 0x1a, 0xeb, 0xe2, 0x4c, 0x0a, 0x0f, 0xc2, 0xc8, 0x07, 0x08, 0x72, 0xd6, 0x05, 0xc8, + 0xd8, 0x3c, 0x55, 0x53, 0x0f, 0x6a, 0xfa, 0x3b, 0xd0, 0x76, 0xd6, 0x85, 0x47, 0x67, 0x73, 0x2b, + 0x8c, 0xc7, 0x60, 0x18, 0xd7, 0xd1, 0x23, 0x32, 0x3a, 0xc8, 0x77, 0xd0, 0x29, 0x7f, 0x16, 0x1e, + 0xe5, 0x1e, 0x81, 0x87, 0x77, 0xc2, 0xf2, 0xad, 0x87, 0x0d, 0xaa, 0x5d, 0xf4, 0x66, 0xa3, 0xa4, + 0x39, 0x9d, 0x43, 0x78, 0xb0, 0xf8, 0x63, 0x78, 0x21, 0xd7, 0xf6, 0xef, 0xc6, 0xf7, 0xc7, 0x12, + 0xe7, 0x95, 0x3a, 0x0b, 0x22, 0x49, 0x0d, 0x1e, 0xc0, 0x46, 0xe2, 0x33, 0xe6, 0x72, 0xf8, 0x4b, + 0x15, 0xe0, 0xea, 0xf7, 0xc0, 0xb6, 0xa1, 0xe3, 0x3e, 0x51, 0xa3, 0x0b, 0x91, 0xe3, 0xfd, 0xf2, + 0x77, 0x6a, 0xc3, 0x59, 0x4f, 0x9d, 0x11, 0xfb, 0xaa, 0xd4, 0x09, 0xbf, 0xde, 0x57, 0xcb, 0x39, + 0x36, 0x32, 0x99, 0x2a, 0x31, 0xd2, 0x93, 0x89, 0x11, 0xd6, 0xf5, 0xd7, 0x46, 0xdc, 0x46, 0xdb, + 0x07, 0x67, 0x62, 0x3f, 0x40, 0x98, 0x69, 0x43, 0x65, 0x6c, 0xba, 0x75, 0x6a, 0x65, 0x2f, 0x57, + 0xf9, 0xdc, 0xf4, 0x8e, 0x4b, 0x96, 0x6b, 0x66, 0x57, 0x2a, 0xd1, 0x3b, 0xe8, 0xdc, 0x5c, 0x64, + 0xff, 0x83, 0x1a, 0xf6, 0x28, 0xd7, 0xd7, 0x70, 0x88, 0x2f, 0xd0, 0x55, 0x81, 0x35, 0x7c, 0x7b, + 0x79, 0x5b, 0x7d, 0x13, 0x6c, 0x65, 0xd0, 0x71, 0xbb, 0x94, 0x1a, 0x37, 0x4e, 0x18, 0xdc, 0x3a, + 0xe1, 0xa7, 0xd0, 0x74, 0x87, 0xf3, 0x42, 0x7e, 0x86, 0x2f, 0x27, 0x9e, 0x92, 0xaa, 0xb3, 0x11, + 0xd3, 0x18, 0xb1, 0x89, 0x96, 0xc5, 0x4c, 0x51, 0x3d, 0x36, 0x62, 0x3f, 0x1b, 0x28, 0x78, 0x9c, + 0xe8, 0xd9, 0xbd, 0x87, 0x1e, 0xb4, 0x4f, 0x28, 0xe0, 0xc7, 0x98, 0xd8, 0xe3, 0xe0, 0xa7, 0x77, + 0x1e, 0x38, 0xd5, 0x92, 0xab, 0x69, 0x4f, 0xe7, 0xd3, 0xfe, 0x54, 0x28, 0x4a, 0x7b, 0xdf, 0x2d, + 0xf1, 0x2c, 0x35, 0x77, 0xbf, 0xc4, 0x7b, 0x38, 0xfb, 0x3b, 0x08, 0xce, 0x9a, 0x84, 0x7d, 0xf9, + 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x25, 0xe3, 0xe8, 0x3d, 0x0b, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/value.pb.go b/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/value.pb.go new file mode 100644 index 000000000..ce1f6a008 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1/value.pb.go @@ -0,0 +1,708 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/api/expr/v1alpha1/value.proto + +package expr // import "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import any "github.com/golang/protobuf/ptypes/any" +import _struct "github.com/golang/protobuf/ptypes/struct" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// Represents a CEL value. +// +// This is similar to `google.protobuf.Value`, but can represent CEL's full +// range of values. +type Value struct { + // Required. The valid kinds of values. + // + // Types that are valid to be assigned to Kind: + // *Value_NullValue + // *Value_BoolValue + // *Value_Int64Value + // *Value_Uint64Value + // *Value_DoubleValue + // *Value_StringValue + // *Value_BytesValue + // *Value_EnumValue + // *Value_ObjectValue + // *Value_MapValue + // *Value_ListValue + // *Value_TypeValue + Kind isValue_Kind `protobuf_oneof:"kind"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Value) Reset() { *m = Value{} } +func (m *Value) String() string { return proto.CompactTextString(m) } +func (*Value) ProtoMessage() {} +func (*Value) Descriptor() ([]byte, []int) { + return fileDescriptor_value_fb447fd6cf9e742a, []int{0} +} +func (m *Value) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Value.Unmarshal(m, b) +} +func (m *Value) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Value.Marshal(b, m, deterministic) +} +func (dst *Value) XXX_Merge(src proto.Message) { + xxx_messageInfo_Value.Merge(dst, src) +} +func (m *Value) XXX_Size() int { + return xxx_messageInfo_Value.Size(m) +} +func (m *Value) XXX_DiscardUnknown() { + xxx_messageInfo_Value.DiscardUnknown(m) +} + +var xxx_messageInfo_Value proto.InternalMessageInfo + +type isValue_Kind interface { + isValue_Kind() +} + +type Value_NullValue struct { + NullValue _struct.NullValue `protobuf:"varint,1,opt,name=null_value,json=nullValue,proto3,enum=google.protobuf.NullValue,oneof"` +} + +type Value_BoolValue struct { + BoolValue bool `protobuf:"varint,2,opt,name=bool_value,json=boolValue,proto3,oneof"` +} + +type Value_Int64Value struct { + Int64Value int64 `protobuf:"varint,3,opt,name=int64_value,json=int64Value,proto3,oneof"` +} + +type Value_Uint64Value struct { + Uint64Value uint64 `protobuf:"varint,4,opt,name=uint64_value,json=uint64Value,proto3,oneof"` +} + +type Value_DoubleValue struct { + DoubleValue float64 `protobuf:"fixed64,5,opt,name=double_value,json=doubleValue,proto3,oneof"` +} + +type Value_StringValue struct { + StringValue string `protobuf:"bytes,6,opt,name=string_value,json=stringValue,proto3,oneof"` +} + +type Value_BytesValue struct { + BytesValue []byte `protobuf:"bytes,7,opt,name=bytes_value,json=bytesValue,proto3,oneof"` +} + +type Value_EnumValue struct { + EnumValue *EnumValue `protobuf:"bytes,9,opt,name=enum_value,json=enumValue,proto3,oneof"` +} + +type Value_ObjectValue struct { + ObjectValue *any.Any `protobuf:"bytes,10,opt,name=object_value,json=objectValue,proto3,oneof"` +} + +type Value_MapValue struct { + MapValue *MapValue `protobuf:"bytes,11,opt,name=map_value,json=mapValue,proto3,oneof"` +} + +type Value_ListValue struct { + ListValue *ListValue `protobuf:"bytes,12,opt,name=list_value,json=listValue,proto3,oneof"` +} + +type Value_TypeValue struct { + TypeValue string `protobuf:"bytes,15,opt,name=type_value,json=typeValue,proto3,oneof"` +} + +func (*Value_NullValue) isValue_Kind() {} + +func (*Value_BoolValue) isValue_Kind() {} + +func (*Value_Int64Value) isValue_Kind() {} + +func (*Value_Uint64Value) isValue_Kind() {} + +func (*Value_DoubleValue) isValue_Kind() {} + +func (*Value_StringValue) isValue_Kind() {} + +func (*Value_BytesValue) isValue_Kind() {} + +func (*Value_EnumValue) isValue_Kind() {} + +func (*Value_ObjectValue) isValue_Kind() {} + +func (*Value_MapValue) isValue_Kind() {} + +func (*Value_ListValue) isValue_Kind() {} + +func (*Value_TypeValue) isValue_Kind() {} + +func (m *Value) GetKind() isValue_Kind { + if m != nil { + return m.Kind + } + return nil +} + +func (m *Value) GetNullValue() _struct.NullValue { + if x, ok := m.GetKind().(*Value_NullValue); ok { + return x.NullValue + } + return _struct.NullValue_NULL_VALUE +} + +func (m *Value) GetBoolValue() bool { + if x, ok := m.GetKind().(*Value_BoolValue); ok { + return x.BoolValue + } + return false +} + +func (m *Value) GetInt64Value() int64 { + if x, ok := m.GetKind().(*Value_Int64Value); ok { + return x.Int64Value + } + return 0 +} + +func (m *Value) GetUint64Value() uint64 { + if x, ok := m.GetKind().(*Value_Uint64Value); ok { + return x.Uint64Value + } + return 0 +} + +func (m *Value) GetDoubleValue() float64 { + if x, ok := m.GetKind().(*Value_DoubleValue); ok { + return x.DoubleValue + } + return 0 +} + +func (m *Value) GetStringValue() string { + if x, ok := m.GetKind().(*Value_StringValue); ok { + return x.StringValue + } + return "" +} + +func (m *Value) GetBytesValue() []byte { + if x, ok := m.GetKind().(*Value_BytesValue); ok { + return x.BytesValue + } + return nil +} + +func (m *Value) GetEnumValue() *EnumValue { + if x, ok := m.GetKind().(*Value_EnumValue); ok { + return x.EnumValue + } + return nil +} + +func (m *Value) GetObjectValue() *any.Any { + if x, ok := m.GetKind().(*Value_ObjectValue); ok { + return x.ObjectValue + } + return nil +} + +func (m *Value) GetMapValue() *MapValue { + if x, ok := m.GetKind().(*Value_MapValue); ok { + return x.MapValue + } + return nil +} + +func (m *Value) GetListValue() *ListValue { + if x, ok := m.GetKind().(*Value_ListValue); ok { + return x.ListValue + } + return nil +} + +func (m *Value) GetTypeValue() string { + if x, ok := m.GetKind().(*Value_TypeValue); ok { + return x.TypeValue + } + return "" +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*Value) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _Value_OneofMarshaler, _Value_OneofUnmarshaler, _Value_OneofSizer, []interface{}{ + (*Value_NullValue)(nil), + (*Value_BoolValue)(nil), + (*Value_Int64Value)(nil), + (*Value_Uint64Value)(nil), + (*Value_DoubleValue)(nil), + (*Value_StringValue)(nil), + (*Value_BytesValue)(nil), + (*Value_EnumValue)(nil), + (*Value_ObjectValue)(nil), + (*Value_MapValue)(nil), + (*Value_ListValue)(nil), + (*Value_TypeValue)(nil), + } +} + +func _Value_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*Value) + // kind + switch x := m.Kind.(type) { + case *Value_NullValue: + b.EncodeVarint(1<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.NullValue)) + case *Value_BoolValue: + t := uint64(0) + if x.BoolValue { + t = 1 + } + b.EncodeVarint(2<<3 | proto.WireVarint) + b.EncodeVarint(t) + case *Value_Int64Value: + b.EncodeVarint(3<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.Int64Value)) + case *Value_Uint64Value: + b.EncodeVarint(4<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.Uint64Value)) + case *Value_DoubleValue: + b.EncodeVarint(5<<3 | proto.WireFixed64) + b.EncodeFixed64(math.Float64bits(x.DoubleValue)) + case *Value_StringValue: + b.EncodeVarint(6<<3 | proto.WireBytes) + b.EncodeStringBytes(x.StringValue) + case *Value_BytesValue: + b.EncodeVarint(7<<3 | proto.WireBytes) + b.EncodeRawBytes(x.BytesValue) + case *Value_EnumValue: + b.EncodeVarint(9<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.EnumValue); err != nil { + return err + } + case *Value_ObjectValue: + b.EncodeVarint(10<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.ObjectValue); err != nil { + return err + } + case *Value_MapValue: + b.EncodeVarint(11<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.MapValue); err != nil { + return err + } + case *Value_ListValue: + b.EncodeVarint(12<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.ListValue); err != nil { + return err + } + case *Value_TypeValue: + b.EncodeVarint(15<<3 | proto.WireBytes) + b.EncodeStringBytes(x.TypeValue) + case nil: + default: + return fmt.Errorf("Value.Kind has unexpected type %T", x) + } + return nil +} + +func _Value_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*Value) + switch tag { + case 1: // kind.null_value + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Kind = &Value_NullValue{_struct.NullValue(x)} + return true, err + case 2: // kind.bool_value + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Kind = &Value_BoolValue{x != 0} + return true, err + case 3: // kind.int64_value + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Kind = &Value_Int64Value{int64(x)} + return true, err + case 4: // kind.uint64_value + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Kind = &Value_Uint64Value{x} + return true, err + case 5: // kind.double_value + if wire != proto.WireFixed64 { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeFixed64() + m.Kind = &Value_DoubleValue{math.Float64frombits(x)} + return true, err + case 6: // kind.string_value + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.Kind = &Value_StringValue{x} + return true, err + case 7: // kind.bytes_value + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeRawBytes(true) + m.Kind = &Value_BytesValue{x} + return true, err + case 9: // kind.enum_value + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(EnumValue) + err := b.DecodeMessage(msg) + m.Kind = &Value_EnumValue{msg} + return true, err + case 10: // kind.object_value + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(any.Any) + err := b.DecodeMessage(msg) + m.Kind = &Value_ObjectValue{msg} + return true, err + case 11: // kind.map_value + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(MapValue) + err := b.DecodeMessage(msg) + m.Kind = &Value_MapValue{msg} + return true, err + case 12: // kind.list_value + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(ListValue) + err := b.DecodeMessage(msg) + m.Kind = &Value_ListValue{msg} + return true, err + case 15: // kind.type_value + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.Kind = &Value_TypeValue{x} + return true, err + default: + return false, nil + } +} + +func _Value_OneofSizer(msg proto.Message) (n int) { + m := msg.(*Value) + // kind + switch x := m.Kind.(type) { + case *Value_NullValue: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(x.NullValue)) + case *Value_BoolValue: + n += 1 // tag and wire + n += 1 + case *Value_Int64Value: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(x.Int64Value)) + case *Value_Uint64Value: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(x.Uint64Value)) + case *Value_DoubleValue: + n += 1 // tag and wire + n += 8 + case *Value_StringValue: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(len(x.StringValue))) + n += len(x.StringValue) + case *Value_BytesValue: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(len(x.BytesValue))) + n += len(x.BytesValue) + case *Value_EnumValue: + s := proto.Size(x.EnumValue) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Value_ObjectValue: + s := proto.Size(x.ObjectValue) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Value_MapValue: + s := proto.Size(x.MapValue) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Value_ListValue: + s := proto.Size(x.ListValue) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *Value_TypeValue: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(len(x.TypeValue))) + n += len(x.TypeValue) + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +// An enum value. +type EnumValue struct { + // The fully qualified name of the enum type. + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + // The value of the enum. + Value int32 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EnumValue) Reset() { *m = EnumValue{} } +func (m *EnumValue) String() string { return proto.CompactTextString(m) } +func (*EnumValue) ProtoMessage() {} +func (*EnumValue) Descriptor() ([]byte, []int) { + return fileDescriptor_value_fb447fd6cf9e742a, []int{1} +} +func (m *EnumValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EnumValue.Unmarshal(m, b) +} +func (m *EnumValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EnumValue.Marshal(b, m, deterministic) +} +func (dst *EnumValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnumValue.Merge(dst, src) +} +func (m *EnumValue) XXX_Size() int { + return xxx_messageInfo_EnumValue.Size(m) +} +func (m *EnumValue) XXX_DiscardUnknown() { + xxx_messageInfo_EnumValue.DiscardUnknown(m) +} + +var xxx_messageInfo_EnumValue proto.InternalMessageInfo + +func (m *EnumValue) GetType() string { + if m != nil { + return m.Type + } + return "" +} + +func (m *EnumValue) GetValue() int32 { + if m != nil { + return m.Value + } + return 0 +} + +// A list. +// +// Wrapped in a message so 'not set' and empty can be differentiated, which is +// required for use in a 'oneof'. +type ListValue struct { + // The ordered values in the list. + Values []*Value `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ListValue) Reset() { *m = ListValue{} } +func (m *ListValue) String() string { return proto.CompactTextString(m) } +func (*ListValue) ProtoMessage() {} +func (*ListValue) Descriptor() ([]byte, []int) { + return fileDescriptor_value_fb447fd6cf9e742a, []int{2} +} +func (m *ListValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ListValue.Unmarshal(m, b) +} +func (m *ListValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ListValue.Marshal(b, m, deterministic) +} +func (dst *ListValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_ListValue.Merge(dst, src) +} +func (m *ListValue) XXX_Size() int { + return xxx_messageInfo_ListValue.Size(m) +} +func (m *ListValue) XXX_DiscardUnknown() { + xxx_messageInfo_ListValue.DiscardUnknown(m) +} + +var xxx_messageInfo_ListValue proto.InternalMessageInfo + +func (m *ListValue) GetValues() []*Value { + if m != nil { + return m.Values + } + return nil +} + +// A map. +// +// Wrapped in a message so 'not set' and empty can be differentiated, which is +// required for use in a 'oneof'. +type MapValue struct { + // The set of map entries. + // + // CEL has fewer restrictions on keys, so a protobuf map represenation + // cannot be used. + Entries []*MapValue_Entry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MapValue) Reset() { *m = MapValue{} } +func (m *MapValue) String() string { return proto.CompactTextString(m) } +func (*MapValue) ProtoMessage() {} +func (*MapValue) Descriptor() ([]byte, []int) { + return fileDescriptor_value_fb447fd6cf9e742a, []int{3} +} +func (m *MapValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MapValue.Unmarshal(m, b) +} +func (m *MapValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MapValue.Marshal(b, m, deterministic) +} +func (dst *MapValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_MapValue.Merge(dst, src) +} +func (m *MapValue) XXX_Size() int { + return xxx_messageInfo_MapValue.Size(m) +} +func (m *MapValue) XXX_DiscardUnknown() { + xxx_messageInfo_MapValue.DiscardUnknown(m) +} + +var xxx_messageInfo_MapValue proto.InternalMessageInfo + +func (m *MapValue) GetEntries() []*MapValue_Entry { + if m != nil { + return m.Entries + } + return nil +} + +// An entry in the map. +type MapValue_Entry struct { + // The key. + // + // Must be unique with in the map. + // Currently only boolean, int, uint, and string values can be keys. + Key *Value `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // The value. + Value *Value `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MapValue_Entry) Reset() { *m = MapValue_Entry{} } +func (m *MapValue_Entry) String() string { return proto.CompactTextString(m) } +func (*MapValue_Entry) ProtoMessage() {} +func (*MapValue_Entry) Descriptor() ([]byte, []int) { + return fileDescriptor_value_fb447fd6cf9e742a, []int{3, 0} +} +func (m *MapValue_Entry) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MapValue_Entry.Unmarshal(m, b) +} +func (m *MapValue_Entry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MapValue_Entry.Marshal(b, m, deterministic) +} +func (dst *MapValue_Entry) XXX_Merge(src proto.Message) { + xxx_messageInfo_MapValue_Entry.Merge(dst, src) +} +func (m *MapValue_Entry) XXX_Size() int { + return xxx_messageInfo_MapValue_Entry.Size(m) +} +func (m *MapValue_Entry) XXX_DiscardUnknown() { + xxx_messageInfo_MapValue_Entry.DiscardUnknown(m) +} + +var xxx_messageInfo_MapValue_Entry proto.InternalMessageInfo + +func (m *MapValue_Entry) GetKey() *Value { + if m != nil { + return m.Key + } + return nil +} + +func (m *MapValue_Entry) GetValue() *Value { + if m != nil { + return m.Value + } + return nil +} + +func init() { + proto.RegisterType((*Value)(nil), "google.api.expr.v1alpha1.Value") + proto.RegisterType((*EnumValue)(nil), "google.api.expr.v1alpha1.EnumValue") + proto.RegisterType((*ListValue)(nil), "google.api.expr.v1alpha1.ListValue") + proto.RegisterType((*MapValue)(nil), "google.api.expr.v1alpha1.MapValue") + proto.RegisterType((*MapValue_Entry)(nil), "google.api.expr.v1alpha1.MapValue.Entry") +} + +func init() { + proto.RegisterFile("google/api/expr/v1alpha1/value.proto", fileDescriptor_value_fb447fd6cf9e742a) +} + +var fileDescriptor_value_fb447fd6cf9e742a = []byte{ + // 518 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x94, 0xcb, 0x6e, 0xd4, 0x30, + 0x14, 0x86, 0x6b, 0xe6, 0xd2, 0xc9, 0x99, 0x11, 0x48, 0x56, 0x17, 0xc3, 0xa8, 0x52, 0x43, 0xca, + 0x22, 0xab, 0x44, 0x33, 0x50, 0x10, 0x2a, 0x9b, 0x8e, 0x5a, 0x69, 0x16, 0x80, 0xaa, 0x2c, 0x58, + 0xb0, 0x41, 0xce, 0xd4, 0x84, 0x50, 0xc7, 0x0e, 0x89, 0x5d, 0x91, 0xc7, 0xe3, 0x01, 0x78, 0x1f, + 0x96, 0xc8, 0xb7, 0x50, 0xa8, 0x46, 0xed, 0x2e, 0xe7, 0xf7, 0xf7, 0xfb, 0x5c, 0x7c, 0x14, 0x78, + 0x5e, 0x08, 0x51, 0x30, 0x9a, 0x92, 0xba, 0x4c, 0xe9, 0x8f, 0xba, 0x49, 0x6f, 0x96, 0x84, 0xd5, + 0x5f, 0xc9, 0x32, 0xbd, 0x21, 0x4c, 0xd1, 0xa4, 0x6e, 0x84, 0x14, 0x78, 0x6e, 0xa9, 0x84, 0xd4, + 0x65, 0xa2, 0xa9, 0xc4, 0x53, 0x8b, 0xa7, 0xce, 0x6f, 0xb8, 0x5c, 0x7d, 0x49, 0x09, 0xef, 0xac, + 0x69, 0x71, 0xf8, 0xff, 0x51, 0x2b, 0x1b, 0xb5, 0x95, 0xf6, 0x34, 0xfa, 0x35, 0x84, 0xd1, 0x47, + 0x9d, 0x02, 0x9f, 0x02, 0x70, 0xc5, 0xd8, 0x67, 0x93, 0x70, 0x8e, 0x42, 0x14, 0x3f, 0x5e, 0x2d, + 0x12, 0x97, 0xd1, 0x9b, 0x93, 0x0f, 0x8a, 0x31, 0xc3, 0x6f, 0xf6, 0xb2, 0x80, 0xfb, 0x00, 0x1f, + 0x01, 0xe4, 0x42, 0x78, 0xf3, 0xa3, 0x10, 0xc5, 0x13, 0x0d, 0x68, 0xcd, 0x02, 0xcf, 0x60, 0x5a, + 0x72, 0xf9, 0xea, 0xa5, 0x23, 0x06, 0x21, 0x8a, 0x07, 0x9b, 0xbd, 0x0c, 0x8c, 0x68, 0x91, 0x63, + 0x98, 0xa9, 0xdb, 0xcc, 0x30, 0x44, 0xf1, 0x70, 0xb3, 0x97, 0x4d, 0xd5, 0xbf, 0xd0, 0x95, 0x50, + 0x39, 0xa3, 0x0e, 0x1a, 0x85, 0x28, 0x46, 0x1a, 0xb2, 0x6a, 0x0f, 0xb5, 0xb2, 0x29, 0x79, 0xe1, + 0xa0, 0x71, 0x88, 0xe2, 0x40, 0x43, 0x56, 0xed, 0x2b, 0xca, 0x3b, 0x49, 0x5b, 0xc7, 0xec, 0x87, + 0x28, 0x9e, 0xe9, 0x8a, 0x8c, 0x68, 0x91, 0x73, 0x00, 0xca, 0x55, 0xe5, 0x88, 0x20, 0x44, 0xf1, + 0x74, 0x75, 0x9c, 0xec, 0x7a, 0x84, 0xe4, 0x82, 0xab, 0xaa, 0x9f, 0x0d, 0xf5, 0x01, 0x7e, 0x03, + 0x33, 0x91, 0x7f, 0xa3, 0x5b, 0xe9, 0xee, 0x01, 0x73, 0xcf, 0xc1, 0x9d, 0xd1, 0x9e, 0xf1, 0x4e, + 0xd7, 0x68, 0x59, 0x6b, 0x3d, 0x83, 0xa0, 0x22, 0xb5, 0xf3, 0x4d, 0x8d, 0x2f, 0xda, 0x9d, 0xff, + 0x3d, 0xa9, 0x7d, 0xfa, 0x49, 0xe5, 0xbe, 0x75, 0x0f, 0xac, 0x6c, 0x7d, 0xee, 0xd9, 0x7d, 0x3d, + 0xbc, 0x2b, 0x5b, 0xd9, 0xf7, 0xc0, 0x7c, 0xa0, 0xdf, 0x57, 0x76, 0xb5, 0x1f, 0xfa, 0x13, 0x37, + 0xcf, 0x40, 0x6b, 0x06, 0x58, 0x8f, 0x61, 0x78, 0x5d, 0xf2, 0xab, 0xe8, 0x04, 0x82, 0x7e, 0x0c, + 0x18, 0xc3, 0x50, 0x13, 0x66, 0x99, 0x82, 0xcc, 0x7c, 0xe3, 0x03, 0x18, 0xfd, 0x5d, 0x92, 0x51, + 0x66, 0x83, 0xe8, 0x1c, 0x82, 0x3e, 0x33, 0x7e, 0x0d, 0x63, 0xa3, 0xb6, 0x73, 0x14, 0x0e, 0xe2, + 0xe9, 0xea, 0x68, 0x77, 0xb9, 0xc6, 0x90, 0x39, 0x3c, 0xfa, 0x89, 0x60, 0xe2, 0x87, 0x80, 0xd7, + 0xb0, 0x4f, 0xb9, 0x6c, 0xca, 0xfe, 0x9a, 0xf8, 0xfe, 0xc9, 0x25, 0x17, 0x5c, 0x36, 0x5d, 0xe6, + 0x8d, 0x8b, 0xef, 0x30, 0x32, 0x0a, 0x5e, 0xc2, 0xe0, 0x9a, 0x76, 0xa6, 0x91, 0x07, 0xd4, 0xa3, + 0x59, 0x7c, 0x72, 0xbb, 0xd1, 0x07, 0x98, 0x2c, 0xbd, 0xae, 0xe0, 0x70, 0x2b, 0xaa, 0x9d, 0xf0, + 0x1a, 0x0c, 0x7d, 0xa9, 0x97, 0xe6, 0x12, 0x7d, 0x7a, 0xeb, 0xb8, 0x42, 0x30, 0xc2, 0x8b, 0x44, + 0x34, 0x45, 0x5a, 0x50, 0x6e, 0x56, 0x2a, 0xb5, 0x47, 0xa4, 0x2e, 0xdb, 0xbb, 0xbf, 0x95, 0x53, + 0x1d, 0xfd, 0x46, 0x28, 0x1f, 0x1b, 0xf6, 0xc5, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf9, 0x53, + 0x8e, 0x99, 0x81, 0x04, 0x00, 0x00, +}