diff -Nru golang-github-google-cel-go-0.11.4+ds/cel/BUILD.bazel golang-github-google-cel-go-0.12.5+ds/cel/BUILD.bazel --- golang-github-google-cel-go-0.11.4+ds/cel/BUILD.bazel 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/cel/BUILD.bazel 2022-12-20 15:30:36.000000000 +0000 @@ -8,9 +8,11 @@ name = "go_default_library", srcs = [ "cel.go", + "decls.go", "env.go", "io.go", "library.go", + "macro.go", "options.go", "program.go", ], @@ -21,6 +23,7 @@ "//checker/decls:go_default_library", "//common:go_default_library", "//common/containers:go_default_library", + "//common/overloads:go_default_library", "//common/types:go_default_library", "//common/types/pb:go_default_library", "//common/types/ref:go_default_library", @@ -46,6 +49,7 @@ srcs = [ "cel_example_test.go", "cel_test.go", + "decls_test.go", "env_test.go", "io_test.go", ], @@ -56,13 +60,11 @@ ":go_default_library", ], deps = [ - "//checker/decls:go_default_library", "//common/operators:go_default_library", "//common/overloads:go_default_library", "//common/types:go_default_library", "//common/types/ref:go_default_library", "//common/types/traits:go_default_library", - "//interpreter/functions:go_default_library", "//test:go_default_library", "//test/proto2pb:go_default_library", "//test/proto3pb:go_default_library", diff -Nru golang-github-google-cel-go-0.11.4+ds/cel/cel_example_test.go golang-github-google-cel-go-0.12.5+ds/cel/cel_example_test.go --- golang-github-google-cel-go-0.11.4+ds/cel/cel_example_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/cel/cel_example_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -19,29 +19,26 @@ "log" "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" - - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) func Example() { - // Create the CEL environment with declarations for the input attributes and - // the desired extension functions. In many cases the desired functionality will - // be present in a built-in function. - decls := cel.Declarations( - // Identifiers used within this expression. - decls.NewVar("i", decls.String), - decls.NewVar("you", decls.String), - // Function to generate a greeting from one person to another. - // i.greet(you) - decls.NewFunction("greet", - decls.NewInstanceOverload("string_greet_string", - []*exprpb.Type{decls.String, decls.String}, - decls.String))) - e, err := cel.NewEnv(decls) + // Create the CEL environment with declarations for the input attributes and the extension functions. + // In many cases the desired functionality will be present in a built-in function. + e, err := cel.NewEnv( + // Variable identifiers used within this expression. + cel.Variable("i", cel.StringType), + cel.Variable("you", cel.StringType), + // Function to generate a greeting from one person to another: i.greet(you) + cel.Function("greet", + cel.MemberOverload("string_greet_string", []*cel.Type{cel.StringType, cel.StringType}, cel.StringType, + cel.BinaryBinding(func(lhs, rhs ref.Val) ref.Val { + return types.String(fmt.Sprintf("Hello %s! Nice to meet you, I'm %s.\n", rhs, lhs)) + }), + ), + ), + ) if err != nil { log.Fatalf("environment creation error: %s\n", err) } @@ -53,14 +50,7 @@ } // Create the program. - funcs := cel.Functions( - &functions.Overload{ - Operator: "string_greet_string", - Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { - return types.String( - fmt.Sprintf("Hello %s! Nice to meet you, I'm %s.\n", rhs, lhs)) - }}) - prg, err := e.Program(ast, funcs) + prg, err := e.Program(ast) if err != nil { log.Fatalf("program creation error: %s\n", err) } @@ -85,17 +75,20 @@ // Create the CEL environment with declarations for the input attributes and // the desired extension functions. In many cases the desired functionality will // be present in a built-in function. - decls := cel.Declarations( + e, err := cel.NewEnv( // Identifiers used within this expression. - decls.NewVar("i", decls.String), - decls.NewVar("you", decls.String), + cel.Variable("i", cel.StringType), + cel.Variable("you", cel.StringType), // Function to generate shake_hands between two people. // shake_hands(i,you) - decls.NewFunction("shake_hands", - decls.NewOverload("shake_hands_string_string", - []*exprpb.Type{decls.String, decls.String}, - decls.String))) - e, err := cel.NewEnv(decls) + cel.Function("shake_hands", + cel.Overload("shake_hands_string_string", []*cel.Type{cel.StringType, cel.StringType}, cel.StringType, + cel.BinaryBinding(func(arg1, arg2 ref.Val) ref.Val { + return types.String(fmt.Sprintf("%v and %v are shaking hands.\n", arg1, arg2)) + }), + ), + ), + ) if err != nil { log.Fatalf("environment creation error: %s\n", err) } @@ -107,22 +100,7 @@ } // Create the program. - funcs := cel.Functions( - &functions.Overload{ - Operator: "shake_hands_string_string", - Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { - s1, ok := lhs.(types.String) - if !ok { - return types.ValOrErr(lhs, "unexpected type '%v' passed to shake_hands", lhs.Type()) - } - s2, ok := rhs.(types.String) - if !ok { - return types.ValOrErr(rhs, "unexpected type '%v' passed to shake_hands", rhs.Type()) - } - return types.String( - fmt.Sprintf("%s and %s are shaking hands.\n", s1, s2)) - }}) - prg, err := e.Program(ast, funcs) + prg, err := e.Program(ast) if err != nil { log.Fatalf("program creation error: %s\n", err) } diff -Nru golang-github-google-cel-go-0.11.4+ds/cel/cel_test.go golang-github-google-cel-go-0.12.5+ds/cel/cel_test.go --- golang-github-google-cel-go-0.11.4+ds/cel/cel_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/cel/cel_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -29,7 +29,6 @@ "google.golang.org/protobuf/reflect/protoreflect" "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/operators" "github.com/google/cel-go/common/overloads" @@ -37,8 +36,6 @@ "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/common/types/traits" "github.com/google/cel-go/interpreter" - "github.com/google/cel-go/interpreter/functions" - "github.com/google/cel-go/parser" "github.com/google/cel-go/test" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" @@ -51,10 +48,10 @@ func Test_ExampleWithBuiltins(t *testing.T) { // Variables used within this expression environment. - decls := Declarations( - decls.NewVar("i", decls.String), - decls.NewVar("you", decls.String)) - env, err := NewEnv(decls) + env, err := NewEnv( + Variable("i", StringType), + Variable("you", StringType), + ) if err != nil { t.Fatalf("environment creation error: %s\n", err) } @@ -90,9 +87,7 @@ // Test whether abbreviations successfully resolve at type-check time (compile time). env, err := NewEnv( Abbrevs("qualified.identifier.name"), - Declarations( - decls.NewVar("qualified.identifier.name.first", decls.String), - ), + Variable("qualified.identifier.name.first", StringType), ) if err != nil { t.Fatal(err) @@ -149,15 +144,14 @@ } } -func TestAbbrevs_Disambiguation(t *testing.T) { +func TestAbbrevsDisambiguation(t *testing.T) { env, err := NewEnv( Abbrevs("external.Expr"), Container("google.api.expr.v1alpha1"), Types(&exprpb.Expr{}), - Declarations( - decls.NewVar("test", decls.Bool), - decls.NewVar("external.Expr", decls.String), - ), + + Variable("test", BoolType), + Variable("external.Expr", StringType), ) if err != nil { t.Fatal(err) @@ -165,15 +159,7 @@ // This expression will return either a string or a protobuf Expr value depending on the value // of the 'test' argument. The fully qualified type name is used indicate that the protobuf // typed 'Expr' should be used rather than the abbreviatation for 'external.Expr'. - ast, iss := env.Compile(`test ? dyn(Expr) : google.api.expr.v1alpha1.Expr{id: 1}`) - if iss.Err() != nil { - t.Fatal(iss.Err()) - } - prg, err := env.Program(ast) - if err != nil { - t.Fatal(err) - } - out, _, err := prg.Eval( + out, err := interpret(t, env, `test ? dyn(Expr) : google.api.expr.v1alpha1.Expr{id: 1}`, map[string]interface{}{ "test": true, "external.Expr": "string expr", @@ -185,7 +171,7 @@ if out.Value() != "string expr" { t.Errorf("got %v, wanted 'string expr'", out) } - out, _, err = prg.Eval( + out, err = interpret(t, env, `test ? dyn(Expr) : google.api.expr.v1alpha1.Expr{id: 1}`, map[string]interface{}{ "test": false, "external.Expr": "wrong expr", @@ -195,7 +181,10 @@ t.Fatal(err) } want := &exprpb.Expr{Id: 1} - got, _ := out.ConvertToNative(reflect.TypeOf(want)) + got, err := out.ConvertToNative(reflect.TypeOf(want)) + if err != nil { + t.Fatal(err) + } if !proto.Equal(got.(*exprpb.Expr), want) { t.Errorf("got %v, wanted '%v'", out, want) } @@ -213,9 +202,10 @@ } func TestCustomEnv(t *testing.T) { - e, _ := NewCustomEnv( - Declarations(decls.NewVar("a.b.c", decls.Bool))) - + e, err := NewCustomEnv(Variable("a.b.c", BoolType)) + if err != nil { + t.Fatalf("NewCustomEnv(a.b.c:bool) failed: %v", err) + } t.Run("err", func(t *testing.T) { _, iss := e.Compile("a.b.c == true") if iss.Err() == nil { @@ -224,12 +214,10 @@ }) t.Run("ok", func(t *testing.T) { - ast, iss := e.Compile("a.b.c") - if iss.Err() != nil { - t.Fatal(iss.Err()) + out, err := interpret(t, e, "a.b.c", map[string]interface{}{"a.b.c": true}) + if err != nil { + t.Fatal(err) } - prg, _ := e.Program(ast) - out, _, _ := prg.Eval(map[string]interface{}{"a.b.c": true}) if out != types.True { t.Errorf("got '%v', wanted 'true'", out.Value()) } @@ -238,31 +226,25 @@ func TestHomogeneousAggregateLiterals(t *testing.T) { e, err := NewCustomEnv( - Declarations( - decls.NewVar("name", decls.String), - decls.NewFunction( - operators.In, - decls.NewOverload(overloads.InList, []*exprpb.Type{ - decls.String, decls.NewListType(decls.String), - }, decls.Bool), - decls.NewOverload(overloads.InMap, []*exprpb.Type{ - decls.String, decls.NewMapType(decls.String, decls.Bool), - }, decls.Bool))), - HomogeneousAggregateLiterals()) + Variable("name", StringType), + Function(operators.In, + Overload(overloads.InList, []*Type{StringType, ListType(StringType)}, BoolType, + BinaryBinding(func(lhs, rhs ref.Val) ref.Val { + return rhs.(traits.Container).Contains(lhs) + }), + ), + Overload(overloads.InMap, []*Type{StringType, MapType(StringType, BoolType)}, BoolType, + BinaryBinding(func(lhs, rhs ref.Val) ref.Val { + return rhs.(traits.Container).Contains(lhs) + }), + ), + ), + HomogeneousAggregateLiterals(), + ) if err != nil { t.Fatalf("NewCustomEnv() failed: %v", err) } - funcs := Functions(&functions.Overload{ - Operator: operators.In, - Binary: func(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") - }, - }) - tests := []struct { name string expr string @@ -326,7 +308,7 @@ if iss.Err() != nil { t.Fatalf("e.Compile(%v) failed: %v", tc.expr, iss.Err()) } - prg, err := e.Program(ast, funcs) + prg, err := e.Program(ast) if err != nil { t.Fatalf("e.Program() failed: %v", err) } @@ -415,7 +397,6 @@ } func TestCustomTypes(t *testing.T) { - exprType := decls.NewObjectType("google.api.expr.v1alpha1.Expr") reg := types.NewEmptyRegistry() e, _ := NewEnv( CustomTypeAdapter(reg), @@ -426,8 +407,8 @@ types.BoolType, types.IntType, types.StringType), - Declarations( - decls.NewVar("expr", exprType))) + Variable("expr", ObjectType("google.api.expr.v1alpha1.Expr")), + ) ast, _ := e.Compile(` expr == Expr{id: 2, @@ -437,8 +418,8 @@ Expr{id: 1, ident_expr: Expr.Ident{ name: "a" }}, Expr{id: 3, ident_expr: Expr.Ident{ name: "b" }}] }}`) - if !proto.Equal(ast.ResultType(), decls.Bool) { - t.Fatalf("got %v, wanted type bool", ast.ResultType()) + if ast.OutputType() != BoolType { + t.Fatalf("got %v, wanted type bool", ast.OutputType()) } prg, _ := e.Program(ast) vars := map[string]interface{}{"expr": &exprpb.Expr{ @@ -481,9 +462,8 @@ e, err := NewEnv( TypeDescs(&fds), - Declarations( - decls.NewVar("myteam", - decls.NewObjectType("cel.testdata.Team")))) + Variable("myteam", ObjectType("cel.testdata.Team")), + ) if err != nil { t.Fatalf("NewEnv() failed: %v", err) } @@ -495,10 +475,7 @@ } // Ensure that isolated types don't leak through. - e2, _ := NewEnv( - Declarations( - decls.NewVar("myteam", - decls.NewObjectType("cel.testdata.Team")))) + e2, _ := NewEnv(Variable("myteam", ObjectType("cel.testdata.Team"))) _, iss = e2.Compile(src) if iss == nil || iss.Err() == nil { t.Errorf("wanted compile failure for unknown message.") @@ -596,7 +573,7 @@ // however, it tests a different code path which aggregates individual // FileDescriptorProto values together. TypeDescs(fileCopy...), - Declarations(decls.NewVar("mutant", decls.NewObjectType("cel.testdata.Mutant"))), + Variable("mutant", ObjectType("cel.testdata.Mutant")), ) if err != nil { t.Fatalf("NewEnv() failed: %v", err) @@ -626,50 +603,40 @@ } func TestGlobalVars(t *testing.T) { - mapStrDyn := decls.NewMapType(decls.String, decls.Dyn) - e, _ := NewEnv( - Declarations( - decls.NewVar("attrs", mapStrDyn), - decls.NewVar("default", decls.Dyn), - decls.NewFunction( - "get", - decls.NewInstanceOverload( - "get_map", - []*exprpb.Type{mapStrDyn, decls.String, decls.Dyn}, - decls.Dyn)))) - ast, _ := e.Compile(`attrs.get("first", attrs.get("second", default))`) - - // Create the program. - funcs := Functions( - &functions.Overload{ - Operator: "get", - Function: func(args ...ref.Val) ref.Val { - if len(args) != 3 { - return types.NewErr("invalid arguments to 'get'") - } - attrs, ok := args[0].(traits.Mapper) - if !ok { - return types.NewErr( - "invalid operand of type '%v' to obj.get(key, def)", - args[0].Type()) - } - key, ok := args[1].(types.String) - if !ok { - return types.NewErr( - "invalid key of type '%v' to obj.get(key, def)", - args[1].Type()) - } - defVal := args[2] - if attrs.Contains(key) == types.True { - return attrs.Get(key) - } - return defVal - }}) + e, err := NewEnv( + Variable("attrs", MapType(StringType, DynType)), + Variable("default", DynType), + Function("get", + MemberOverload("get_map", []*Type{MapType(StringType, DynType), StringType, DynType}, DynType, + FunctionBinding(func(args ...ref.Val) ref.Val { + attrs, ok := args[0].(traits.Mapper) + if !ok { + return types.NewErr( + "invalid operand of type '%v' to obj.get(key, def)", + args[0].Type()) + } + key := args[1] + defVal := args[2] + if attrs.Contains(key) == types.True { + return attrs.Get(key) + } + return defVal + }), + ), + ), + ) + if err != nil { + t.Fatalf("NewEnv() failed: %v", err) + } + ast, iss := e.Compile(`attrs.get("first", attrs.get("second", default))`) + if iss.Err() != nil { + t.Fatalf("e.Parse() failed: %v", iss.Err()) + } // Global variables can be configured as a ProgramOption and optionally overridden on Eval. // Add a previous globals map to confirm the order of shadowing and a final empty global // map to show that globals are not clobbered. - prg, _ := e.Program(ast, funcs, + prg, err := e.Program(ast, Globals(map[string]interface{}{ "default": "shadow me", }), @@ -678,11 +645,27 @@ }), Globals(map[string]interface{}{}), ) + if err != nil { + t.Fatalf("e.Program() failed: %v", err) + } + + t.Run("bad_attrs", func(t *testing.T) { + out, _, err := prg.Eval(map[string]interface{}{ + "attrs": []string{"one", "two"}, + }) + if err == nil { + t.Errorf("prg.Eval() of incorrect arg type invoked function, wanted error, got %v", out) + } + }) t.Run("global_default", func(t *testing.T) { vars := map[string]interface{}{ - "attrs": map[string]interface{}{}} - out, _, _ := prg.Eval(vars) + "attrs": map[string]interface{}{}, + } + out, _, err := prg.Eval(vars) + if err != nil { + t.Fatalf("prg.Eval() failed: %v", err) + } if out.Equal(types.String("third")) != types.True { t.Errorf("got '%v', expected 'third'.", out.Value()) } @@ -691,7 +674,10 @@ t.Run("attrs_alt", func(t *testing.T) { vars := map[string]interface{}{ "attrs": map[string]interface{}{"second": "yep"}} - out, _, _ := prg.Eval(vars) + out, _, err := prg.Eval(vars) + if err != nil { + t.Fatalf("prg.Eval(vars) failed: %v", err) + } if out.Equal(types.String("yep")) != types.True { t.Errorf("got '%v', expected 'yep'.", out.Value()) } @@ -708,83 +694,60 @@ }) } -func TestClearMacros(t *testing.T) { - e, err := NewEnv(ClearMacros()) +func TestMacroSubset(t *testing.T) { + // Only enable the 'has' macro rather than all parser macros. + env, err := NewEnv( + ClearMacros(), Macros(HasMacro), + Variable("name", MapType(StringType, StringType)), + ) if err != nil { - t.Fatalf("NewEnv(ClearMacros()) failed: %v", err) - } - ast, iss := e.Parse("has(a.b)") - if iss.Err() != nil { - t.Fatalf("Parse(`has(a.b)`) failed: %v", iss.Err()) + t.Fatalf("NewEnv() failed: %v", err) } - pe, err := AstToParsedExpr(ast) + out, err := interpret(t, env, `has(name.first)`, + map[string]interface{}{ + "name": map[string]string{ + "first": "Jim", + }, + }) if err != nil { - t.Fatalf("AstToParsedExpr(ast) failed: %v", err) + t.Fatal(err) } - want := &exprpb.Expr{ - Id: 1, - ExprKind: &exprpb.Expr_CallExpr{ - CallExpr: &exprpb.Expr_Call{ - Function: "has", - Args: []*exprpb.Expr{ - { - Id: 3, - ExprKind: &exprpb.Expr_SelectExpr{ - SelectExpr: &exprpb.Expr_Select{ - Operand: &exprpb.Expr{ - Id: 2, - ExprKind: &exprpb.Expr_IdentExpr{ - IdentExpr: &exprpb.Expr_Ident{Name: "a"}, - }, - }, - Field: "b", - }, - }, - }, - }, - }, - }, + if out != types.True { + t.Errorf("got %v, wanted true", out) } - if !proto.Equal(pe.GetExpr(), want) { - t.Errorf("Parse() produced AST with macro replacement rather than call. got %v, wanted %v", pe, want) + out, err = interpret(t, env, `[1, 2].all(i, i > 0)`, NoVars()) + if err == nil { + t.Errorf("got %v, wanted err", out) } } func TestCustomMacro(t *testing.T) { - joinMacro := parser.NewReceiverMacro("join", 1, - func(eh parser.ExprHelper, - target *exprpb.Expr, - args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + joinMacro := NewReceiverMacro("join", 1, + func(meh MacroExprHelper, iterRange *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { delim := args[0] - iterIdent := eh.Ident("__iter__") - accuIdent := eh.Ident("__result__") - init := eh.LiteralString("") - condition := eh.LiteralBool(true) - step := eh.GlobalCall( + iterIdent := meh.Ident("__iter__") + accuIdent := meh.AccuIdent() + accuInit := meh.LiteralString("") + condition := meh.LiteralBool(true) + step := meh.GlobalCall( + // __result__.size() > 0 ? __result__ + delim + __iter__ : __iter__ operators.Conditional, - eh.GlobalCall(operators.Greater, - eh.ReceiverCall("size", accuIdent), - eh.LiteralInt(0)), - eh.GlobalCall( - operators.Add, - eh.GlobalCall( - operators.Add, - accuIdent, - delim), - iterIdent), + meh.GlobalCall(operators.Greater, meh.ReceiverCall("size", accuIdent), meh.LiteralInt(0)), + meh.GlobalCall(operators.Add, meh.GlobalCall(operators.Add, accuIdent, delim), iterIdent), iterIdent) - return eh.Fold( + return meh.Fold( "__iter__", - target, - "__result__", - init, + iterRange, + accuIdent.GetIdentExpr().GetName(), + accuInit, condition, step, accuIdent), nil }) - e, _ := NewEnv( - Macros(joinMacro), - ) + e, err := NewEnv(Macros(joinMacro)) + if err != nil { + t.Fatalf("NewEnv(joinMacro) failed: %v", err) + } ast, iss := e.Compile(`['hello', 'cel', 'friend'].join(',')`) if iss.Err() != nil { t.Fatal(iss.Err()) @@ -802,6 +765,83 @@ } } +func TestCustomExistsMacro(t *testing.T) { + env, err := NewEnv( + Variable("attr", MapType(StringType, BoolType)), + Macros( + NewGlobalVarArgMacro("kleeneOr", + func(meh MacroExprHelper, unused *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + inputs := meh.NewList(args...) + eqOne, err := ExistsMacroExpander(meh, inputs, []*exprpb.Expr{ + meh.Ident("__iter__"), + meh.GlobalCall(operators.Equals, meh.Ident("__iter__"), meh.LiteralInt(1)), + }) + if err != nil { + return nil, err + } + eqZero, err := ExistsMacroExpander(meh, inputs, []*exprpb.Expr{ + meh.Ident("__iter__"), + meh.GlobalCall(operators.Equals, meh.Ident("__iter__"), meh.LiteralInt(0)), + }) + if err != nil { + return nil, err + } + return meh.GlobalCall( + operators.Conditional, + eqOne, + meh.LiteralInt(1), + meh.GlobalCall( + operators.Conditional, + eqZero, + meh.LiteralInt(0), + meh.LiteralInt(-1), + ), + ), nil + }, + ), + NewGlobalMacro("kleeneEq", 2, + func(meh MacroExprHelper, unused *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + attr := args[0] + value := args[1] + hasAttr, err := HasMacroExpander(meh, nil, []*exprpb.Expr{attr}) + if err != nil { + return nil, err + } + return meh.GlobalCall( + operators.Conditional, + meh.GlobalCall(operators.LogicalNot, hasAttr), + meh.LiteralInt(0), + meh.GlobalCall( + operators.Conditional, + meh.GlobalCall(operators.Equals, attr, value), + meh.LiteralInt(1), + meh.LiteralInt(-1), + ), + ), nil + }, + ), + ), + ) + if err != nil { + t.Fatalf("NewEnv() failed: %v", err) + } + ast, iss := env.Compile("kleeneOr(kleeneEq(attr.value, true), kleeneOr(0, 1, 1)) == 1") + if iss.Err() != nil { + t.Fatalf("env.Compile() failed: %v", iss.Err()) + } + prg, err := env.Program(ast) + if err != nil { + t.Fatalf("env.Program(ast) failed: %v", err) + } + out, _, err := prg.Eval(map[string]interface{}{"attr": map[string]bool{"value": false}}) + if err != nil { + t.Errorf("prg.Eval() got %v, wanted non-error", err) + } + if out != types.True { + t.Errorf("prg.Eval() got %v, wanted true", out) + } +} + func TestAstIsChecked(t *testing.T) { e, err := NewEnv() if err != nil { @@ -829,9 +869,9 @@ func TestEvalOptions(t *testing.T) { e, _ := NewEnv( - Declarations( - decls.NewVar("k", decls.String), - decls.NewVar("v", decls.Bool))) + Variable("k", StringType), + Variable("v", BoolType), + ) ast, _ := e.Compile(`{k: true}[k] || v != false`) prg, err := e.Program(ast, EvalOptions(OptExhaustiveEval)) @@ -871,11 +911,7 @@ } func TestContextEval(t *testing.T) { - env, err := NewEnv( - Declarations( - decls.NewVar("items", decls.NewListType(decls.Int)), - ), - ) + env, err := NewEnv(Variable("items", ListType(IntType))) if err != nil { t.Fatalf("NewEnv() failed: %v", err) } @@ -915,9 +951,7 @@ func BenchmarkContextEval(b *testing.B) { env, err := NewEnv( - Declarations( - decls.NewVar("items", decls.NewListType(decls.Int)), - ), + Variable("items", ListType(IntType)), ) if err != nil { b.Fatalf("NewEnv() failed: %v", err) @@ -949,28 +983,32 @@ func TestEvalRecover(t *testing.T) { e, err := NewEnv( - Declarations( - decls.NewFunction("panic", - decls.NewOverload("panic", []*exprpb.Type{}, decls.Bool)), - )) + Function("panic", + Overload("global_panic", []*Type{}, BoolType, + FunctionBinding(func(args ...ref.Val) ref.Val { + panic("watch me recover") + }), + ), + ), + ) if err != nil { t.Fatalf("NewEnv() failed: %v", err) } - funcs := Functions(&functions.Overload{ - Operator: "panic", - Function: func(args ...ref.Val) ref.Val { - panic("watch me recover") - }, - }) // Test standard evaluation. - pAst, _ := e.Parse("panic()") - prgm, _ := e.Program(pAst, funcs) + pAst, iss := e.Parse("panic()") + if iss.Err() != nil { + t.Fatalf("e.Parse('panic()') failed: %v", iss.Err()) + } + prgm, err := e.Program(pAst) + if err != nil { + t.Fatalf("e.Program(Ast) failed: %v", err) + } _, _, err = prgm.Eval(map[string]interface{}{}) if err.Error() != "internal error: watch me recover" { t.Errorf("got '%v', wanted 'internal error: watch me recover'", err) } // Test the factory-based evaluation. - prgm, _ = e.Program(pAst, funcs, EvalOptions(OptTrackState)) + prgm, _ = e.Program(pAst, EvalOptions(OptTrackState)) _, _, err = prgm.Eval(map[string]interface{}{}) if err.Error() != "internal error: watch me recover" { t.Errorf("got '%v', wanted 'internal error: watch me recover'", err) @@ -979,10 +1017,8 @@ func TestResidualAst(t *testing.T) { e, _ := NewEnv( - Declarations( - decls.NewVar("x", decls.Int), - decls.NewVar("y", decls.Int), - ), + Variable("x", IntType), + Variable("y", IntType), ) unkVars := e.UnknownVars() ast, _ := e.Parse(`x < 10 && (y == 0 || 'hello' != 'goodbye')`) @@ -1009,14 +1045,11 @@ } } -func TestResidualAst_Complex(t *testing.T) { +func TestResidualAstComplex(t *testing.T) { e, _ := NewEnv( - Declarations( - decls.NewVar("resource.name", decls.String), - decls.NewVar("request.time", decls.Timestamp), - decls.NewVar("request.auth.claims", - decls.NewMapType(decls.String, decls.String)), - ), + Variable("resource.name", StringType), + Variable("request.time", TimestampType), + Variable("request.auth.claims", MapType(StringType, StringType)), ) unkVars, _ := PartialVars( map[string]interface{}{ @@ -1057,12 +1090,10 @@ } } -func Benchmark_EvalOptions(b *testing.B) { +func BenchmarkEvalOptions(b *testing.B) { e, _ := NewEnv( - Declarations( - decls.NewVar("ai", decls.Int), - decls.NewVar("ar", decls.NewMapType(decls.String, decls.String)), - ), + Variable("ai", IntType), + Variable("ar", MapType(StringType, StringType)), ) ast, _ := e.Compile("ai == 20 || ar['foo'] == 'bar'") vars := map[string]interface{}{ @@ -1096,10 +1127,7 @@ e, _ := NewEnv( Container("google.api.expr.v1alpha1"), Types(&exprpb.Expr{}), - Declarations( - decls.NewVar("expr", - decls.NewObjectType("google.api.expr.v1alpha1.Expr")), - ), + Variable("expr", ObjectType("google.api.expr.v1alpha1.Expr")), ) e2, _ := e.Extend( CustomTypeAdapter(types.DefaultTypeAdapter), @@ -1126,24 +1154,24 @@ func TestEnvExtensionIsolation(t *testing.T) { baseEnv, err := NewEnv( Container("google.expr"), - Declarations( - decls.NewVar("age", decls.Int), - decls.NewVar("gender", decls.String), - decls.NewVar("country", decls.String), - ), + Variable("age", IntType), + Variable("gender", StringType), + Variable("country", StringType), ) if err != nil { t.Fatal(err) } env1, err := baseEnv.Extend( Types(&proto2pb.TestAllTypes{}), - Declarations(decls.NewVar("name", decls.String))) + Variable("name", StringType), + ) if err != nil { t.Fatal(err) } env2, err := baseEnv.Extend( Types(&proto3pb.TestAllTypes{}), - Declarations(decls.NewVar("group", decls.String))) + Variable("group", StringType), + ) if err != nil { t.Fatal(err) } @@ -1223,10 +1251,7 @@ e, err := NewEnv( Container("google.api.expr.v1alpha1"), Types(&exprpb.Expr{}), - Declarations( - decls.NewVar("expr", - decls.NewObjectType("google.api.expr.v1alpha1.Expr")), - ), + Variable("expr", ObjectType("google.api.expr.v1alpha1.Expr")), ) if err != nil { t.Fatalf("NewEnv() failed: %v", err) @@ -1286,7 +1311,7 @@ } } - env, _ := NewEnv(Declarations(decls.NewVar("foo", decls.Int))) + env, _ := NewEnv(Variable("foo", IntType)) ast, _ := env.Compile(`foo == -1 + 2 * 3 / 3`) _, err := env.Program(ast, EvalOptions(OptPartialEval), @@ -1369,12 +1394,12 @@ // TestEstimateCostAndRuntimeCost sanity checks that the cost systems are usable from the program API. func TestEstimateCostAndRuntimeCost(t *testing.T) { - intList := decls.NewListType(decls.Int) + intList := ListType(IntType) zeroCost := checker.CostEstimate{} cases := []struct { name string expr string - decls []*exprpb.Decl + decls []EnvOption hints map[string]int64 want checker.CostEstimate in interface{} @@ -1388,16 +1413,16 @@ { name: "identity", expr: `input`, - decls: []*exprpb.Decl{decls.NewVar("input", intList)}, + decls: []EnvOption{Variable("input", intList)}, want: checker.CostEstimate{Min: 1, Max: 1}, in: map[string]interface{}{"input": []int{1, 2}}, }, { name: "str concat", expr: `"abcdefg".contains(str1 + str2)`, - decls: []*exprpb.Decl{ - decls.NewVar("str1", decls.String), - decls.NewVar("str2", decls.String), + decls: []EnvOption{ + Variable("str1", StringType), + Variable("str2", StringType), }, hints: map[string]int64{"str1": 10, "str2": 10}, want: checker.CostEstimate{Min: 2, Max: 6}, @@ -1410,9 +1435,7 @@ if tc.hints == nil { tc.hints = map[string]int64{} } - e, err := NewEnv( - Declarations(tc.decls...), - Types(&proto3pb.TestAllTypes{})) + e, err := NewEnv(append(tc.decls, Types(&proto3pb.TestAllTypes{}))...) if err != nil { t.Fatalf("NewEnv(opts ...EnvOption) failed to create an environment: %s\n", err) } @@ -1457,11 +1480,9 @@ func TestResidualAst_AttributeQualifiers(t *testing.T) { e, _ := NewEnv( - Declarations( - decls.NewVar("x", decls.NewMapType(decls.String, decls.Dyn)), - decls.NewVar("y", decls.NewListType(decls.Int)), - decls.NewVar("u", decls.Int), - ), + Variable("x", MapType(StringType, DynType)), + Variable("y", ListType(IntType)), + Variable("u", IntType), ) ast, _ := e.Parse(`x.abc == u && x["abc"] == u && x[x.string] == u && y[0] == u && y[x.zero] == u && (true ? x : y).abc == u && (false ? y : x).abc == u`) prg, _ := e.Program(ast, @@ -1498,10 +1519,8 @@ func TestResidualAst_Modified(t *testing.T) { e, _ := NewEnv( - Declarations( - decls.NewVar("x", decls.NewMapType(decls.String, decls.Int)), - decls.NewVar("y", decls.Int), - ), + Variable("x", MapType(StringType, IntType)), + Variable("y", IntType), ) ast, _ := e.Parse("x == y") prg, _ := e.Program(ast, @@ -1635,3 +1654,279 @@ }) } } + +func TestDefaultUTCTimeZone(t *testing.T) { + env, err := NewEnv(Variable("x", TimestampType), DefaultUTCTimeZone(true)) + if err != nil { + t.Fatalf("NewEnv() failed: %v", err) + } + out, err := interpret(t, env, ` + x.getFullYear() == 1970 + && x.getMonth() == 0 + && x.getDayOfYear() == 0 + && x.getDayOfMonth() == 0 + && x.getDate() == 1 + && x.getDayOfWeek() == 4 + && x.getHours() == 2 + && x.getMinutes() == 5 + && x.getSeconds() == 6 + && x.getMilliseconds() == 1 + && x.getFullYear('-07:30') == 1969 + && x.getDayOfYear('-07:30') == 364 + && x.getMonth('-07:30') == 11 + && x.getDayOfMonth('-07:30') == 30 + && x.getDate('-07:30') == 31 + && x.getDayOfWeek('-07:30') == 3 + && x.getHours('-07:30') == 18 + && x.getMinutes('-07:30') == 35 + && x.getSeconds('-07:30') == 6 + && x.getMilliseconds('-07:30') == 1 + && x.getFullYear('23:15') == 1970 + && x.getDayOfYear('23:15') == 1 + && x.getMonth('23:15') == 0 + && x.getDayOfMonth('23:15') == 1 + && x.getDate('23:15') == 2 + && x.getDayOfWeek('23:15') == 5 + && x.getHours('23:15') == 1 + && x.getMinutes('23:15') == 20 + && x.getSeconds('23:15') == 6 + && x.getMilliseconds('23:15') == 1`, + map[string]interface{}{ + "x": time.Unix(7506, 1000000).Local(), + }) + if err != nil { + t.Fatalf("prg.Eval() failed: %v", err) + } + if out != types.True { + t.Errorf("Eval() got %v, wanted true", out) + } +} + +func TestDefaultUTCTimeZoneExtension(t *testing.T) { + env, err := NewEnv( + Variable("x", TimestampType), + Variable("y", DurationType), + DefaultUTCTimeZone(true), + ) + if err != nil { + t.Fatalf("NewEnv() failed: %v", err) + } + env, err = env.Extend() + if err != nil { + t.Fatalf("env.Extend() failed: %v", err) + } + out, err := interpret(t, env, ` + x.getFullYear() == 1970 + && y.getHours() == 2 + && y.getMinutes() == 120 + && y.getSeconds() == 7235 + && y.getMilliseconds() == 7235000`, + map[string]interface{}{ + "x": time.Unix(7506, 1000000).Local(), + "y": time.Duration(7235) * time.Second, + }, + ) + if err != nil { + t.Fatalf("prg.Eval() failed: %v", err) + } + if out != types.True { + t.Errorf("Eval() got %v, wanted true", out.Value()) + } +} + +func TestDefaultUTCTimeZoneError(t *testing.T) { + env, err := NewEnv(Variable("x", TimestampType), DefaultUTCTimeZone(true)) + if err != nil { + t.Fatalf("NewEnv() failed: %v", err) + } + out, err := interpret(t, env, ` + x.getFullYear(':xx') == 1969 + || x.getDayOfYear('xx:') == 364 + || x.getMonth('Am/Ph') == 11 + || x.getDayOfMonth('Am/Ph') == 30 + || x.getDate('Am/Ph') == 31 + || x.getDayOfWeek('Am/Ph') == 3 + || x.getHours('Am/Ph') == 19 + || x.getMinutes('Am/Ph') == 5 + || x.getSeconds('Am/Ph') == 6 + || x.getMilliseconds('Am/Ph') == 1 + `, map[string]interface{}{ + "x": time.Unix(7506, 1000000).Local(), + }, + ) + if err == nil { + t.Fatalf("prg.Eval() got %v wanted error", out) + } +} + +func TestDynamicDispatch(t *testing.T) { + env, err := NewEnv( + HomogeneousAggregateLiterals(), + Function("first", + MemberOverload("first_list_int", []*Type{ListType(IntType)}, IntType, + UnaryBinding(func(list ref.Val) ref.Val { + l := list.(traits.Lister) + if l.Size() == types.IntZero { + return types.IntZero + } + return l.Get(types.IntZero) + }), + ), + MemberOverload("first_list_double", []*Type{ListType(DoubleType)}, DoubleType, + UnaryBinding(func(list ref.Val) ref.Val { + l := list.(traits.Lister) + if l.Size() == types.IntZero { + return types.Double(0.0) + } + return l.Get(types.IntZero) + }), + ), + MemberOverload("first_list_string", []*Type{ListType(StringType)}, StringType, + UnaryBinding(func(list ref.Val) ref.Val { + l := list.(traits.Lister) + if l.Size() == types.IntZero { + return types.String("") + } + return l.Get(types.IntZero) + }), + ), + MemberOverload("first_list_list_string", []*Type{ListType(ListType(StringType))}, ListType(StringType), + UnaryBinding(func(list ref.Val) ref.Val { + l := list.(traits.Lister) + if l.Size() == types.IntZero { + return types.DefaultTypeAdapter.NativeToValue([]string{}) + } + return l.Get(types.IntZero) + }), + ), + ), + ) + if err != nil { + t.Fatalf("NewEnv() failed: %v", err) + } + out, err := interpret(t, env, ` + [].first() == 0 + && [1, 2].first() == 1 + && [1.0, 2.0].first() == 1.0 + && ["hello", "world"].first() == "hello" + && [["hello"], ["world", "!"]].first().first() == "hello" + && [[], ["empty"]].first().first() == "" + && dyn([1, 2]).first() == 1 + && dyn([1.0, 2.0]).first() == 1.0 + && dyn(["hello", "world"]).first() == "hello" + && dyn([["hello"], ["world", "!"]]).first().first() == "hello" + `, map[string]interface{}{}, + ) + if err != nil { + t.Fatalf("prg.Eval() failed: %v", err) + } + if out != types.True { + t.Fatalf("prg.Eval() got %v wanted true", out) + } +} + +func BenchmarkDynamicDispatch(b *testing.B) { + env, err := NewEnv( + HomogeneousAggregateLiterals(), + Function("first", + MemberOverload("first_list_int", []*Type{ListType(IntType)}, IntType, + UnaryBinding(func(list ref.Val) ref.Val { + l := list.(traits.Lister) + if l.Size() == types.IntZero { + return types.IntZero + } + return l.Get(types.IntZero) + }), + ), + MemberOverload("first_list_double", []*Type{ListType(DoubleType)}, DoubleType, + UnaryBinding(func(list ref.Val) ref.Val { + l := list.(traits.Lister) + if l.Size() == types.IntZero { + return types.Double(0.0) + } + return l.Get(types.IntZero) + }), + ), + MemberOverload("first_list_string", []*Type{ListType(StringType)}, StringType, + UnaryBinding(func(list ref.Val) ref.Val { + l := list.(traits.Lister) + if l.Size() == types.IntZero { + return types.String("") + } + return l.Get(types.IntZero) + }), + ), + MemberOverload("first_list_list_string", []*Type{ListType(ListType(StringType))}, ListType(StringType), + UnaryBinding(func(list ref.Val) ref.Val { + l := list.(traits.Lister) + if l.Size() == types.IntZero { + return types.DefaultTypeAdapter.NativeToValue([]string{}) + } + return l.Get(types.IntZero) + }), + ), + ), + ) + if err != nil { + b.Fatalf("NewEnv() failed: %v", err) + } + prg := compile(b, env, ` + [].first() == 0 + && [1, 2].first() == 1 + && [1.0, 2.0].first() == 1.0 + && ["hello", "world"].first() == "hello" + && [["hello"], ["world", "!"]].first().first() == "hello"`) + prgDyn := compile(b, env, ` + dyn([]).first() == 0 + && dyn([1, 2]).first() == 1 + && dyn([1.0, 2.0]).first() == 1.0 + && dyn(["hello", "world"]).first() == "hello" + && dyn([["hello"], ["world", "!"]]).first().first() == "hello"`) + b.ResetTimer() + b.Run("DirectDispatch", func(b *testing.B) { + for i := 0; i < b.N; i++ { + prg.Eval(NoVars()) + } + }) + b.ResetTimer() + b.Run("DynamicDispatch", func(b *testing.B) { + for i := 0; i < b.N; i++ { + prgDyn.Eval(NoVars()) + } + }) +} + +func compile(t testing.TB, env *Env, expr string) Program { + t.Helper() + prg, err := compileOrError(t, env, expr) + if err != nil { + t.Fatal(err) + } + return prg +} + +func compileOrError(t testing.TB, env *Env, expr string) (Program, error) { + t.Helper() + ast, iss := env.Compile(expr) + if iss.Err() != nil { + return nil, fmt.Errorf("env.Compile(%s) failed: %v", expr, iss.Err()) + } + prg, err := env.Program(ast, EvalOptions(OptOptimize)) + if err != nil { + return nil, fmt.Errorf("env.Program() failed: %v", err) + } + return prg, nil +} + +func interpret(t testing.TB, env *Env, expr string, vars interface{}) (ref.Val, error) { + t.Helper() + prg, err := compileOrError(t, env, expr) + if err != nil { + return nil, err + } + out, _, err := prg.Eval(vars) + if err != nil { + return nil, fmt.Errorf("prg.Eval(%v) failed: %v", vars, err) + } + return out, nil +} diff -Nru golang-github-google-cel-go-0.11.4+ds/cel/decls.go golang-github-google-cel-go-0.12.5+ds/cel/decls.go --- golang-github-google-cel-go-0.11.4+ds/cel/decls.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/cel/decls.go 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,1179 @@ +// Copyright 2022 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" + "strings" + + "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/common/types/traits" + "github.com/google/cel-go/interpreter/functions" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// Kind indicates a CEL type's kind which is used to differentiate quickly between simple and complex types. +type Kind uint + +const ( + // DynKind represents a dynamic type. This kind only exists at type-check time. + DynKind Kind = iota + + // AnyKind represents a google.protobuf.Any type. This kind only exists at type-check time. + AnyKind + + // BoolKind represents a boolean type. + BoolKind + + // BytesKind represents a bytes type. + BytesKind + + // DoubleKind represents a double type. + DoubleKind + + // DurationKind represents a CEL duration type. + DurationKind + + // IntKind represents an integer type. + IntKind + + // ListKind represents a list type. + ListKind + + // MapKind represents a map type. + MapKind + + // NullTypeKind represents a null type. + NullTypeKind + + // OpaqueKind represents an abstract type which has no accessible fields. + OpaqueKind + + // StringKind represents a string type. + StringKind + + // StructKind represents a structured object with typed fields. + StructKind + + // TimestampKind represents a a CEL time type. + TimestampKind + + // TypeKind represents the CEL type. + TypeKind + + // TypeParamKind represents a parameterized type whose type name will be resolved at type-check time, if possible. + TypeParamKind + + // UintKind represents a uint type. + UintKind +) + +var ( + // AnyType represents the google.protobuf.Any type. + AnyType = &Type{ + kind: AnyKind, + runtimeType: types.NewTypeValue("google.protobuf.Any"), + } + // BoolType represents the bool type. + BoolType = &Type{ + kind: BoolKind, + runtimeType: types.BoolType, + } + // BytesType represents the bytes type. + BytesType = &Type{ + kind: BytesKind, + runtimeType: types.BytesType, + } + // DoubleType represents the double type. + DoubleType = &Type{ + kind: DoubleKind, + runtimeType: types.DoubleType, + } + // DurationType represents the CEL duration type. + DurationType = &Type{ + kind: DurationKind, + runtimeType: types.DurationType, + } + // DynType represents a dynamic CEL type whose type will be determined at runtime from context. + DynType = &Type{ + kind: DynKind, + runtimeType: types.NewTypeValue("dyn"), + } + // IntType represents the int type. + IntType = &Type{ + kind: IntKind, + runtimeType: types.IntType, + } + // NullType represents the type of a null value. + NullType = &Type{ + kind: NullTypeKind, + runtimeType: types.NullType, + } + // StringType represents the string type. + StringType = &Type{ + kind: StringKind, + runtimeType: types.StringType, + } + // TimestampType represents the time type. + TimestampType = &Type{ + kind: TimestampKind, + runtimeType: types.TimestampType, + } + // TypeType represents a CEL type + TypeType = &Type{ + kind: TypeKind, + runtimeType: types.TypeType, + } + //UintType represents a uint type. + UintType = &Type{ + kind: UintKind, + runtimeType: types.UintType, + } +) + +// Type holds a reference to a runtime type with an optional type-checked set of type parameters. +type Type struct { + // kind indicates general category of the type. + kind Kind + + // runtimeType is the runtime type of the declaration. + runtimeType ref.Type + + // parameters holds the optional type-checked set of type parameters that are used during static analysis. + parameters []*Type + + // isAssignableType function determines whether one type is assignable to this type. + // A nil value for the isAssignableType function falls back to equality of kind, runtimeType, and parameters. + isAssignableType func(other *Type) bool + + // isAssignableRuntimeType function determines whether the runtime type (with erasure) is assignable to this type. + // A nil value for the isAssignableRuntimeType function falls back to the equality of the type or type name. + isAssignableRuntimeType func(other ref.Val) bool +} + +// IsAssignableType determines whether the current type is type-check assignable from the input fromType. +func (t *Type) IsAssignableType(fromType *Type) bool { + if t.isAssignableType != nil { + return t.isAssignableType(fromType) + } + return t.defaultIsAssignableType(fromType) +} + +// IsAssignableRuntimeType determines whether the current type is runtime assignable from the input runtimeType. +// +// At runtime, parameterized types are erased and so a function which type-checks to support a map(string, string) +// will have a runtime assignable type of a map. +func (t *Type) IsAssignableRuntimeType(val ref.Val) bool { + if t.isAssignableRuntimeType != nil { + return t.isAssignableRuntimeType(val) + } + return t.defaultIsAssignableRuntimeType(val) +} + +// String returns a human-readable definition of the type name. +func (t *Type) String() string { + if len(t.parameters) == 0 { + return t.runtimeType.TypeName() + } + params := make([]string, len(t.parameters)) + for i, p := range t.parameters { + params[i] = p.String() + } + return fmt.Sprintf("%s(%s)", t.runtimeType.TypeName(), strings.Join(params, ", ")) +} + +// isDyn indicates whether the type is dynamic in any way. +func (t *Type) isDyn() bool { + return t.kind == DynKind || t.kind == AnyKind || t.kind == TypeParamKind +} + +// equals indicates whether two types have the same kind, type name, and parameters. +func (t *Type) equals(other *Type) bool { + if t.kind != other.kind || + t.runtimeType.TypeName() != other.runtimeType.TypeName() || + len(t.parameters) != len(other.parameters) { + return false + } + for i, p := range t.parameters { + if !p.equals(other.parameters[i]) { + return false + } + } + return true +} + +// defaultIsAssignableType provides the standard definition of what it means for one type to be assignable to another +// where any of the following may return a true result: +// - The from types are the same instance +// - The target type is dynamic +// - The fromType has the same kind and type name as the target type, and all parameters of the target type +// are IsAssignableType() from the parameters of the fromType. +func (t *Type) defaultIsAssignableType(fromType *Type) bool { + if t == fromType || t.isDyn() { + return true + } + if t.kind != fromType.kind || + t.runtimeType.TypeName() != fromType.runtimeType.TypeName() || + len(t.parameters) != len(fromType.parameters) { + return false + } + for i, tp := range t.parameters { + fp := fromType.parameters[i] + if !tp.IsAssignableType(fp) { + return false + } + } + return true +} + +// defaultIsAssignableRuntimeType inspects the type and in the case of list and map elements, the key and element types +// to determine whether a ref.Val is assignable to the declared type for a function signature. +func (t *Type) defaultIsAssignableRuntimeType(val ref.Val) bool { + valType := val.Type() + if !(t.runtimeType == valType || t.isDyn() || t.runtimeType.TypeName() == valType.TypeName()) { + return false + } + switch t.runtimeType { + case types.ListType: + elemType := t.parameters[0] + l := val.(traits.Lister) + if l.Size() == types.IntZero { + return true + } + it := l.Iterator() + for it.HasNext() == types.True { + elemVal := it.Next() + return elemType.IsAssignableRuntimeType(elemVal) + } + case types.MapType: + keyType := t.parameters[0] + elemType := t.parameters[1] + m := val.(traits.Mapper) + if m.Size() == types.IntZero { + return true + } + it := m.Iterator() + for it.HasNext() == types.True { + keyVal := it.Next() + elemVal := m.Get(keyVal) + return keyType.IsAssignableRuntimeType(keyVal) && elemType.IsAssignableRuntimeType(elemVal) + } + } + return true +} + +// ListType creates an instances of a list type value with the provided element type. +func ListType(elemType *Type) *Type { + return &Type{ + kind: ListKind, + runtimeType: types.ListType, + parameters: []*Type{elemType}, + } +} + +// MapType creates an instance of a map type value with the provided key and value types. +func MapType(keyType, valueType *Type) *Type { + return &Type{ + kind: MapKind, + runtimeType: types.MapType, + parameters: []*Type{keyType, valueType}, + } +} + +// NullableType creates an instance of a nullable type with the provided wrapped type. +// +// Note: only primitive types are supported as wrapped types. +func NullableType(wrapped *Type) *Type { + return &Type{ + kind: wrapped.kind, + runtimeType: wrapped.runtimeType, + parameters: wrapped.parameters, + isAssignableType: func(other *Type) bool { + return NullType.IsAssignableType(other) || wrapped.IsAssignableType(other) + }, + isAssignableRuntimeType: func(other ref.Val) bool { + return NullType.IsAssignableRuntimeType(other) || wrapped.IsAssignableRuntimeType(other) + }, + } +} + +// OpaqueType creates an abstract parameterized type with a given name. +func OpaqueType(name string, params ...*Type) *Type { + return &Type{ + kind: OpaqueKind, + runtimeType: types.NewTypeValue(name), + parameters: params, + } +} + +// ObjectType creates a type references to an externally defined type, e.g. a protobuf message type. +func ObjectType(typeName string) *Type { + return &Type{ + kind: StructKind, + runtimeType: types.NewObjectTypeValue(typeName), + } +} + +// TypeParamType creates a parameterized type instance. +func TypeParamType(paramName string) *Type { + return &Type{ + kind: TypeParamKind, + runtimeType: types.NewTypeValue(paramName), + } +} + +// Variable creates an instance of a variable declaration with a variable name and type. +func Variable(name string, t *Type) EnvOption { + return func(e *Env) (*Env, error) { + et, err := TypeToExprType(t) + if err != nil { + return nil, err + } + e.declarations = append(e.declarations, decls.NewVar(name, et)) + return e, nil + } +} + +// Function defines a function and overloads with optional singleton or per-overload bindings. +// +// Using Function is roughly equivalent to calling Declarations() to declare the function signatures +// and Functions() to define the function bindings, if they have been defined. Specifying the +// same function name more than once will result in the aggregation of the function overloads. If any +// signatures conflict between the existing and new function definition an error will be raised. +// However, if the signatures are identical and the overload ids are the same, the redefinition will +// be considered a no-op. +// +// One key difference with using Function() is that each FunctionDecl provided will handle dynamic +// dispatch based on the type-signatures of the overloads provided which means overload resolution at +// runtime is handled out of the box rather than via a custom binding for overload resolution via +// Functions(): +// +// - Overloads are searched in the order they are declared +// - Dynamic dispatch for lists and maps is limited by inspection of the list and map contents +// at runtime. Empty lists and maps will result in a 'default dispatch' +// - In the event that a default dispatch occurs, the first overload provided is the one invoked +// +// If you intend to use overloads which differentiate based on the key or element type of a list or +// map, consider using a generic function instead: e.g. func(list(T)) or func(map(K, V)) as this +// will allow your implementation to determine how best to handle dispatch and the default behavior +// for empty lists and maps whose contents cannot be inspected. +// +// For functions which use parameterized opaque types (abstract types), consider using a singleton +// function which is capable of inspecting the contents of the type and resolving the appropriate +// overload as CEL can only make inferences by type-name regarding such types. +func Function(name string, opts ...FunctionOpt) EnvOption { + return func(e *Env) (*Env, error) { + fn := &functionDecl{ + name: name, + overloads: []*overloadDecl{}, + options: opts, + } + err := fn.init() + if err != nil { + return nil, err + } + _, err = functionDeclToExprDecl(fn) + if err != nil { + return nil, err + } + if existing, found := e.functions[fn.name]; found { + fn, err = existing.merge(fn) + if err != nil { + return nil, err + } + } + e.functions[name] = fn + return e, nil + } +} + +// FunctionOpt defines a functional option for configuring a function declaration. +type FunctionOpt func(*functionDecl) (*functionDecl, error) + +// SingletonUnaryBinding creates a singleton function defintion to be used for all function overloads. +// +// Note, this approach works well if operand is expected to have a specific trait which it implements, +// e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings. +func SingletonUnaryBinding(fn functions.UnaryOp, traits ...int) FunctionOpt { + trait := 0 + for _, t := range traits { + trait = trait | t + } + return func(f *functionDecl) (*functionDecl, error) { + if f.singleton != nil { + return nil, fmt.Errorf("function already has a singleton binding: %s", f.name) + } + f.singleton = &functions.Overload{ + Operator: f.name, + Unary: fn, + OperandTrait: trait, + } + return f, nil + } +} + +// SingletonBinaryImpl creates a singleton function definition to be used with all function overloads. +// +// Note, this approach works well if operand is expected to have a specific trait which it implements, +// e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings. +func SingletonBinaryImpl(fn functions.BinaryOp, traits ...int) FunctionOpt { + trait := 0 + for _, t := range traits { + trait = trait | t + } + return func(f *functionDecl) (*functionDecl, error) { + if f.singleton != nil { + return nil, fmt.Errorf("function already has a singleton binding: %s", f.name) + } + f.singleton = &functions.Overload{ + Operator: f.name, + Binary: fn, + OperandTrait: trait, + } + return f, nil + } +} + +// SingletonFunctionImpl creates a singleton function definition to be used with all function overloads. +// +// Note, this approach works well if operand is expected to have a specific trait which it implements, +// e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings. +func SingletonFunctionImpl(fn functions.FunctionOp, traits ...int) FunctionOpt { + trait := 0 + for _, t := range traits { + trait = trait | t + } + return func(f *functionDecl) (*functionDecl, error) { + if f.singleton != nil { + return nil, fmt.Errorf("function already has a singleton binding: %s", f.name) + } + f.singleton = &functions.Overload{ + Operator: f.name, + Function: fn, + OperandTrait: trait, + } + return f, nil + } +} + +// Overload defines a new global overload with an overload id, argument types, and result type. Through the +// use of OverloadOpt options, the overload may also be configured with a binding, an operand trait, and to +// be non-strict. +// +// Note: function bindings should be commonly configured with Overload instances whereas operand traits and +// strict-ness should be rare occurrences. +func Overload(overloadID string, args []*Type, resultType *Type, opts ...OverloadOpt) FunctionOpt { + return newOverload(overloadID, false, args, resultType, opts...) +} + +// MemberOverload defines a new receiver-style overload (or member function) with an overload id, argument types, +// and result type. Through the use of OverloadOpt options, the overload may also be configured with a binding, +// an operand trait, and to be non-strict. +// +// Note: function bindings should be commonly configured with Overload instances whereas operand traits and +// strict-ness should be rare occurrences. +func MemberOverload(overloadID string, args []*Type, resultType *Type, opts ...OverloadOpt) FunctionOpt { + return newOverload(overloadID, true, args, resultType, opts...) +} + +// OverloadOpt is a functional option for configuring a function overload. +type OverloadOpt func(*overloadDecl) (*overloadDecl, error) + +// UnaryBinding provides the implementation of a unary overload. The provided function is protected by a runtime +// type-guard which ensures runtime type agreement between the overload signature and runtime argument types. +func UnaryBinding(binding functions.UnaryOp) OverloadOpt { + return func(o *overloadDecl) (*overloadDecl, error) { + if o.hasBinding() { + return nil, fmt.Errorf("overload already has a binding: %s", o.id) + } + if len(o.argTypes) != 1 { + return nil, fmt.Errorf("unary function bound to non-unary overload: %s", o.id) + } + o.unaryOp = binding + return o, nil + } +} + +// BinaryBinding provides the implementation of a binary overload. The provided function is protected by a runtime +// type-guard which ensures runtime type agreement between the overload signature and runtime argument types. +func BinaryBinding(binding functions.BinaryOp) OverloadOpt { + return func(o *overloadDecl) (*overloadDecl, error) { + if o.hasBinding() { + return nil, fmt.Errorf("overload already has a binding: %s", o.id) + } + if len(o.argTypes) != 2 { + return nil, fmt.Errorf("binary function bound to non-binary overload: %s", o.id) + } + o.binaryOp = binding + return o, nil + } +} + +// FunctionBinding provides the implementation of a variadic overload. The provided function is protected by a runtime +// type-guard which ensures runtime type agreement between the overload signature and runtime argument types. +func FunctionBinding(binding functions.FunctionOp) OverloadOpt { + return func(o *overloadDecl) (*overloadDecl, error) { + if o.hasBinding() { + return nil, fmt.Errorf("overload already has a binding: %s", o.id) + } + o.functionOp = binding + return o, nil + } +} + +// OverloadIsNonStrict enables the function to be called with error and unknown argument values. +// +// Note: do not use this option unless absoluately necessary as it should be an uncommon feature. +func OverloadIsNonStrict() OverloadOpt { + return func(o *overloadDecl) (*overloadDecl, error) { + o.nonStrict = true + return o, nil + } +} + +// OverloadOperandTrait configures a set of traits which the first argument to the overload must implement in order to be +// successfully invoked. +func OverloadOperandTrait(trait int) OverloadOpt { + return func(o *overloadDecl) (*overloadDecl, error) { + o.operandTrait = trait + return o, nil + } +} + +type functionDecl struct { + name string + overloads []*overloadDecl + options []FunctionOpt + singleton *functions.Overload + initialized bool +} + +// init ensures that a function's options have been applied. +// +// This function is used in both the environment configuration and internally for function merges. +func (f *functionDecl) init() error { + if f.initialized { + return nil + } + f.initialized = true + + var err error + for _, opt := range f.options { + f, err = opt(f) + if err != nil { + return err + } + } + if len(f.overloads) == 0 { + return fmt.Errorf("function %s must have at least one overload", f.name) + } + return nil +} + +// bindings produces a set of function bindings, if any are defined. +func (f *functionDecl) bindings() ([]*functions.Overload, error) { + overloads := []*functions.Overload{} + nonStrict := false + for _, o := range f.overloads { + if o.hasBinding() { + overload := &functions.Overload{ + Operator: o.id, + Unary: o.guardedUnaryOp(f.name), + Binary: o.guardedBinaryOp(f.name), + Function: o.guardedFunctionOp(f.name), + OperandTrait: o.operandTrait, + NonStrict: o.nonStrict, + } + overloads = append(overloads, overload) + nonStrict = nonStrict || o.nonStrict + } + } + if f.singleton != nil { + if len(overloads) != 0 { + return nil, fmt.Errorf("singleton function incompatible with specialized overloads: %s", f.name) + } + return []*functions.Overload{ + { + Operator: f.name, + Unary: f.singleton.Unary, + Binary: f.singleton.Binary, + Function: f.singleton.Function, + OperandTrait: f.singleton.OperandTrait, + }, + }, nil + } + if len(overloads) == 0 { + return overloads, nil + } + // Single overload. Replicate an entry for it using the function name as well. + if len(overloads) == 1 { + if overloads[0].Operator == f.name { + return overloads, nil + } + return append(overloads, &functions.Overload{ + Operator: f.name, + Unary: overloads[0].Unary, + Binary: overloads[0].Binary, + Function: overloads[0].Function, + NonStrict: overloads[0].NonStrict, + OperandTrait: overloads[0].OperandTrait, + }), nil + } + // All of the defined overloads are wrapped into a top-level function which + // performs dynamic dispatch to the proper overload based on the argument types. + bindings := append([]*functions.Overload{}, overloads...) + funcDispatch := func(args ...ref.Val) ref.Val { + for _, o := range f.overloads { + if !o.matchesRuntimeSignature(args...) { + continue + } + switch len(args) { + case 1: + if o.unaryOp != nil { + return o.unaryOp(args[0]) + } + case 2: + if o.binaryOp != nil { + return o.binaryOp(args[0], args[1]) + } + } + if o.functionOp != nil { + return o.functionOp(args...) + } + // eventually this will fall through to the noSuchOverload below. + } + return noSuchOverload(f.name, args...) + } + function := &functions.Overload{ + Operator: f.name, + Function: funcDispatch, + NonStrict: nonStrict, + } + return append(bindings, function), nil +} + +// merge one function declaration with another. +// +// If a function is extended, by say adding new overloads to an existing function, then it is merged with the +// prior definition of the function at which point its overloads must not collide with pre-existing overloads +// and its bindings (singleton, or per-overload) must not conflict with previous definitions either. +func (f *functionDecl) merge(other *functionDecl) (*functionDecl, error) { + if f.name != other.name { + return nil, fmt.Errorf("cannot merge unrelated functions. %s and %s", f.name, other.name) + } + err := f.init() + if err != nil { + return nil, err + } + err = other.init() + if err != nil { + return nil, err + } + merged := &functionDecl{ + name: f.name, + overloads: make([]*overloadDecl, len(f.overloads)), + options: []FunctionOpt{}, + initialized: true, + singleton: f.singleton, + } + copy(merged.overloads, f.overloads) + for _, o := range other.overloads { + err := merged.addOverload(o) + if err != nil { + return nil, fmt.Errorf("function declaration merge failed: %v", err) + } + } + if other.singleton != nil { + if merged.singleton != nil { + return nil, fmt.Errorf("function already has a binding: %s", f.name) + } + merged.singleton = other.singleton + } + return merged, nil +} + +// addOverload ensures that the new overload does not collide with an existing overload signature; +// however, if the function signatures are identical, the implementation may be rewritten as its +// difficult to compare functions by object identity. +func (f *functionDecl) addOverload(overload *overloadDecl) error { + for index, o := range f.overloads { + if o.id != overload.id && o.signatureOverlaps(overload) { + return fmt.Errorf("overload signature collision in function %s: %s collides with %s", f.name, o.id, overload.id) + } + if o.id == overload.id { + if o.signatureEquals(overload) && o.nonStrict == overload.nonStrict { + // Allow redefinition of an overload implementation so long as the signatures match. + f.overloads[index] = overload + return nil + } else { + return fmt.Errorf("overload redefinition in function. %s: %s has multiple definitions", f.name, o.id) + } + } + } + f.overloads = append(f.overloads, overload) + return nil +} + +func noSuchOverload(funcName string, args ...ref.Val) ref.Val { + argTypes := make([]string, len(args)) + for i, arg := range args { + argTypes[i] = arg.Type().TypeName() + } + signature := strings.Join(argTypes, ", ") + return types.NewErr("no such overload: %s(%s)", funcName, signature) +} + +// overloadDecl contains all of the relevant information regarding a specific function overload. +type overloadDecl struct { + id string + argTypes []*Type + resultType *Type + memberFunction bool + + // binding options, optional but encouraged. + unaryOp functions.UnaryOp + binaryOp functions.BinaryOp + functionOp functions.FunctionOp + + // behavioral options, uncommon + nonStrict bool + operandTrait int +} + +func (o *overloadDecl) hasBinding() bool { + return o.unaryOp != nil || o.binaryOp != nil || o.functionOp != nil +} + +// guardedUnaryOp creates an invocation guard around the provided unary operator, if one is defined. +func (o *overloadDecl) guardedUnaryOp(funcName string) functions.UnaryOp { + if o.unaryOp == nil { + return nil + } + return func(arg ref.Val) ref.Val { + if !o.matchesRuntimeUnarySignature(arg) { + return noSuchOverload(funcName, arg) + } + return o.unaryOp(arg) + } +} + +// guardedBinaryOp creates an invocation guard around the provided binary operator, if one is defined. +func (o *overloadDecl) guardedBinaryOp(funcName string) functions.BinaryOp { + if o.binaryOp == nil { + return nil + } + return func(arg1, arg2 ref.Val) ref.Val { + if !o.matchesRuntimeBinarySignature(arg1, arg2) { + return noSuchOverload(funcName, arg1, arg2) + } + return o.binaryOp(arg1, arg2) + } +} + +// guardedFunctionOp creates an invocation guard around the provided variadic function binding, if one is provided. +func (o *overloadDecl) guardedFunctionOp(funcName string) functions.FunctionOp { + if o.functionOp == nil { + return nil + } + return func(args ...ref.Val) ref.Val { + if !o.matchesRuntimeSignature(args...) { + return noSuchOverload(funcName, args...) + } + return o.functionOp(args...) + } +} + +// matchesRuntimeUnarySignature indicates whether the argument type is runtime assiganble to the overload's expected argument. +func (o *overloadDecl) matchesRuntimeUnarySignature(arg ref.Val) bool { + if o.nonStrict && types.IsUnknownOrError(arg) { + return true + } + return o.argTypes[0].IsAssignableRuntimeType(arg) && (o.operandTrait == 0 || arg.Type().HasTrait(o.operandTrait)) +} + +// matchesRuntimeBinarySignature indicates whether the argument types are runtime assiganble to the overload's expected arguments. +func (o *overloadDecl) matchesRuntimeBinarySignature(arg1, arg2 ref.Val) bool { + if o.nonStrict { + if types.IsUnknownOrError(arg1) { + return types.IsUnknownOrError(arg2) || o.argTypes[1].IsAssignableRuntimeType(arg2) + } + } else if !o.argTypes[1].IsAssignableRuntimeType(arg2) { + return false + } + return o.argTypes[0].IsAssignableRuntimeType(arg1) && (o.operandTrait == 0 || arg1.Type().HasTrait(o.operandTrait)) +} + +// matchesRuntimeSignature indicates whether the argument types are runtime assiganble to the overload's expected arguments. +func (o *overloadDecl) matchesRuntimeSignature(args ...ref.Val) bool { + if len(args) != len(o.argTypes) { + return false + } + if len(args) == 0 { + return true + } + allArgsMatch := true + for i, arg := range args { + if o.nonStrict && types.IsUnknownOrError(arg) { + continue + } + allArgsMatch = allArgsMatch && o.argTypes[i].IsAssignableRuntimeType(arg) + } + + arg := args[0] + return allArgsMatch && (o.operandTrait == 0 || (o.nonStrict && types.IsUnknownOrError(arg)) || arg.Type().HasTrait(o.operandTrait)) +} + +// signatureEquals indicates whether one overload has an identical signature to another overload. +// +// Providing a duplicate signature is not an issue, but an overloapping signature is problematic. +func (o *overloadDecl) signatureEquals(other *overloadDecl) bool { + if o.id != other.id || o.memberFunction != other.memberFunction || len(o.argTypes) != len(other.argTypes) { + return false + } + for i, at := range o.argTypes { + oat := other.argTypes[i] + if !at.equals(oat) { + return false + } + } + return o.resultType.equals(other.resultType) +} + +// signatureOverlaps indicates whether one overload has an overlapping signature with another overload. +// +// The 'other' overload must first be checked for equality before determining whether it overlaps in order to be completely accurate. +func (o *overloadDecl) signatureOverlaps(other *overloadDecl) bool { + if o.memberFunction != other.memberFunction || len(o.argTypes) != len(other.argTypes) { + return false + } + argsOverlap := true + for i, argType := range o.argTypes { + otherArgType := other.argTypes[i] + argsOverlap = argsOverlap && + (argType.IsAssignableType(otherArgType) || + otherArgType.IsAssignableType(argType)) + } + return argsOverlap +} + +func newOverload(overloadID string, memberFunction bool, args []*Type, resultType *Type, opts ...OverloadOpt) FunctionOpt { + return func(f *functionDecl) (*functionDecl, error) { + overload := &overloadDecl{ + id: overloadID, + argTypes: args, + resultType: resultType, + memberFunction: memberFunction, + } + var err error + for _, opt := range opts { + overload, err = opt(overload) + if err != nil { + return nil, err + } + } + err = f.addOverload(overload) + if err != nil { + return nil, err + } + return f, nil + } +} + +func maybeWrapper(t *Type, pbType *exprpb.Type) *exprpb.Type { + if t.IsAssignableType(NullType) { + return decls.NewWrapperType(pbType) + } + return pbType +} + +// TypeToExprType converts a CEL-native type representation to a protobuf CEL Type representation. +func TypeToExprType(t *Type) (*exprpb.Type, error) { + switch t.kind { + case AnyKind: + return decls.Any, nil + case BoolKind: + return maybeWrapper(t, decls.Bool), nil + case BytesKind: + return maybeWrapper(t, decls.Bytes), nil + case DoubleKind: + return maybeWrapper(t, decls.Double), nil + case DurationKind: + return decls.Duration, nil + case DynKind: + return decls.Dyn, nil + case IntKind: + return maybeWrapper(t, decls.Int), nil + case ListKind: + et, err := TypeToExprType(t.parameters[0]) + if err != nil { + return nil, err + } + return decls.NewListType(et), nil + case MapKind: + kt, err := TypeToExprType(t.parameters[0]) + if err != nil { + return nil, err + } + vt, err := TypeToExprType(t.parameters[1]) + if err != nil { + return nil, err + } + return decls.NewMapType(kt, vt), nil + case NullTypeKind: + return decls.Null, nil + case OpaqueKind: + params := make([]*exprpb.Type, len(t.parameters)) + for i, p := range t.parameters { + pt, err := TypeToExprType(p) + if err != nil { + return nil, err + } + params[i] = pt + } + return decls.NewAbstractType(t.runtimeType.TypeName(), params...), nil + case StringKind: + return maybeWrapper(t, decls.String), nil + case StructKind: + switch t.runtimeType.TypeName() { + case "google.protobuf.Any": + return decls.Any, nil + case "google.protobuf.Duration": + return decls.Duration, nil + case "google.protobuf.Timestamp": + return decls.Timestamp, nil + case "google.protobuf.Value": + return decls.Dyn, nil + case "google.protobuf.ListValue": + return decls.NewListType(decls.Dyn), nil + case "google.protobuf.Struct": + return decls.NewMapType(decls.String, decls.Dyn), nil + case "google.protobuf.BoolValue": + return decls.NewWrapperType(decls.Bool), nil + case "google.protobuf.BytesValue": + return decls.NewWrapperType(decls.Bytes), nil + case "google.protobuf.DoubleValue", "google.protobuf.FloatValue": + return decls.NewWrapperType(decls.Double), nil + case "google.protobuf.Int32Value", "google.protobuf.Int64Value": + return decls.NewWrapperType(decls.Int), nil + case "google.protobuf.StringValue": + return decls.NewWrapperType(decls.String), nil + case "google.protobuf.UInt32Value", "google.protobuf.UInt64Value": + return decls.NewWrapperType(decls.Uint), nil + default: + return decls.NewObjectType(t.runtimeType.TypeName()), nil + } + case TimestampKind: + return decls.Timestamp, nil + case TypeParamKind: + return decls.NewTypeParamType(t.runtimeType.TypeName()), nil + case TypeKind: + return decls.NewTypeType(decls.Dyn), nil + case UintKind: + return maybeWrapper(t, decls.Uint), nil + } + return nil, fmt.Errorf("missing type conversion to proto: %v", t) +} + +// ExprTypeToType converts a protobuf CEL type representation to a CEL-native type representation. +func ExprTypeToType(t *exprpb.Type) (*Type, error) { + switch t.GetTypeKind().(type) { + case *exprpb.Type_Dyn: + return DynType, nil + case *exprpb.Type_AbstractType_: + paramTypes := make([]*Type, len(t.GetAbstractType().GetParameterTypes())) + for i, p := range t.GetAbstractType().GetParameterTypes() { + pt, err := ExprTypeToType(p) + if err != nil { + return nil, err + } + paramTypes[i] = pt + } + return OpaqueType(t.GetAbstractType().GetName(), paramTypes...), nil + case *exprpb.Type_ListType_: + et, err := ExprTypeToType(t.GetListType().GetElemType()) + if err != nil { + return nil, err + } + return ListType(et), nil + case *exprpb.Type_MapType_: + kt, err := ExprTypeToType(t.GetMapType().GetKeyType()) + if err != nil { + return nil, err + } + vt, err := ExprTypeToType(t.GetMapType().GetValueType()) + if err != nil { + return nil, err + } + return MapType(kt, vt), nil + case *exprpb.Type_MessageType: + switch t.GetMessageType() { + case "google.protobuf.Any": + return AnyType, nil + case "google.protobuf.Duration": + return DurationType, nil + case "google.protobuf.Timestamp": + return TimestampType, nil + case "google.protobuf.Value": + return DynType, nil + case "google.protobuf.ListValue": + return ListType(DynType), nil + case "google.protobuf.Struct": + return MapType(StringType, DynType), nil + case "google.protobuf.BoolValue": + return NullableType(BoolType), nil + case "google.protobuf.BytesValue": + return NullableType(BytesType), nil + case "google.protobuf.DoubleValue", "google.protobuf.FloatValue": + return NullableType(DoubleType), nil + case "google.protobuf.Int32Value", "google.protobuf.Int64Value": + return NullableType(IntType), nil + case "google.protobuf.StringValue": + return NullableType(StringType), nil + case "google.protobuf.UInt32Value", "google.protobuf.UInt64Value": + return NullableType(UintType), nil + default: + return ObjectType(t.GetMessageType()), nil + } + case *exprpb.Type_Null: + return NullType, nil + case *exprpb.Type_Primitive: + switch t.GetPrimitive() { + case exprpb.Type_BOOL: + return BoolType, nil + case exprpb.Type_BYTES: + return BytesType, nil + case exprpb.Type_DOUBLE: + return DoubleType, nil + case exprpb.Type_INT64: + return IntType, nil + case exprpb.Type_STRING: + return StringType, nil + case exprpb.Type_UINT64: + return UintType, nil + default: + return nil, fmt.Errorf("unsupported primitive type: %v", t) + } + case *exprpb.Type_TypeParam: + return TypeParamType(t.GetTypeParam()), nil + case *exprpb.Type_Type: + return TypeType, nil + case *exprpb.Type_WellKnown: + switch t.GetWellKnown() { + case exprpb.Type_ANY: + return AnyType, nil + case exprpb.Type_DURATION: + return DurationType, nil + case exprpb.Type_TIMESTAMP: + return TimestampType, nil + default: + return nil, fmt.Errorf("unsupported well-known type: %v", t) + } + case *exprpb.Type_Wrapper: + t, err := ExprTypeToType(&exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: t.GetWrapper()}}) + if err != nil { + return nil, err + } + return NullableType(t), nil + default: + return nil, fmt.Errorf("unsupported type: %v", t) + } +} + +// ExprDeclToDeclaration converts a protobuf CEL declaration to a CEL-native declaration, either a Variable or Function. +func ExprDeclToDeclaration(d *exprpb.Decl) (EnvOption, error) { + switch d.GetDeclKind().(type) { + case *exprpb.Decl_Function: + overloads := d.GetFunction().GetOverloads() + opts := make([]FunctionOpt, len(overloads)) + for i, o := range overloads { + args := make([]*Type, len(o.GetParams())) + for j, p := range o.GetParams() { + a, err := ExprTypeToType(p) + if err != nil { + return nil, err + } + args[j] = a + } + res, err := ExprTypeToType(o.GetResultType()) + if err != nil { + return nil, err + } + opts[i] = Overload(o.GetOverloadId(), args, res) + } + return Function(d.GetName(), opts...), nil + case *exprpb.Decl_Ident: + t, err := ExprTypeToType(d.GetIdent().GetType()) + if err != nil { + return nil, err + } + return Variable(d.GetName(), t), nil + default: + return nil, fmt.Errorf("unsupported decl: %v", d) + } + +} + +func functionDeclToExprDecl(f *functionDecl) (*exprpb.Decl, error) { + overloads := make([]*exprpb.Decl_FunctionDecl_Overload, len(f.overloads)) + i := 0 + for _, o := range f.overloads { + paramNames := map[string]struct{}{} + argTypes := make([]*exprpb.Type, len(o.argTypes)) + for j, a := range o.argTypes { + collectParamNames(paramNames, a) + at, err := TypeToExprType(a) + if err != nil { + return nil, err + } + argTypes[j] = at + } + collectParamNames(paramNames, o.resultType) + resultType, err := TypeToExprType(o.resultType) + if err != nil { + return nil, err + } + if len(paramNames) == 0 { + if o.memberFunction { + overloads[i] = decls.NewInstanceOverload(o.id, argTypes, resultType) + } else { + overloads[i] = decls.NewOverload(o.id, argTypes, resultType) + } + } else { + params := []string{} + for pn := range paramNames { + params = append(params, pn) + } + if o.memberFunction { + overloads[i] = decls.NewParameterizedInstanceOverload(o.id, argTypes, resultType, params) + } else { + overloads[i] = decls.NewParameterizedOverload(o.id, argTypes, resultType, params) + } + } + i++ + } + return decls.NewFunction(f.name, overloads...), nil +} + +func collectParamNames(paramNames map[string]struct{}, arg *Type) { + if arg.kind == TypeParamKind { + paramNames[arg.runtimeType.TypeName()] = struct{}{} + } + for _, param := range arg.parameters { + collectParamNames(paramNames, param) + } +} diff -Nru golang-github-google-cel-go-0.11.4+ds/cel/decls_test.go golang-github-google-cel-go-0.12.5+ds/cel/decls_test.go --- golang-github-google-cel-go-0.11.4+ds/cel/decls_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/cel/decls_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,1172 @@ +// Copyright 2022 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" + "math" + "reflect" + "strings" + "testing" + "time" + + "github.com/google/cel-go/checker/decls" + "github.com/google/cel-go/common/operators" + "github.com/google/cel-go/common/overloads" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + "github.com/google/cel-go/interpreter/functions" + + "google.golang.org/protobuf/proto" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +var dispatchTests = []struct { + expr string + out interface{} +}{ + { + expr: "max(-1)", + out: types.IntNegOne, + }, + { + expr: "max(-1, 0)", + out: types.IntZero, + }, + { + expr: "max(-1, 0, 1)", + out: types.IntOne, + }, + { + expr: "max(dyn(1.2))", + out: fmt.Errorf("no such overload: max(double)"), + }, + + { + expr: "max(1, dyn(1.2))", + out: fmt.Errorf("no such overload: max(int, double)"), + }, + { + expr: "max(1, 2, dyn(1.2))", + out: fmt.Errorf("no such overload: max(int, int, double)"), + }, + { + expr: "max(err, 1)", + out: fmt.Errorf("error argument"), + }, + { + expr: "max(err, unk)", + out: fmt.Errorf("error argument"), + }, + { + expr: "max(unk, unk)", + out: types.Unknown{42}, + }, + { + expr: "max(unk, unk, unk)", + out: types.Unknown{42}, + }, +} + +func TestFunctionMerge(t *testing.T) { + size := Function("size", + Overload("size_map", []*Type{MapType(TypeParamType("K"), TypeParamType("V"))}, IntType), + Overload("size_list", []*Type{ListType(TypeParamType("V"))}, IntType), + Overload("size_string", []*Type{StringType}, IntType), + Overload("size_bytes", []*Type{BytesType}, IntType), + MemberOverload("map_size", []*Type{MapType(TypeParamType("K"), TypeParamType("V"))}, IntType), + MemberOverload("list_size", []*Type{ListType(TypeParamType("V"))}, IntType), + MemberOverload("string_size", []*Type{StringType}, IntType), + MemberOverload("bytes_size", []*Type{BytesType}, IntType), + SingletonUnaryBinding(func(arg ref.Val) ref.Val { + return arg.(traits.Sizer).Size() + }, traits.SizerType), + ) + // Note, the size() implementation is inherited from the singleton implementation for the size function. + // It is possible to redefine the singleton, but the singleton approach is incompatible with specialized + // overloads as the singleton is compatible with the parse-only approach and compiled approach; but + // a mix of singleton and specialized overloads might result in a singleton which does not encompass + // dynamic dispatch to all possible overloads. + sizeExt := Function("size", + Overload("size_vector", []*Type{OpaqueType("vector", TypeParamType("V"))}, IntType), + MemberOverload("vector_size", []*Type{OpaqueType("vector", TypeParamType("V"))}, IntType)) + + vectorExt := Function("vector", + Overload("vector_list", []*Type{ListType(TypeParamType("V"))}, OpaqueType("vector", TypeParamType("V")), + UnaryBinding(func(list ref.Val) ref.Val { + return list + }))) + + eq := Function(operators.Equals, + Overload(operators.Equals, []*Type{TypeParamType("T"), TypeParamType("T")}, BoolType, + BinaryBinding(func(lhs, rhs ref.Val) ref.Val { + return lhs.Equal(rhs) + }))) + + e, err := NewCustomEnv(size, sizeExt, vectorExt, eq) + if err != nil { + t.Fatalf("NewCustomEnv() failed: %v", err) + } + ast, iss := e.Compile(`[[0].size() == 1, + {'a': true, 'b': false}.size() == 2, + 'hello'.size() == 5, + b'hello'.size() == 5, + vector([1.2, 2.3, 3.4]).size() == 3]`) + if iss.Err() != nil { + t.Fatalf("Compile() errored: %v", iss.Err()) + } + if !reflect.DeepEqual(ast.OutputType(), ListType(BoolType)) { + t.Errorf("Compile() produced a %v, wanted bool", ast.OutputType()) + } + if ast.OutputType().String() != "list(bool)" { + t.Errorf("ast.OutputType().String() produced %s, wanted list(bool)", ast.OutputType()) + } + prg, err := e.Program(ast) + if err != nil { + t.Fatalf("e.Program(ast) failed: %v", err) + } + out, _, err := prg.Eval(NoVars()) + if err != nil { + t.Errorf("prg.Eval() errored: %v", err) + } + want := types.DefaultTypeAdapter.NativeToValue([]bool{true, true, true, true, true}) + if out.Equal(want) != types.True { + t.Errorf("prg.Eval() got %v, wanted %v", out, want) + } + + _, err = NewCustomEnv(size, size) + if err == nil || !strings.Contains(err.Error(), "already has a binding") { + t.Errorf("NewCustomEnv(size, size) did not produce the expected error: %v", err) + } + e, err = NewCustomEnv(size, + Function("size", + Overload("size_int", []*Type{IntType}, IntType, + UnaryBinding(func(arg ref.Val) ref.Val { return types.Int(2) }), + ), + ), + ) + if err != nil { + t.Fatalf("NewCustomEnv(size, ) failed: %v", err) + } + _, err = e.Program(ast) + if err == nil || !strings.Contains(err.Error(), "incompatible with specialized overloads") { + t.Errorf("NewCustomEnv(size, size_specialization) did not produce the expected error: %v", err) + } +} + +func TestFunctionMergeDuplicate(t *testing.T) { + maxFunc := Function("max", + Overload("max_int", []*Type{IntType}, IntType), + Overload("max_int", []*Type{IntType}, IntType), + ) + _, err := NewCustomEnv(maxFunc, maxFunc) + if err != nil { + t.Fatalf("NewCustomEnv() failed: %v", err) + } +} + +func TestFunctionMergeDeclarationAndDefinition(t *testing.T) { + idFuncDecl := Function("id", Overload("id", []*Type{TypeParamType("T")}, TypeParamType("T"), OverloadIsNonStrict())) + idFuncDef := Function("id", + Overload("id", []*Type{TypeParamType("T")}, TypeParamType("T"), OverloadIsNonStrict(), + UnaryBinding(func(arg ref.Val) ref.Val { + return arg + }), + ), + ) + env, err := NewCustomEnv(Variable("x", AnyType), idFuncDecl, idFuncDef) + if err != nil { + t.Fatalf("NewCustomEnv() failed: %v", err) + } + ast, iss := env.Compile("id(x)") + if iss.Err() != nil { + t.Fatalf("env.Compile(id(x)) failed: %v", iss.Err()) + } + prg, err := env.Program(ast) + if err != nil { + t.Fatalf("env.Program() failed: %v", err) + } + out, _, err := prg.Eval(map[string]interface{}{"x": true}) + if err != nil { + t.Fatalf("prg.Eval(x: true) errored: %v", err) + } + if out != types.True { + t.Errorf("prg.Eval() yielded %v, wanted true", out) + } +} + +func TestFunctionMergeCollision(t *testing.T) { + maxFunc := Function("max", + Overload("max_int", []*Type{IntType}, IntType), + Overload("max_int2", []*Type{IntType}, IntType), + ) + _, err := NewCustomEnv(maxFunc, maxFunc) + if err == nil { + t.Fatal("NewCustomEnv() succeeded, wanted collision error") + } +} + +func TestFunctionNoOverloads(t *testing.T) { + _, err := NewCustomEnv(Function("right", SingletonBinaryImpl(func(arg1, arg2 ref.Val) ref.Val { + return arg2 + }))) + if err == nil || !strings.Contains(err.Error(), "must have at least one overload") { + t.Errorf("got %v for the error state, wanted 'no overloads'", err) + } +} + +func TestSingletonUnaryImplRedefinition(t *testing.T) { + _, err := NewCustomEnv( + Function("id", + Overload("id_any", []*Type{AnyType}, AnyType), + SingletonUnaryBinding(func(arg ref.Val) ref.Val { + return arg + }), + SingletonUnaryBinding(func(arg ref.Val) ref.Val { + return arg + }), + ), + ) + if err == nil || !strings.Contains(err.Error(), "already has a singleton binding") { + t.Errorf("NewCustomEnv() got %v, wanted already has a singleton singleton binding", err) + } +} + +func TestSingletonUnaryImpl(t *testing.T) { + // Test the case where the singleton unary impl is merged with the earlier declaration. + e, err := NewCustomEnv( + Variable("x", AnyType), + Function("id", Overload("id_any", []*Type{AnyType}, AnyType)), + Function("id", Overload("id_any", []*Type{AnyType}, AnyType), SingletonUnaryBinding(func(arg ref.Val) ref.Val { return arg })), + ) + if err != nil { + t.Errorf("NewCustomEnv() failed: %v", err) + } + ast, iss := e.Parse("id(x)") + if iss.Err() != nil { + t.Fatalf("Parse('id(x)') failed: %v", iss.Err()) + } + prg, err := e.Program(ast) + if err != nil { + t.Fatalf("Program() failed: %v", err) + } + out, _, err := prg.Eval(map[string]interface{}{"x": "hello"}) + if err != nil { + t.Errorf("prg.Eval(x=hello) failed: %v", err) + } + if out.Equal(types.String("hello")) != types.True { + t.Errorf("Eval got %v, wanted 'hello'", out) + } +} + +func TestSingletonUnaryImplParameterized(t *testing.T) { + // Test the case where the singleton unary impl is merged with the earlier declaration. + e, err := NewCustomEnv( + Variable("x", AnyType), + Function("isSorted", MemberOverload("list_int_is_sorted", []*Type{ListType(IntType)}, BoolType)), + Function("isSorted", MemberOverload("list_uint_is_sorted", []*Type{ListType(UintType)}, BoolType), + SingletonUnaryBinding(func(arg ref.Val) ref.Val { return types.True })), + ) + if err != nil { + t.Errorf("NewCustomEnv() failed: %v", err) + } + ast, iss := e.Parse("x.isSorted()") + if iss.Err() != nil { + t.Fatalf("Parse('x.isSorted()') failed: %v", iss.Err()) + } + prg, err := e.Program(ast) + if err != nil { + t.Fatalf("Program() failed: %v", err) + } + out, _, err := prg.Eval(map[string]interface{}{"x": []int{1, 2, 3}}) + if err != nil { + t.Errorf("prg.Eval(x=[1,2,3]) failed: %v", err) + } + if out != types.True { + t.Errorf("Eval got %v, wanted true", out) + } +} + +func TestSingletonBinaryImplRedefinition(t *testing.T) { + _, err := NewCustomEnv( + Function("right", + Overload("right_double_double", []*Type{DoubleType, DoubleType}, DoubleType), + SingletonBinaryImpl(func(arg1, arg2 ref.Val) ref.Val { + return arg2 + }, traits.ComparerType), + SingletonBinaryImpl(func(arg1, arg2 ref.Val) ref.Val { + return arg2 + }), + )) + if err == nil || !strings.Contains(err.Error(), "already has a singleton binding") { + t.Errorf("NewCustomEnv() got %v, wanted already has a singleton binding", err) + } +} + +func TestSingletonBinaryImpl(t *testing.T) { + _, err := NewCustomEnv( + Function("right", + Overload("right_int_int", []*Type{IntType, IntType}, IntType), + Overload("right_double_double", []*Type{DoubleType, DoubleType}, DoubleType), + Overload("right_string_string", []*Type{StringType, StringType}, StringType), + SingletonBinaryImpl(func(arg1, arg2 ref.Val) ref.Val { + return arg2 + }, traits.ComparerType), + ), + ) + if err != nil { + t.Errorf("NewCustomEnv() failed: %v", err) + } +} + +func TestSingletonFunctionImplRedefinition(t *testing.T) { + _, err := NewCustomEnv( + Function("id", + Overload("id_any", []*Type{AnyType}, AnyType), + SingletonFunctionImpl(func(args ...ref.Val) ref.Val { + return args[0] + }, traits.ComparerType), + SingletonFunctionImpl(func(args ...ref.Val) ref.Val { + return args[0] + }, traits.ComparerType), + ), + ) + if err == nil || !strings.Contains(err.Error(), "already has a singleton binding") { + t.Errorf("NewCustomEnv() got %v, wanted already has a singleton binding", err) + } +} + +func TestSingletonFunctionImpl(t *testing.T) { + env, err := NewCustomEnv( + Variable("unk", DynType), + Variable("err", DynType), + Function("dyn", + Overload("dyn", []*Type{DynType}, DynType), + SingletonUnaryBinding(func(arg ref.Val) ref.Val { + return arg + })), + Function("max", + Overload("max_int", []*Type{IntType}, IntType), + Overload("max_int_int", []*Type{IntType, IntType}, IntType), + Overload("max_int_int_int", []*Type{IntType, IntType, IntType}, IntType), + SingletonFunctionImpl(func(args ...ref.Val) ref.Val { + max := types.Int(math.MinInt64) + for _, arg := range args { + i, ok := arg.(types.Int) + if !ok { + // With a singleton implementation, the error handling must be explicitly + // performed as a binding detail of the singleton function. + // With custom overload implementations, a function guard is automatically + // added to the function to validate that the runtime types are compatible + // to provide some basic invocation protections. + return noSuchOverload("max", args...) + } + if i > max { + max = i + } + } + return max + }), + ), + ) + if err != nil { + t.Fatalf("NewCustomEnv() failed: %v", err) + } + + for _, tc := range dispatchTests { + tc := tc + t.Run(fmt.Sprintf("Parse(%s)", tc.expr), func(t *testing.T) { + testParse(t, env, tc.expr, tc.out) + }) + } + for _, tc := range dispatchTests { + tc := tc + t.Run(fmt.Sprintf("Compile(%s)", tc.expr), func(t *testing.T) { + testCompile(t, env, tc.expr, tc.out) + }) + } +} + +func TestUnaryImplRedefinition(t *testing.T) { + _, err := NewCustomEnv( + Function("dyn", + Overload("dyn", []*Type{DynType}, DynType, + UnaryBinding(func(arg ref.Val) ref.Val { return arg }), + // redefinition. + UnaryBinding(func(arg ref.Val) ref.Val { return arg }), + ), + ), + ) + if err == nil || !strings.Contains(err.Error(), "already has a binding") { + t.Errorf("redefinition of function impl did not produce expected error: %v", err) + } +} + +func TestUnaryImpl(t *testing.T) { + _, err := NewCustomEnv( + Function("dyn", + Overload("dyn", []*Type{}, DynType, + // wrong arg count + UnaryBinding(func(arg ref.Val) ref.Val { return arg }), + ), + ), + ) + if err == nil || !strings.Contains(err.Error(), "function bound to non-unary overload") { + t.Errorf("bad binding did not produce expected error: %v", err) + } + + e, err := NewCustomEnv( + Function("size", + Overload("size_non_strict", []*Type{ListType(DynType)}, IntType, + OverloadIsNonStrict(), + OverloadOperandTrait(traits.SizerType), + UnaryBinding(func(arg ref.Val) ref.Val { + if types.IsUnknownOrError(arg) { + return arg + } + return arg.(traits.Sizer).Size() + }), + ), + ), + Variable("x", ListType(DynType)), + ) + if err != nil { + t.Fatalf("NewCustomEnv() failed: %v", err) + } + ast, iss := e.Compile("size(x)") + if iss.Err() != nil { + t.Fatalf("Compile(size(x)) failed: %v", iss.Err()) + } + prg, err := e.Program(ast) + if err != nil { + t.Fatalf("Program() failed: %v", err) + } + out, _, err := prg.Eval(map[string]interface{}{"x": types.Unknown{1}}) + if err != nil { + t.Fatalf("prg.Eval(x=unk) failed: %v", err) + } + if !reflect.DeepEqual(out, types.Unknown{1}) { + t.Errorf("prg.Eval(x=unk) returned %v, wanted unknown{1}", out) + } +} + +func TestBinaryImplRedefinition(t *testing.T) { + _, err := NewCustomEnv( + Function("right", + Overload("right_int_int", []*Type{IntType, IntType}, IntType, + BinaryBinding(func(arg1, arg2 ref.Val) ref.Val { return arg2 }), + // redefinition. + BinaryBinding(func(arg1, arg2 ref.Val) ref.Val { return arg2 }), + ), + ), + ) + if err == nil || !strings.Contains(err.Error(), "already has a binding") { + t.Errorf("redefinition of function impl did not produce expected error: %v", err) + } + + _, err = NewCustomEnv( + Function("right", + Overload("right_int_int", []*Type{IntType, IntType}, IntType, + BinaryBinding(func(arg1, arg2 ref.Val) ref.Val { return arg2 }), + ), + Overload("right_int_int", []*Type{IntType, IntType, DurationType}, IntType, + FunctionBinding(func(args ...ref.Val) ref.Val { return args[0] }), + ), + ), + ) + if err == nil || !strings.Contains(err.Error(), "multiple definitions") { + t.Errorf("redefinition of right_int_int did not produce expected error: %v", err) + } + + _, err = NewCustomEnv( + Function("elem_type", + Overload("elem_type_list", []*Type{ListType(TypeParamType("T"))}, TypeType), + Overload("elem_type_list", []*Type{ListType(DynType)}, TypeType), + ), + ) + if err == nil || !strings.Contains(err.Error(), "multiple definitions") { + t.Errorf("redefinition of elem_type_list did not produce expected error: %v", err) + } +} + +func TestBinaryImpl(t *testing.T) { + e, err := NewCustomEnv( + Function("max", + Overload("max_int_int", []*Type{IntType, IntType}, IntType, + OverloadIsNonStrict(), + BinaryBinding(func(arg1, arg2 ref.Val) ref.Val { + if types.IsUnknownOrError(arg1) { + return arg2 + } + if types.IsUnknownOrError(arg2) { + return arg1 + } + i1 := arg1.(types.Int) + i2 := arg2.(types.Int) + if i1 > i2 { + return i1 + } + return i2 + }), + ), + ), + Variable("x", IntType), + Variable("y", IntType), + ) + if err != nil { + t.Fatalf("NewCustomEnv() failed: %v", err) + } + ast, iss := e.Parse("max(x, y)") + if iss.Err() != nil { + t.Fatalf("Parse(max(x, y))) failed: %v", iss.Err()) + } + prg, err := e.Program(ast) + if err != nil { + t.Fatalf("Program() failed: %v", err) + } + out, _, err := prg.Eval(map[string]interface{}{"x": types.Unknown{1}, "y": 1}) + if err != nil { + t.Fatalf("prg.Eval(x=unk) failed: %v", err) + } + if !reflect.DeepEqual(out, types.IntOne) { + t.Errorf("prg.Eval(x=unk, y=1) returned %v, wanted 1", out) + } + out, _, err = prg.Eval(map[string]interface{}{"x": 2, "y": types.Unknown{2}}) + if err != nil { + t.Fatalf("prg.Eval(x=2, y=unk) failed: %v", err) + } + if !reflect.DeepEqual(out, types.Int(2)) { + t.Errorf("prg.Eval(x=2, y=unk) returned %v, wanted 2", out) + } + out, _, err = prg.Eval(map[string]interface{}{"x": 2, "y": 1}) + if err != nil { + t.Fatalf("prg.Eval(x=2, y=1) failed: %v", err) + } + if !reflect.DeepEqual(out, types.Int(2)) { + t.Errorf("prg.Eval(x=2, y=1) returned %v, wanted 2", out) + } + + _, err = NewCustomEnv( + Function("right", + Overload("right_int_int", []*Type{IntType, IntType, IntType}, IntType, + // wrong arg count + BinaryBinding(func(arg1, arg2 ref.Val) ref.Val { return arg2 }), + ), + ), + ) + if err == nil || !strings.Contains(err.Error(), "function bound to non-binary overload") { + t.Errorf("bad binding did not produce expected error: %v", err) + } +} + +func TestFunctionImplRedefinition(t *testing.T) { + _, err := NewCustomEnv( + Function("right", + Overload("right_int_int_int", []*Type{IntType, IntType, IntType}, IntType, + FunctionBinding(func(args ...ref.Val) ref.Val { return args[0] }), + // redefinition. + FunctionBinding(func(args ...ref.Val) ref.Val { return args[1] }), + ), + ), + ) + if err == nil || !strings.Contains(err.Error(), "already has a binding") { + t.Errorf("redefinition of function impl did not produce expected error: %v", err) + } +} + +func TestFunctionImpl(t *testing.T) { + e, err := NewCustomEnv( + Variable("unk", DynType), + Variable("err", DynType), + Function("dyn", + Overload("dyn", []*Type{DynType}, DynType), + SingletonUnaryBinding(func(arg ref.Val) ref.Val { + return arg + })), + Function("max", + Overload("max_int", []*Type{IntType}, IntType, + UnaryBinding(func(arg ref.Val) ref.Val { return arg })), + Overload("max_int_int", []*Type{IntType, IntType}, IntType, + BinaryBinding(func(lhs, rhs ref.Val) ref.Val { + if lhs.(types.Int).Compare(rhs) == types.IntNegOne { + return rhs + } + return lhs + })), + Overload("max_int_int_int", []*Type{IntType, IntType, IntType}, IntType, + FunctionBinding(func(args ...ref.Val) ref.Val { + max := types.Int(math.MinInt64) + for _, arg := range args { + i := arg.(types.Int) + if i > max { + max = i + } + } + return max + })), + ), + ) + if err != nil { + t.Fatalf("NewCustomEnv() failed: %v", err) + } + + for _, tc := range dispatchTests { + tc := tc + t.Run(fmt.Sprintf("Parse(%s)", tc.expr), func(t *testing.T) { + testParse(t, e, tc.expr, tc.out) + }) + } + for _, tc := range dispatchTests { + tc := tc + t.Run(fmt.Sprintf("Compile(%s)", tc.expr), func(t *testing.T) { + testCompile(t, e, tc.expr, tc.out) + }) + } +} + +func TestIsAssignableType(t *testing.T) { + if !NullableType(DoubleType).IsAssignableType(NullType) { + t.Error("nullable double cannot be assigned from null") + } + if !NullableType(DoubleType).IsAssignableType(DoubleType) { + t.Error("nullable double cannot be assigned from double") + } + if !OpaqueType("vector", NullableType(DoubleType)).IsAssignableType(OpaqueType("vector", NullType)) { + t.Error("vector(nullable(double)) could not be assigned from vector(null)") + } + if !OpaqueType("vector", DynType).IsAssignableType(OpaqueType("vector", NullableType(IntType))) { + t.Error("vector(dyn) could not be assigned from vector(nullable(int))") + } + if OpaqueType("vector", NullableType(DoubleType)).IsAssignableType(OpaqueType("vector", IntType)) { + t.Error("vector(nullable(double)) should not be assignable from vector(int)") + } + if OpaqueType("vector", NullableType(DoubleType)).IsAssignableType(OpaqueType("vector", DynType)) { + t.Error("vector(nullable(double)) should not be assignable from vector(int)") + } +} + +func TestIsAssignableRuntimeType(t *testing.T) { + if !NullableType(DoubleType).IsAssignableRuntimeType(types.NullValue) { + t.Error("nullable double cannot be assigned from null") + } + if !NullableType(DoubleType).IsAssignableRuntimeType(types.Double(0.0)) { + t.Error("nullable double cannot be assigned from double") + } + if !MapType(StringType, DurationType).IsAssignableRuntimeType( + types.DefaultTypeAdapter.NativeToValue(map[string]time.Duration{})) { + t.Error("map(string, duration) not assignable to map at runtime") + } + if !MapType(StringType, DurationType).IsAssignableRuntimeType( + types.DefaultTypeAdapter.NativeToValue(map[string]time.Duration{"one": time.Duration(1)})) { + t.Error("map(string, duration) not assignable to map at runtime") + } + if !MapType(StringType, DynType).IsAssignableRuntimeType( + types.DefaultTypeAdapter.NativeToValue(map[string]time.Duration{"one": time.Duration(1)})) { + t.Error("map(string, dyn) not assignable to map at runtime") + } + if MapType(StringType, DynType).IsAssignableRuntimeType( + types.DefaultTypeAdapter.NativeToValue(map[int64]time.Duration{1: time.Duration(1)})) { + t.Error("map(string, dyn) must not be assignable to map(int, duration) at runtime") + } +} + +func TestTypeToExprType(t *testing.T) { + tests := []struct { + in *Type + out *exprpb.Type + unidirectional bool + }{ + { + in: OpaqueType("vector", DoubleType, DoubleType), + out: decls.NewAbstractType("vector", decls.Double, decls.Double), + }, + { + in: AnyType, + out: decls.Any, + }, + { + in: BoolType, + out: decls.Bool, + }, + { + in: BytesType, + out: decls.Bytes, + }, + { + in: DoubleType, + out: decls.Double, + }, + { + in: DurationType, + out: decls.Duration, + }, + { + in: DynType, + out: decls.Dyn, + }, + { + in: IntType, + out: decls.Int, + }, + { + in: ListType(TypeParamType("T")), + out: decls.NewListType(decls.NewTypeParamType("T")), + }, + { + in: MapType(TypeParamType("K"), TypeParamType("V")), + out: decls.NewMapType(decls.NewTypeParamType("K"), decls.NewTypeParamType("V")), + }, + { + in: NullType, + out: decls.Null, + }, + { + in: ObjectType("google.type.Expr"), + out: decls.NewObjectType("google.type.Expr"), + }, + { + in: StringType, + out: decls.String, + }, + { + in: TimestampType, + out: decls.Timestamp, + }, + { + in: TypeType, + out: decls.NewTypeType(decls.Dyn), + }, + { + in: UintType, + out: decls.Uint, + }, + { + in: NullableType(BoolType), + out: decls.NewWrapperType(decls.Bool), + }, + { + in: NullableType(BytesType), + out: decls.NewWrapperType(decls.Bytes), + }, + { + in: NullableType(DoubleType), + out: decls.NewWrapperType(decls.Double), + }, + { + in: NullableType(IntType), + out: decls.NewWrapperType(decls.Int), + }, + { + in: NullableType(StringType), + out: decls.NewWrapperType(decls.String), + }, + { + in: NullableType(UintType), + out: decls.NewWrapperType(decls.Uint), + }, + { + in: ObjectType("google.protobuf.Any"), + out: decls.Any, + unidirectional: true, + }, + { + in: ObjectType("google.protobuf.Duration"), + out: decls.Duration, + unidirectional: true, + }, + { + in: ObjectType("google.protobuf.Timestamp"), + out: decls.Timestamp, + unidirectional: true, + }, + { + in: ObjectType("google.protobuf.Value"), + out: decls.Dyn, + unidirectional: true, + }, + { + in: ObjectType("google.protobuf.ListValue"), + out: decls.NewListType(decls.Dyn), + unidirectional: true, + }, + { + in: ObjectType("google.protobuf.Struct"), + out: decls.NewMapType(decls.String, decls.Dyn), + unidirectional: true, + }, + { + in: ObjectType("google.protobuf.BoolValue"), + out: decls.NewWrapperType(decls.Bool), + unidirectional: true, + }, + { + in: ObjectType("google.protobuf.BytesValue"), + out: decls.NewWrapperType(decls.Bytes), + unidirectional: true, + }, + { + in: ObjectType("google.protobuf.DoubleValue"), + out: decls.NewWrapperType(decls.Double), + unidirectional: true, + }, + { + in: ObjectType("google.protobuf.FloatValue"), + out: decls.NewWrapperType(decls.Double), + unidirectional: true, + }, + { + in: ObjectType("google.protobuf.Int32Value"), + out: decls.NewWrapperType(decls.Int), + unidirectional: true, + }, + { + in: ObjectType("google.protobuf.Int64Value"), + out: decls.NewWrapperType(decls.Int), + unidirectional: true, + }, + { + in: ObjectType("google.protobuf.StringValue"), + out: decls.NewWrapperType(decls.String), + unidirectional: true, + }, + { + in: ObjectType("google.protobuf.UInt32Value"), + out: decls.NewWrapperType(decls.Uint), + unidirectional: true, + }, + { + in: ObjectType("google.protobuf.UInt64Value"), + out: decls.NewWrapperType(decls.Uint), + unidirectional: true, + }, + } + + for _, tc := range tests { + tc := tc + t.Run(tc.in.String(), func(t *testing.T) { + got, err := TypeToExprType(tc.in) + if err != nil { + t.Fatalf("TypeToExprType(%v) failed: %v", tc.in, err) + } + if !proto.Equal(got, tc.out) { + t.Errorf("TypeToExprType(%v) returned %v, wanted %v", tc.in, got, tc.out) + } + if tc.unidirectional { + return + } + roundTrip, err := ExprTypeToType(got) + if err != nil { + t.Fatalf("ExprTypeToType(%v) failed: %v", got, err) + } + if !tc.in.equals(roundTrip) { + t.Errorf("ExprTypeToType(%v) returned %v, wanted %v", got, roundTrip, tc.in) + } + }) + } +} + +func TestExprTypeToType(t *testing.T) { + tests := []struct { + in *exprpb.Type + out *Type + }{ + { + in: decls.NewObjectType("google.protobuf.Any"), + out: AnyType, + }, + { + in: decls.NewObjectType("google.protobuf.Duration"), + out: DurationType, + }, + { + in: decls.NewObjectType("google.protobuf.Timestamp"), + out: TimestampType, + }, + { + in: decls.NewObjectType("google.protobuf.Value"), + out: DynType, + }, + { + in: decls.NewObjectType("google.protobuf.ListValue"), + out: ListType(DynType), + }, + { + in: decls.NewObjectType("google.protobuf.Struct"), + out: MapType(StringType, DynType), + }, + { + in: decls.NewObjectType("google.protobuf.BoolValue"), + out: NullableType(BoolType), + }, + { + in: decls.NewObjectType("google.protobuf.BytesValue"), + out: NullableType(BytesType), + }, + { + in: decls.NewObjectType("google.protobuf.DoubleValue"), + out: NullableType(DoubleType), + }, + { + in: decls.NewObjectType("google.protobuf.FloatValue"), + out: NullableType(DoubleType), + }, + { + in: decls.NewObjectType("google.protobuf.Int32Value"), + out: NullableType(IntType), + }, + { + in: decls.NewObjectType("google.protobuf.Int64Value"), + out: NullableType(IntType), + }, + { + in: decls.NewObjectType("google.protobuf.StringValue"), + out: NullableType(StringType), + }, + { + in: decls.NewObjectType("google.protobuf.UInt32Value"), + out: NullableType(UintType), + }, + { + in: decls.NewObjectType("google.protobuf.UInt64Value"), + out: NullableType(UintType), + }, + } + + for _, tc := range tests { + tc := tc + t.Run(tc.in.String(), func(t *testing.T) { + got, err := ExprTypeToType(tc.in) + if err != nil { + t.Fatalf("ExprTypeToType(%v) failed: %v", tc.in, err) + } + if !got.equals(tc.out) { + t.Errorf("ExprTypeToType(%v) returned %v, wanted %v", tc.in, got, tc.out) + } + }) + } +} + +func TestExprTypeToTypeInvalid(t *testing.T) { + tests := []struct { + in *exprpb.Type + out string + }{ + { + in: &exprpb.Type{}, + out: "unsupported type", + }, + { + in: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{}}, + out: "unsupported primitive type", + }, + { + in: &exprpb.Type{TypeKind: &exprpb.Type_WellKnown{}}, + out: "unsupported well-known type", + }, + { + in: decls.NewListType(&exprpb.Type{}), + out: "unsupported type", + }, + { + in: decls.NewMapType(&exprpb.Type{}, decls.Dyn), + out: "unsupported type", + }, + { + in: decls.NewMapType(decls.Dyn, &exprpb.Type{}), + out: "unsupported type", + }, + { + in: decls.NewAbstractType("bad", &exprpb.Type{}), + out: "unsupported type", + }, + { + in: &exprpb.Type{TypeKind: &exprpb.Type_Wrapper{}}, + out: "unsupported primitive type", + }, + } + + for _, tc := range tests { + tc := tc + t.Run(tc.in.String(), func(t *testing.T) { + _, err := ExprTypeToType(tc.in) + if err == nil || !strings.Contains(err.Error(), tc.out) { + t.Fatalf("ExprTypeToType(%v) got %v, wanted error %v", tc.in, err, tc.out) + } + }) + } +} + +func TestExprDeclToDeclaration(t *testing.T) { + size, err := ExprDeclToDeclaration( + decls.NewFunction("size", decls.NewOverload("size_string", []*exprpb.Type{decls.String}, decls.Int)), + ) + if err != nil { + t.Fatalf("ExprDeclToDeclaration(size) failed: %v", err) + } + x, err := ExprDeclToDeclaration(decls.NewVar("x", decls.String)) + if err != nil { + t.Fatalf("ExprDeclToDeclaration(x) failed: %v", err) + } + e, err := NewCustomEnv(size, x) + if err != nil { + t.Fatalf("NewCustomEnv() failed: %v", err) + } + ast, iss := e.Compile("size(x)") + if iss.Err() != nil { + t.Fatalf("Compile(size(x)) failed: %v", iss.Err()) + } + prg, err := e.Program(ast, Functions(&functions.Overload{ + Operator: overloads.SizeString, + Unary: func(arg ref.Val) ref.Val { + str, ok := arg.(types.String) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + return types.Int(len([]rune(string(str)))) + }, + })) + if err != nil { + t.Fatalf("Program(ast) failed: %v", err) + } + out, _, err := prg.Eval(map[string]interface{}{"x": "hello"}) + if err != nil { + t.Fatalf("prg.Eval(x=hello) failed: %v", err) + } + if out.Equal(types.Int(5)) != types.True { + t.Errorf("prg.Eval(size(x)) got %v, wanted 5", out) + } +} + +func TestExprDeclToDeclarationInvalid(t *testing.T) { + tests := []struct { + in *exprpb.Decl + out string + }{ + { + in: &exprpb.Decl{}, + out: "unsupported decl", + }, + { + in: &exprpb.Decl{ + Name: "bad_var", + DeclKind: &exprpb.Decl_Ident{ + Ident: &exprpb.Decl_IdentDecl{ + Type: decls.NewListType(&exprpb.Type{}), + }, + }, + }, + out: "unsupported type", + }, + { + in: &exprpb.Decl{ + Name: "bad_func_return", + DeclKind: &exprpb.Decl_Function{ + Function: &exprpb.Decl_FunctionDecl{ + Overloads: []*exprpb.Decl_FunctionDecl_Overload{ + { + OverloadId: "bad_overload", + ResultType: &exprpb.Type{}, + }, + }, + }, + }, + }, + out: "unsupported type", + }, + { + in: &exprpb.Decl{ + Name: "bad_func_arg", + DeclKind: &exprpb.Decl_Function{ + Function: &exprpb.Decl_FunctionDecl{ + Overloads: []*exprpb.Decl_FunctionDecl_Overload{ + { + OverloadId: "bad_overload", + Params: []*exprpb.Type{{}}, + ResultType: decls.Dyn, + }, + }, + }, + }, + }, + out: "unsupported type", + }, + } + + for _, tc := range tests { + tc := tc + t.Run(tc.in.String(), func(t *testing.T) { + _, err := ExprDeclToDeclaration(tc.in) + if err == nil || !strings.Contains(err.Error(), tc.out) { + t.Fatalf("ExprDeclToDeclarations(%v) got %v, wanted error %v", tc.in, err, tc.out) + } + }) + } +} + +func testParse(t testing.TB, env *Env, expr string, want interface{}) { + t.Helper() + ast, iss := env.Parse(expr) + if iss.Err() != nil { + t.Fatalf("env.Parse(%s) failed: %v", expr, iss.Err()) + } + prg, err := env.Program(ast) + if err != nil { + t.Fatalf("env.Program() failed: %v", err) + } + out, _, err := prg.Eval(map[string]interface{}{"err": types.NewErr("error argument"), "unk": types.Unknown{42}}) + switch want := want.(type) { + case types.Unknown: + if !reflect.DeepEqual(want, out.(types.Unknown)) { + t.Errorf("prg.Eval() got %v, wanted %v", out, want) + } + case ref.Val: + if want.Equal(out) != types.True { + t.Errorf("prg.Eval() got %v, wanted %v", out, want) + } + case error: + if err == nil || want.Error() != err.Error() { + t.Errorf("prg.Eval() got error '%v', wanted '%v'", err, want) + } + } +} + +func testCompile(t testing.TB, env *Env, expr string, want interface{}) { + t.Helper() + ast, iss := env.Compile(expr) + if iss.Err() != nil { + t.Fatalf("env.Compile(%s) failed: %v", expr, iss.Err()) + } + prg, err := env.Program(ast) + if err != nil { + t.Fatalf("env.Program() failed: %v", err) + } + out, _, err := prg.Eval(map[string]interface{}{"err": types.NewErr("error argument"), "unk": types.Unknown{42}}) + switch want := want.(type) { + case types.Unknown: + if !reflect.DeepEqual(want, out.(types.Unknown)) { + t.Errorf("prg.Eval() got %v, wanted %v", out, want) + } + case ref.Val: + if want.Equal(out) != types.True { + t.Errorf("prg.Eval() got %v, wanted %v", out, want) + } + case error: + if err == nil || want.Error() != err.Error() { + t.Errorf("prg.Eval() got error '%v', wanted '%v'", err, want) + } + } +} diff -Nru golang-github-google-cel-go-0.11.4+ds/cel/env.go golang-github-google-cel-go-0.12.5+ds/cel/env.go --- golang-github-google-cel-go-0.11.4+ds/cel/env.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/cel/env.go 2022-12-20 15:30:36.000000000 +0000 @@ -61,11 +61,23 @@ // 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. +// +// Deprecated: use OutputType func (ast *Ast) ResultType() *exprpb.Type { if !ast.IsChecked() { return decls.Dyn } - return ast.typeMap[ast.expr.Id] + return ast.typeMap[ast.expr.GetId()] +} + +// OutputType returns the output type of the expression if the Ast has been type-checked, else +// returns cel.DynType as the parse step cannot infer types. +func (ast *Ast) OutputType() *Type { + t, err := ExprTypeToType(ast.ResultType()) + if err != nil { + return DynType + } + return t } // Source returns a view of the input used to create the Ast. This source may be complete or @@ -82,12 +94,14 @@ // Env encapsulates the context necessary to perform parsing, type checking, or generation of // evaluable programs for different expressions. type Env struct { - Container *containers.Container - declarations []*exprpb.Decl - macros []parser.Macro - adapter ref.TypeAdapter - provider ref.TypeProvider - features map[int]bool + Container *containers.Container + functions map[string]*functionDecl + declarations []*exprpb.Decl + macros []parser.Macro + adapter ref.TypeAdapter + provider ref.TypeProvider + features map[int]bool + appliedFeatures map[int]bool // Internal parser representation prsr *parser.Parser @@ -137,13 +151,15 @@ return nil, err } return (&Env{ - declarations: []*exprpb.Decl{}, - macros: []parser.Macro{}, - Container: containers.DefaultContainer, - adapter: registry, - provider: registry, - features: map[int]bool{}, - progOpts: []ProgramOption{}, + declarations: []*exprpb.Decl{}, + functions: map[string]*functionDecl{}, + macros: []parser.Macro{}, + Container: containers.DefaultContainer, + adapter: registry, + provider: registry, + features: map[int]bool{}, + appliedFeatures: map[int]bool{}, + progOpts: []ProgramOption{}, }).configure(opts) } @@ -280,16 +296,27 @@ for k, v := range e.features { featuresCopy[k] = v } + appliedFeaturesCopy := make(map[int]bool, len(e.appliedFeatures)) + for k, v := range e.appliedFeatures { + appliedFeaturesCopy[k] = v + } + funcsCopy := make(map[string]*functionDecl, len(e.functions)) + for k, v := range e.functions { + funcsCopy[k] = v + } + // TODO: functions copy needs to happen here. ext := &Env{ - Container: e.Container, - declarations: decsCopy, - macros: macsCopy, - progOpts: progOptsCopy, - adapter: adapter, - features: featuresCopy, - provider: provider, - chkOpts: chkOptsCopy, + Container: e.Container, + declarations: decsCopy, + functions: funcsCopy, + macros: macsCopy, + progOpts: progOptsCopy, + adapter: adapter, + features: featuresCopy, + appliedFeatures: appliedFeaturesCopy, + provider: provider, + chkOpts: chkOptsCopy, } return ext.configure(opts) } @@ -436,6 +463,28 @@ } } + // If the default UTC timezone fix has been enabled, make sure the library is configured + if e.HasFeature(featureDefaultUTCTimeZone) { + if _, found := e.appliedFeatures[featureDefaultUTCTimeZone]; !found { + e, err = Lib(timeUTCLibrary{})(e) + if err != nil { + return nil, err + } + // record that the feature has been applied since it will generate declarations + // and functions which will be propagated on Extend() calls and which should only + // be registered once. + e.appliedFeatures[featureDefaultUTCTimeZone] = true + } + } + + // Initialize all of the functions configured within the environment. + for _, fn := range e.functions { + err = fn.init() + if err != nil { + return nil, err + } + } + // Configure the parser. prsrOpts := []parser.Option{parser.Macros(e.macros...)} if e.HasFeature(featureEnableMacroCallTracking) { @@ -446,8 +495,7 @@ return nil, err } - // The simplest way to eagerly validate declarations on environment creation is to compile - // a dummy program and check for the presence of e.chkErr being non-nil. + // Ensure that the checker init happens eagerly rather than lazily. if e.HasFeature(featureEagerlyValidateDeclarations) { err := e.initChecker() if err != nil { @@ -473,11 +521,26 @@ e.chkErr = err return } + // Add the statically configured declarations. err = ce.Add(e.declarations...) if err != nil { e.chkErr = err return } + // Add the function declarations which are derived from the FunctionDecl instances. + for _, fn := range e.functions { + fnDecl, err := functionDeclToExprDecl(fn) + if err != nil { + e.chkErr = err + return + } + err = ce.Add(fnDecl) + if err != nil { + e.chkErr = err + return + } + } + // Add function declarations here separately. e.chk = ce }) return e.chkErr diff -Nru golang-github-google-cel-go-0.11.4+ds/cel/env_test.go golang-github-google-cel-go-0.12.5+ds/cel/env_test.go --- golang-github-google-cel-go-0.11.4+ds/cel/env_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/cel/env_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -18,12 +18,9 @@ "reflect" "testing" - "github.com/google/cel-go/checker/decls" "github.com/google/cel-go/common" "github.com/google/cel-go/common/operators" "github.com/google/cel-go/common/types" - - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) func TestIssuesNil(t *testing.T) { @@ -167,13 +164,10 @@ } for i := 0; i < b.N; i++ { ext, err := env.Extend( - Declarations( - decls.NewVar("test_var", decls.String), - decls.NewFunction( - operators.In, - decls.NewOverload("string_in_string", []*exprpb.Type{ - decls.String, decls.String, - }, decls.Bool)), + Variable("test_var", StringType), + Function( + operators.In, + Overload("string_in_string", []*Type{StringType, StringType}, BoolType), ), ) if err != nil { diff -Nru golang-github-google-cel-go-0.11.4+ds/cel/io.go golang-github-google-cel-go-0.12.5+ds/cel/io.go --- golang-github-google-cel-go-0.11.4+ds/cel/io.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/cel/io.go 2022-12-20 15:30:36.000000000 +0000 @@ -241,7 +241,7 @@ if err != nil { return nil, err } - return adapter.NativeToValue(msg.(proto.Message)), nil + return adapter.NativeToValue(msg), nil case *exprpb.Value_MapValue: m := v.GetMapValue() entries := make(map[ref.Val]ref.Val) diff -Nru golang-github-google-cel-go-0.11.4+ds/cel/io_test.go golang-github-google-cel-go-0.12.5+ds/cel/io_test.go --- golang-github-google-cel-go-0.11.4+ds/cel/io_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/cel/io_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -21,10 +21,10 @@ "github.com/google/cel-go/checker/decls" "github.com/google/cel-go/common/types" - "github.com/google/cel-go/test/proto3pb" "google.golang.org/protobuf/proto" + proto3pb "github.com/google/cel-go/test/proto3pb" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) diff -Nru golang-github-google-cel-go-0.11.4+ds/cel/library.go golang-github-google-cel-go-0.12.5+ds/cel/library.go --- golang-github-google-cel-go-0.11.4+ds/cel/library.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/cel/library.go 2022-12-20 15:30:36.000000000 +0000 @@ -15,9 +15,15 @@ package cel import ( + "strconv" + "strings" + "time" + "github.com/google/cel-go/checker" + "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/interpreter/functions" - "github.com/google/cel-go/parser" ) // Library provides a collection of EnvOption and ProgramOption values used to configure a CEL @@ -65,7 +71,7 @@ func (stdLibrary) CompileOptions() []EnvOption { return []EnvOption{ Declarations(checker.StandardDeclarations()...), - Macros(parser.AllMacros...), + Macros(StandardMacros...), } } @@ -75,3 +81,263 @@ Functions(functions.StandardOverloads()...), } } + +type timeUTCLibrary struct{} + +func (timeUTCLibrary) CompileOptions() []EnvOption { + return timeOverloadDeclarations +} + +func (timeUTCLibrary) ProgramOptions() []ProgramOption { + return []ProgramOption{} +} + +// Declarations and functions which enable using UTC on time.Time inputs when the timezone is unspecified +// in the CEL expression. +var ( + utcTZ = types.String("UTC") + + timeOverloadDeclarations = []EnvOption{ + Function(overloads.TimeGetHours, + MemberOverload(overloads.DurationToHours, []*Type{DurationType}, IntType, + UnaryBinding(func(dur ref.Val) ref.Val { + d := dur.(types.Duration) + return types.Int(d.Hours()) + }))), + Function(overloads.TimeGetMinutes, + MemberOverload(overloads.DurationToMinutes, []*Type{DurationType}, IntType, + UnaryBinding(func(dur ref.Val) ref.Val { + d := dur.(types.Duration) + return types.Int(d.Minutes()) + }))), + Function(overloads.TimeGetSeconds, + MemberOverload(overloads.DurationToSeconds, []*Type{DurationType}, IntType, + UnaryBinding(func(dur ref.Val) ref.Val { + d := dur.(types.Duration) + return types.Int(d.Seconds()) + }))), + Function(overloads.TimeGetMilliseconds, + MemberOverload(overloads.DurationToMilliseconds, []*Type{DurationType}, IntType, + UnaryBinding(func(dur ref.Val) ref.Val { + d := dur.(types.Duration) + return types.Int(d.Milliseconds()) + }))), + Function(overloads.TimeGetFullYear, + MemberOverload(overloads.TimestampToYear, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetFullYear(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToYearWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetFullYear), + ), + ), + Function(overloads.TimeGetMonth, + MemberOverload(overloads.TimestampToMonth, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetMonth(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToMonthWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetMonth), + ), + ), + Function(overloads.TimeGetDayOfYear, + MemberOverload(overloads.TimestampToDayOfYear, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetDayOfYear(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToDayOfYearWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(func(ts, tz ref.Val) ref.Val { + return timestampGetDayOfYear(ts, tz) + }), + ), + ), + Function(overloads.TimeGetDayOfMonth, + MemberOverload(overloads.TimestampToDayOfMonthZeroBased, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetDayOfMonthZeroBased(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToDayOfMonthZeroBasedWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetDayOfMonthZeroBased), + ), + ), + Function(overloads.TimeGetDate, + MemberOverload(overloads.TimestampToDayOfMonthOneBased, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetDayOfMonthOneBased(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToDayOfMonthOneBasedWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetDayOfMonthOneBased), + ), + ), + Function(overloads.TimeGetDayOfWeek, + MemberOverload(overloads.TimestampToDayOfWeek, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetDayOfWeek(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToDayOfWeekWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetDayOfWeek), + ), + ), + Function(overloads.TimeGetHours, + MemberOverload(overloads.TimestampToHours, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetHours(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToHoursWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetHours), + ), + ), + Function(overloads.TimeGetMinutes, + MemberOverload(overloads.TimestampToMinutes, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetMinutes(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToMinutesWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetMinutes), + ), + ), + Function(overloads.TimeGetSeconds, + MemberOverload(overloads.TimestampToSeconds, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetSeconds(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToSecondsWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetSeconds), + ), + ), + Function(overloads.TimeGetMilliseconds, + MemberOverload(overloads.TimestampToMilliseconds, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetMilliseconds(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToMillisecondsWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetMilliseconds), + ), + ), + } +) + +func timestampGetFullYear(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.Year()) +} + +func timestampGetMonth(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + // CEL spec indicates that the month should be 0-based, but the Time value + // for Month() is 1-based. + return types.Int(t.Month() - 1) +} + +func timestampGetDayOfYear(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.YearDay() - 1) +} + +func timestampGetDayOfMonthZeroBased(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.Day() - 1) +} + +func timestampGetDayOfMonthOneBased(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.Day()) +} + +func timestampGetDayOfWeek(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.Weekday()) +} + +func timestampGetHours(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.Hour()) +} + +func timestampGetMinutes(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.Minute()) +} + +func timestampGetSeconds(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.Second()) +} + +func timestampGetMilliseconds(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.Nanosecond() / 1000000) +} + +func inTimeZone(ts, tz ref.Val) (time.Time, error) { + t := ts.(types.Timestamp) + val := string(tz.(types.String)) + ind := strings.Index(val, ":") + if ind == -1 { + loc, err := time.LoadLocation(val) + if err != nil { + return time.Time{}, err + } + return t.In(loc), nil + } + + // 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 time.Time{}, err + } + min, err := strconv.Atoi(string(val[ind+1:])) + if err != nil { + return time.Time{}, 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 t.In(timezone), nil +} diff -Nru golang-github-google-cel-go-0.11.4+ds/cel/macro.go golang-github-google-cel-go-0.12.5+ds/cel/macro.go --- golang-github-google-cel-go-0.11.4+ds/cel/macro.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/cel/macro.go 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,139 @@ +// Copyright 2022 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 ( + "github.com/google/cel-go/common" + "github.com/google/cel-go/parser" + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// Macro describes a function signature to match and the MacroExpander to apply. +// +// Note: when a Macro should apply to multiple overloads (based on arg count) of a given function, +// a Macro should be created per arg-count or as a var arg macro. +type Macro = parser.Macro + +// MacroExpander converts a call and its associated arguments into a new CEL abstract syntax tree, or an error +// if the input arguments are not suitable for the expansion requirements for the macro in question. +// +// The MacroExpander accepts as arguments a MacroExprHelper as well as the arguments used in the function call +// and produces as output an Expr ast node. +// +// Note: when the Macro.IsReceiverStyle() method returns true, the target argument will be nil. +type MacroExpander = parser.MacroExpander + +// MacroExprHelper exposes helper methods for creating new expressions within a CEL abstract syntax tree. +type MacroExprHelper = parser.ExprHelper + +// NewGlobalMacro creates a Macro for a global function with the specified arg count. +func NewGlobalMacro(function string, argCount int, expander MacroExpander) Macro { + return parser.NewGlobalMacro(function, argCount, expander) +} + +// NewReceiverMacro creates a Macro for a receiver function matching the specified arg count. +func NewReceiverMacro(function string, argCount int, expander MacroExpander) Macro { + return parser.NewReceiverMacro(function, argCount, expander) +} + +// NewGlobalVarArgMacro creates a Macro for a global function with a variable arg count. +func NewGlobalVarArgMacro(function string, expander MacroExpander) Macro { + return parser.NewGlobalVarArgMacro(function, expander) +} + +// NewReceiverVarArgMacro creates a Macro for a receiver function matching a variable arg count. +func NewReceiverVarArgMacro(function string, expander MacroExpander) Macro { + return parser.NewReceiverVarArgMacro(function, expander) +} + +// HasMacroExpander expands the input call arguments into a presence test, e.g. has(.field) +func HasMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + return parser.MakeHas(meh, target, args) +} + +// ExistsMacroExpander expands the input call arguments into a comprehension that returns true if any of the +// elements in the range match the predicate expressions: +// .exists(, ) +func ExistsMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + return parser.MakeExists(meh, target, args) +} + +// ExistsOneMacroExpander expands the input call arguments into a comprehension that returns true if exactly +// one of the elements in the range match the predicate expressions: +// .exists_one(, ) +func ExistsOneMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + return parser.MakeExistsOne(meh, target, args) +} + +// MapMacroExpander expands the input call arguments into a comprehension that transforms each element in the +// input to produce an output list. +// +// There are two call patterns supported by map: +// .map(, ) +// .map(, , ) +// In the second form only iterVar values which return true when provided to the predicate expression +// are transformed. +func MapMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + return parser.MakeMap(meh, target, args) +} + +// FilterMacroExpander expands the input call arguments into a comprehension which produces a list which contains +// only elements which match the provided predicate expression: +// .filter(, ) +func FilterMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + return parser.MakeFilter(meh, target, args) +} + +var ( + // Aliases to each macro in the CEL standard environment. + // Note: reassigning these macro variables may result in undefined behavior. + + // HasMacro expands "has(m.f)" which tests the presence of a field, avoiding the need to + // specify the field as a string. + HasMacro = parser.HasMacro + + // AllMacro expands "range.all(var, predicate)" into a comprehension which ensures that all + // elements in the range satisfy the predicate. + AllMacro = parser.AllMacro + + // ExistsMacro expands "range.exists(var, predicate)" into a comprehension which ensures that + // some element in the range satisfies the predicate. + ExistsMacro = parser.ExistsMacro + + // ExistsOneMacro expands "range.exists_one(var, predicate)", which is true if for exactly one + // element in range the predicate holds. + ExistsOneMacro = parser.ExistsOneMacro + + // MapMacro expands "range.map(var, function)" into a comprehension which applies the function + // to each element in the range to produce a new list. + MapMacro = parser.MapMacro + + // MapFilterMacro expands "range.map(var, predicate, function)" into a comprehension which + // first filters the elements in the range by the predicate, then applies the transform function + // to produce a new list. + MapFilterMacro = parser.MapFilterMacro + + // FilterMacro expands "range.filter(var, predicate)" into a comprehension which filters + // elements in the range, producing a new list from the elements that satisfy the predicate. + FilterMacro = parser.FilterMacro + + // StandardMacros provides an alias to all the CEL macros defined in the standard environment. + StandardMacros = []Macro{ + HasMacro, AllMacro, ExistsMacro, ExistsOneMacro, MapMacro, MapFilterMacro, FilterMacro, + } + + // NoMacros provides an alias to an empty list of macros + NoMacros = []Macro{} +) diff -Nru golang-github-google-cel-go-0.11.4+ds/cel/options.go golang-github-google-cel-go-0.12.5+ds/cel/options.go --- golang-github-google-cel-go-0.11.4+ds/cel/options.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/cel/options.go 2022-12-20 15:30:36.000000000 +0000 @@ -29,7 +29,6 @@ "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/interpreter" "github.com/google/cel-go/interpreter/functions" - "github.com/google/cel-go/parser" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" descpb "google.golang.org/protobuf/types/descriptorpb" @@ -57,6 +56,11 @@ // Enable eager validation of declarations to ensure that Env values created // with `Extend` inherit a validated list of declarations from the parent Env. featureEagerlyValidateDeclarations + + // Enable the use of the default UTC timezone when a timezone is not specified + // on a CEL timestamp operation. This fixes the scenario where the input time + // is not already in UTC. + featureDefaultUTCTimeZone ) // EnvOption is a functional interface for configuring the environment. @@ -68,7 +72,7 @@ // comprehensions such as `all` and `exists` are enabled only via macros. func ClearMacros() EnvOption { return func(e *Env) (*Env, error) { - e.macros = parser.NoMacros + e.macros = NoMacros return e, nil } } @@ -99,8 +103,6 @@ // for the environment. The NewEnv call builds on top of the standard CEL declarations. For a // purely custom set of declarations use NewCustomEnv. func Declarations(decls ...*exprpb.Decl) EnvOption { - // 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 @@ -132,7 +134,7 @@ // Macros option extends the macro set configured in the environment. // // Note: This option must be specified after ClearMacros if used together. -func Macros(macros ...parser.Macro) EnvOption { +func Macros(macros ...Macro) EnvOption { return func(e *Env) (*Env, error) { e.macros = append(e.macros, macros...) return e, nil @@ -332,6 +334,9 @@ } // Functions adds function overloads that extend or override the set of CEL built-ins. +// +// Deprecated: use Function() instead to declare the function, its overload signatures, +// and the overload implementations. func Functions(funcs ...*functions.Overload) ProgramOption { return func(p *prog) (*prog, error) { if err := p.dispatcher.Add(funcs...); err != nil { @@ -442,7 +447,7 @@ } func fieldToCELType(field protoreflect.FieldDescriptor) (*exprpb.Type, error) { - if field.Kind() == protoreflect.MessageKind { + if field.Kind() == protoreflect.MessageKind || field.Kind() == protoreflect.GroupKind { msgName := (string)(field.Message().FullName()) wellKnownType, found := pb.CheckedWellKnowns[msgName] if found { @@ -523,6 +528,12 @@ return features(featureCrossTypeNumericComparisons, enabled) } +// DefaultUTCTimeZone ensures that time-based operations use the UTC timezone rather than the +// input time's local timezone. +func DefaultUTCTimeZone(enabled bool) EnvOption { + return features(featureDefaultUTCTimeZone, enabled) +} + // features sets the given feature flags. See list of Feature constants above. func features(flag int, enabled bool) EnvOption { return func(e *Env) (*Env, error) { diff -Nru golang-github-google-cel-go-0.11.4+ds/cel/program.go golang-github-google-cel-go-0.12.5+ds/cel/program.go --- golang-github-google-cel-go-0.11.4+ds/cel/program.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/cel/program.go 2022-12-20 15:30:36.000000000 +0000 @@ -168,6 +168,18 @@ } } + // Add the function bindings created via Function() options. + for _, fn := range e.functions { + bindings, err := fn.bindings() + if err != nil { + return nil, err + } + err = disp.Add(bindings...) + if err != nil { + return nil, err + } + } + // Set the attribute factory after the options have been set. var attrFactory interpreter.AttributeFactory if p.evalOpts&OptPartialEval == OptPartialEval { diff -Nru golang-github-google-cel-go-0.11.4+ds/checker/checker.go golang-github-google-cel-go-0.12.5+ds/checker/checker.go --- golang-github-google-cel-go-0.11.4+ds/checker/checker.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/checker/checker.go 2022-12-20 15:30:36.000000000 +0000 @@ -80,10 +80,10 @@ return } - switch e.ExprKind.(type) { + switch e.GetExprKind().(type) { case *exprpb.Expr_ConstExpr: literal := e.GetConstExpr() - switch literal.ConstantKind.(type) { + switch literal.GetConstantKind().(type) { case *exprpb.Constant_BoolValue: c.checkBoolLiteral(e) case *exprpb.Constant_BytesValue: @@ -149,8 +149,8 @@ identExpr := e.GetIdentExpr() // Check to see if the identifier is declared. if ident := c.env.LookupIdent(identExpr.GetName()); ident != nil { - c.setType(e, ident.GetIdent().Type) - c.setReference(e, newIdentReference(ident.GetName(), ident.GetIdent().Value)) + c.setType(e, ident.GetIdent().GetType()) + c.setReference(e, newIdentReference(ident.GetName(), ident.GetIdent().GetValue())) // Overwrite the identifier with its fully qualified name. identExpr.Name = ident.GetName() return @@ -186,23 +186,20 @@ } // Interpret as field selection, first traversing down the operand. - c.check(sel.Operand) - targetType := c.getType(sel.Operand) + c.check(sel.GetOperand()) + targetType := substitute(c.mappings, c.getType(sel.GetOperand()), false) // Assume error type by default as most types do not support field selection. resultType := decls.Error switch kindOf(targetType) { case kindMap: // Maps yield their value type as the selection result type. mapType := targetType.GetMapType() - resultType = mapType.ValueType + resultType = mapType.GetValueType() case kindObject: // Objects yield their field type declaration as the selection result type, but only if // the field is defined. messageType := targetType - if fieldType, found := c.lookupFieldType( - c.location(e), - messageType.GetMessageType(), - sel.Field); found { + if fieldType, found := c.lookupFieldType(c.location(e), messageType.GetMessageType(), sel.GetField()); found { resultType = fieldType.Type } case kindTypeParam: @@ -224,7 +221,7 @@ if sel.TestOnly { resultType = decls.Bool } - c.setType(e, resultType) + c.setType(e, substitute(c.mappings, resultType, false)) } func (c *checker) checkCall(e *exprpb.Expr) { @@ -320,15 +317,15 @@ var resultType *exprpb.Type var checkedRef *exprpb.Reference - for _, overload := range fn.GetFunction().Overloads { + for _, overload := range fn.GetFunction().GetOverloads() { // Determine whether the overload is currently considered. if c.env.isOverloadDisabled(overload.GetOverloadId()) { continue } // Ensure the call style for the overload matches. - if (target == nil && overload.IsInstanceFunction) || - (target != nil && !overload.IsInstanceFunction) { + if (target == nil && overload.GetIsInstanceFunction()) || + (target != nil && !overload.GetIsInstanceFunction()) { // not a compatible call style. continue } @@ -348,13 +345,11 @@ if checkedRef == nil { checkedRef = newFunctionReference(overload.GetOverloadId()) } else { - checkedRef.OverloadId = append(checkedRef.OverloadId, overload.GetOverloadId()) + checkedRef.OverloadId = append(checkedRef.GetOverloadId(), overload.GetOverloadId()) } // First matching overload, determines result type. - fnResultType := substitute(c.mappings, - overloadType.GetFunction().GetResultType(), - false) + fnResultType := substitute(c.mappings, overloadType.GetFunction().GetResultType(), false) if resultType == nil { resultType = fnResultType } else if !isDyn(resultType) && !proto.Equal(fnResultType, resultType) { @@ -375,7 +370,7 @@ func (c *checker) checkCreateList(e *exprpb.Expr) { create := e.GetListExpr() var elemType *exprpb.Type - for _, e := range create.Elements { + for _, e := range create.GetElements() { c.check(e) elemType = c.joinTypes(c.location(e), elemType, c.getType(e)) } @@ -388,7 +383,7 @@ func (c *checker) checkCreateStruct(e *exprpb.Expr) { str := e.GetStructExpr() - if str.MessageName != "" { + if str.GetMessageName() != "" { c.checkCreateMessage(e) } else { c.checkCreateMap(e) @@ -419,22 +414,22 @@ msgVal := e.GetStructExpr() // Determine the type of the message. messageType := decls.Error - decl := c.env.LookupIdent(msgVal.MessageName) + decl := c.env.LookupIdent(msgVal.GetMessageName()) if decl == nil { c.errors.undeclaredReference( - c.location(e), c.env.container.Name(), msgVal.MessageName) + c.location(e), c.env.container.Name(), msgVal.GetMessageName()) return } // Ensure the type name is fully qualified in the AST. msgVal.MessageName = decl.GetName() c.setReference(e, newIdentReference(decl.GetName(), nil)) ident := decl.GetIdent() - identKind := kindOf(ident.Type) + identKind := kindOf(ident.GetType()) if identKind != kindError { if identKind != kindType { - c.errors.notAType(c.location(e), ident.Type) + c.errors.notAType(c.location(e), ident.GetType()) } else { - messageType = ident.Type.GetType() + messageType = ident.GetType().GetType() if kindOf(messageType) != kindObject { c.errors.notAMessageType(c.location(e), messageType) messageType = decls.Error @@ -450,12 +445,12 @@ // Check the field initializers. for _, ent := range msgVal.GetEntries() { field := ent.GetFieldKey() - value := ent.Value + value := ent.GetValue() c.check(value) fieldType := decls.Error if t, found := c.lookupFieldType( - c.locationByID(ent.Id), + c.locationByID(ent.GetId()), messageType.GetMessageType(), field); found { fieldType = t.Type @@ -469,18 +464,18 @@ 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) + c.check(comp.GetIterRange()) + c.check(comp.GetAccuInit()) + accuType := c.getType(comp.GetAccuInit()) + rangeType := substitute(c.mappings, c.getType(comp.GetIterRange()), false) var varType *exprpb.Type switch kindOf(rangeType) { case kindList: - varType = rangeType.GetListType().ElemType + varType = rangeType.GetListType().GetElemType() case kindMap: // Ranges over the keys. - varType = rangeType.GetMapType().KeyType + varType = rangeType.GetMapType().GetKeyType() case kindDyn, kindError, kindTypeParam: // Set the range type to DYN to prevent assignment to a potentially incorrect type // at a later point in type-checking. The isAssignable call will update the type @@ -489,28 +484,28 @@ // Set the range iteration variable to type DYN as well. varType = decls.Dyn default: - c.errors.notAComprehensionRange(c.location(comp.IterRange), rangeType) + c.errors.notAComprehensionRange(c.location(comp.GetIterRange()), rangeType) varType = decls.Error } // Create a scope for the comprehension since it has a local accumulation variable. // This scope will contain the accumulation variable used to compute the result. c.env = c.env.enterScope() - c.env.Add(decls.NewVar(comp.AccuVar, accuType)) + c.env.Add(decls.NewVar(comp.GetAccuVar(), accuType)) // Create a block scope for the loop. c.env = c.env.enterScope() - c.env.Add(decls.NewVar(comp.IterVar, varType)) + c.env.Add(decls.NewVar(comp.GetIterVar(), varType)) // 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) + c.check(comp.GetLoopCondition()) + c.assertType(comp.GetLoopCondition(), decls.Bool) + c.check(comp.GetLoopStep()) + c.assertType(comp.GetLoopStep(), accuType) // Exit the loop's block scope before checking the result. c.env = c.env.exitScope() - c.check(comp.Result) + c.check(comp.GetResult()) // Exit the comprehension scope. c.env = c.env.exitScope() - c.setType(e, c.getType(comp.Result)) + c.setType(e, substitute(c.mappings, c.getType(comp.GetResult()), false)) } // Checks compatibility of joined types, and returns the most general common type. @@ -576,25 +571,25 @@ } func (c *checker) setType(e *exprpb.Expr, t *exprpb.Type) { - if old, found := c.types[e.Id]; found && !proto.Equal(old, t) { + if old, found := c.types[e.GetId()]; found && !proto.Equal(old, t) { c.errors.ReportError(c.location(e), "(Incompatible) Type already exists for expression: %v(%d) old:%v, new:%v", e, e.GetId(), old, t) return } - c.types[e.Id] = t + c.types[e.GetId()] = t } func (c *checker) getType(e *exprpb.Expr) *exprpb.Type { - return c.types[e.Id] + return c.types[e.GetId()] } func (c *checker) setReference(e *exprpb.Expr, r *exprpb.Reference) { - if old, found := c.references[e.Id]; found && !proto.Equal(old, r) { + if old, found := c.references[e.GetId()]; found && !proto.Equal(old, r) { c.errors.ReportError(c.location(e), - "Reference already exists for expression: %v(%d) old:%v, new:%v", e, e.Id, old, r) + "Reference already exists for expression: %v(%d) old:%v, new:%v", e, e.GetId(), old, r) return } - c.references[e.Id] = r + c.references[e.GetId()] = r } func (c *checker) assertType(e *exprpb.Expr, t *exprpb.Type) { @@ -616,7 +611,7 @@ } func (c *checker) location(e *exprpb.Expr) common.Location { - return c.locationByID(e.Id) + return c.locationByID(e.GetId()) } func (c *checker) locationByID(id int64) common.Location { @@ -624,7 +619,7 @@ var line = 1 if offset, found := positions[id]; found { col := int(offset) - for _, lineOffset := range c.sourceInfo.LineOffsets { + for _, lineOffset := range c.sourceInfo.GetLineOffsets() { if lineOffset < offset { line++ col = int(offset - lineOffset) diff -Nru golang-github-google-cel-go-0.11.4+ds/checker/checker_test.go golang-github-google-cel-go-0.12.5+ds/checker/checker_test.go --- golang-github-google-cel-go-0.11.4+ds/checker/checker_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/checker/checker_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -1397,7 +1397,7 @@ { in: `[].map(x, [].map(y, x in y && y in x))`, err: ` - ERROR: :1:33: found no matching overload for '@in' applied to '(type_param:"_var2" , type_param:"_var0" )' + ERROR: :1:33: found no matching overload for '@in' applied to '(_var2, _var0)' | [].map(x, [].map(y, x in y && y in x)) | ................................^`, }, @@ -1908,6 +1908,134 @@ __result__~list(list(list(int)))^__result__)~list(list(list(int))) `, }, + { + in: `values.filter(i, i.content != "").map(i, i.content)`, + outType: decls.NewListType(decls.String), + env: testEnv{ + idents: []*exprpb.Decl{ + decls.NewVar("values", decls.NewListType(decls.NewMapType(decls.String, decls.String))), + }, + }, + out: `__comprehension__( + // Variable + i, + // Target + __comprehension__( + // Variable + i, + // Target + values~list(map(string, string))^values, + // Accumulator + __result__, + // Init + []~list(map(string, string)), + // LoopCondition + true~bool, + // LoopStep + _?_:_( + _!=_( + i~map(string, string)^i.content~string, + ""~string + )~bool^not_equals, + _+_( + __result__~list(map(string, string))^__result__, + [ + i~map(string, string)^i + ]~list(map(string, string)) + )~list(map(string, string))^add_list, + __result__~list(map(string, string))^__result__ + )~list(map(string, string))^conditional, + // Result + __result__~list(map(string, string))^__result__)~list(map(string, string)), + // Accumulator + __result__, + // Init + []~list(string), + // LoopCondition + true~bool, + // LoopStep + _+_( + __result__~list(string)^__result__, + [ + i~map(string, string)^i.content~string + ]~list(string) + )~list(string)^add_list, + // Result + __result__~list(string)^__result__)~list(string)`, + }, + { + in: `[{}.map(c,c,c)]+[{}.map(c,c,c)]`, + outType: decls.NewListType(decls.NewListType(decls.Bool)), + out: `_+_( + [ + __comprehension__( + // Variable + c, + // Target + {}~map(bool, dyn), + // Accumulator + __result__, + // Init + []~list(bool), + // LoopCondition + true~bool, + // LoopStep + _?_:_( + c~bool^c, + _+_( + __result__~list(bool)^__result__, + [ + c~bool^c + ]~list(bool) + )~list(bool)^add_list, + __result__~list(bool)^__result__ + )~list(bool)^conditional, + // Result + __result__~list(bool)^__result__)~list(bool) + ]~list(list(bool)), + [ + __comprehension__( + // Variable + c, + // Target + {}~map(bool, dyn), + // Accumulator + __result__, + // Init + []~list(bool), + // LoopCondition + true~bool, + // LoopStep + _?_:_( + c~bool^c, + _+_( + __result__~list(bool)^__result__, + [ + c~bool^c + ]~list(bool) + )~list(bool)^add_list, + __result__~list(bool)^__result__ + )~list(bool)^conditional, + // Result + __result__~list(bool)^__result__)~list(bool) + ]~list(list(bool)) + )~list(list(bool))^add_list`, + }, + { + in: "type(testAllTypes.nestedgroup.nested_id) == int", + env: testEnv{ + idents: []*exprpb.Decl{ + decls.NewVar("testAllTypes", decls.NewObjectType("google.expr.proto2.test.TestAllTypes")), + }, + }, + outType: decls.Bool, + out: `_==_( + type( + testAllTypes~google.expr.proto2.test.TestAllTypes^testAllTypes.nestedgroup~google.expr.proto2.test.TestAllTypes.NestedGroup.nested_id~int + )~type(int)^type, + int~type(int)^int + )~bool^equals`, + }, } var testEnvs = map[string]testEnv{ diff -Nru golang-github-google-cel-go-0.11.4+ds/checker/cost.go golang-github-google-cel-go-0.12.5+ds/checker/cost.go --- golang-github-google-cel-go-0.11.4+ds/checker/cost.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/checker/cost.go 2022-12-20 15:30:36.000000000 +0000 @@ -88,9 +88,9 @@ return e.derivedSize } var v uint64 - switch ek := e.expr.ExprKind.(type) { + switch ek := e.expr.GetExprKind().(type) { case *exprpb.Expr_ConstExpr: - switch ck := ek.ConstExpr.ConstantKind.(type) { + switch ck := ek.ConstExpr.GetConstantKind().(type) { case *exprpb.Constant_StringValue: v = uint64(len(ck.StringValue)) case *exprpb.Constant_BytesValue: @@ -103,10 +103,10 @@ return nil } case *exprpb.Expr_ListExpr: - v = uint64(len(ek.ListExpr.Elements)) + v = uint64(len(ek.ListExpr.GetElements())) case *exprpb.Expr_StructExpr: - if ek.StructExpr.MessageName == "" { - v = uint64(len(ek.StructExpr.Entries)) + if ek.StructExpr.GetMessageName() == "" { + v = uint64(len(ek.StructExpr.GetEntries())) } default: return nil @@ -297,7 +297,7 @@ return CostEstimate{} } var cost CostEstimate - switch e.ExprKind.(type) { + switch e.GetExprKind().(type) { case *exprpb.Expr_ConstExpr: cost = constCost case *exprpb.Expr_IdentExpr: @@ -323,7 +323,7 @@ // build and track the field path if iterRange, ok := c.iterRanges.peek(identExpr.GetName()); ok { - switch c.checkedExpr.TypeMap[iterRange].TypeKind.(type) { + switch c.checkedExpr.TypeMap[iterRange].GetTypeKind().(type) { case *exprpb.Type_ListType_: c.addPath(e, append(c.exprPath[iterRange], "@items")) case *exprpb.Type_MapType_: @@ -350,7 +350,7 @@ } // build and track the field path - c.addPath(e, append(c.getPath(sel.GetOperand()), sel.Field)) + c.addPath(e, append(c.getPath(sel.GetOperand()), sel.GetField())) return sum } @@ -476,6 +476,15 @@ if l := c.estimator.EstimateSize(t); l != nil { return *l } + // return an estimate of 1 for return types of set + // lengths, since strings/bytes/more complex objects could be of + // variable length + if isScalar(t.Type()) { + // TODO: since the logic for size estimation is split between + // ComputedSize and isScalar, changing one will likely require changing + // the other, so they should be merged in the future if possible + return SizeEstimate{Min: 1, Max: 1} + } return SizeEstimate{Min: 0, Max: math.MaxUint64} } @@ -599,3 +608,20 @@ } return &astNode{path: path, t: c.getType(e), expr: e, derivedSize: derivedSize} } + +// isScalar returns true if the given type is known to be of a constant size at +// compile time. isScalar will return false for strings (they are variable-width) +// in addition to protobuf.Any and protobuf.Value (their size is not knowable at compile time). +func isScalar(t *exprpb.Type) bool { + switch kindOf(t) { + case kindPrimitive: + if t.GetPrimitive() != exprpb.Type_STRING && t.GetPrimitive() != exprpb.Type_BYTES { + return true + } + case kindWellKnown: + if t.GetWellKnown() == exprpb.Type_DURATION || t.GetWellKnown() == exprpb.Type_TIMESTAMP { + return true + } + } + return false +} diff -Nru golang-github-google-cel-go-0.11.4+ds/checker/cost_test.go golang-github-google-cel-go-0.12.5+ds/checker/cost_test.go --- golang-github-google-cel-go-0.11.4+ds/checker/cost_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/checker/cost_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -354,6 +354,67 @@ hints: map[string]int64{"str1": 10, "str2": 10}, wanted: CostEstimate{Min: 2, Max: 6}, }, + { + name: "list size comparison", + expr: `list1.size() == list2.size()`, + decls: []*exprpb.Decl{ + decls.NewVar("list1", decls.NewListType(decls.Int)), + decls.NewVar("list2", decls.NewListType(decls.Int)), + }, + wanted: CostEstimate{Min: 5, Max: 5}, + }, + { + name: "list size from ternary", + expr: `x > y ? list1.size() : list2.size()`, + decls: []*exprpb.Decl{ + decls.NewVar("x", decls.Int), + decls.NewVar("y", decls.Int), + decls.NewVar("list1", decls.NewListType(decls.Int)), + decls.NewVar("list2", decls.NewListType(decls.Int)), + }, + wanted: CostEstimate{Min: 5, Max: 5}, + }, + { + name: "str endsWith equality", + expr: `str1.endsWith("abcdefghijklmnopqrstuvwxyz") == str2.endsWith("abcdefghijklmnopqrstuvwxyz")`, + decls: []*exprpb.Decl{ + decls.NewVar("str1", decls.String), + decls.NewVar("str2", decls.String), + }, + wanted: CostEstimate{Min: 9, Max: 9}, + }, + { + name: "nested subexpression operators", + expr: `((5 != 6) == (1 == 2)) == ((3 <= 4) == (9 != 9))`, + wanted: CostEstimate{Min: 7, Max: 7}, + }, + { + name: "str size estimate", + expr: `string(timestamp1) == string(timestamp2)`, + decls: []*exprpb.Decl{ + decls.NewVar("timestamp1", decls.Timestamp), + decls.NewVar("timestamp2", decls.Timestamp), + }, + wanted: CostEstimate{Min: 5, Max: 1844674407370955268}, + }, + { + name: "timestamp equality check", + expr: `timestamp1 == timestamp2`, + decls: []*exprpb.Decl{ + decls.NewVar("timestamp1", decls.Timestamp), + decls.NewVar("timestamp2", decls.Timestamp), + }, + wanted: CostEstimate{Min: 3, Max: 3}, + }, + { + name: "duration inequality check", + expr: `duration1 != duration2`, + decls: []*exprpb.Decl{ + decls.NewVar("duration1", decls.Duration), + decls.NewVar("duration2", decls.Duration), + }, + wanted: CostEstimate{Min: 3, Max: 3}, + }, } for _, tc := range cases { diff -Nru golang-github-google-cel-go-0.11.4+ds/checker/env.go golang-github-google-cel-go-0.12.5+ds/checker/env.go --- golang-github-google-cel-go-0.11.4+ds/checker/env.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/checker/env.go 2022-12-20 15:30:36.000000000 +0000 @@ -181,8 +181,7 @@ overload.GetParams()...) overloadErased := substitute(emptyMappings, overloadFunction, true) for _, existing := range function.GetOverloads() { - existingFunction := decls.NewFunctionType(existing.GetResultType(), - existing.GetParams()...) + existingFunction := decls.NewFunctionType(existing.GetResultType(), existing.GetParams()...) existingErased := substitute(emptyMappings, existingFunction, true) overlap := isAssignable(emptyMappings, overloadErased, existingErased) != nil || isAssignable(emptyMappings, existingErased, overloadErased) != nil @@ -213,18 +212,33 @@ // Adds a function decl if one doesn't already exist, then adds all overloads from the Decl. // If overload overlaps with an existing overload, adds to the errors in the Env instead. func (e *Env) setFunction(decl *exprpb.Decl) []errorMsg { + errorMsgs := make([]errorMsg, 0) + overloads := decl.GetFunction().GetOverloads() current := e.declarations.FindFunction(decl.Name) if current == nil { //Add the function declaration without overloads and check the overloads below. current = decls.NewFunction(decl.Name) } else { + existingOverloads := map[string]*exprpb.Decl_FunctionDecl_Overload{} + for _, overload := range current.GetFunction().GetOverloads() { + existingOverloads[overload.GetOverloadId()] = overload + } + newOverloads := []*exprpb.Decl_FunctionDecl_Overload{} + for _, overload := range overloads { + existing, found := existingOverloads[overload.GetOverloadId()] + if !found || !proto.Equal(existing, overload) { + newOverloads = append(newOverloads, overload) + } + } + overloads = newOverloads + if len(newOverloads) == 0 { + return errorMsgs + } // Copy on write since we don't know where this original definition came from. current = proto.Clone(current).(*exprpb.Decl) } e.declarations.SetFunction(current) - - errorMsgs := make([]errorMsg, 0) - for _, overload := range decl.GetFunction().GetOverloads() { + for _, overload := range overloads { errorMsgs = append(errorMsgs, e.addOverload(current, overload)...) } return errorMsgs @@ -235,6 +249,9 @@ func (e *Env) addIdent(decl *exprpb.Decl) errorMsg { current := e.declarations.FindIdentInScope(decl.Name) if current != nil { + if proto.Equal(current, decl) { + return "" + } return overlappingIdentifierError(decl.Name) } e.declarations.AddIdent(decl) diff -Nru golang-github-google-cel-go-0.11.4+ds/checker/env_test.go golang-github-google-cel-go-0.12.5+ds/checker/env_test.go --- golang-github-google-cel-go-0.11.4+ds/checker/env_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/checker/env_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -54,12 +54,8 @@ func TestOverlappingOverload(t *testing.T) { env := newStdEnv(t) - paramA := decls.NewTypeParamType("A") - typeParamAList := []string{"A"} err := env.Add(decls.NewFunction(overloads.TypeConvertDyn, - decls.NewParameterizedOverload(overloads.ToDyn, - []*exprpb.Type{paramA}, decls.Dyn, - typeParamAList))) + decls.NewOverload(overloads.ToDyn, []*exprpb.Type{decls.String}, decls.Dyn))) if err == nil { t.Error("Got nil, wanted error") } else if !strings.Contains(err.Error(), "overlapping overload") { diff -Nru golang-github-google-cel-go-0.11.4+ds/checker/printer.go golang-github-google-cel-go-0.12.5+ds/checker/printer.go --- golang-github-google-cel-go-0.11.4+ds/checker/printer.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/checker/printer.go 2022-12-20 15:30:36.000000000 +0000 @@ -32,22 +32,22 @@ if !isExpr { return result } - t := a.checks.TypeMap[e.Id] + t := a.checks.TypeMap[e.GetId()] if t != nil { result += "~" result += FormatCheckedType(t) } - switch e.ExprKind.(type) { + switch e.GetExprKind().(type) { case *exprpb.Expr_IdentExpr, *exprpb.Expr_CallExpr, *exprpb.Expr_StructExpr, *exprpb.Expr_SelectExpr: - if ref, found := a.checks.ReferenceMap[e.Id]; found { + if ref, found := a.checks.ReferenceMap[e.GetId()]; found { if len(ref.GetOverloadId()) == 0 { result += "^" + ref.Name } else { - for i, overload := range ref.OverloadId { + for i, overload := range ref.GetOverloadId() { if i == 0 { result += "^" } else { diff -Nru golang-github-google-cel-go-0.11.4+ds/checker/types.go golang-github-google-cel-go-0.12.5+ds/checker/types.go --- golang-github-google-cel-go-0.11.4+ds/checker/types.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/checker/types.go 2022-12-20 15:30:36.000000000 +0000 @@ -52,13 +52,13 @@ t.GetFunction().GetArgTypes(), false) case kindList: - return fmt.Sprintf("list(%s)", FormatCheckedType(t.GetListType().ElemType)) + return fmt.Sprintf("list(%s)", FormatCheckedType(t.GetListType().GetElemType())) case kindObject: return t.GetMessageType() case kindMap: return fmt.Sprintf("map(%s, %s)", - FormatCheckedType(t.GetMapType().KeyType), - FormatCheckedType(t.GetMapType().ValueType)) + FormatCheckedType(t.GetMapType().GetKeyType()), + FormatCheckedType(t.GetMapType().GetValueType())) case kindNull: return "null" case kindPrimitive: @@ -88,6 +88,8 @@ FormatCheckedType(decls.NewPrimitiveType(t.GetWrapper()))) case kindError: return "!error!" + case kindTypeParam: + return t.GetTypeParam() } return t.String() } @@ -150,12 +152,12 @@ } return true case kindList: - return isEqualOrLessSpecific(t1.GetListType().ElemType, t2.GetListType().ElemType) + return isEqualOrLessSpecific(t1.GetListType().GetElemType(), t2.GetListType().GetElemType()) case kindMap: m1 := t1.GetMapType() m2 := t2.GetMapType() - return isEqualOrLessSpecific(m1.KeyType, m2.KeyType) && - isEqualOrLessSpecific(m1.ValueType, m2.ValueType) + return isEqualOrLessSpecific(m1.GetKeyType(), m2.GetKeyType()) && + isEqualOrLessSpecific(m1.GetValueType(), m2.GetValueType()) case kindType: return true default: @@ -163,7 +165,7 @@ } } -/// internalIsAssignable returns true if t1 is assignable to t2. +// / internalIsAssignable returns true if t1 is assignable to t2. func internalIsAssignable(m *mapping, t1 *exprpb.Type, t2 *exprpb.Type) bool { // Process type parameters. kind1, kind2 := kindOf(t1), kindOf(t2) @@ -251,7 +253,12 @@ } // If the types are compatible, pick the more general type and return true if internalIsAssignable(m, t1, t2Sub) { - m.add(t2, mostGeneral(t1, t2Sub)) + t2New := mostGeneral(t1, t2Sub) + // only update the type reference map if the target type does not occur within it. + if notReferencedIn(m, t2, t2New) { + m.add(t2, t2New) + } + // acknowledge the type agreement, and that the substitution is already tracked. return true, true } return false, true @@ -265,18 +272,14 @@ // 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 { +func internalIsAssignableAbstractType(m *mapping, a1 *exprpb.Type_AbstractType, a2 *exprpb.Type_AbstractType) bool { return a1.GetName() == a2.GetName() && internalIsAssignableList(m, a1.GetParameterTypes(), a2.GetParameterTypes()) } // internalIsAssignableFunction returns true if the function return type and arg types are // assignable. -func internalIsAssignableFunction(m *mapping, - f1 *exprpb.Type_FunctionType, - f2 *exprpb.Type_FunctionType) bool { +func internalIsAssignableFunction(m *mapping, f1 *exprpb.Type_FunctionType, f2 *exprpb.Type_FunctionType) bool { f1ArgTypes := flattenFunctionTypes(f1) f2ArgTypes := flattenFunctionTypes(f2) if internalIsAssignableList(m, f1ArgTypes, f2ArgTypes) { @@ -356,7 +359,7 @@ if t == nil || t.TypeKind == nil { return kindUnknown } - switch t.TypeKind.(type) { + switch t.GetTypeKind().(type) { case *exprpb.Type_Error: return kindError case *exprpb.Type_Function: @@ -418,10 +421,10 @@ } return true case kindList: - return notReferencedIn(m, t, withinType.GetListType().ElemType) + return notReferencedIn(m, t, withinType.GetListType().GetElemType()) case kindMap: mt := withinType.GetMapType() - return notReferencedIn(m, t, mt.KeyType) && notReferencedIn(m, t, mt.ValueType) + return notReferencedIn(m, t, mt.GetKeyType()) && notReferencedIn(m, t, mt.GetValueType()) case kindWrapper: return notReferencedIn(m, t, decls.NewPrimitiveType(withinType.GetWrapper())) default: @@ -450,17 +453,17 @@ case kindFunction: fn := t.GetFunction() rt := substitute(m, fn.ResultType, typeParamToDyn) - args := make([]*exprpb.Type, len(fn.ArgTypes)) + args := make([]*exprpb.Type, len(fn.GetArgTypes())) for i, a := range fn.ArgTypes { args[i] = substitute(m, a, typeParamToDyn) } return decls.NewFunctionType(rt, args...) case kindList: - return decls.NewListType(substitute(m, t.GetListType().ElemType, typeParamToDyn)) + return decls.NewListType(substitute(m, t.GetListType().GetElemType(), typeParamToDyn)) case kindMap: mt := t.GetMapType() - return decls.NewMapType(substitute(m, mt.KeyType, typeParamToDyn), - substitute(m, mt.ValueType, typeParamToDyn)) + return decls.NewMapType(substitute(m, mt.GetKeyType(), typeParamToDyn), + substitute(m, mt.GetValueType(), typeParamToDyn)) case kindType: if t.GetType() != nil { return decls.NewTypeType(substitute(m, t.GetType(), typeParamToDyn)) diff -Nru golang-github-google-cel-go-0.11.4+ds/codelab/codelab.go golang-github-google-cel-go-0.12.5+ds/codelab/codelab.go --- golang-github-google-cel-go-0.11.4+ds/codelab/codelab.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/codelab/codelab.go 2022-12-20 15:30:36.000000000 +0000 @@ -25,18 +25,15 @@ "time" "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/common/types/traits" - _ "github.com/google/cel-go/interpreter/functions" "github.com/golang/glog" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/encoding/prototext" "google.golang.org/protobuf/proto" - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" rpcpb "google.golang.org/genproto/googleapis/rpc/context/attribute_context" structpb "google.golang.org/protobuf/types/known/structpb" tpb "google.golang.org/protobuf/types/known/timestamppb" @@ -147,14 +144,14 @@ // compile will parse and check an expression `expr` against a given // environment `env` and determine whether the resulting type of the expression // matches the `exprType` provided as input. -func compile(env *cel.Env, expr string, exprType *exprpb.Type) *cel.Ast { +func compile(env *cel.Env, expr string, celType *cel.Type) *cel.Ast { ast, iss := env.Compile(expr) if iss.Err() != nil { glog.Exit(iss.Err()) } - if !proto.Equal(ast.ResultType(), exprType) { + if !reflect.DeepEqual(ast.OutputType(), celType) { glog.Exitf( - "Got %v, wanted %v result type", ast.ResultType(), exprType) + "Got %v, wanted %v result type", ast.OutputType(), celType) } fmt.Printf("%s\n\n", strings.ReplaceAll(expr, "\t", " ")) return ast @@ -223,30 +220,19 @@ } // mapContainsKeyValue implements the custom function: -// `map.contains(key, value) bool`. +// +// `map.contains(key, value) bool`. func mapContainsKeyValue(args ...ref.Val) ref.Val { - // Check the argument input count. - if len(args) != 3 { - return types.NewErr("no such overload") - } - obj := args[0] - m, isMap := obj.(traits.Mapper) - // Ensure the argument is a CEL map type, otherwise error. - // The type-checking is a best effort check to ensure that the types provided - // to functions match the ones specified; however, it is always possible that - // the implementation does not match the declaration. Always check arguments - // types whenever there is a possibility that your function will deal with - // dynamic content. - if !isMap { - // The helper ValOrErr ensures that errors on input are propagated. - return types.ValOrErr(obj, "no such overload") - } + // The declaration of the function ensures that only arguments which match + // the mapContainsKey signature will be provided to the function. + m := args[0].(traits.Mapper) // CEL has many interfaces for dealing with different type abstractions. // The traits.Mapper interface unifies field presence testing on proto // messages and maps. key := args[1] v, found := m.Find(key) + // If not found and the value was non-nil, the value is an error per the // `Find` contract. Propagate it accordingly. if !found { diff -Nru golang-github-google-cel-go-0.11.4+ds/codelab/go.mod golang-github-google-cel-go-0.12.5+ds/codelab/go.mod --- golang-github-google-cel-go-0.11.4+ds/codelab/go.mod 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/codelab/go.mod 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,18 @@ +module github.com/google/cel-go/codelab + +go 1.17 + +require ( + github.com/golang/glog v1.0.0 + github.com/google/cel-go v0.12.4 + google.golang.org/genproto v0.0.0-20220714152414-ccd2914cffd4 + google.golang.org/protobuf v1.28.0 +) + +require ( + github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220626175859-9abda183db8e // indirect + github.com/stoewer/go-strcase v1.2.0 // indirect + golang.org/x/text v0.3.7 // indirect +) + +replace github.com/google/cel-go => ../. diff -Nru golang-github-google-cel-go-0.11.4+ds/codelab/go.sum golang-github-google-cel-go-0.12.5+ds/codelab/go.sum --- golang-github-google-cel-go-0.11.4+ds/codelab/go.sum 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/codelab/go.sum 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,147 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed h1:ue9pVfIcP+QMEjfgo/Ez4ZjNZfonGgR6NgjMaJMu1Cg= +github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= +github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220626175859-9abda183db8e h1:bt6SW1eSSvdmmsG0KqyxYXorcTnFBTX7hfVR1+68+jg= +github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220626175859-9abda183db8e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 h1:hrbNEivu7Zn1pxvHk6MBrq9iE22woVILTHqexqBxe6I= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220714152414-ccd2914cffd4 h1:y2IEhgO0Rmt0axD3Se6N7D5e8yhTG9dUiFCyMbaaN7U= +google.golang.org/genproto v0.0.0-20220714152414-ccd2914cffd4/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff -Nru golang-github-google-cel-go-0.11.4+ds/codelab/solution/codelab.go golang-github-google-cel-go-0.12.5+ds/codelab/solution/codelab.go --- golang-github-google-cel-go-0.11.4+ds/codelab/solution/codelab.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/codelab/solution/codelab.go 2022-12-20 15:30:36.000000000 +0000 @@ -24,19 +24,16 @@ "strings" "time" - "github.com/golang/glog" - "google.golang.org/protobuf/encoding/protojson" - "google.golang.org/protobuf/encoding/prototext" - "google.golang.org/protobuf/proto" - "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/common/types/traits" - "github.com/google/cel-go/interpreter/functions" - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + "github.com/golang/glog" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/encoding/prototext" + "google.golang.org/protobuf/proto" + rpcpb "google.golang.org/genproto/googleapis/rpc/context/attribute_context" structpb "google.golang.org/protobuf/types/known/structpb" tpb "google.golang.org/protobuf/types/known/timestamppb" @@ -75,11 +72,11 @@ if iss.Err() != nil { glog.Exit(iss.Err()) } - // Check the result type is a string. - if !proto.Equal(checked.ResultType(), decls.String) { + // Check the output type is a string. + if checked.OutputType() != cel.StringType { glog.Exitf( "Got %v, wanted %v result type", - checked.ResultType(), decls.String) + checked.OutputType(), cel.StringType) } // Plan the program. program, err := env.Program(checked) @@ -101,15 +98,14 @@ // the google.rpc.context.AttributeContext.Request type. env, err := cel.NewEnv( cel.Types(&rpcpb.AttributeContext_Request{}), - cel.Declarations( - decls.NewVar("request", - decls.NewObjectType("google.rpc.context.AttributeContext.Request")), + cel.Variable("request", + cel.ObjectType("google.rpc.context.AttributeContext.Request"), ), ) if err != nil { glog.Exit(err) } - ast := compile(env, `request.auth.claims.group == 'admin'`, decls.Bool) + ast := compile(env, `request.auth.claims.group == 'admin'`, cel.BoolType) program, _ := env.Program(ast) // Evaluate a request object that sets the proper group claim. @@ -132,16 +128,14 @@ fmt.Println("=== Exercise 3: Logical AND/OR ===\n") env, _ := cel.NewEnv( cel.Types(&rpcpb.AttributeContext_Request{}), - cel.Declarations( - decls.NewVar("request", - decls.NewObjectType("google.rpc.context.AttributeContext.Request"), - ), + cel.Variable("request", + cel.ObjectType("google.rpc.context.AttributeContext.Request"), ), ) ast := compile(env, `request.auth.claims.group == 'admin' || request.auth.principal == 'user:me@acme.co'`, - decls.Bool) + cel.BoolType) program, _ := env.Program(ast) // Evaluate once with no claims and the proper user. @@ -166,42 +160,32 @@ // key in map && map[key] == value // Useful components of the type-signature for 'contains'. - typeParamA := decls.NewTypeParamType("A") - typeParamB := decls.NewTypeParamType("B") - mapAB := decls.NewMapType(typeParamA, typeParamB) + typeParamA := cel.TypeParamType("A") + typeParamB := cel.TypeParamType("B") + mapAB := cel.MapType(typeParamA, typeParamB) // Env declaration. env, _ := cel.NewEnv( cel.Types(&rpcpb.AttributeContext_Request{}), - cel.Declarations( - // Declare the request. - decls.NewVar("request", - decls.NewObjectType("google.rpc.context.AttributeContext.Request"), - ), - // Declare the custom contains function. - decls.NewFunction("contains", - decls.NewParameterizedInstanceOverload( - "map_contains_key_value", - []*exprpb.Type{mapAB, typeParamA, typeParamB}, - decls.Bool, - []string{"A", "B"}, - ), - ), + // Declare the request. + cel.Variable("request", + cel.ObjectType("google.rpc.context.AttributeContext.Request"), + ), + // Declare the custom contains function and its implementation. + cel.Function("contains", + cel.MemberOverload("map_contains_key_value", + []*cel.Type{mapAB, typeParamA, typeParamB}, + cel.BoolType, + cel.FunctionBinding(mapContainsKeyValue)), ), ) ast := compile(env, `request.auth.claims.contains('group', 'admin')`, - decls.Bool) + cel.BoolType) - // Construct the program plan and provide the 'contains' function impl. + // Construct the program plan. // Output: false - program, err := env.Program(ast, - cel.Functions( - &functions.Overload{ - Operator: "map_contains_key_value", - Function: mapContainsKeyValue, - }), - ) + program, err := env.Program(ast) if err != nil { glog.Exit(err) } @@ -220,9 +204,7 @@ // Note the quoted keys in the CEL map literal. For proto messages the // field names are unquoted as they represent well-defined identifiers. env, _ := cel.NewEnv( - cel.Declarations( - decls.NewVar("now", decls.Timestamp), - ), + cel.Variable("now", cel.TimestampType), ) ast := compile(env, ` {'aud': 'my-project', @@ -235,13 +217,13 @@ 'nbf': now, 'sub': 'serviceAccount:delegate@acme.co' }`, - decls.NewMapType(decls.String, decls.Dyn)) + cel.MapType(cel.StringType, cel.DynType)) program, _ := env.Program(ast) out, _, _ := eval( program, map[string]interface{}{ - "now": &tpb.Timestamp{Seconds: time.Now().Unix()}, + "now": time.Now(), }, ) // The output of the program is a CEL map type, but it can be converted @@ -264,10 +246,8 @@ env, _ := cel.NewEnv( cel.Container("google.rpc.context.AttributeContext"), cel.Types(requestType), - cel.Declarations( - decls.NewVar("jwt", decls.NewMapType(decls.String, decls.Dyn)), - decls.NewVar("now", decls.Timestamp), - ), + cel.Variable("jwt", cel.MapType(cel.StringType, cel.DynType)), + cel.Variable("now", cel.TimestampType), ) // Compile the `Request` message construction expression and validate that the @@ -287,7 +267,7 @@ }, time: now }`, - decls.NewObjectType("google.rpc.context.AttributeContext.Request")) + cel.ObjectType("google.rpc.context.AttributeContext.Request")) program, _ := env.Program(ast) // Construct the message. The result is a ref.Val that returns a dynamic proto message. @@ -302,7 +282,7 @@ "group": "admin", }, }, - "now": &tpb.Timestamp{Seconds: time.Now().Unix()}, + "now": time.Now(), }, ) // Unwrap the CEL value to a proto. Make sure to use the `ConvertToNative` to convert @@ -326,16 +306,14 @@ // values containing only strings that end with '@acme.co`. func exercise7() { fmt.Println("=== Exercise 7: Macros ===\n") - env, _ := cel.NewEnv( - cel.Declarations(decls.NewVar("jwt", decls.Dyn)), - ) + env, _ := cel.NewEnv(cel.Variable("jwt", cel.DynType)) ast := compile(env, `jwt.extra_claims.exists(c, c.startsWith('group')) && jwt.extra_claims .filter(c, c.startsWith('group')) .all(c, jwt.extra_claims[c] .all(g, g.endsWith('@acme.co')))`, - decls.Bool) + cel.BoolType) program, _ := env.Program(ast) // Evaluate a complex-ish JWT with two groups that satisfy the criteria. @@ -366,14 +344,12 @@ fmt.Println("=== Exercise 8: Tuning ===\n") // Declare the `x` and 'y' variables as input into the expression. env, _ := cel.NewEnv( - cel.Declarations( - decls.NewVar("x", decls.Int), - decls.NewVar("y", decls.Uint), - ), + cel.Variable("x", cel.IntType), + cel.Variable("y", cel.UintType), ) ast := compile(env, `x in [1, 2, 3, 4, 5] && type(y) == uint`, - decls.Bool) + cel.BoolType) // Turn on optimization. trueVars := map[string]interface{}{"x": int64(4), "y": uint64(2)} program, _ := env.Program(ast, cel.EvalOptions(cel.OptOptimize)) @@ -409,16 +385,14 @@ // compile will parse and check an expression `expr` against a given // environment `env` and determine whether the resulting type of the expression // matches the `exprType` provided as input. -func compile(env *cel.Env, expr string, exprType *exprpb.Type) *cel.Ast { +func compile(env *cel.Env, expr string, celType *cel.Type) *cel.Ast { ast, iss := env.Compile(expr) if iss.Err() != nil { glog.Exit(iss.Err()) } - if !proto.Equal(ast.ResultType(), exprType) { + if !reflect.DeepEqual(ast.OutputType(), celType) { glog.Exitf( - "Got %v, wanted %v result type", - ast.ResultType(), - exprType) + "Got %v, wanted %v result type", ast.OutputType(), celType) } fmt.Printf("%s\n\n", strings.ReplaceAll(expr, "\t", " ")) return ast @@ -487,30 +461,19 @@ } // mapContainsKeyValue implements the custom function: -// `map.contains(key, value) bool`. +// +// `map.contains(key, value) bool`. func mapContainsKeyValue(args ...ref.Val) ref.Val { - // Check the argument input count. - if len(args) != 3 { - return types.NewErr("no such overload") - } - obj := args[0] - m, isMap := obj.(traits.Mapper) - // Ensure the argument is a CEL map type, otherwise error. - // The type-checking is a best effort check to ensure that the types provided - // to functions match the ones specified; however, it is always possible that - // the implementation does not match the declaration. Always check arguments - // types whenever there is a possibility that your function will deal with - // dynamic content. - if !isMap { - // The helper ValOrErr ensures that errors on input are propagated. - return types.ValOrErr(obj, "no such overload") - } + // The declaration of the function ensures that only arguments which match + // the mapContainsKey signature will be provided to the function. + m := args[0].(traits.Mapper) // CEL has many interfaces for dealing with different type abstractions. // The traits.Mapper interface unifies field presence testing on proto // messages and maps. key := args[1] v, found := m.Find(key) + // If not found and the value was non-nil, the value is an error per the // `Find` contract. Propagate it accordingly. if !found { diff -Nru golang-github-google-cel-go-0.11.4+ds/common/containers/container.go golang-github-google-cel-go-0.12.5+ds/common/containers/container.go --- golang-github-google-cel-go-0.11.4+ds/common/containers/container.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/common/containers/container.go 2022-12-20 15:30:36.000000000 +0000 @@ -98,12 +98,12 @@ // // Given a container 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 +// 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 // // If aliases or abbreviations are configured for the container, then alias names will take // precedence over containerized names. @@ -145,9 +145,9 @@ // If the name is qualified, the first component of the qualified name is checked against known // aliases. Any alias that is found in a qualified name is expanded in the result: // -// alias: R -> my.alias.R -// name: R.S.T -// output: my.alias.R.S.T +// alias: R -> my.alias.R +// name: R.S.T +// output: my.alias.R.S.T // // Note, the name must not have a leading dot. func (c *Container) findAlias(name string) (string, bool) { @@ -177,19 +177,19 @@ // Abbreviations can be useful when working with variables, functions, and especially types from // multiple namespaces: // -// // CEL object construction -// qual.pkg.version.ObjTypeName{ -// field: alt.container.ver.FieldTypeName{value: ...} -// } +// // CEL object construction +// qual.pkg.version.ObjTypeName{ +// field: alt.container.ver.FieldTypeName{value: ...} +// } // // Only one the qualified names above may be used as the CEL container, so at least one of these // references must be a long qualified name within an otherwise short CEL program. Using the // following abbreviations, the program becomes much simpler: // -// // CEL Go option -// Abbrevs("qual.pkg.version.ObjTypeName", "alt.container.ver.FieldTypeName") -// // Simplified Object construction -// ObjTypeName{field: FieldTypeName{value: ...}} +// // CEL Go option +// Abbrevs("qual.pkg.version.ObjTypeName", "alt.container.ver.FieldTypeName") +// // Simplified Object construction +// ObjTypeName{field: FieldTypeName{value: ...}} // // There are a few rules for the qualified names and the simple abbreviations generated from them: // - Qualified names must be dot-delimited, e.g. `package.subpkg.name`. @@ -198,13 +198,13 @@ // - The abbreviation must not collide with unqualified names in use. // // Abbreviations are distinct from container-based references in the following important ways: -// - Abbreviations must expand to a fully-qualified name. -// - Expanded abbreviations do not participate in namespace resolution. -// - Abbreviation expansion is done instead of the container search for a matching identifier. -// - Containers follow C++ namespace resolution rules with searches from the most qualified name -// to the least qualified name. -// - Container references within the CEL program may be relative, and are resolved to fully -// qualified names at either type-check time or program plan time, whichever comes first. +// - Abbreviations must expand to a fully-qualified name. +// - Expanded abbreviations do not participate in namespace resolution. +// - Abbreviation expansion is done instead of the container search for a matching identifier. +// - Containers follow C++ namespace resolution rules with searches from the most qualified name +// to the least qualified name. +// - Container references within the CEL program may be relative, and are resolved to fully +// qualified names at either type-check time or program plan time, whichever comes first. // // If there is ever a case where an identifier could be in both the container and as an // abbreviation, the abbreviation wins as this will ensure that the meaning of a program is @@ -298,18 +298,18 @@ // ToQualifiedName converts an expression AST into a qualified name if possible, with a boolean // 'found' value that indicates if the conversion is successful. func ToQualifiedName(e *exprpb.Expr) (string, bool) { - switch e.ExprKind.(type) { + switch e.GetExprKind().(type) { case *exprpb.Expr_IdentExpr: id := e.GetIdentExpr() - return id.Name, true + return id.GetName(), true case *exprpb.Expr_SelectExpr: sel := e.GetSelectExpr() // Test only expressions are not valid as qualified names. if sel.GetTestOnly() { return "", false } - if qual, found := ToQualifiedName(sel.Operand); found { - return qual + "." + sel.Field, true + if qual, found := ToQualifiedName(sel.GetOperand()); found { + return qual + "." + sel.GetField(), true } } return "", false diff -Nru golang-github-google-cel-go-0.11.4+ds/common/debug/debug.go golang-github-google-cel-go-0.12.5+ds/common/debug/debug.go --- golang-github-google-cel-go-0.11.4+ds/common/debug/debug.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/common/debug/debug.go 2022-12-20 15:30:36.000000000 +0000 @@ -102,9 +102,9 @@ } func (w *debugWriter) appendSelect(sel *exprpb.Expr_Select) { - w.Buffer(sel.Operand) + w.Buffer(sel.GetOperand()) w.append(".") - w.append(sel.Field) + w.append(sel.GetField()) if sel.TestOnly { w.append("~test-only~") } @@ -112,15 +112,15 @@ func (w *debugWriter) appendCall(call *exprpb.Expr_Call) { if call.Target != nil { - w.Buffer(call.Target) + w.Buffer(call.GetTarget()) w.append(".") } - w.append(call.Function) + w.append(call.GetFunction()) w.append("(") if len(call.GetArgs()) > 0 { w.addIndent() w.appendLine() - for i, arg := range call.Args { + for i, arg := range call.GetArgs() { if i > 0 { w.append(",") w.appendLine() @@ -138,7 +138,7 @@ if len(list.GetElements()) > 0 { w.appendLine() w.addIndent() - for i, elem := range list.Elements { + for i, elem := range list.GetElements() { if i > 0 { w.append(",") w.appendLine() @@ -160,19 +160,19 @@ } func (w *debugWriter) appendObject(obj *exprpb.Expr_CreateStruct) { - w.append(obj.MessageName) + w.append(obj.GetMessageName()) w.append("{") - if len(obj.Entries) > 0 { + if len(obj.GetEntries()) > 0 { w.appendLine() w.addIndent() - for i, entry := range obj.Entries { + for i, entry := range obj.GetEntries() { if i > 0 { w.append(",") w.appendLine() } w.append(entry.GetFieldKey()) w.append(":") - w.Buffer(entry.Value) + w.Buffer(entry.GetValue()) w.adorn(entry) } w.removeIndent() @@ -183,17 +183,17 @@ func (w *debugWriter) appendMap(obj *exprpb.Expr_CreateStruct) { w.append("{") - if len(obj.Entries) > 0 { + if len(obj.GetEntries()) > 0 { w.appendLine() w.addIndent() - for i, entry := range obj.Entries { + for i, entry := range obj.GetEntries() { if i > 0 { w.append(",") w.appendLine() } w.Buffer(entry.GetMapKey()) w.append(":") - w.Buffer(entry.Value) + w.Buffer(entry.GetValue()) w.adorn(entry) } w.removeIndent() @@ -208,43 +208,43 @@ w.appendLine() w.append("// Variable") w.appendLine() - w.append(comprehension.IterVar) + w.append(comprehension.GetIterVar()) w.append(",") w.appendLine() w.append("// Target") w.appendLine() - w.Buffer(comprehension.IterRange) + w.Buffer(comprehension.GetIterRange()) w.append(",") w.appendLine() w.append("// Accumulator") w.appendLine() - w.append(comprehension.AccuVar) + w.append(comprehension.GetAccuVar()) w.append(",") w.appendLine() w.append("// Init") w.appendLine() - w.Buffer(comprehension.AccuInit) + w.Buffer(comprehension.GetAccuInit()) w.append(",") w.appendLine() w.append("// LoopCondition") w.appendLine() - w.Buffer(comprehension.LoopCondition) + w.Buffer(comprehension.GetLoopCondition()) w.append(",") w.appendLine() w.append("// LoopStep") w.appendLine() - w.Buffer(comprehension.LoopStep) + w.Buffer(comprehension.GetLoopStep()) w.append(",") w.appendLine() w.append("// Result") w.appendLine() - w.Buffer(comprehension.Result) + w.Buffer(comprehension.GetResult()) w.append(")") w.removeIndent() } func formatLiteral(c *exprpb.Constant) string { - switch c.ConstantKind.(type) { + switch c.GetConstantKind().(type) { case *exprpb.Constant_BoolValue: return fmt.Sprintf("%t", c.GetBoolValue()) case *exprpb.Constant_BytesValue: diff -Nru golang-github-google-cel-go-0.11.4+ds/common/operators/operators.go golang-github-google-cel-go-0.12.5+ds/common/operators/operators.go --- golang-github-google-cel-go-0.11.4+ds/common/operators/operators.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/common/operators/operators.go 2022-12-20 15:30:36.000000000 +0000 @@ -141,3 +141,13 @@ } return op.precedence } + +// Arity returns the number of argument the operator takes +// -1 is returned if an undefined symbol is provided +func Arity(symbol string) int { + op, found := operatorMap[symbol] + if !found { + return -1 + } + return op.arity +} diff -Nru golang-github-google-cel-go-0.11.4+ds/common/types/pb/equal.go golang-github-google-cel-go-0.12.5+ds/common/types/pb/equal.go --- golang-github-google-cel-go-0.11.4+ds/common/types/pb/equal.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/common/types/pb/equal.go 2022-12-20 15:30:36.000000000 +0000 @@ -21,7 +21,8 @@ "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/types/known/anypb" + + anypb "google.golang.org/protobuf/types/known/anypb" ) // Equal returns whether two proto.Message instances are equal using the following criteria: diff -Nru golang-github-google-cel-go-0.11.4+ds/common/types/pb/equal_test.go golang-github-google-cel-go-0.12.5+ds/common/types/pb/equal_test.go --- golang-github-google-cel-go-0.11.4+ds/common/types/pb/equal_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/common/types/pb/equal_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -20,9 +20,8 @@ "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/anypb" - proto3pb "github.com/google/cel-go/test/proto3pb" + anypb "google.golang.org/protobuf/types/known/anypb" ) func TestEqual(t *testing.T) { diff -Nru golang-github-google-cel-go-0.11.4+ds/common/types/pb/pb_test.go golang-github-google-cel-go-0.12.5+ds/common/types/pb/pb_test.go --- golang-github-google-cel-go-0.11.4+ds/common/types/pb/pb_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/common/types/pb/pb_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -24,7 +24,7 @@ proto3pb "github.com/google/cel-go/test/proto3pb" descpb "google.golang.org/protobuf/types/descriptorpb" dynamicpb "google.golang.org/protobuf/types/dynamicpb" - "google.golang.org/protobuf/types/known/durationpb" + durationpb "google.golang.org/protobuf/types/known/durationpb" tpb "google.golang.org/protobuf/types/known/timestamppb" ) diff -Nru golang-github-google-cel-go-0.11.4+ds/common/types/pb/type.go golang-github-google-cel-go-0.12.5+ds/common/types/pb/type.go --- golang-github-google-cel-go-0.11.4+ds/common/types/pb/type.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/common/types/pb/type.go 2022-12-20 15:30:36.000000000 +0000 @@ -118,7 +118,7 @@ switch fieldDesc.Kind() { case protoreflect.EnumKind: reflectType = reflectTypeOf(protoreflect.EnumNumber(0)) - case protoreflect.MessageKind: + case protoreflect.GroupKind, protoreflect.MessageKind: zeroMsg = dynamicpb.NewMessage(fieldDesc.Message()) reflectType = reflectTypeOf(zeroMsg) default: @@ -267,7 +267,8 @@ // IsMessage returns true if the field is of message type. func (fd *FieldDescription) IsMessage() bool { - return fd.desc.Kind() == protoreflect.MessageKind + kind := fd.desc.Kind() + return kind == protoreflect.MessageKind || kind == protoreflect.GroupKind } // IsOneof returns true if the field is declared within a oneof block. @@ -316,7 +317,7 @@ } func (fd *FieldDescription) typeDefToType() *exprpb.Type { - if fd.desc.Kind() == protoreflect.MessageKind { + if fd.desc.Kind() == protoreflect.MessageKind || fd.desc.Kind() == protoreflect.GroupKind { msgType := string(fd.desc.Message().FullName()) if wk, found := CheckedWellKnowns[msgType]; found { return wk diff -Nru golang-github-google-cel-go-0.11.4+ds/common/types/pb/type_test.go golang-github-google-cel-go-0.12.5+ds/common/types/pb/type_test.go --- golang-github-google-cel-go-0.11.4+ds/common/types/pb/type_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/common/types/pb/type_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -22,6 +22,7 @@ "github.com/google/cel-go/checker/decls" "google.golang.org/protobuf/proto" + proto2pb "github.com/google/cel-go/test/proto2pb" proto3pb "github.com/google/cel-go/test/proto3pb" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" dynamicpb "google.golang.org/protobuf/types/dynamicpb" @@ -53,6 +54,37 @@ } } +func TestTypeDescriptionGroupFields(t *testing.T) { + pbdb := NewDb() + msg := &proto2pb.TestAllTypes{} + pbdb.RegisterMessage(msg) + td, found := pbdb.DescribeType(string(msg.ProtoReflect().Descriptor().FullName())) + if !found { + t.Fatalf("pbdb.DescribeType(%v) not found", msg) + } + field, found := td.FieldByName("nestedgroup") + if !found { + t.Fatal("TypeDescription.FieldByName('nestedgroup') could not be found") + } + if !field.IsMessage() { + t.Errorf("Group field 'nestedgroup' is type %v, wanted message type", field.Descriptor()) + } + if !proto.Equal(field.CheckedType(), decls.NewObjectType("google.expr.proto2.test.TestAllTypes.NestedGroup")) { + t.Errorf("field.CheckedType() got %v, wanted 'google.expr.proto2.test.TestAllTypes.NestedGroup'", field.CheckedType()) + } + ng, found := pbdb.DescribeType(string(field.Descriptor().Message().FullName())) + if !found { + t.Fatalf("pbdb.DescribeType(%v) not found", field.Descriptor().Message().FullName()) + } + groupFields := ng.FieldMap() + if groupFields["nested_name"].ReflectType() != reflect.TypeOf("") { + t.Errorf("groupFields['nested_name'] is type %v, not string", groupFields["nested_name"].ReflectType()) + } + if groupFields["nested_id"].ReflectType() != reflect.TypeOf(int32(1)) { + t.Errorf("groupFields['nested_id'] is type %v, not int32", groupFields["nested_id"].ReflectType()) + } +} + func TestTypeDescriptionFieldMap(t *testing.T) { pbdb := NewDb() msg := &proto3pb.NestedTestAllTypes{} diff -Nru golang-github-google-cel-go-0.11.4+ds/common/types/ref/reference.go golang-github-google-cel-go-0.12.5+ds/common/types/ref/reference.go --- golang-github-google-cel-go-0.11.4+ds/common/types/ref/reference.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/common/types/ref/reference.go 2022-12-20 15:30:36.000000000 +0000 @@ -12,8 +12,7 @@ // 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 contains the reference interfaces used throughout the types components. package ref import ( @@ -29,31 +28,27 @@ // 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. + // 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. +// 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 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 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 returns the raw value of the instance which may not be directly compatible with the expression + // language types. Value() interface{} } diff -Nru golang-github-google-cel-go-0.11.4+ds/common/types/timestamp.go golang-github-google-cel-go-0.12.5+ds/common/types/timestamp.go --- golang-github-google-cel-go-0.11.4+ds/common/types/timestamp.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/common/types/timestamp.go 2022-12-20 15:30:36.000000000 +0000 @@ -299,7 +299,7 @@ if err != nil { return wrapErr(err) } - min, err := strconv.Atoi(string(val[ind+1])) + min, err := strconv.Atoi(string(val[ind+1:])) if err != nil { return wrapErr(err) } diff -Nru golang-github-google-cel-go-0.11.4+ds/common/types/timestamp_test.go golang-github-google-cel-go-0.12.5+ds/common/types/timestamp_test.go --- golang-github-google-cel-go-0.11.4+ds/common/types/timestamp_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/common/types/timestamp_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -23,6 +23,7 @@ "github.com/google/cel-go/common/overloads" "github.com/google/cel-go/common/types/ref" + "google.golang.org/protobuf/proto" anypb "google.golang.org/protobuf/types/known/anypb" @@ -312,9 +313,48 @@ } } +func TestTimestampGetDayOfMonth(t *testing.T) { + // 1970-01-01T02:05:06Z + ts := timestampOf(time.Unix(7506, 0).UTC()) + mon := ts.Receive(overloads.TimeGetDayOfMonth, overloads.TimestampToDayOfMonthZeroBased, []ref.Val{}) + if !mon.Equal(Int(0)).(Bool) { + t.Errorf("ts.getDayOfMonth() got %v, wanted 0", mon) + } + // 1969-12-31T19:05:06Z + monTz := ts.Receive(overloads.TimeGetDayOfMonth, overloads.TimestampToDayOfMonthZeroBasedWithTz, + []ref.Val{String("America/Phoenix")}) + if !monTz.Equal(Int(30)).(Bool) { + t.Errorf("ts.getDayOfMonth() got %v, wanted 30", mon) + } + // 1969-12-31T19:05:06Z + monTz = ts.Receive(overloads.TimeGetDayOfMonth, overloads.TimestampToDayOfMonthZeroBasedWithTz, + []ref.Val{String("-07:00")}) + if !monTz.Equal(Int(30)).(Bool) { + t.Errorf("ts.getDayOfMonth() got %v, wanted 30", mon) + } + + // 1970-01-01T02:05:06Z + mon = ts.Receive(overloads.TimeGetDate, overloads.TimestampToDayOfMonthOneBased, []ref.Val{}) + if !mon.Equal(Int(1)).(Bool) { + t.Errorf("ts.getDate() got %v, wanted 1", mon) + } + // 1969-12-31T19:05:06Z + monTz = ts.Receive(overloads.TimeGetDate, overloads.TimestampToDayOfMonthOneBasedWithTz, + []ref.Val{String("America/Phoenix")}) + if !monTz.Equal(Int(31)).(Bool) { + t.Errorf("ts.getDate() got %v, wanted 31", mon) + } + // 1970-01-02T01:05:06Z + monTz = ts.Receive(overloads.TimeGetDate, overloads.TimestampToDayOfMonthOneBasedWithTz, + []ref.Val{String("+23:00")}) + if !monTz.Equal(Int(2)).(Bool) { + t.Errorf("ts.getDate() got %v, wanted 2", mon) + } +} + func TestTimestampGetDayOfYear(t *testing.T) { // 1970-01-01T02:05:06Z - ts := Timestamp{Time: time.Unix(7506, 0).UTC()} + ts := timestampOf(time.Unix(7506, 0).UTC()) hr := ts.Receive(overloads.TimeGetDayOfYear, overloads.TimestampToDayOfYear, []ref.Val{}) if !hr.Equal(Int(0)).(Bool) { t.Error("Expected 0, got", hr) @@ -332,18 +372,48 @@ } } +func TestTimestampGetFullYear(t *testing.T) { + // 1970-01-01T02:05:06Z + ts := Timestamp{Time: time.Unix(7506, 0).UTC()} + year := ts.Receive(overloads.TimeGetFullYear, overloads.TimestampToYear, []ref.Val{}) + if !year.Equal(Int(1970)).(Bool) { + t.Errorf("ts.getFullYear() got %v, wanted 1970", year) + } + // 1969-12-31T19:05:06Z + yearTz := ts.Receive(overloads.TimeGetFullYear, overloads.TimestampToYearWithTz, + []ref.Val{String("America/Phoenix")}) + if !yearTz.Equal(Int(1969)).(Bool) { + t.Errorf("ts.getFullYear('America/Phoenix') got %v, wanted 1969", yearTz) + } +} + func TestTimestampGetMonth(t *testing.T) { // 1970-01-01T02:05:06Z ts := Timestamp{Time: time.Unix(7506, 0).UTC()} hr := ts.Receive(overloads.TimeGetMonth, overloads.TimestampToMonth, []ref.Val{}) if !hr.Equal(Int(0)).(Bool) { - t.Error("Expected 0, got", hr) + t.Errorf("ts.getMonth() got %v, wanted 0", hr) } // 1969-12-31T19:05:06Z hrTz := ts.Receive(overloads.TimeGetMonth, overloads.TimestampToMonthWithTz, []ref.Val{String("America/Phoenix")}) if !hrTz.Equal(Int(11)).(Bool) { - t.Error("Expected 11, got", hrTz) + t.Errorf("ts.getMonth('America/Phoenix') got %v, wanted 11", hrTz) + } +} + +func TestTimestampGetDayOfWeek(t *testing.T) { + // 1970-01-01T02:05:06Z + ts := Timestamp{Time: time.Unix(7506, 0).UTC()} + day := ts.Receive(overloads.TimeGetDayOfWeek, overloads.TimestampToDayOfWeek, []ref.Val{}) + if !day.Equal(Int(4)).(Bool) { + t.Errorf("ts.getDayOfWeek() got %v, wanted 4", day) + } + // 1969-12-31T19:05:06Z + dayTz := ts.Receive(overloads.TimeGetDayOfWeek, overloads.TimestampToDayOfWeekWithTz, + []ref.Val{String("America/Phoenix")}) + if !dayTz.Equal(Int(3)).(Bool) { + t.Errorf("ts.getDayOfWeek('America/Phoenix') got %v, wanted 3", dayTz) } } @@ -352,13 +422,13 @@ ts := Timestamp{Time: time.Unix(7506, 0).UTC()} hr := ts.Receive(overloads.TimeGetHours, overloads.TimestampToHours, []ref.Val{}) if !hr.Equal(Int(2)).(Bool) { - t.Error("Expected 2 hours, got", hr) + t.Errorf("ts.getHours() got %v, wanted 2", hr) } // 1969-12-31T19:05:06Z hrTz := ts.Receive(overloads.TimeGetHours, overloads.TimestampToHoursWithTz, []ref.Val{String("America/Phoenix")}) if !hrTz.Equal(Int(19)).(Bool) { - t.Error("Expected 19 hours, got", hrTz) + t.Errorf("ts.getHours('America/Phoenix') got %v, wanted 19 hours", hrTz) } } @@ -367,13 +437,13 @@ ts := Timestamp{Time: time.Unix(7506, 0).UTC()} min := ts.Receive(overloads.TimeGetMinutes, overloads.TimestampToMinutes, []ref.Val{}) if !min.Equal(Int(5)).(Bool) { - t.Error("Expected 5 minutes, got", min) + t.Errorf("ts.getMinutes() got %v, wanted 5 minutes", min) } // 1969-12-31T19:05:06Z minTz := ts.Receive(overloads.TimeGetMinutes, overloads.TimestampToMinutesWithTz, []ref.Val{String("America/Phoenix")}) if !minTz.Equal(Int(5)).(Bool) { - t.Error("Expected 5 minutes, got", minTz) + t.Errorf("ts.getMinutes('America/Phoenix') got %v, wanted 5 minutes", min) } } @@ -382,12 +452,27 @@ ts := Timestamp{Time: time.Unix(7506, 0).UTC()} sec := ts.Receive(overloads.TimeGetSeconds, overloads.TimestampToSeconds, []ref.Val{}) if !sec.Equal(Int(6)).(Bool) { - t.Error("Expected 6 seconds, got", sec) + t.Errorf("ts.getSeconds() got %v, wanted 6 seconds", sec) } // 1969-12-31T19:05:06Z secTz := ts.Receive(overloads.TimeGetSeconds, overloads.TimestampToSecondsWithTz, []ref.Val{String("America/Phoenix")}) if !secTz.Equal(Int(6)).(Bool) { - t.Error("Expected 6 seconds, got", secTz) + t.Errorf("ts.getSeconds('America/Phoenix') got %v, wanted 6 seconds", secTz) + } +} + +func TestTimestampGetMilliseconds(t *testing.T) { + // 1970-01-01T02:05:06Z + ts := Timestamp{Time: time.Unix(7506, 1000000).UTC()} + ms := ts.Receive(overloads.TimeGetMilliseconds, overloads.TimestampToMilliseconds, []ref.Val{}) + if !ms.Equal(Int(1)).(Bool) { + t.Errorf("ts.getMilliseconds() got %v, wanted 1 ms", ms) + } + // 1969-12-31T19:05:06Z + msTz := ts.Receive(overloads.TimeGetMilliseconds, overloads.TimestampToMillisecondsWithTz, + []ref.Val{String("America/Phoenix")}) + if !msTz.Equal(Int(1)).(Bool) { + t.Errorf("ts.getMilliseconds('America/Phoenix') got %v, wanted 1 ms", msTz) } } diff -Nru golang-github-google-cel-go-0.11.4+ds/debian/changelog golang-github-google-cel-go-0.12.5+ds/debian/changelog --- golang-github-google-cel-go-0.11.4+ds/debian/changelog 2022-12-19 15:19:38.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/debian/changelog 2022-12-20 15:30:46.000000000 +0000 @@ -1,3 +1,11 @@ +golang-github-google-cel-go (0.12.5+ds-1) unstable; urgency=medium + + * New upstream version 0.12.5+ds + * d/control: Update dependencies + * d/rules: Do not build binary + + -- Peymaneh Tue, 20 Dec 2022 16:30:46 +0100 + golang-github-google-cel-go (0.11.4+ds-3) unstable; urgency=medium * d/rules: Build packages needed for autopkgtest diff -Nru golang-github-google-cel-go-0.11.4+ds/debian/control golang-github-google-cel-go-0.12.5+ds/debian/control --- golang-github-google-cel-go-0.11.4+ds/debian/control 2022-12-19 15:19:38.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/debian/control 2022-12-20 15:30:46.000000000 +0000 @@ -12,7 +12,8 @@ golang-golang-x-text-dev, golang-google-protobuf-dev, golang-github-google-go-cmp-dev, - golang-github-stoewer-go-strcase-dev + golang-github-stoewer-go-strcase-dev, + golang-github-chzyer-readline-dev, Standards-Version: 4.6.1.0 Vcs-Browser: https://salsa.debian.org/go-team/packages/golang-github-google-cel-go Vcs-Git: https://salsa.debian.org/go-team/packages/golang-github-google-cel-go.git @@ -26,6 +27,7 @@ golang-glog-dev, golang-golang-x-text-dev, golang-github-stoewer-go-strcase-dev, + golang-github-chzyer-readline-dev, ${misc:Depends} Description: Common Expression Language (go runtime) The Common Expression Language (CEL) is a simple expression language built on diff -Nru golang-github-google-cel-go-0.11.4+ds/debian/rules golang-github-google-cel-go-0.12.5+ds/debian/rules --- golang-github-google-cel-go-0.11.4+ds/debian/rules 2022-12-19 15:19:38.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/debian/rules 2022-12-20 15:30:46.000000000 +0000 @@ -1,7 +1,7 @@ #!/usr/bin/make -f #export DH_VERBOSE := 1 -export DH_GOLANG_EXCLUDES := bin server examples codelab +export DH_GOLANG_EXCLUDES := bin server examples codelab repl/main export BUILDDIR := build %: diff -Nru golang-github-google-cel-go-0.11.4+ds/examples/custom_global_function_test.go golang-github-google-cel-go-0.12.5+ds/examples/custom_global_function_test.go --- golang-github-google-cel-go-0.11.4+ds/examples/custom_global_function_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/examples/custom_global_function_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -19,23 +19,26 @@ "log" "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" - - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) func ExampleCustomGlobalFunction() { - d := cel.Declarations( - decls.NewVar("i", decls.String), - decls.NewVar("you", decls.String), - decls.NewFunction("shake_hands", - decls.NewOverload("shake_hands_string_string", - []*exprpb.Type{decls.String, decls.String}, - decls.String))) - env, err := cel.NewEnv(d) + env, err := cel.NewEnv( + cel.Variable("i", cel.StringType), + cel.Variable("you", cel.StringType), + cel.Function("shake_hands", + cel.Overload("shake_hands_string_string", + []*cel.Type{cel.StringType, cel.StringType}, + cel.StringType, + cel.BinaryBinding(func(lhs, rhs ref.Val) ref.Val { + return types.String( + fmt.Sprintf("%s and %s are shaking hands.\n", lhs, rhs)) + }, + ), + ), + ), + ) if err != nil { log.Fatalf("environment creation error: %v\n", err) } @@ -44,13 +47,7 @@ if iss.Err() != nil { log.Fatalln(iss.Err()) } - shakeFunc := &functions.Overload{ - Operator: "shake_hands_string_string", - Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { - return types.String( - fmt.Sprintf("%s and %s are shaking hands.\n", lhs, rhs)) - }} - prg, err := env.Program(ast, cel.Functions(shakeFunc)) + prg, err := env.Program(ast) if err != nil { log.Fatalf("Program creation error: %v\n", err) } diff -Nru golang-github-google-cel-go-0.11.4+ds/examples/custom_instance_function_test.go golang-github-google-cel-go-0.12.5+ds/examples/custom_instance_function_test.go --- golang-github-google-cel-go-0.11.4+ds/examples/custom_instance_function_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/examples/custom_instance_function_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -19,12 +19,8 @@ "log" "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" - - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) func ExampleCustomInstanceFunction() { @@ -58,26 +54,21 @@ func (customLib) CompileOptions() []cel.EnvOption { return []cel.EnvOption{ - cel.Declarations( - decls.NewVar("i", decls.String), - decls.NewVar("you", decls.String), - decls.NewFunction("greet", - decls.NewInstanceOverload("string_greet_string", - []*exprpb.Type{decls.String, decls.String}, - decls.String))), - } -} - -func (customLib) ProgramOptions() []cel.ProgramOption { - return []cel.ProgramOption{ - cel.Functions( - &functions.Overload{ - Operator: "string_greet_string", - Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { + cel.Variable("i", cel.StringType), + cel.Variable("you", cel.StringType), + cel.Function("greet", + cel.MemberOverload("string_greet_string", + []*cel.Type{cel.StringType, cel.StringType}, + cel.StringType, + cel.BinaryBinding(func(lhs, rhs ref.Val) ref.Val { return types.String( fmt.Sprintf("Hello %s! Nice to meet you, I'm %s.\n", rhs, lhs)) - }, - }, + }), + ), ), } } + +func (customLib) ProgramOptions() []cel.ProgramOption { + return []cel.ProgramOption{} +} diff -Nru golang-github-google-cel-go-0.11.4+ds/examples/README.md golang-github-google-cel-go-0.12.5+ds/examples/README.md --- golang-github-google-cel-go-0.11.4+ds/examples/README.md 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/examples/README.md 2022-12-20 15:30:36.000000000 +0000 @@ -6,14 +6,13 @@ name. ```go -import ( - "github.com/google/cel-go/cel" - "github.com/google/cel-go/checker/decls" -) - - d := cel.Declarations(decls.NewVar("name", decls.String)) - env, err := cel.NewEnv(d) +import "github.com/google/cel-go/cel" + env, err := cel.NewEnv(cel.Variable("name", cel.StringType)) + // Check err for environment setup errors. + if err != nil { + log.Fatalln(err) + } ast, iss := env.Compile(`"Hello world! I'm " + name + "."`) // Check iss for compilation errors. if iss.Err() != nil { @@ -40,35 +39,30 @@ ``` First we need to declare two string variables and `greet` function. -`NewInstanceOverload` must be used if we want to declare function which will -operate on a type. First element of slice passed as `argTypes` into -`NewInstanceOverload` is declaration of instance type. Next elements are -parameters of function. - -```go - decls.NewVar("i", decls.String), - decls.NewVar("you", decls.String), - decls.NewFunction("greet", - decls.NewInstanceOverload("string_greet_string", - []*exprpb.Type{decls.String, decls.String}, - decls.String)) - ... // Create env and compile -``` - -Let's implement `greet` function and pass it to `program`. We will be using -`Binary`, because `greet` function uses 2 parameters (1st instance, 2nd -function parameter). +`Function` must be used if we want to declare an extension to CEL. The +`MemberOverload` declares an overload id, a list of arguments where the +first element the `argTypes` slice is the target type of the member +function. The remaining argument types are the signature of the member +method. ```go - greetFunc := &functions.Overload{ - Operator: "string_greet_string", - Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { - return types.String( - fmt.Sprintf("Hello %s! Nice to meet you, I'm %s.\n", rhs, lhs)) - }} - prg, err := env.Program(c, cel.Functions(greetFunc)) - - out, _, err := prg.Eval(map[string]interface{}{ + env, _ := cel.NewEnv( + cel.Variable("i", cel.StringType), + cel.Variable("you", cel.StringType), + cel.Function("greet", + cel.MemberOverload("string_greet_string", + []*cel.Type{cel.StringType, cel.StringType}, + cel.StringType, + cel.BinaryBinding(func (lhs, rhs ref.Val) ref.Val { + return types.String( + fmt.Sprintf("Hello %s! Nice to meet you, I'm %s.\n", rhs, lhs)) + }, + ), + ), + ), + ) + prg, _ := env.Program(c) + out, _, _ := prg.Eval(map[string]interface{}{ "i": "CEL", "you": "world", }) @@ -87,26 +81,27 @@ shake_hands -> "%s and %s are shaking hands." ``` -In order to declare global function we need to use `NewOverload`: +In order to declare global function we need to use `Overload` instead +of `MemberOverload` in the `Function` option: ```go - decls.NewVar("i", decls.String), - decls.NewVar("you", decls.String), - decls.NewFunction("shake_hands", - decls.NewOverload("shake_hands_string_string", - []*exprpb.Type{decls.String, decls.String}, - decls.String)) - ... // Create env and compile. - - shakeFunc := &functions.Overload{ - Operator: "shake_hands_string_string", - Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { - return types.String( - fmt.Sprintf("%s and %s are shaking hands.\n", lhs, rhs)) - }} - prg, err := env.Program(c, cel.Functions(shakeFunc)) - - out, _, err := prg.Eval(map[string]interface{}{ + env, _ := cel.NewEnv( + cel.Variable("i", cel.StringType), + cel.Variable("you", cel.StringType), + cel.Function("shake_hands", + cel.Overload("shake_hands_string_string", + []*cel.Type{cel.StringType, cel.StringType}, + cel.StringType, + cel.BinaryBinding(func(lhs, rhs ref.Val) ref.Val { + return types.String( + fmt.Sprintf("%s and %s are shaking hands.\n", lhs, rhs)) + }, + ), + ), + ), + ) + prg, _ := env.Program(c) + out, _, _ := prg.Eval(map[string]interface{}{ "i": "CEL", "you": "world", }) diff -Nru golang-github-google-cel-go-0.11.4+ds/examples/simple_test.go golang-github-google-cel-go-0.12.5+ds/examples/simple_test.go --- golang-github-google-cel-go-0.11.4+ds/examples/simple_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/examples/simple_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -19,12 +19,10 @@ "log" "github.com/google/cel-go/cel" - "github.com/google/cel-go/checker/decls" ) func ExampleSimple() { - d := cel.Declarations(decls.NewVar("name", decls.String)) - env, err := cel.NewEnv(d) + env, err := cel.NewEnv(cel.Variable("name", cel.StringType)) if err != nil { log.Fatalf("environment creation error: %v\n", err) } diff -Nru golang-github-google-cel-go-0.11.4+ds/ext/BUILD.bazel golang-github-google-cel-go-0.12.5+ds/ext/BUILD.bazel --- golang-github-google-cel-go-0.11.4+ds/ext/BUILD.bazel 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/ext/BUILD.bazel 2022-12-20 15:30:36.000000000 +0000 @@ -15,12 +15,8 @@ visibility = ["//visibility:public"], deps = [ "//cel:go_default_library", - "//checker/decls:go_default_library", "//common/types:go_default_library", "//common/types/ref:go_default_library", - "//common/types/traits:go_default_library", - "//interpreter/functions:go_default_library", - "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", ], ) diff -Nru golang-github-google-cel-go-0.11.4+ds/ext/encoders.go golang-github-google-cel-go-0.12.5+ds/ext/encoders.go --- golang-github-google-cel-go-0.11.4+ds/ext/encoders.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/ext/encoders.go 2022-12-20 15:30:36.000000000 +0000 @@ -16,12 +16,11 @@ import ( "encoding/base64" + "reflect" "github.com/google/cel-go/cel" - "github.com/google/cel-go/checker/decls" - "github.com/google/cel-go/interpreter/functions" - - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" ) // Encoders returns a cel.EnvOption to configure extended functions for string, byte, and object @@ -57,42 +56,23 @@ func (encoderLib) CompileOptions() []cel.EnvOption { return []cel.EnvOption{ - cel.Declarations( - decls.NewFunction("base64.decode", - decls.NewOverload("base64_decode_string", - []*exprpb.Type{decls.String}, - decls.Bytes)), - decls.NewFunction("base64.encode", - decls.NewOverload("base64_encode_bytes", - []*exprpb.Type{decls.Bytes}, - decls.String)), - ), + cel.Function("base64.decode", + cel.Overload("base64_decode_string", []*cel.Type{cel.StringType}, cel.BytesType, + cel.UnaryBinding(func(str ref.Val) ref.Val { + s := str.(types.String) + return bytesOrError(base64DecodeString(string(s))) + }))), + cel.Function("base64.encode", + cel.Overload("base64_encode_bytes", []*cel.Type{cel.BytesType}, cel.StringType, + cel.UnaryBinding(func(bytes ref.Val) ref.Val { + b := bytes.(types.Bytes) + return stringOrError(base64EncodeBytes([]byte(b))) + }))), } } func (encoderLib) ProgramOptions() []cel.ProgramOption { - wrappedBase64EncodeBytes := callInBytesOutString(base64EncodeBytes) - wrappedBase64DecodeString := callInStrOutBytes(base64DecodeString) - return []cel.ProgramOption{ - cel.Functions( - &functions.Overload{ - Operator: "base64.decode", - Unary: wrappedBase64DecodeString, - }, - &functions.Overload{ - Operator: "base64_decode_string", - Unary: wrappedBase64DecodeString, - }, - &functions.Overload{ - Operator: "base64.encode", - Unary: wrappedBase64EncodeBytes, - }, - &functions.Overload{ - Operator: "base64_encode_bytes", - Unary: wrappedBase64EncodeBytes, - }, - ), - } + return []cel.ProgramOption{} } func base64DecodeString(str string) ([]byte, error) { @@ -102,3 +82,7 @@ func base64EncodeBytes(bytes []byte) (string, error) { return base64.StdEncoding.EncodeToString(bytes), nil } + +var ( + bytesListType = reflect.TypeOf([]byte{}) +) diff -Nru golang-github-google-cel-go-0.11.4+ds/ext/encoders_test.go golang-github-google-cel-go-0.12.5+ds/ext/encoders_test.go --- golang-github-google-cel-go-0.11.4+ds/ext/encoders_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/ext/encoders_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -16,6 +16,7 @@ import ( "fmt" + "strings" "testing" "github.com/google/cel-go/cel" @@ -76,9 +77,8 @@ tt.Fatalf("got %v, wanted error %s for expr: %s", out.Value(), tc.err, tc.expr) } - if tc.err != err.Error() { - tt.Errorf("got error %v, wanted error %s for expr: %s", - err, tc.err, tc.expr) + if !strings.Contains(err.Error(), tc.err) { + tt.Errorf("got error %v, wanted error %s for expr: %s", err, tc.err, tc.expr) } } else if err != nil { tt.Fatal(err) diff -Nru golang-github-google-cel-go-0.11.4+ds/ext/guards.go golang-github-google-cel-go-0.12.5+ds/ext/guards.go --- golang-github-google-cel-go-0.11.4+ds/ext/guards.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/ext/guards.go 2022-12-20 15:30:36.000000000 +0000 @@ -17,287 +17,34 @@ 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" ) // function invocation guards for common call signatures within extension functions. -func callInBytesOutString(fn func([]byte) (string, error)) functions.UnaryOp { - return func(val ref.Val) ref.Val { - vVal, ok := val.(types.Bytes) - if !ok { - return types.MaybeNoSuchOverloadErr(val) - } - str, err := fn([]byte(vVal)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.String(str) +func intOrError(i int64, err error) ref.Val { + if err != nil { + return types.NewErr(err.Error()) } + return types.Int(i) } -func callInStrOutBytes(fn func(string) ([]byte, error)) functions.UnaryOp { - return func(val ref.Val) ref.Val { - vVal, ok := val.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(val) - } - byt, err := fn(string(vVal)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.Bytes(byt) +func bytesOrError(bytes []byte, err error) ref.Val { + if err != nil { + return types.NewErr(err.Error()) } + return types.Bytes(bytes) } -func callInStrOutStr(fn func(string) (string, error)) functions.UnaryOp { - return func(val ref.Val) ref.Val { - vVal, ok := val.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(val) - } - str, err := fn(string(vVal)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.String(str) +func stringOrError(str string, err error) ref.Val { + if err != nil { + return types.NewErr(err.Error()) } + return types.String(str) } -func callInStrIntOutStr(fn func(string, int64) (string, error)) functions.BinaryOp { - return func(val, arg ref.Val) ref.Val { - vVal, ok := val.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(val) - } - argVal, ok := arg.(types.Int) - if !ok { - return types.MaybeNoSuchOverloadErr(arg) - } - out, err := fn(string(vVal), int64(argVal)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.String(out) - } -} - -func callInStrStrOutInt(fn func(string, string) (int64, error)) functions.BinaryOp { - return func(val, arg ref.Val) ref.Val { - vVal, ok := val.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(val) - } - argVal, ok := arg.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(arg) - } - out, err := fn(string(vVal), string(argVal)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.Int(out) - } -} - -func callInStrStrOutListStr(fn func(string, string) ([]string, error)) functions.BinaryOp { - return func(val, arg ref.Val) ref.Val { - vVal, ok := val.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(val) - } - argVal, ok := arg.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(arg) - } - out, err := fn(string(vVal), string(argVal)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.DefaultTypeAdapter.NativeToValue(out) - } -} - -func callInStrIntIntOutStr(fn func(string, int64, int64) (string, error)) functions.FunctionOp { - return func(args ...ref.Val) ref.Val { - if len(args) != 3 { - return types.NoSuchOverloadErr() - } - vVal, ok := args[0].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[0]) - } - arg1Val, ok := args[1].(types.Int) - if !ok { - return types.MaybeNoSuchOverloadErr(args[1]) - } - arg2Val, ok := args[2].(types.Int) - if !ok { - return types.MaybeNoSuchOverloadErr(args[2]) - } - out, err := fn(string(vVal), int64(arg1Val), int64(arg2Val)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.String(out) - } -} - -func callInStrStrStrOutStr(fn func(string, string, string) (string, error)) functions.FunctionOp { - return func(args ...ref.Val) ref.Val { - if len(args) != 3 { - return types.NoSuchOverloadErr() - } - vVal, ok := args[0].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[0]) - } - arg1Val, ok := args[1].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[1]) - } - arg2Val, ok := args[2].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[2]) - } - out, err := fn(string(vVal), string(arg1Val), string(arg2Val)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.String(out) - } -} - -func callInStrStrIntOutInt(fn func(string, string, int64) (int64, error)) functions.FunctionOp { - return func(args ...ref.Val) ref.Val { - if len(args) != 3 { - return types.NoSuchOverloadErr() - } - vVal, ok := args[0].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[0]) - } - arg1Val, ok := args[1].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[1]) - } - arg2Val, ok := args[2].(types.Int) - if !ok { - return types.MaybeNoSuchOverloadErr(args[2]) - } - out, err := fn(string(vVal), string(arg1Val), int64(arg2Val)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.Int(out) - } -} - -func callInStrStrIntOutListStr(fn func(string, string, int64) ([]string, error)) functions.FunctionOp { - return func(args ...ref.Val) ref.Val { - if len(args) != 3 { - return types.NoSuchOverloadErr() - } - vVal, ok := args[0].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[0]) - } - arg1Val, ok := args[1].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[1]) - } - arg2Val, ok := args[2].(types.Int) - if !ok { - return types.MaybeNoSuchOverloadErr(args[2]) - } - out, err := fn(string(vVal), string(arg1Val), int64(arg2Val)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.DefaultTypeAdapter.NativeToValue(out) - } -} - -func callInStrStrStrIntOutStr(fn func(string, string, string, int64) (string, error)) functions.FunctionOp { - return func(args ...ref.Val) ref.Val { - if len(args) != 4 { - return types.NoSuchOverloadErr() - } - vVal, ok := args[0].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[0]) - } - arg1Val, ok := args[1].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[1]) - } - arg2Val, ok := args[2].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[2]) - } - arg3Val, ok := args[3].(types.Int) - if !ok { - return types.MaybeNoSuchOverloadErr(args[3]) - } - out, err := fn(string(vVal), string(arg1Val), string(arg2Val), int64(arg3Val)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.String(out) - } -} - -func callInListStrOutStr(fn func([]string) (string, error)) functions.UnaryOp { - return func(args1 ref.Val) ref.Val { - vVal, ok := args1.(traits.Lister) - if !ok { - return types.MaybeNoSuchOverloadErr(args1) - } - strings := make([]string, vVal.Size().Value().(int64)) - i := 0 - for it := vVal.Iterator(); it.HasNext() == types.True; { - next := it.Next() - v, ok := next.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(next) - } - strings[i] = string(v) - i++ - } - out, err := fn(strings) - if err != nil { - return types.NewErr(err.Error()) - } - return types.DefaultTypeAdapter.NativeToValue(out) - } -} - -func callInListStrStrOutStr(fn func([]string, string) (string, error)) functions.BinaryOp { - return func(args1, args2 ref.Val) ref.Val { - vVal, ok := args1.(traits.Lister) - if !ok { - return types.MaybeNoSuchOverloadErr(args1) - } - arg1Val, ok := args2.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args2) - } - strings := make([]string, vVal.Size().Value().(int64)) - i := 0 - for it := vVal.Iterator(); it.HasNext() == types.True; { - next := it.Next() - v, ok := next.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(next) - } - strings[i] = string(v) - i++ - } - out, err := fn(strings, string(arg1Val)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.DefaultTypeAdapter.NativeToValue(out) +func listStringOrError(strs []string, err error) ref.Val { + if err != nil { + return types.NewErr(err.Error()) } + return types.DefaultTypeAdapter.NativeToValue(strs) } diff -Nru golang-github-google-cel-go-0.11.4+ds/ext/strings.go golang-github-google-cel-go-0.12.5+ds/ext/strings.go --- golang-github-google-cel-go-0.11.4+ds/ext/strings.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/ext/strings.go 2022-12-20 15:30:36.000000000 +0000 @@ -19,16 +19,13 @@ import ( "fmt" + "reflect" "strings" "unicode" "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" - - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) // Strings returns a cel.EnvOption to configure extended functions for string manipulation. @@ -207,194 +204,128 @@ func (stringLib) CompileOptions() []cel.EnvOption { return []cel.EnvOption{ - cel.Declarations( - decls.NewFunction("charAt", - decls.NewInstanceOverload("string_char_at_int", - []*exprpb.Type{decls.String, decls.Int}, - decls.String)), - decls.NewFunction("indexOf", - decls.NewInstanceOverload("string_index_of_string", - []*exprpb.Type{decls.String, decls.String}, - decls.Int), - decls.NewInstanceOverload("string_index_of_string_int", - []*exprpb.Type{decls.String, decls.String, decls.Int}, - decls.Int)), - decls.NewFunction("lastIndexOf", - decls.NewInstanceOverload("string_last_index_of_string", - []*exprpb.Type{decls.String, decls.String}, - decls.Int), - decls.NewInstanceOverload("string_last_index_of_string_int", - []*exprpb.Type{decls.String, decls.String, decls.Int}, - decls.Int)), - decls.NewFunction("lowerAscii", - decls.NewInstanceOverload("string_lower_ascii", - []*exprpb.Type{decls.String}, - decls.String)), - decls.NewFunction("replace", - decls.NewInstanceOverload("string_replace_string_string", - []*exprpb.Type{decls.String, decls.String, decls.String}, - decls.String), - decls.NewInstanceOverload("string_replace_string_string_int", - []*exprpb.Type{decls.String, decls.String, decls.String, decls.Int}, - decls.String)), - decls.NewFunction("split", - decls.NewInstanceOverload("string_split_string", - []*exprpb.Type{decls.String, decls.String}, - decls.NewListType(decls.String)), - decls.NewInstanceOverload("string_split_string_int", - []*exprpb.Type{decls.String, decls.String, decls.Int}, - decls.NewListType(decls.String))), - decls.NewFunction("substring", - decls.NewInstanceOverload("string_substring_int", - []*exprpb.Type{decls.String, decls.Int}, - decls.String), - decls.NewInstanceOverload("string_substring_int_int", - []*exprpb.Type{decls.String, decls.Int, decls.Int}, - decls.String)), - decls.NewFunction("trim", - decls.NewInstanceOverload("string_trim", - []*exprpb.Type{decls.String}, - decls.String)), - decls.NewFunction("upperAscii", - decls.NewInstanceOverload("string_upper_ascii", - []*exprpb.Type{decls.String}, - decls.String)), - decls.NewFunction("join", - decls.NewInstanceOverload("list_join", - []*exprpb.Type{decls.NewListType(decls.String)}, - decls.String), - decls.NewInstanceOverload("list_join_string", - []*exprpb.Type{decls.NewListType(decls.String), decls.String}, - decls.String), - ), - ), + cel.Function("charAt", + cel.MemberOverload("string_char_at_int", []*cel.Type{cel.StringType, cel.IntType}, cel.StringType, + cel.BinaryBinding(func(str, ind ref.Val) ref.Val { + s := str.(types.String) + i := ind.(types.Int) + return stringOrError(charAt(string(s), int64(i))) + }))), + cel.Function("indexOf", + cel.MemberOverload("string_index_of_string", []*cel.Type{cel.StringType, cel.StringType}, cel.IntType, + cel.BinaryBinding(func(str, substr ref.Val) ref.Val { + s := str.(types.String) + sub := substr.(types.String) + return intOrError(indexOf(string(s), string(sub))) + })), + cel.MemberOverload("string_index_of_string_int", []*cel.Type{cel.StringType, cel.StringType, cel.IntType}, cel.IntType, + cel.FunctionBinding(func(args ...ref.Val) ref.Val { + s := args[0].(types.String) + sub := args[1].(types.String) + offset := args[2].(types.Int) + return intOrError(indexOfOffset(string(s), string(sub), int64(offset))) + }))), + cel.Function("lastIndexOf", + cel.MemberOverload("string_last_index_of_string", []*cel.Type{cel.StringType, cel.StringType}, cel.IntType, + cel.BinaryBinding(func(str, substr ref.Val) ref.Val { + s := str.(types.String) + sub := substr.(types.String) + return intOrError(lastIndexOf(string(s), string(sub))) + })), + cel.MemberOverload("string_last_index_of_string_int", []*cel.Type{cel.StringType, cel.StringType, cel.IntType}, cel.IntType, + cel.FunctionBinding(func(args ...ref.Val) ref.Val { + s := args[0].(types.String) + sub := args[1].(types.String) + offset := args[2].(types.Int) + return intOrError(lastIndexOfOffset(string(s), string(sub), int64(offset))) + }))), + cel.Function("lowerAscii", + cel.MemberOverload("string_lower_ascii", []*cel.Type{cel.StringType}, cel.StringType, + cel.UnaryBinding(func(str ref.Val) ref.Val { + s := str.(types.String) + return stringOrError(lowerASCII(string(s))) + }))), + cel.Function("replace", + cel.MemberOverload( + "string_replace_string_string", []*cel.Type{cel.StringType, cel.StringType, cel.StringType}, cel.StringType, + cel.FunctionBinding(func(args ...ref.Val) ref.Val { + str := args[0].(types.String) + old := args[1].(types.String) + new := args[2].(types.String) + return stringOrError(replace(string(str), string(old), string(new))) + })), + cel.MemberOverload( + "string_replace_string_string_int", []*cel.Type{cel.StringType, cel.StringType, cel.StringType, cel.IntType}, cel.StringType, + cel.FunctionBinding(func(args ...ref.Val) ref.Val { + str := args[0].(types.String) + old := args[1].(types.String) + new := args[2].(types.String) + n := args[3].(types.Int) + return stringOrError(replaceN(string(str), string(old), string(new), int64(n))) + }))), + cel.Function("split", + cel.MemberOverload("string_split_string", []*cel.Type{cel.StringType, cel.StringType}, cel.ListType(cel.StringType), + cel.BinaryBinding(func(str, separator ref.Val) ref.Val { + s := str.(types.String) + sep := separator.(types.String) + return listStringOrError(split(string(s), string(sep))) + })), + cel.MemberOverload("string_split_string_int", []*cel.Type{cel.StringType, cel.StringType, cel.IntType}, cel.ListType(cel.StringType), + cel.FunctionBinding(func(args ...ref.Val) ref.Val { + s := args[0].(types.String) + sep := args[1].(types.String) + n := args[2].(types.Int) + return listStringOrError(splitN(string(s), string(sep), int64(n))) + }))), + cel.Function("substring", + cel.MemberOverload("string_substring_int", []*cel.Type{cel.StringType, cel.IntType}, cel.StringType, + cel.BinaryBinding(func(str, offset ref.Val) ref.Val { + s := str.(types.String) + off := offset.(types.Int) + return stringOrError(substr(string(s), int64(off))) + })), + cel.MemberOverload("string_substring_int_int", []*cel.Type{cel.StringType, cel.IntType, cel.IntType}, cel.StringType, + cel.FunctionBinding(func(args ...ref.Val) ref.Val { + s := args[0].(types.String) + start := args[1].(types.Int) + end := args[2].(types.Int) + return stringOrError(substrRange(string(s), int64(start), int64(end))) + }))), + cel.Function("trim", + cel.MemberOverload("string_trim", []*cel.Type{cel.StringType}, cel.StringType, + cel.UnaryBinding(func(str ref.Val) ref.Val { + s := str.(types.String) + return stringOrError(trimSpace(string(s))) + }))), + cel.Function("upperAscii", + cel.MemberOverload("string_upper_ascii", []*cel.Type{cel.StringType}, cel.StringType, + cel.UnaryBinding(func(str ref.Val) ref.Val { + s := str.(types.String) + return stringOrError(upperASCII(string(s))) + }))), + cel.Function("join", + cel.MemberOverload("list_join", []*cel.Type{cel.ListType(cel.StringType)}, cel.StringType, + cel.UnaryBinding(func(list ref.Val) ref.Val { + l, err := list.ConvertToNative(stringListType) + if err != nil { + return types.NewErr(err.Error()) + } + return stringOrError(join(l.([]string))) + })), + cel.MemberOverload("list_join_string", []*cel.Type{cel.ListType(cel.StringType), cel.StringType}, cel.StringType, + cel.BinaryBinding(func(list, delim ref.Val) ref.Val { + l, err := list.ConvertToNative(stringListType) + if err != nil { + return types.NewErr(err.Error()) + } + d := delim.(types.String) + return stringOrError(joinSeparator(l.([]string), string(d))) + }))), } } func (stringLib) ProgramOptions() []cel.ProgramOption { - wrappedReplace := callInStrStrStrOutStr(replace) - wrappedReplaceN := callInStrStrStrIntOutStr(replaceN) - return []cel.ProgramOption{ - cel.Functions( - &functions.Overload{ - Operator: "charAt", - Binary: callInStrIntOutStr(charAt), - }, - &functions.Overload{ - Operator: "string_char_at_int", - Binary: callInStrIntOutStr(charAt), - }, - &functions.Overload{ - Operator: "indexOf", - Binary: callInStrStrOutInt(indexOf), - Function: callInStrStrIntOutInt(indexOfOffset), - }, - &functions.Overload{ - Operator: "string_index_of_string", - Binary: callInStrStrOutInt(indexOf), - }, - &functions.Overload{ - Operator: "string_index_of_string_int", - Function: callInStrStrIntOutInt(indexOfOffset), - }, - &functions.Overload{ - Operator: "lastIndexOf", - Binary: callInStrStrOutInt(lastIndexOf), - Function: callInStrStrIntOutInt(lastIndexOfOffset), - }, - &functions.Overload{ - Operator: "string_last_index_of_string", - Binary: callInStrStrOutInt(lastIndexOf), - }, - &functions.Overload{ - Operator: "string_last_index_of_string_int", - Function: callInStrStrIntOutInt(lastIndexOfOffset), - }, - &functions.Overload{ - Operator: "lowerAscii", - Unary: callInStrOutStr(lowerASCII), - }, - &functions.Overload{ - Operator: "string_lower_ascii", - Unary: callInStrOutStr(lowerASCII), - }, - &functions.Overload{ - Operator: "replace", - Function: func(values ...ref.Val) ref.Val { - if len(values) == 3 { - return wrappedReplace(values...) - } - if len(values) == 4 { - return wrappedReplaceN(values...) - } - return types.NoSuchOverloadErr() - }, - }, - &functions.Overload{ - Operator: "string_replace_string_string", - Function: wrappedReplace, - }, - &functions.Overload{ - Operator: "string_replace_string_string_int", - Function: wrappedReplaceN, - }, - &functions.Overload{ - Operator: "split", - Binary: callInStrStrOutListStr(split), - Function: callInStrStrIntOutListStr(splitN), - }, - &functions.Overload{ - Operator: "string_split_string", - Binary: callInStrStrOutListStr(split), - }, - &functions.Overload{ - Operator: "string_split_string_int", - Function: callInStrStrIntOutListStr(splitN), - }, - &functions.Overload{ - Operator: "substring", - Binary: callInStrIntOutStr(substr), - Function: callInStrIntIntOutStr(substrRange), - }, - &functions.Overload{ - Operator: "string_substring_int", - Binary: callInStrIntOutStr(substr), - }, - &functions.Overload{ - Operator: "string_substring_int_int", - Function: callInStrIntIntOutStr(substrRange), - }, - &functions.Overload{ - Operator: "trim", - Unary: callInStrOutStr(trimSpace), - }, - &functions.Overload{ - Operator: "string_trim", - Unary: callInStrOutStr(trimSpace), - }, - &functions.Overload{ - Operator: "upperAscii", - Unary: callInStrOutStr(upperASCII), - }, - &functions.Overload{ - Operator: "string_upper_ascii", - Unary: callInStrOutStr(upperASCII), - }, - &functions.Overload{ - Operator: "join", - Unary: callInListStrOutStr(join), - Binary: callInListStrStrOutStr(joinSeparator), - }, - &functions.Overload{ - Operator: "list_join", - Unary: callInListStrOutStr(join), - }, - &functions.Overload{ - Operator: "list_join_string", - Binary: callInListStrStrOutStr(joinSeparator), - }, - ), - } + return []cel.ProgramOption{} } func charAt(str string, ind int64) (string, error) { @@ -546,3 +477,7 @@ func join(strs []string) (string, error) { return strings.Join(strs, ""), nil } + +var ( + stringListType = reflect.TypeOf([]string{}) +) diff -Nru golang-github-google-cel-go-0.11.4+ds/ext/strings_test.go golang-github-google-cel-go-0.12.5+ds/ext/strings_test.go --- golang-github-google-cel-go-0.11.4+ds/ext/strings_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/ext/strings_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -16,6 +16,7 @@ import ( "fmt" + "strings" "testing" "github.com/google/cel-go/cel" @@ -305,7 +306,7 @@ tt.Fatalf("got value %v, wanted error %s for expr: %s", out.Value(), tc.err, tc.expr) } - if tc.err != err.Error() { + if !strings.Contains(err.Error(), tc.err) { tt.Errorf("got error %v, wanted error %s for expr: %s", err, tc.err, tc.expr) } } else if err != nil { diff -Nru golang-github-google-cel-go-0.11.4+ds/go.mod golang-github-google-cel-go-0.12.5+ds/go.mod --- golang-github-google-cel-go-0.11.4+ds/go.mod 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/go.mod 2022-12-20 15:30:36.000000000 +0000 @@ -4,7 +4,6 @@ require ( github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed - github.com/golang/glog v1.0.0 github.com/golang/protobuf v1.5.2 github.com/stoewer/go-strcase v1.2.0 golang.org/x/text v0.3.7 diff -Nru golang-github-google-cel-go-0.11.4+ds/go.sum golang-github-google-cel-go-0.12.5+ds/go.sum --- golang-github-google-cel-go-0.11.4+ds/go.sum 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/go.sum 2022-12-20 15:30:36.000000000 +0000 @@ -2,8 +2,6 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220209173558-ad29539cd2e9 h1:zvkJv+9Pxm1nnEMcKnShREt4qtduHKz4iw4AB4ul0Ao= -github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220209173558-ad29539cd2e9/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed h1:ue9pVfIcP+QMEjfgo/Ez4ZjNZfonGgR6NgjMaJMu1Cg= github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -12,8 +10,8 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -21,12 +19,10 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -47,8 +43,9 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -75,6 +72,7 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -86,7 +84,9 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -109,8 +109,6 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6 h1:FglFEfyj61zP3c6LgjmVHxYxZWXYul9oiS1EZqD5gLc= -google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 h1:hrbNEivu7Zn1pxvHk6MBrq9iE22woVILTHqexqBxe6I= google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -119,7 +117,7 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -131,7 +129,6 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff -Nru golang-github-google-cel-go-0.11.4+ds/interpreter/interpretable.go golang-github-google-cel-go-0.12.5+ds/interpreter/interpretable.go --- golang-github-google-cel-go-0.11.4+ds/interpreter/interpretable.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/interpreter/interpretable.go 2022-12-20 15:30:36.000000000 +0000 @@ -445,7 +445,7 @@ } // 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)) { + if un.impl != nil && (un.trait == 0 || (!strict && types.IsUnknownOrError(argVal)) || argVal.Type().HasTrait(un.trait)) { return un.impl(argVal) } // Otherwise, if the argument is a ReceiverType attempt to invoke the receiver method on the @@ -511,7 +511,7 @@ } // 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)) { + if bin.impl != nil && (bin.trait == 0 || (!strict && types.IsUnknownOrError(lVal)) || 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 @@ -582,7 +582,7 @@ // 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)) { + if fn.impl != nil && (fn.trait == 0 || (!strict && types.IsUnknownOrError(arg0)) || arg0.Type().HasTrait(fn.trait)) { return fn.impl(argVals...) } // Otherwise, if the argument is a ReceiverType attempt to invoke the receiver method on the @@ -835,7 +835,9 @@ varActivationPool.Put(accuCtx) // Convert a mutable list to an immutable one, if the comprehension has generated a list as a result. if !types.IsUnknownOrError(res) && buildingList { - res = res.(traits.MutableLister).ToImmutableList() + if _, ok := res.(traits.MutableLister); ok { + res = res.(traits.MutableLister).ToImmutableList() + } } return res } diff -Nru golang-github-google-cel-go-0.11.4+ds/interpreter/planner.go golang-github-google-cel-go-0.12.5+ds/interpreter/planner.go --- golang-github-google-cel-go-0.11.4+ds/interpreter/planner.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/interpreter/planner.go 2022-12-20 15:30:36.000000000 +0000 @@ -95,7 +95,7 @@ // 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) { + switch expr.GetExprKind().(type) { case *exprpb.Expr_CallExpr: return p.decorate(p.planCall(expr)) case *exprpb.Expr_IdentExpr: @@ -146,10 +146,10 @@ func (p *planner) planCheckedIdent(id int64, identRef *exprpb.Reference) (Interpretable, error) { // Plan a constant reference if this is the case for this simple identifier. - if identRef.Value != nil { + if identRef.GetValue() != nil { return p.Plan(&exprpb.Expr{Id: id, ExprKind: &exprpb.Expr_ConstExpr{ - ConstExpr: identRef.Value, + ConstExpr: identRef.GetValue(), }}) } @@ -157,9 +157,9 @@ // registered with the provider. cType := p.typeMap[id] if cType.GetType() != nil { - cVal, found := p.provider.FindIdent(identRef.Name) + cVal, found := p.provider.FindIdent(identRef.GetName()) if !found { - return nil, fmt.Errorf("reference to undefined type: %s", identRef.Name) + return nil, fmt.Errorf("reference to undefined type: %s", identRef.GetName()) } return NewConstValue(id, cVal), nil } @@ -167,14 +167,15 @@ // Otherwise, return the attribute for the resolved identifier name. return &evalAttr{ adapter: p.adapter, - attr: p.attrFactory.AbsoluteAttribute(id, identRef.Name), + attr: p.attrFactory.AbsoluteAttribute(id, identRef.GetName()), }, 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. +// +// 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) { // If the Select id appears in the reference map from the CheckedExpr proto then it is either // a namespaced identifier or enum value. @@ -193,7 +194,7 @@ var fieldType *ref.FieldType opType := p.typeMap[sel.GetOperand().GetId()] if opType.GetMessageType() != "" { - ft, found := p.provider.FindFieldType(opType.GetMessageType(), sel.Field) + ft, found := p.provider.FindFieldType(opType.GetMessageType(), sel.GetField()) if found && ft.IsSet != nil && ft.GetFrom != nil { fieldType = ft } @@ -213,15 +214,15 @@ if sel.TestOnly { // Return the test only eval expression. return &evalTestOnly{ - id: expr.Id, - field: types.String(sel.Field), + id: expr.GetId(), + field: types.String(sel.GetField()), fieldType: fieldType, op: op, }, nil } // Build a qualifier. qual, err := p.attrFactory.NewQualifier( - opType, expr.Id, sel.Field) + opType, expr.GetId(), sel.GetField()) if err != nil { return nil, err } @@ -302,8 +303,18 @@ case 0: return p.planCallZero(expr, fnName, oName, fnDef) case 1: + // If the FunctionOp has been used, then use it as it may exist for the purposes + // of dynamic dispatch within a singleton function implementation. + if fnDef != nil && fnDef.Unary == nil && fnDef.Function != nil { + return p.planCallVarArgs(expr, fnName, oName, fnDef, args) + } return p.planCallUnary(expr, fnName, oName, fnDef, args) case 2: + // If the FunctionOp has been used, then use it as it may exist for the purposes + // of dynamic dispatch within a singleton function implementation. + if fnDef != nil && fnDef.Binary == nil && fnDef.Function != nil { + return p.planCallVarArgs(expr, fnName, oName, fnDef, args) + } return p.planCallBinary(expr, fnName, oName, fnDef, args) default: return p.planCallVarArgs(expr, fnName, oName, fnDef, args) @@ -319,7 +330,7 @@ return nil, fmt.Errorf("no such overload: %s()", function) } return &evalZeroArity{ - id: expr.Id, + id: expr.GetId(), function: function, overload: overload, impl: impl.Function, @@ -344,7 +355,7 @@ nonStrict = impl.NonStrict } return &evalUnary{ - id: expr.Id, + id: expr.GetId(), function: function, overload: overload, arg: args[0], @@ -372,7 +383,7 @@ nonStrict = impl.NonStrict } return &evalBinary{ - id: expr.Id, + id: expr.GetId(), function: function, overload: overload, lhs: args[0], @@ -401,7 +412,7 @@ nonStrict = impl.NonStrict } return &evalVarArgs{ - id: expr.Id, + id: expr.GetId(), function: function, overload: overload, args: args, @@ -415,7 +426,7 @@ func (p *planner) planCallEqual(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) { return &evalEq{ - id: expr.Id, + id: expr.GetId(), lhs: args[0], rhs: args[1], }, nil @@ -425,7 +436,7 @@ func (p *planner) planCallNotEqual(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) { return &evalNe{ - id: expr.Id, + id: expr.GetId(), lhs: args[0], rhs: args[1], }, nil @@ -435,7 +446,7 @@ func (p *planner) planCallLogicalAnd(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) { return &evalAnd{ - id: expr.Id, + id: expr.GetId(), lhs: args[0], rhs: args[1], }, nil @@ -445,7 +456,7 @@ func (p *planner) planCallLogicalOr(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) { return &evalOr{ - id: expr.Id, + id: expr.GetId(), lhs: args[0], rhs: args[1], }, nil @@ -476,7 +487,7 @@ return &evalAttr{ adapter: p.adapter, - attr: p.attrFactory.ConditionalAttribute(expr.Id, cond, tAttr, fAttr), + attr: p.attrFactory.ConditionalAttribute(expr.GetId(), cond, tAttr, fAttr), }, nil } @@ -531,7 +542,7 @@ elems[i] = elemVal } return &evalList{ - id: expr.Id, + id: expr.GetId(), elems: elems, adapter: p.adapter, }, nil @@ -560,7 +571,7 @@ vals[i] = valVal } return &evalMap{ - id: expr.Id, + id: expr.GetId(), keys: keys, vals: vals, adapter: p.adapter, @@ -586,7 +597,7 @@ vals[i] = val } return &evalObj{ - id: expr.Id, + id: expr.GetId(), typeName: typeName, fields: fields, vals: vals, @@ -618,7 +629,7 @@ return nil, err } return &evalFold{ - id: expr.Id, + id: expr.GetId(), accuVar: fold.AccuVar, accu: accu, iterVar: fold.IterVar, @@ -636,12 +647,12 @@ if err != nil { return nil, err } - return NewConstValue(expr.Id, val), nil + return NewConstValue(expr.GetId(), 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) { + switch c.GetConstantKind().(type) { case *exprpb.Constant_BoolValue: return p.adapter.NativeToValue(c.GetBoolValue()), nil case *exprpb.Constant_BytesValue: diff -Nru golang-github-google-cel-go-0.11.4+ds/interpreter/prune.go golang-github-google-cel-go-0.12.5+ds/interpreter/prune.go --- golang-github-google-cel-go-0.11.4+ds/interpreter/prune.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/interpreter/prune.go 2022-12-20 15:30:36.000000000 +0000 @@ -41,17 +41,23 @@ // A) // 1) Evaluate expr with some unknowns, // 2) If result is unknown: -// a) PruneAst -// b) Goto 1 +// +// 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) +// +// 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. +// +// value. +// // 4) PruneAst // 4) Maybe cache the expression // This is effectively constant folding the expression. How the environment is @@ -232,9 +238,9 @@ // transform, or expression was not evaluated. If possible, drill down // more. - switch node.ExprKind.(type) { + switch node.GetExprKind().(type) { case *exprpb.Expr_SelectExpr: - if operand, pruned := p.prune(node.GetSelectExpr().Operand); pruned { + if operand, pruned := p.prune(node.GetSelectExpr().GetOperand()); pruned { return &exprpb.Expr{ Id: node.GetId(), ExprKind: &exprpb.Expr_SelectExpr{ diff -Nru golang-github-google-cel-go-0.11.4+ds/interpreter/runtimecost_test.go golang-github-google-cel-go-0.12.5+ds/interpreter/runtimecost_test.go --- golang-github-google-cel-go-0.11.4+ds/interpreter/runtimecost_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/interpreter/runtimecost_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -29,8 +29,8 @@ "github.com/google/cel-go/common/overloads" "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/parser" - "github.com/google/cel-go/test/proto3pb" + proto3pb "github.com/google/cel-go/test/proto3pb" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) diff -Nru golang-github-google-cel-go-0.11.4+ds/parser/helper.go golang-github-google-cel-go-0.12.5+ds/parser/helper.go --- golang-github-google-cel-go-0.11.4+ds/parser/helper.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/parser/helper.go 2022-12-20 15:30:36.000000000 +0000 @@ -217,7 +217,7 @@ return &exprpb.Expr{Id: expr.GetId()} } - switch expr.ExprKind.(type) { + switch expr.GetExprKind().(type) { case *exprpb.Expr_CallExpr: // Iterate the AST from `expr` recursively looking for macros. Because we are at most // starting from the top level macro, this recursion is bounded by the size of the AST. This @@ -435,6 +435,11 @@ return e.parserHelper.newIdent(e.nextMacroID(), name) } +// AccuIdent implements the ExprHelper interface method. +func (e *exprHelper) AccuIdent() *exprpb.Expr { + return e.parserHelper.newIdent(e.nextMacroID(), AccumulatorName) +} + // GlobalCall implements the ExprHelper interface method. func (e *exprHelper) GlobalCall(function string, args ...*exprpb.Expr) *exprpb.Expr { return e.parserHelper.newGlobalCall(e.nextMacroID(), function, args...) diff -Nru golang-github-google-cel-go-0.11.4+ds/parser/macro.go golang-github-google-cel-go-0.12.5+ds/parser/macro.go --- golang-github-google-cel-go-0.11.4+ds/parser/macro.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/parser/macro.go 2022-12-20 15:30:36.000000000 +0000 @@ -23,8 +23,6 @@ exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) -// TODO: Consider moving macros to common. - // NewGlobalMacro creates a Macro for a global function with the specified arg count. func NewGlobalMacro(function string, argCount int, expander MacroExpander) Macro { return ¯o{ @@ -50,8 +48,7 @@ varArgStyle: true} } -// NewReceiverVarArgMacro creates a Macro for a receiver function matching a variable arg -// count. +// NewReceiverVarArgMacro creates a Macro for a receiver function matching a variable arg count. func NewReceiverVarArgMacro(function string, expander MacroExpander) Macro { return ¯o{ function: function, @@ -135,9 +132,13 @@ return fmt.Sprintf("%s:*:%v", name, receiverStyle) } -// MacroExpander converts the target and args of a function call that matches a Macro. +// MacroExpander converts a call and its associated arguments into a new CEL abstract syntax tree, or an error +// if the input arguments are not suitable for the expansion requirements for the macro in question. +// +// The MacroExpander accepts as arguments a MacroExprHelper as well as the arguments used in the function call +// and produces as output an Expr ast node. // -// Note: when the Macros.IsReceiverStyle() is true, the target argument will be nil. +// Note: when the Macro.IsReceiverStyle() method returns true, the target argument will be nil. type MacroExpander func(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) @@ -208,6 +209,9 @@ // Ident creates an identifier Expr value. Ident(name string) *exprpb.Expr + // AccuIdent returns an accumulator identifier for use with comprehension results. + AccuIdent() *exprpb.Expr + // GlobalCall creates a function call Expr value for a global (free) function. GlobalCall(function string, args ...*exprpb.Expr) *exprpb.Expr @@ -225,34 +229,44 @@ } var ( + // HasMacro expands "has(m.f)" which tests the presence of a field, avoiding the need to + // specify the field as a string. + HasMacro = NewGlobalMacro(operators.Has, 1, MakeHas) + + // AllMacro expands "range.all(var, predicate)" into a comprehension which ensures that all + // elements in the range satisfy the predicate. + AllMacro = NewReceiverMacro(operators.All, 2, MakeAll) + + // ExistsMacro expands "range.exists(var, predicate)" into a comprehension which ensures that + // some element in the range satisfies the predicate. + ExistsMacro = NewReceiverMacro(operators.Exists, 2, MakeExists) + + // ExistsOneMacro expands "range.exists_one(var, predicate)", which is true if for exactly one + // element in range the predicate holds. + ExistsOneMacro = NewReceiverMacro(operators.ExistsOne, 2, MakeExistsOne) + + // MapMacro expands "range.map(var, function)" into a comprehension which applies the function + // to each element in the range to produce a new list. + MapMacro = NewReceiverMacro(operators.Map, 2, MakeMap) + + // MapFilterMacro expands "range.map(var, predicate, function)" into a comprehension which + // first filters the elements in the range by the predicate, then applies the transform function + // to produce a new list. + MapFilterMacro = NewReceiverMacro(operators.Map, 3, MakeMap) + + // FilterMacro expands "range.filter(var, predicate)" into a comprehension which filters + // elements in the range, producing a new list from the elements that satisfy the predicate. + FilterMacro = NewReceiverMacro(operators.Filter, 2, MakeFilter) + // AllMacros includes the list of all spec-supported macros. AllMacros = []Macro{ - // The macro "has(m.f)" which tests the presence of a field, avoiding the need to specify - // the field as a string. - NewGlobalMacro(operators.Has, 1, makeHas), - - // The macro "range.all(var, predicate)", which is true if for all elements in range the - // predicate holds. - NewReceiverMacro(operators.All, 2, makeAll), - - // The macro "range.exists(var, predicate)", which is true if for at least one element in - // range the predicate holds. - NewReceiverMacro(operators.Exists, 2, makeExists), - - // The macro "range.exists_one(var, predicate)", which is true if for exactly one element - // in range the predicate holds. - NewReceiverMacro(operators.ExistsOne, 2, makeExistsOne), - - // The macro "range.map(var, function)", applies the function to the vars in the range. - NewReceiverMacro(operators.Map, 2, makeMap), - - // The macro "range.map(var, predicate, function)", applies the function to the vars in - // the range for which the predicate holds true. The other variables are filtered out. - NewReceiverMacro(operators.Map, 3, makeMap), - - // The macro "range.filter(var, predicate)", filters out the variables for which the - // predicate is false. - NewReceiverMacro(operators.Filter, 2, makeFilter), + HasMacro, + AllMacro, + ExistsMacro, + ExistsOneMacro, + MapMacro, + MapFilterMacro, + FilterMacro, } // NoMacros list. @@ -270,62 +284,36 @@ quantifierExistsOne ) -func makeAll(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { +// MakeAll expands the input call arguments into a comprehension that returns true if all of the +// elements in the range match the predicate expressions: +// .all(, ) +func MakeAll(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { return makeQuantifier(quantifierAll, eh, target, args) } -func makeExists(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { +// MakeExists expands the input call arguments into a comprehension that returns true if any of the +// elements in the range match the predicate expressions: +// .exists(, ) +func MakeExists(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { return makeQuantifier(quantifierExists, eh, target, args) } -func makeExistsOne(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { +// MakeExistsOne expands the input call arguments into a comprehension that returns true if exactly +// one of the elements in the range match the predicate expressions: +// .exists_one(, ) +func MakeExistsOne(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { return makeQuantifier(quantifierExistsOne, eh, target, args) } -func makeQuantifier(kind quantifierKind, eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { - v, found := extractIdent(args[0]) - if !found { - location := eh.OffsetLocation(args[0].GetId()) - return nil, &common.Error{ - Message: "argument must be a simple name", - Location: location} - } - accuIdent := func() *exprpb.Expr { - return eh.Ident(AccumulatorName) - } - - var init *exprpb.Expr - var condition *exprpb.Expr - var step *exprpb.Expr - var result *exprpb.Expr - switch kind { - case quantifierAll: - init = eh.LiteralBool(true) - condition = eh.GlobalCall(operators.NotStrictlyFalse, accuIdent()) - step = eh.GlobalCall(operators.LogicalAnd, accuIdent(), args[1]) - result = accuIdent() - case quantifierExists: - init = eh.LiteralBool(false) - condition = eh.GlobalCall( - operators.NotStrictlyFalse, - eh.GlobalCall(operators.LogicalNot, accuIdent())) - step = eh.GlobalCall(operators.LogicalOr, accuIdent(), args[1]) - result = accuIdent() - case quantifierExistsOne: - zeroExpr := eh.LiteralInt(0) - oneExpr := eh.LiteralInt(1) - init = zeroExpr - condition = eh.LiteralBool(true) - step = eh.GlobalCall(operators.Conditional, args[1], - eh.GlobalCall(operators.Add, accuIdent(), oneExpr), accuIdent()) - result = eh.GlobalCall(operators.Equals, accuIdent(), oneExpr) - default: - return nil, &common.Error{Message: fmt.Sprintf("unrecognized quantifier '%v'", kind)} - } - return eh.Fold(v, target, AccumulatorName, init, condition, step, result), nil -} - -func makeMap(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { +// MakeMap expands the input call arguments into a comprehension that transforms each element in the +// input to produce an output list. +// +// There are two call patterns supported by map: +// .map(, ) +// .map(, , ) +// In the second form only iterVar values which return true when provided to the predicate expression +// are transformed. +func MakeMap(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { v, found := extractIdent(args[0]) if !found { return nil, &common.Error{Message: "argument is not an identifier"} @@ -345,7 +333,6 @@ accuExpr := eh.Ident(AccumulatorName) init := eh.NewList() condition := eh.LiteralBool(true) - // TODO: use compiler internal method for faster, stateful add. step := eh.GlobalCall(operators.Add, accuExpr, eh.NewList(fn)) if filter != nil { @@ -354,7 +341,10 @@ return eh.Fold(v, target, AccumulatorName, init, condition, step, accuExpr), nil } -func makeFilter(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { +// MakeFilter expands the input call arguments into a comprehension which produces a list which contains +// only elements which match the provided predicate expression: +// .filter(, ) +func MakeFilter(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { v, found := extractIdent(args[0]) if !found { return nil, &common.Error{Message: "argument is not an identifier"} @@ -364,12 +354,60 @@ accuExpr := eh.Ident(AccumulatorName) init := eh.NewList() condition := eh.LiteralBool(true) - // TODO: use compiler internal method for faster, stateful add. step := eh.GlobalCall(operators.Add, accuExpr, eh.NewList(args[0])) step = eh.GlobalCall(operators.Conditional, filter, step, accuExpr) return eh.Fold(v, target, AccumulatorName, init, condition, step, accuExpr), nil } +// MakeHas expands the input call arguments into a presence test, e.g. has(.field) +func MakeHas(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + if s, ok := args[0].ExprKind.(*exprpb.Expr_SelectExpr); ok { + return eh.PresenceTest(s.SelectExpr.GetOperand(), s.SelectExpr.GetField()), nil + } + return nil, &common.Error{Message: "invalid argument to has() macro"} +} + +func makeQuantifier(kind quantifierKind, eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + v, found := extractIdent(args[0]) + if !found { + location := eh.OffsetLocation(args[0].GetId()) + return nil, &common.Error{ + Message: "argument must be a simple name", + Location: location, + } + } + + var init *exprpb.Expr + var condition *exprpb.Expr + var step *exprpb.Expr + var result *exprpb.Expr + switch kind { + case quantifierAll: + init = eh.LiteralBool(true) + condition = eh.GlobalCall(operators.NotStrictlyFalse, eh.AccuIdent()) + step = eh.GlobalCall(operators.LogicalAnd, eh.AccuIdent(), args[1]) + result = eh.AccuIdent() + case quantifierExists: + init = eh.LiteralBool(false) + condition = eh.GlobalCall( + operators.NotStrictlyFalse, + eh.GlobalCall(operators.LogicalNot, eh.AccuIdent())) + step = eh.GlobalCall(operators.LogicalOr, eh.AccuIdent(), args[1]) + result = eh.AccuIdent() + case quantifierExistsOne: + zeroExpr := eh.LiteralInt(0) + oneExpr := eh.LiteralInt(1) + init = zeroExpr + condition = eh.LiteralBool(true) + step = eh.GlobalCall(operators.Conditional, args[1], + eh.GlobalCall(operators.Add, eh.AccuIdent(), oneExpr), eh.AccuIdent()) + result = eh.GlobalCall(operators.Equals, eh.AccuIdent(), oneExpr) + default: + return nil, &common.Error{Message: fmt.Sprintf("unrecognized quantifier '%v'", kind)} + } + return eh.Fold(v, target, AccumulatorName, init, condition, step, result), nil +} + func extractIdent(e *exprpb.Expr) (string, bool) { switch e.ExprKind.(type) { case *exprpb.Expr_IdentExpr: @@ -377,10 +415,3 @@ } return "", false } - -func makeHas(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { - if s, ok := args[0].ExprKind.(*exprpb.Expr_SelectExpr); ok { - return eh.PresenceTest(s.SelectExpr.GetOperand(), s.SelectExpr.GetField()), nil - } - return nil, &common.Error{Message: "invalid argument to has() macro"} -} diff -Nru golang-github-google-cel-go-0.11.4+ds/parser/parser.go golang-github-google-cel-go-0.12.5+ds/parser/parser.go --- golang-github-google-cel-go-0.11.4+ds/parser/parser.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/parser/parser.go 2022-12-20 15:30:36.000000000 +0000 @@ -46,7 +46,7 @@ } } if p.maxRecursionDepth == 0 { - p.maxRecursionDepth = 200 + p.maxRecursionDepth = 250 } if p.maxRecursionDepth == -1 { p.maxRecursionDepth = int((^uint(0)) >> 1) @@ -270,6 +270,7 @@ errors *parseErrors helper *parserHelper macros map[string]Macro + recursionDepth int maxRecursionDepth int errorRecoveryLimit int errorRecoveryLookaheadTokenLimit int @@ -352,6 +353,13 @@ // Visitor implementations. func (p *parser) Visit(tree antlr.ParseTree) interface{} { + p.recursionDepth++ + if p.recursionDepth > p.maxRecursionDepth { + panic(&recursionError{message: "max recursion depth exceeded"}) + } + defer func() { + p.recursionDepth-- + }() switch tree.(type) { case *gen.StartContext: return p.VisitStart(tree.(*gen.StartContext)) @@ -799,13 +807,13 @@ if e == nil { return "", false } - switch e.ExprKind.(type) { + switch e.GetExprKind().(type) { case *exprpb.Expr_IdentExpr: return e.GetIdentExpr().GetName(), true case *exprpb.Expr_SelectExpr: s := e.GetSelectExpr() - if prefix, found := p.extractQualifiedName(s.Operand); found { - return prefix + "." + s.Field, true + if prefix, found := p.extractQualifiedName(s.GetOperand()); found { + return prefix + "." + s.GetField(), true } } // TODO: Add a method to Source to get location from character offset. diff -Nru golang-github-google-cel-go-0.11.4+ds/parser/parser_test.go golang-github-google-cel-go-0.12.5+ds/parser/parser_test.go --- golang-github-google-cel-go-0.11.4+ds/parser/parser_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/parser/parser_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -1551,6 +1551,15 @@ a^#3:*expr.Expr_IdentExpr#.b^#4:*expr.Expr_SelectExpr# )^#5:has#`, }, + { + I: `y!=y!=y!=y!=y!=y!=y!=y!=y!=-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y + !=-y!=-y-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y + !=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y!=-y + !=-y-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y + !=-y!=-y-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y + !=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y!=-y!=-y-y!=-y`, + E: `ERROR: :-1:0: max recursion depth exceeded`, + }, } type testInfo struct { diff -Nru golang-github-google-cel-go-0.11.4+ds/parser/unparser.go golang-github-google-cel-go-0.12.5+ds/parser/unparser.go --- golang-github-google-cel-go-0.11.4+ds/parser/unparser.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/parser/unparser.go 2022-12-20 15:30:36.000000000 +0000 @@ -36,9 +36,29 @@ // - 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) +// +// This function optionally takes in one or more UnparserOption to alter the unparsing behavior, such as +// performing word wrapping on expressions. +func Unparse(expr *exprpb.Expr, info *exprpb.SourceInfo, opts ...UnparserOption) (string, error) { + unparserOpts := &unparserOption{ + wrapOnColumn: defaultWrapOnColumn, + wrapAfterColumnLimit: defaultWrapAfterColumnLimit, + operatorsToWrapOn: defaultOperatorsToWrapOn, + } + + var err error + for _, opt := range opts { + unparserOpts, err = opt(unparserOpts) + if err != nil { + return "", err + } + } + + un := &unparser{ + info: info, + options: unparserOpts, + } + err = un.visit(expr) if err != nil { return "", err } @@ -47,8 +67,10 @@ // unparser visits an expression to reconstruct a human-readable string from an AST. type unparser struct { - str strings.Builder - info *exprpb.SourceInfo + str strings.Builder + info *exprpb.SourceInfo + options *unparserOption + lastWrappedIndex int } func (un *unparser) visit(expr *exprpb.Expr) error { @@ -59,7 +81,7 @@ if visited || err != nil { return err } - switch expr.ExprKind.(type) { + switch expr.GetExprKind().(type) { case *exprpb.Expr_CallExpr: return un.visitCall(expr) case *exprpb.Expr_ConstExpr: @@ -135,9 +157,8 @@ if !found { return fmt.Errorf("cannot unmangle operator: %s", fun) } - un.str.WriteString(" ") - un.str.WriteString(unmangled) - un.str.WriteString(" ") + + un.writeOperatorWithWrapping(fun, unmangled) return un.visitMaybeNested(rhs, rhsParen) } @@ -151,7 +172,8 @@ if err != nil { return err } - un.str.WriteString(" ? ") + un.writeOperatorWithWrapping(operators.Conditional, "?") + // add parens if operand is a conditional itself. nested = isSamePrecedence(operators.Conditional, args[1]) || isComplexOperator(args[1]) @@ -159,6 +181,7 @@ if err != nil { return err } + un.str.WriteString(" : ") // add parens if operand is a conditional itself. nested = isSamePrecedence(operators.Conditional, args[2]) || @@ -226,7 +249,7 @@ func (un *unparser) visitConst(expr *exprpb.Expr) error { c := expr.GetConstExpr() - switch c.ConstantKind.(type) { + switch c.GetConstantKind().(type) { case *exprpb.Constant_BoolValue: un.str.WriteString(strconv.FormatBool(c.GetBoolValue())) case *exprpb.Constant_BytesValue: @@ -444,3 +467,130 @@ } return b.String() } + +// writeOperatorWithWrapping outputs the operator and inserts a newline for operators configured +// in the unparser options. +func (un *unparser) writeOperatorWithWrapping(fun string, unmangled string) bool { + _, wrapOperatorExists := un.options.operatorsToWrapOn[fun] + lineLength := un.str.Len() - un.lastWrappedIndex + len(fun) + + if wrapOperatorExists && lineLength >= un.options.wrapOnColumn { + un.lastWrappedIndex = un.str.Len() + // wrapAfterColumnLimit flag dictates whether the newline is placed + // before or after the operator + if un.options.wrapAfterColumnLimit { + // Input: a && b + // Output: a &&\nb + un.str.WriteString(" ") + un.str.WriteString(unmangled) + un.str.WriteString("\n") + } else { + // Input: a && b + // Output: a\n&& b + un.str.WriteString("\n") + un.str.WriteString(unmangled) + un.str.WriteString(" ") + } + return true + } else { + un.str.WriteString(" ") + un.str.WriteString(unmangled) + un.str.WriteString(" ") + } + return false +} + +// Defined defaults for the unparser options +var ( + defaultWrapOnColumn = 80 + defaultWrapAfterColumnLimit = true + defaultOperatorsToWrapOn = map[string]bool{ + operators.LogicalAnd: true, + operators.LogicalOr: true, + } +) + +// UnparserOption is a functional option for configuring the output formatting +// of the Unparse function. +type UnparserOption func(*unparserOption) (*unparserOption, error) + +// Internal representation of the UnparserOption type +type unparserOption struct { + wrapOnColumn int + operatorsToWrapOn map[string]bool + wrapAfterColumnLimit bool +} + +// WrapOnColumn wraps the output expression when its string length exceeds a specified limit +// for operators set by WrapOnOperators function or by default, "&&" and "||" will be wrapped. +// +// Example usage: +// +// Unparse(expr, sourceInfo, WrapOnColumn(40), WrapOnOperators(Operators.LogicalAnd)) +// +// This will insert a newline immediately after the logical AND operator for the below example input: +// +// Input: +// 'my-principal-group' in request.auth.claims && request.auth.claims.iat > now - duration('5m') +// +// Output: +// 'my-principal-group' in request.auth.claims && +// request.auth.claims.iat > now - duration('5m') +func WrapOnColumn(col int) UnparserOption { + return func(opt *unparserOption) (*unparserOption, error) { + if col < 1 { + return nil, fmt.Errorf("Invalid unparser option. Wrap column value must be greater than or equal to 1. Got %v instead", col) + } + opt.wrapOnColumn = col + return opt, nil + } +} + +// WrapOnOperators specifies which operators to perform word wrapping on an output expression when its string length +// exceeds the column limit set by WrapOnColumn function. +// +// Word wrapping is supported on non-unary symbolic operators. Refer to operators.go for the full list +// +// This will replace any previously supplied operators instead of merging them. +func WrapOnOperators(symbols ...string) UnparserOption { + return func(opt *unparserOption) (*unparserOption, error) { + opt.operatorsToWrapOn = make(map[string]bool) + for _, symbol := range symbols { + _, found := operators.FindReverse(symbol) + if !found { + return nil, fmt.Errorf("Invalid unparser option. Unsupported operator: %s", symbol) + } + arity := operators.Arity(symbol) + if arity < 2 { + return nil, fmt.Errorf("Invalid unparser option. Unary operators are unsupported: %s", symbol) + } + + opt.operatorsToWrapOn[symbol] = true + } + + return opt, nil + } +} + +// WrapAfterColumnLimit dictates whether to insert a newline before or after the specified operator +// when word wrapping is performed. +// +// Example usage: +// +// Unparse(expr, sourceInfo, WrapOnColumn(40), WrapOnOperators(Operators.LogicalAnd), WrapAfterColumnLimit(false)) +// +// This will insert a newline immediately before the logical AND operator for the below example input, ensuring +// that the length of a line never exceeds the specified column limit: +// +// Input: +// 'my-principal-group' in request.auth.claims && request.auth.claims.iat > now - duration('5m') +// +// Output: +// 'my-principal-group' in request.auth.claims +// && request.auth.claims.iat > now - duration('5m') +func WrapAfterColumnLimit(wrapAfter bool) UnparserOption { + return func(opt *unparserOption) (*unparserOption, error) { + opt.wrapAfterColumnLimit = wrapAfter + return opt, nil + } +} diff -Nru golang-github-google-cel-go-0.11.4+ds/parser/unparser_test.go golang-github-google-cel-go-0.12.5+ds/parser/unparser_test.go --- golang-github-google-cel-go-0.11.4+ds/parser/unparser_test.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/parser/unparser_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -20,6 +20,8 @@ "testing" "github.com/google/cel-go/common" + "github.com/google/cel-go/common/operators" + "google.golang.org/protobuf/proto" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" @@ -31,6 +33,7 @@ in string out interface{} requiresMacroCalls bool + unparserOptions []UnparserOption }{ {name: "call_add", in: `a + b - c`}, {name: "call_and", in: `a && b && c && d && e`}, @@ -138,6 +141,281 @@ in: `[1, 2, 3].map(x, x >= 2, x * 4).filter(x, x <= 10)`, requiresMacroCalls: true, }, + + // These expressions will not be wrapped because they haven't met the + // conditions required by the provided unparser options + { + name: "call_no_wrap_no_operators", + in: "a + b + c + d", + out: "a + b + c + d", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + }, + }, + { + name: "call_no_wrap_column_limit_large_val", + in: "a + b + c + d", + out: "a + b + c + d", + unparserOptions: []UnparserOption{ + WrapOnColumn(1000), + WrapOnOperators(operators.Add), + }, + }, + { + name: "call_no_wrap_column_limit_equal_length_to_input", + in: "a + b + c + d", + out: "a + b + c + d", + unparserOptions: []UnparserOption{ + WrapOnColumn(13), + WrapOnOperators(operators.Add), + }, + }, + + // These expressions will be formatted based on the unparser options provided + { + name: "call_wrap_add", + in: "a + b - d * e", + out: "a +\nb - d * e", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.Add), + }, + }, + { + name: "call_wrap_add_subtract", + in: "a * b + c - d * e", + out: "a * b +\nc -\nd * e", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.Add, operators.Subtract), + }, + }, + { + name: "call_wrap_add_subtract", + in: "a * b + c - d * e", + out: "a * b +\nc -\nd * e", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.Add, operators.Subtract), + }, + }, + { + name: "call_wrap_logical_and", + in: "a && b && c && d && e", + out: "a &&\nb &&\nc &&\nd &&\ne", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.LogicalAnd), + }, + }, + { + name: "call_wrap_logical_and_2", + in: "a && b", + out: "a &&\nb", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.LogicalAnd), + }, + }, + { + name: "call_wrap_conditional", + in: "a ? b : c ? d : e", + out: "a ?\nb : (c ?\nd : e)", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.Conditional), + }, + }, + { + name: "call_wrap_or", + in: "a || b || c || d || e", + out: "a ||\nb ||\nc ||\nd ||\ne", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.LogicalOr), + }, + }, + { + name: "call_wrap_equals", + in: "a == b == c == d == e", + out: "a ==\nb ==\nc ==\nd ==\ne", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.Equals), + }, + }, + { + name: "call_wrap_greater", + in: "a > b > c > d > e", + out: "a >\nb >\nc >\nd >\ne", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.Greater), + }, + }, + { + name: "call_wrap_greater_equals", + in: "a >= b >= c >= d >= e", + out: "a >=\nb >=\nc >=\nd >=\ne", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.GreaterEquals), + }, + }, + { + name: "call_wrap_in", + in: "a in b in c in d in e", + out: "a in\nb in\nc in\nd in\ne", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.In), + }, + }, + { + name: "call_wrap_less", + in: "a < b < c < d < e", + out: "a <\nb <\nc <\nd <\ne", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.Less), + }, + }, + { + name: "call_wrap_less_equals", + in: "a <= b <= c <= d <= e", + out: "a <=\nb <=\nc <=\nd <=\ne", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.LessEquals), + }, + }, + { + name: "call_wrap_not_equals", + in: "a != b != c != d != e", + out: "a !=\nb !=\nc !=\nd !=\ne", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.NotEquals), + }, + }, + { + name: "call_wrap_divide", + in: "a / b / c / d / e", + out: "a /\nb /\nc /\nd /\ne", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.Divide), + }, + }, + { + name: "call_wrap_modulo", + in: "a % b % c % d % e", + out: "a %\nb %\nc %\nd %\ne", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.Modulo), + }, + }, + { + name: "call_wrap_multiply", + in: "a * b * c * d * e", + out: "a *\nb *\nc *\nd *\ne", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.Multiply), + }, + }, + { + name: "call_wrap_logical_and_long_variables", + in: "longVariableA && longVariableB && longVariableC", + out: "longVariableA &&\nlongVariableB &&\nlongVariableC", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.LogicalAnd), + }, + }, + { + name: "comp_chained_wrap_comparisons", + in: "[1, 2, 3].map(x, x >= 2, x * 4).filter(x, x <= 10)", + out: "[1, 2, 3].map(x, x >=\n2, x * 4).filter(x, x <=\n10)", + requiresMacroCalls: true, + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.GreaterEquals, operators.LessEquals), + }, + }, + { + name: "call_wrap_before_add", + in: "a + b - d * e", + out: "a\n+ b - d * e", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.Add), + WrapAfterColumnLimit(false), + }, + }, + { + name: "call_wrap_before_add_subtract", + in: "a * b + c - d * e", + out: "a * b\n+ c\n- d * e", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.Add, operators.Subtract), + WrapAfterColumnLimit(false), + }, + }, + { + name: "call_wrap_logical_and_long_variables", + in: "longVariableA && longVariableB && longVariableC", + out: "longVariableA\n&& longVariableB\n&& longVariableC", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + WrapOnOperators(operators.LogicalAnd), + WrapAfterColumnLimit(false), + }, + }, + { + name: "call_wrap_logical_and_long_input", + in: `"my-principal-group" in request.auth.claims && request.auth.claims.iat > now - duration("5m")`, + out: `"my-principal-group" in request.auth.claims &&` + "\n" + `request.auth.claims.iat > now - duration("5m")`, + unparserOptions: []UnparserOption{ + WrapOnColumn(40), + WrapOnOperators(operators.LogicalAnd), + }, + }, + { + name: "call_wrap_before_logical_and_long_input", + in: `"my-principal-group" in request.auth.claims && request.auth.claims.iat > now - duration("5m")`, + out: `"my-principal-group" in request.auth.claims` + "\n" + `&& request.auth.claims.iat > now - duration("5m")`, + unparserOptions: []UnparserOption{ + WrapOnColumn(40), + WrapOnOperators(operators.LogicalAnd), + WrapAfterColumnLimit(false), + }, + }, + { + // By default: + // - Column limit is at 80 + // - && and || are wrapped + // - Wrapping occurs after the symbol + name: "call_wrap_default", + in: `jwt.extra_claims.filter(c, c.startsWith("group")).all(c, jwt.extra_claims[c].all(g, g.endsWith("@acme.co"))) && jwt.extra_claims.exists(c, c.startsWith("group")) || request.auth.claims.group == "admin" || request.auth.principal == "user:me@acme.co"`, + out: `jwt.extra_claims.filter(c, c.startsWith("group")).all(c, jwt.extra_claims[c].all(g, g.endsWith("@acme.co"))) &&` + + "\n" + + `jwt.extra_claims.exists(c, c.startsWith("group")) || request.auth.claims.group == "admin" ||` + + "\n" + + `request.auth.principal == "user:me@acme.co"`, + requiresMacroCalls: true, + }, + { + // && and || are wrapped by default if only the column limit is specified + name: "call_wrap_default_operators", + in: "longVariableA && longVariableB || longVariableC + longVariableD - longVariableE", + out: "longVariableA &&\nlongVariableB ||\nlongVariableC + longVariableD - longVariableE", + unparserOptions: []UnparserOption{ + WrapOnColumn(3), + }, + }, } for _, tst := range tests { @@ -154,7 +432,8 @@ if len(iss.GetErrors()) > 0 { t.Fatalf("parser.Parse(%s) failed: %v", tc.in, iss.ToDisplayString()) } - out, err := Unparse(p.GetExpr(), p.GetSourceInfo()) + out, err := Unparse(p.GetExpr(), p.GetSourceInfo(), tc.unparserOptions...) + if err != nil { t.Fatalf("Unparse(%s) failed: %v", tc.in, err) } @@ -179,10 +458,18 @@ } func TestUnparseErrors(t *testing.T) { + validConstantExpression := &exprpb.Expr{ + ExprKind: &exprpb.Expr_ConstExpr{ + ConstExpr: &exprpb.Constant{ + ConstantKind: &exprpb.Constant_NullValue{}, + }, + }, + } tests := []struct { - name string - in *exprpb.Expr - err error + name string + in *exprpb.Expr + err error + unparserOptions []UnparserOption }{ {name: "empty_expr", in: &exprpb.Expr{}, err: errors.New("unsupported expression")}, { @@ -245,12 +532,44 @@ }, err: errors.New("unsupported expression"), }, + { + name: "bad_unparser_option_wrap_column_zero", + in: validConstantExpression, + err: errors.New("Invalid unparser option. Wrap column value must be greater than or equal to 1. Got 0 instead"), + unparserOptions: []UnparserOption{ + WrapOnColumn(0), + }, + }, + { + name: "bad_unparser_option_wrap_column_negative", + in: validConstantExpression, + err: errors.New("Invalid unparser option. Wrap column value must be greater than or equal to 1. Got -1 instead"), + unparserOptions: []UnparserOption{ + WrapOnColumn(-1), + }, + }, + { + name: "bad_unparser_option_unsupported_operator", + in: validConstantExpression, + err: errors.New("Invalid unparser option. Unsupported operator: bogus"), + unparserOptions: []UnparserOption{ + WrapOnOperators("bogus"), + }, + }, + { + name: "bad_unparser_option_unary_operator", + in: validConstantExpression, + err: errors.New("Invalid unparser option. Unary operators are unsupported: " + operators.Negate), + unparserOptions: []UnparserOption{ + WrapOnOperators(operators.Negate), + }, + }, } for _, tst := range tests { tc := tst t.Run(tc.name, func(t *testing.T) { - out, err := Unparse(tc.in, &exprpb.SourceInfo{}) + out, err := Unparse(tc.in, &exprpb.SourceInfo{}, tc.unparserOptions...) if err == nil { t.Fatalf("Unparse(%v) got %v, wanted error %v", tc.in, out, tc.err) } diff -Nru golang-github-google-cel-go-0.11.4+ds/README.md golang-github-google-cel-go-0.12.5+ds/README.md --- golang-github-google-cel-go-0.11.4+ds/README.md 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/README.md 2022-12-20 15:30:36.000000000 +0000 @@ -60,15 +60,12 @@ environment option: ```go -import( - "github.com/google/cel-go/cel" - "github.com/google/cel-go/checker/decls" -) +import "github.com/google/cel-go/cel" env, err := cel.NewEnv( - cel.Declarations( - decls.NewVar("name", decls.String), - decls.NewVar("group", decls.String))) + cel.Variable("name", cel.StringType), + cel.Variable("group", cel.StringType), +) ``` That's it. The environment is ready to be use for parsing and type-checking. diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/BUILD.bazel golang-github-google-cel-go-0.12.5+ds/repl/BUILD.bazel --- golang-github-google-cel-go-0.11.4+ds/repl/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/BUILD.bazel 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,61 @@ +# Copyright 2022 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 +# +# https://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. + +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +package( + default_visibility = ["//repl:__subpackages__"], + licenses = ["notice"], +) + +go_library( + name = "go_default_library", + srcs = [ + "commands.go", + "evaluator.go", + "typefmt.go", + ], + importpath = "github.com/google/cel-go/repl", + deps = [ + "//cel:go_default_library", + "//checker/decls:go_default_library", + "//common/types:go_default_library", + "//common/types/ref:go_default_library", + "//interpreter:go_default_library", + "//interpreter/functions:go_default_library", + "//repl/parser:go_default_library", + "@com_github_antlr_antlr4_runtime_go_antlr//:go_default_library", + "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_protobuf//encoding/prototext:go_default_library", + "@org_golang_google_protobuf//proto:go_default_library", + "@org_golang_google_protobuf//types/descriptorpb:go_default_library", + ], +) + +go_test( + name = "go_default_test", + size = "small", + srcs = [ + "commands_test.go", + "evaluator_test.go", + "typefmt_test.go", + ], + data = glob(["testdata/**"]), + embed = [":go_default_library"], + deps = [ + "//cel:go_default_library", + "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_protobuf//proto:go_default_library", + ], +) diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/commands.go golang-github-google-cel-go-0.12.5+ds/repl/commands.go --- golang-github-google-cel-go-0.11.4+ds/repl/commands.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/commands.go 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,326 @@ +// Copyright 2022 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 +// +// https://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 repl + +import ( + "errors" + "fmt" + "strings" + + "github.com/google/cel-go/repl/parser" + + "github.com/antlr/antlr4/runtime/Go/antlr" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +var letUsage = `Let introduces a variable or function defined by a sub-CEL expression. +%let (: )? = +%let ( : , ...) : -> ` + +var declareUsage = `Declare introduces a variable or function for type checking, but doesn't define a value for it. +%declare : +%declare ( : , ...) : +` +var deleteUsage = `Delete removes a variable or function declaration from the evaluation context. +%delete ` + +type letVarCmd struct { + identifier string + typeHint *exprpb.Type + src string +} + +type letFnCmd struct { + identifier string + resultType *exprpb.Type + params []letFunctionParam + src string +} + +type delCmd struct { + identifier string +} + +type simpleCmd struct { + cmd string + args []string +} + +type evalCmd struct { + expr string +} + +// Cmder interface provides normalized command name from a repl command. +// Command specifics are available via checked type casting to the specific +// command type. +type Cmder interface { + // Cmd returns the normalized name for the command. + Cmd() string +} + +func (c *letVarCmd) Cmd() string { + if c.src == "" { + return "declare" + } + return "let" +} + +func (c *letFnCmd) Cmd() string { + if c.src == "" { + return "declare" + } + return "let" +} + +func (c *delCmd) Cmd() string { + return "delete" +} + +func (c *simpleCmd) Cmd() string { + return c.cmd +} + +func (c *evalCmd) Cmd() string { + return "eval" +} + +type commandParseListener struct { + antlr.DefaultErrorListener + parser.BaseCommandsListener + + errs []error + cmd Cmder + usage string +} + +func (c *commandParseListener) reportIssue(e error) { + c.errs = append(c.errs, e) +} + +// extractSourceText extracts original text from a parse rule match. +// Preserves original whitespace if possible. +func extractSourceText(ctx antlr.ParserRuleContext) string { + if ctx.GetStart() == nil || ctx.GetStop() == nil || + ctx.GetStart().GetStart() < 0 || ctx.GetStop().GetStop() < 0 { + // fallback to the normalized parse + return ctx.GetText() + } + s, e := ctx.GetStart().GetStart(), ctx.GetStop().GetStop() + return ctx.GetStart().GetInputStream().GetText(s, e) +} + +// Parse parses a repl command line into a command object. This provides +// the normalized command name plus any parsed parameters (e.g. variable names +// in let statements). +// +// An error is returned if the statement isn't well formed. See the parser +// pacakage for details on the antlr grammar. +func Parse(line string) (Cmder, error) { + line = strings.TrimSpace(line) + listener := &commandParseListener{} + is := antlr.NewInputStream(line) + lexer := parser.NewCommandsLexer(is) + lexer.RemoveErrorListeners() + lexer.AddErrorListener(listener) + p := parser.NewCommandsParser(antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)) + p.RemoveErrorListeners() + p.AddErrorListener(listener) + + antlr.ParseTreeWalkerDefault.Walk(listener, p.StartCommand()) + + if len(listener.errs) > 0 { + errFmt := make([]string, len(listener.errs)) + for i, err := range listener.errs { + errFmt[i] = err.Error() + } + + if listener.usage != "" { + errFmt = append(errFmt, "", "Usage:", listener.usage) + } + return nil, errors.New(strings.Join(errFmt, "\n")) + } + + return listener.cmd, nil +} + +// ANTLR interface implementations + +// Implement antlr ErrorListener interface for syntax errors. +func (c *commandParseListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) { + c.errs = append(c.errs, fmt.Errorf("(%d:%d) %s", line, column, msg)) +} + +// Implement ANTLR interface for commands listener. +func (c *commandParseListener) EnterSimple(ctx *parser.SimpleContext) { + cmd := "undefined" + if ctx.GetCmd() != nil { + cmd = ctx.GetCmd().GetText()[1:] + } + var args []string + for _, arg := range ctx.GetArgs() { + a := arg.GetText() + if strings.HasPrefix(a, "-") { + a = "--" + strings.ToLower(strings.TrimLeft(a, "-")) + } else { + a = strings.Trim(a, "\"'") + } + args = append(args, a) + + } + c.cmd = &simpleCmd{cmd: cmd, args: args} +} + +func (c *commandParseListener) EnterEmpty(ctx *parser.EmptyContext) { + c.cmd = &simpleCmd{cmd: "null"} +} + +func (c *commandParseListener) EnterLet(ctx *parser.LetContext) { + c.usage = letUsage + if ctx.GetFn() != nil { + c.cmd = &letFnCmd{} + } else if ctx.GetVar() != nil { + c.cmd = &letVarCmd{} + } else { + c.errs = append(c.errs, fmt.Errorf("missing declaration in let")) + } +} + +func (c *commandParseListener) EnterDeclare(ctx *parser.DeclareContext) { + c.usage = declareUsage + if ctx.GetFn() != nil { + c.cmd = &letFnCmd{} + } else if ctx.GetVar() != nil { + c.cmd = &letVarCmd{} + } else { + c.errs = append(c.errs, fmt.Errorf("missing declaration in declare")) + } +} + +func (c *commandParseListener) ExitDeclare(ctx *parser.DeclareContext) { + var typeHint *exprpb.Type + switch cmd := c.cmd.(type) { + case *letVarCmd: + typeHint = cmd.typeHint + case *letFnCmd: + typeHint = cmd.resultType + } + if typeHint == nil { + c.reportIssue(errors.New("result type required for declare")) + } +} + +func (c *commandParseListener) EnterDelete(ctx *parser.DeleteContext) { + c.usage = deleteUsage + if ctx.GetVar() == nil && ctx.GetFn() == nil { + c.reportIssue(errors.New("missing identifier in delete")) + return + } + c.cmd = &delCmd{} +} + +func (c *commandParseListener) EnterExprCmd(ctx *parser.ExprCmdContext) { + c.cmd = &evalCmd{} +} + +func (c *commandParseListener) ExitFnDecl(ctx *parser.FnDeclContext) { + switch cmd := c.cmd.(type) { + case *letFnCmd: + if ctx.GetId() == nil { + c.reportIssue(errors.New("missing identifier in function declaration")) + return + } + if ctx.GetRType() == nil { + c.reportIssue(errors.New("missing result type in function declaration")) + return + } + cmd.identifier = ctx.GetId().GetText() + ty, err := ParseType(ctx.GetRType().GetText()) + if err != nil { + c.reportIssue(err) + } + for _, p := range ctx.GetParams() { + if p.GetT() == nil { + c.reportIssue(errors.New("missing type in function param declaration")) + continue + } + if p.GetPid() == nil { + c.reportIssue(errors.New("missing identifier in function param declaration")) + } + ty, err := ParseType(p.GetT().GetText()) + if err != nil { + c.reportIssue(err) + } + cmd.params = append(cmd.params, letFunctionParam{ + identifier: p.GetPid().GetText(), + typeHint: ty, + }) + + } + cmd.resultType = ty + case *delCmd: + if ctx.GetId() == nil { + c.reportIssue(errors.New("missing identifier in delete")) + } + cmd.identifier = ctx.GetId().GetText() + default: + c.reportIssue(errors.New("unexepected function declaration")) + } +} + +func (c *commandParseListener) ExitQualId(ctx *parser.QualIdContext) { + if ctx.GetRid() == nil { + c.reportIssue(errors.New("missing root identifier")) + } +} + +func (c *commandParseListener) ExitVarDecl(ctx *parser.VarDeclContext) { + switch cmd := c.cmd.(type) { + case *letVarCmd: + if ctx.GetId() == nil { + c.reportIssue(errors.New("no identifier in variable declaration")) + return + } + cmd.identifier = ctx.GetId().GetText() + if ctx.GetT() != nil { + ty, err := ParseType(ctx.GetT().GetText()) + if err != nil { + c.reportIssue(err) + } + cmd.typeHint = ty + } + case *delCmd: + if ctx.GetId() == nil { + c.reportIssue(errors.New("missing identifier in delete")) + } + cmd.identifier = ctx.GetId().GetText() + default: + c.reportIssue(errors.New("unexpected var declaration")) + } +} + +func (c *commandParseListener) ExitExpr(ctx *parser.ExprContext) { + expr := extractSourceText(ctx) + switch cmd := c.cmd.(type) { + case *evalCmd: + cmd.expr = expr + case *letFnCmd: + cmd.src = expr + case *letVarCmd: + cmd.src = expr + default: + c.reportIssue(errors.New("unexpected CEL expression")) + } +} diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/commands_test.go golang-github-google-cel-go-0.12.5+ds/repl/commands_test.go --- golang-github-google-cel-go-0.11.4+ds/repl/commands_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/commands_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,297 @@ +// Copyright 2022 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 +// +// https://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 repl + +import ( + "fmt" + "strings" + "testing" + + "google.golang.org/protobuf/proto" +) + +func cmdMatches(t testing.TB, got Cmder, expected Cmder) (result bool) { + t.Helper() + + defer func() { + // catch type assertion errors + if v := recover(); v != nil { + result = false + } + }() + + switch want := expected.(type) { + case *evalCmd: + gotEval := got.(*evalCmd) + return gotEval.expr == want.expr + case *delCmd: + gotDel := got.(*delCmd) + return gotDel.identifier == want.identifier + case *simpleCmd: + gotSimple := got.(*simpleCmd) + if len(gotSimple.args) != len(want.args) { + return false + } + for i, a := range want.args { + if gotSimple.args[i] != a { + return false + } + } + return gotSimple.cmd == want.cmd + case *letFnCmd: + gotLetFn := got.(*letFnCmd) + if gotLetFn.identifier != want.identifier || + gotLetFn.src != want.src || + !proto.Equal(gotLetFn.resultType, want.resultType) || + len(gotLetFn.params) != len(want.params) { + return false + } + for i, wantP := range want.params { + if gotLetFn.params[i].identifier != wantP.identifier || + !proto.Equal(gotLetFn.params[i].typeHint, wantP.typeHint) { + return false + } + } + return true + case *letVarCmd: + gotLetVar := got.(*letVarCmd) + return gotLetVar.identifier == want.identifier && + proto.Equal(gotLetVar.typeHint, want.typeHint) && + gotLetVar.src == want.src + } + return false +} + +func (c *evalCmd) String() string { + return fmt.Sprintf("%%eval %s", c.expr) +} + +func (c *letVarCmd) String() string { + return fmt.Sprintf("%%let %s : %s = %s", c.identifier, UnparseType(c.typeHint), c.src) +} + +func fmtParam(p letFunctionParam) string { + return fmt.Sprintf("%s : %s", p.identifier, UnparseType(p.typeHint)) +} + +func fmtParams(ps []letFunctionParam) string { + buf := make([]string, len(ps)) + for i, p := range ps { + buf[i] = fmtParam(p) + } + return strings.Join(buf, ", ") +} + +func (c *letFnCmd) String() string { + return fmt.Sprintf("%%let %s (%s) : %s -> %s", c.identifier, fmtParams(c.params), UnparseType(c.resultType), c.src) +} + +func (c *delCmd) String() string { + return fmt.Sprintf("%%delete %s", c.identifier) +} + +func (c *simpleCmd) String() string { + flagFmt := strings.Join(c.args, " ") + return fmt.Sprintf("%%%s %s", c.cmd, flagFmt) +} + +func TestParse(t *testing.T) { + var testCases = []struct { + commandLine string + wantCmd Cmder + }{ + { + commandLine: "%let x = 1", + wantCmd: &letVarCmd{ + identifier: "x", + typeHint: nil, + src: "1", + }, + }, + { + commandLine: "%let com.google.x = 1", + wantCmd: &letVarCmd{ + identifier: "com.google.x", + typeHint: nil, + src: "1", + }, + }, + { + commandLine: "%let x: int = 1", + wantCmd: &letVarCmd{ + identifier: "x", + typeHint: mustParseType(t, "int"), + src: "1", + }, + }, + { + commandLine: `%eval x + 2`, + wantCmd: &evalCmd{expr: "x + 2"}, + }, + { + commandLine: "x + 2", + wantCmd: &evalCmd{expr: "x + 2"}, + }, + { + commandLine: `%exit`, + wantCmd: &simpleCmd{cmd: "exit"}, + }, + { + commandLine: `%arbitrary --flag -FLAG 'string literal\n'`, + wantCmd: &simpleCmd{cmd: "arbitrary", + args: []string{ + "--flag", "--flag", "string literal\\n", + }, + }, + }, + { + commandLine: " ", + wantCmd: &simpleCmd{cmd: "null"}, + }, + { + commandLine: `%delete x`, + wantCmd: &delCmd{identifier: "x"}, + }, + { + commandLine: `%delete com.google.x`, + wantCmd: &delCmd{identifier: "com.google.x"}, + }, + { + commandLine: `%declare x: int`, + wantCmd: &letVarCmd{ + identifier: "x", + typeHint: mustParseType(t, "int"), + src: "", + }, + }, + { + commandLine: `%let fn (x : int) : int -> x + 2`, + wantCmd: &letFnCmd{ + identifier: "fn", + params: []letFunctionParam{ + {identifier: "x", typeHint: mustParseType(t, "int")}, + }, + resultType: mustParseType(t, "int"), + src: "x + 2", + }, + }, + { + commandLine: `%let int.plus (x : int) : int -> this + x`, + wantCmd: &letFnCmd{ + identifier: "int.plus", + params: []letFunctionParam{ + {identifier: "x", typeHint: mustParseType(t, "int")}, + }, + resultType: mustParseType(t, "int"), + src: "this + x", + }, + }, + { + commandLine: `%let fn () : int -> 2 + 2`, + wantCmd: &letFnCmd{ + identifier: "fn", + params: []letFunctionParam{}, + resultType: mustParseType(t, "int"), + src: "2 + 2", + }, + }, + { + commandLine: `%let fn (x:int, y :int) : int -> x + y`, + wantCmd: &letFnCmd{ + identifier: "fn", + params: []letFunctionParam{ + {identifier: "x", typeHint: mustParseType(t, "int")}, + {identifier: "y", typeHint: mustParseType(t, "int")}, + }, + resultType: mustParseType(t, "int"), + src: "x + y", + }, + }, + { + commandLine: `%declare fn (x : int) : int`, + wantCmd: &letFnCmd{ + identifier: "fn", + params: []letFunctionParam{ + {identifier: "x", typeHint: mustParseType(t, "int")}, + }, + resultType: mustParseType(t, "int"), + src: "", + }, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.commandLine, func(t *testing.T) { + cmd, err := Parse(tc.commandLine) + if err != nil { + t.Errorf("Parse(\"%s\") failed: %s", tc.commandLine, err) + } + if cmd == nil || !cmdMatches(t, cmd, tc.wantCmd) { + t.Errorf("Parse('%s') got (%s) wanted (%s)", tc.commandLine, + cmd, tc.wantCmd) + } + }) + } +} + +func TestParseErrors(t *testing.T) { + var testCases = []struct { + commandLine string + }{ + { + // not an identifier + commandLine: "%let 123 = 1", + }, + { + // no assignment + commandLine: "%let x: int", + }, + { + // no assignment + commandLine: "%let fn() : int", + }, + { + // missing types + commandLine: "%let fn (x) -> x + 1", + }, + { + // missing arg id + commandLine: "%let fn (: int) : int -> x + 1", + }, + { + // type required for declare + commandLine: "%declare x", + }, + { + // not an identifier + commandLine: "%declare 123", + }, + { + // not an identifier + commandLine: "%declare 1() : int", + }, + { + // not an identifier + commandLine: "%delete 123", + }, + } + for _, tc := range testCases { + _, err := Parse(tc.commandLine) + if err == nil { + t.Errorf("Parse(\"%s\") ok wanted error", tc.commandLine) + } + } +} diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/evaluator.go golang-github-google-cel-go-0.12.5+ds/repl/evaluator.go --- golang-github-google-cel-go-0.11.4+ds/repl/evaluator.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/evaluator.go 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,836 @@ +// Copyright 2022 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 +// +// https://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 repl defines a set of utilities for working with command line processing of CEL. +package repl + +import ( + "errors" + "fmt" + "io/ioutil" + "strings" + + "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" + "github.com/google/cel-go/interpreter/functions" + + "google.golang.org/protobuf/encoding/prototext" + "google.golang.org/protobuf/proto" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + descpb "google.golang.org/protobuf/types/descriptorpb" +) + +// letVariable let variable representation +type letVariable struct { + identifier string + src string + typeHint *exprpb.Type + + // memoized results from building the expression AST and program + resultType *exprpb.Type + env *cel.Env + ast *cel.Ast + prog cel.Program +} + +type letFunctionParam struct { + identifier string + typeHint *exprpb.Type +} + +// letFunction coordinates let function data (type definition and CEL function implementation). +type letFunction struct { + identifier string + src string + resultType *exprpb.Type + params []letFunctionParam + receiver *exprpb.Type // if not nil indicates an instance function + + // memoized results from building the expression AST and program + env *cel.Env // the context env for repl evaluation + fnEnv *cel.Env // the env for implementing the extension fn + prog cel.Program + impl functions.FunctionOp +} + +func typeAssignable(rtType ref.Type, declType *exprpb.Type) bool { + // TODO(issue/535): add better type agreement support + return UnparseType(declType) == rtType.TypeName() +} + +func checkArgsMatch(params []letFunctionParam, args []ref.Val) error { + if len(params) != len(args) { + return fmt.Errorf("got %d args, expected %d", len(args), len(params)) + } + for i, arg := range args { + if !typeAssignable(arg.Type(), params[i].typeHint) { + return fmt.Errorf("got %s, expected %s for argument %d", arg.Type().TypeName(), UnparseType(params[i].typeHint), i) + } + } + return nil +} + +func (l *letFunction) updateImpl(env *cel.Env, deps []*functions.Overload) error { + var paramVars []*exprpb.Decl + + if l.receiver != nil { + paramVars = append(paramVars, decls.NewVar("this", l.receiver)) + } + + for _, p := range l.params { + paramVars = append(paramVars, decls.NewVar(p.identifier, p.typeHint)) + } + + var err error + l.fnEnv, err = env.Extend(cel.Declarations(paramVars...)) + if err != nil { + return err + } + + ast, iss := l.fnEnv.Compile(l.src) + + if iss != nil { + return iss.Err() + } + + if !proto.Equal(ast.ResultType(), l.resultType) { + return fmt.Errorf("got result type %s for %s", UnparseType(ast.ResultType()), l) + } + + l.prog, err = l.fnEnv.Program(ast, cel.Functions(deps...)) + + if err != nil { + return err + } + + l.impl = func(args ...ref.Val) ref.Val { + var err error + var instance ref.Val + if l.receiver != nil { + instance = args[0] + args = args[1:] + } + err = checkArgsMatch(l.params, args) + if err != nil { + return types.NewErr("error evaluating %s: %v", l, err) + } + + activation := make(map[string]interface{}) + for i, param := range l.params { + activation[param.identifier] = args[i] + } + + if instance != nil { + if !typeAssignable(instance.Type(), l.receiver) { + return types.NewErr("error evaluating %s: got receiver type: %s wanted %s", l, instance.Type().TypeName(), UnparseType(l.receiver)) + } + activation["this"] = instance + } + + val, _, err := l.prog.Eval(activation) + + if err != nil { + return types.NewErr("error evaluating %s: %v", l, err) + } + + return val + } + return nil +} + +func (l *letFunction) update(env *cel.Env, deps []*functions.Overload) error { + var err error + if l.src != "" { + err = l.updateImpl(env, deps) + if err != nil { + return err + } + } + + paramTypes := make([]*exprpb.Type, len(l.params)) + for i, p := range l.params { + paramTypes[i] = p.typeHint + } + + var opt cel.EnvOption + if l.receiver != nil { + paramTypes = append([]*exprpb.Type{l.receiver}, paramTypes...) + opt = cel.Declarations( + decls.NewFunction(l.identifier, + decls.NewInstanceOverload( + l.identifier, + paramTypes, + l.resultType, + ))) + } else { + opt = cel.Declarations( + decls.NewFunction( + l.identifier, + decls.NewOverload(l.identifier, + paramTypes, + l.resultType))) + } + + l.env, err = env.Extend(opt) + if err != nil { + return err + } + + return nil +} + +func (l letVariable) String() string { + return fmt.Sprintf("%s = %s", l.identifier, l.src) +} + +func formatParams(params []letFunctionParam) string { + fmtParams := make([]string, len(params)) + + for i, p := range params { + fmtParams[i] = fmt.Sprintf("%s: %s", p.identifier, UnparseType(p.typeHint)) + } + + return fmt.Sprintf("(%s)", strings.Join(fmtParams, ", ")) +} + +func (l letFunction) String() string { + receiverFmt := "" + if l.receiver != nil { + receiverFmt = fmt.Sprintf("%s.", UnparseType(l.receiver)) + } + + return fmt.Sprintf("%s%s%s : %s -> %s", receiverFmt, l.identifier, formatParams(l.params), UnparseType(l.resultType), l.src) +} + +func (l *letFunction) generateFunction() *functions.Overload { + argLen := len(l.params) + if l.receiver != nil { + argLen++ + } + switch argLen { + case 1: + return &functions.Overload{ + Operator: l.identifier, + Unary: func(v ref.Val) ref.Val { return l.impl(v) }, + } + case 2: + return &functions.Overload{ + Operator: l.identifier, + Binary: func(lhs ref.Val, rhs ref.Val) ref.Val { return l.impl(lhs, rhs) }, + } + default: + return &functions.Overload{ + Operator: l.identifier, + Function: l.impl, + } + } +} + +// Reset plan if we need to recompile based on a dependency change. +func (l *letVariable) clearPlan() { + l.resultType = nil + l.env = nil + l.ast = nil + l.prog = nil +} + +// Optioner interface represents an option set on the base CEL environment used by +// the evaluator. +type Optioner interface { + // Option returns the cel.EnvOption that should be applied to the + // environment. + Option() cel.EnvOption +} + +// EvaluationContext context for the repl. +// Handles maintaining state for multiple let expressions. +type EvaluationContext struct { + letVars []letVariable + letFns []letFunction + options []Optioner +} + +func (ctx *EvaluationContext) indexLetVar(name string) int { + for idx, el := range ctx.letVars { + if el.identifier == name { + return idx + } + } + return -1 +} + +func (ctx *EvaluationContext) getEffectiveEnv(env *cel.Env) *cel.Env { + if len(ctx.letVars) > 0 { + env = ctx.letVars[len(ctx.letVars)-1].env + } else if len(ctx.letFns) > 0 { + env = ctx.letFns[len(ctx.letFns)-1].env + } else if len(ctx.options) > 0 { + for _, opt := range ctx.options { + env, _ = env.Extend(opt.Option()) + } + } + + return env +} + +func (ctx *EvaluationContext) indexLetFn(name string) int { + for idx, el := range ctx.letFns { + if el.identifier == name { + return idx + } + } + return -1 +} + +func (ctx *EvaluationContext) copy() *EvaluationContext { + var cpy EvaluationContext + cpy.options = make([]Optioner, len(ctx.options)) + copy(cpy.options, ctx.options) + cpy.letVars = make([]letVariable, len(ctx.letVars)) + copy(cpy.letVars, ctx.letVars) + cpy.letFns = make([]letFunction, len(ctx.letFns)) + copy(cpy.letFns, ctx.letFns) + return &cpy +} + +func (ctx *EvaluationContext) delLetVar(name string) { + idx := ctx.indexLetVar(name) + if idx < 0 { + // no-op if deleting something that's not defined + return + } + + ctx.letVars = append(ctx.letVars[:idx], ctx.letVars[idx+1:]...) + + for i := idx; i < len(ctx.letVars); i++ { + ctx.letVars[i].clearPlan() + } +} + +func (ctx *EvaluationContext) delLetFn(name string) { + idx := ctx.indexLetFn(name) + if idx < 0 { + // no-op if deleting something that's not defined + return + } + + ctx.letFns = append(ctx.letFns[:idx], ctx.letFns[idx+1:]...) + + for i := range ctx.letVars { + ctx.letVars[i].clearPlan() + } +} + +// Add or update an existing let then invalidate any computed plans. +func (ctx *EvaluationContext) addLetVar(name string, expr string, typeHint *exprpb.Type) { + idx := ctx.indexLetVar(name) + newVar := letVariable{identifier: name, src: expr, typeHint: typeHint} + if idx < 0 { + ctx.letVars = append(ctx.letVars, newVar) + } else { + ctx.letVars[idx] = newVar + for i := idx + 1; i < len(ctx.letVars); i++ { + // invalidate dependant let exprs + ctx.letVars[i].clearPlan() + } + } +} + +// Try to normalize a defined function name as either a namespaced function or a receiver call. +func (ctx *EvaluationContext) resolveFn(name string) (string, *exprpb.Type) { + leadingDot := "" + id := name + if strings.HasPrefix(name, ".") { + id = strings.TrimLeft(name, ".") + leadingDot = "." + } + qualifiers := strings.Split(id, ".") + if len(qualifiers) == 1 { + return qualifiers[0], nil + } + + namespace := strings.Join(qualifiers[:len(qualifiers)-1], ".") + id = qualifiers[len(qualifiers)-1] + + maybeType, err := ParseType(leadingDot + namespace) + if err != nil { + return name, nil + } + + switch maybeType.TypeKind.(type) { + // unsupported type assume it's just namespaced + case *exprpb.Type_AbstractType_: + case *exprpb.Type_MessageType: + case *exprpb.Type_Error: + case *exprpb.Type_Function: + default: + return id, maybeType + } + + return name, nil +} + +// Add or update an existing let then invalidate any computed plans. +func (ctx *EvaluationContext) addLetFn(name string, params []letFunctionParam, resultType *exprpb.Type, expr string) { + name, receiver := ctx.resolveFn(name) + idx := ctx.indexLetFn(name) + newFn := letFunction{identifier: name, params: params, receiver: receiver, resultType: resultType, src: expr} + if idx < 0 { + ctx.letFns = append(ctx.letFns, newFn) + } else { + ctx.letFns[idx] = newFn + } + + for i := 0; i < len(ctx.letVars); i++ { + // invalidate dependant let exprs + ctx.letVars[i].clearPlan() + } +} + +func (ctx *EvaluationContext) addOption(opt Optioner) { + ctx.options = append(ctx.options, opt) + + for i := 0; i < len(ctx.letVars); i++ { + // invalidate dependant let exprs + ctx.letVars[i].clearPlan() + } +} + +// programOptions generates the program options for planning. +// Assumes context has been planned. +func (ctx *EvaluationContext) programOptions() cel.ProgramOption { + var fns = make([]*functions.Overload, len(ctx.letFns)) + for i, fn := range ctx.letFns { + fns[i] = fn.generateFunction() + } + return cel.Functions(fns...) +} + +// Evaluator provides basic environment for evaluating an expression with +// applied context. +type Evaluator struct { + env *cel.Env + ctx EvaluationContext +} + +// NewEvaluator returns an inialized evaluator +func NewEvaluator() (*Evaluator, error) { + env, err := cel.NewEnv() + if err != nil { + return nil, err + } + + return &Evaluator{env: env}, nil +} + +// Attempt to update context in place after an update. +// This is done eagerly to help avoid introducing an invalid 'let' expression. +// The planned expressions are evaluated as needed when evaluating a (non-let) CEL expression. +// Return an error if any of the updates fail. +func updateContextPlans(ctx *EvaluationContext, env *cel.Env) error { + for _, opt := range ctx.options { + var err error + env, err = env.Extend(opt.Option()) + if err != nil { + return err + } + } + overloads := make([]*functions.Overload, 0) + for i := range ctx.letFns { + letFn := &ctx.letFns[i] + err := letFn.update(env, overloads) + if err != nil { + return fmt.Errorf("error updating %s: %w", letFn, err) + } + env = letFn.env + // if no src, this is declared but not defined. + if letFn.src != "" { + overloads = append(overloads, letFn.generateFunction()) + } + + } + for i := range ctx.letVars { + el := &ctx.letVars[i] + // Check if the let variable has a definition and needs to be re-planned + if el.prog == nil && el.src != "" { + ast, iss := env.Compile(el.src) + if iss != nil { + return fmt.Errorf("error updating %v\n%w", el, iss.Err()) + } + + if el.typeHint != nil && !proto.Equal(ast.ResultType(), el.typeHint) { + return fmt.Errorf("error updating %v\ntype mismatch got %v expected %v", + el, + UnparseType(ast.ResultType()), + UnparseType(el.typeHint)) + } + + el.ast = ast + el.resultType = ast.ResultType() + + plan, err := env.Program(ast, ctx.programOptions()) + if err != nil { + return err + } + el.prog = plan + } else if el.src == "" { + // Variable is declared but not defined, just update the type checking environment + el.resultType = el.typeHint + } + if el.env == nil { + env, err := env.Extend(cel.Declarations(decls.NewVar(el.identifier, el.resultType))) + if err != nil { + return err + } + el.env = env + } + env = el.env + } + return nil +} + +// AddLetVar adds a let variable to the evaluation context. +// The expression is planned but evaluated lazily. +func (e *Evaluator) AddLetVar(name string, expr string, typeHint *exprpb.Type) error { + // copy the current context and attempt to update dependant expressions. + // if successful, swap the current context with the updated copy. + ctx := e.ctx.copy() + ctx.addLetVar(name, expr, typeHint) + err := updateContextPlans(ctx, e.env) + if err != nil { + return err + } + e.ctx = *ctx + return nil +} + +// AddLetFn adds a let function to the evaluation context. +func (e *Evaluator) AddLetFn(name string, params []letFunctionParam, resultType *exprpb.Type, expr string) error { + // copy the current context and attempt to update dependant expressions. + // if successful, swap the current context with the updated copy. + cpy := e.ctx.copy() + cpy.addLetFn(name, params, resultType, expr) + err := updateContextPlans(cpy, e.env) + if err != nil { + return err + } + e.ctx = *cpy + return nil +} + +// AddDeclVar declares a variable in the environment but doesn't register an expr with it. +// This allows planning to succeed, but with no value for the variable at runtime. +func (e *Evaluator) AddDeclVar(name string, typeHint *exprpb.Type) error { + ctx := e.ctx.copy() + ctx.addLetVar(name, "", typeHint) + err := updateContextPlans(ctx, e.env) + if err != nil { + return err + } + e.ctx = *ctx + return nil +} + +// AddDeclFn declares a function in the environment but doesn't register an expr with it. +// This allows planning to succeed, but with no value for the function at runtime. +func (e *Evaluator) AddDeclFn(name string, params []letFunctionParam, typeHint *exprpb.Type) error { + ctx := e.ctx.copy() + ctx.addLetFn(name, params, typeHint, "") + err := updateContextPlans(ctx, e.env) + if err != nil { + return err + } + e.ctx = *ctx + return nil +} + +// AddOption adds an option to the basic environment. +// Options are applied before evaluating any of the let statements. +// Returns an error if setting the option prevents planning any of the defined let expressions. +func (e *Evaluator) AddOption(opt Optioner) error { + cpy := e.ctx.copy() + cpy.addOption(opt) + err := updateContextPlans(cpy, e.env) + if err != nil { + return err + } + e.ctx = *cpy + return nil +} + +// DelLetVar removes a variable from the evaluation context. +// If deleting the variable breaks a later expression, this function will return an error without modifying the context. +func (e *Evaluator) DelLetVar(name string) error { + ctx := e.ctx.copy() + ctx.delLetVar(name) + err := updateContextPlans(ctx, e.env) + if err != nil { + return err + } + e.ctx = *ctx + return nil +} + +// DelLetFn removes a function from the evaluation context. +// If deleting the function breaks a later expression, this function will return an error without modifying the context. +func (e *Evaluator) DelLetFn(name string) error { + ctx := e.ctx.copy() + ctx.delLetFn(name) + err := updateContextPlans(ctx, e.env) + if err != nil { + return err + } + e.ctx = *ctx + return nil +} + +// Status returns a stringified view of the current evaluator state. +func (e *Evaluator) Status() string { + var options, funcs, vars string + + for _, opt := range e.ctx.options { + options = options + fmt.Sprintf("%s\n", opt) + } + + for _, fn := range e.ctx.letFns { + cmd := "let" + if fn.src == "" { + cmd = "declare" + } + funcs = funcs + fmt.Sprintf("%%%s %s\n", cmd, fn) + } + + for _, lVar := range e.ctx.letVars { + cmd := "let" + if lVar.src == "" { + cmd = "declare" + } + vars = vars + fmt.Sprintf("%%%s %s\n", cmd, lVar) + } + return fmt.Sprintf("// Options\n%s\n// Functions\n%s\n// Variables\n%s", options, funcs, vars) +} + +// applyContext evaluates the let expressions in the context to build an activation for the given expression. +// returns the environment for compiling and planning the top level CEL expression and an activation with the +// values of the let expressions. +func (e *Evaluator) applyContext() (*cel.Env, interpreter.Activation, error) { + var vars = make(map[string]interface{}) + + for _, el := range e.ctx.letVars { + if el.prog == nil { + // Declared but not defined variable so nothing to evaluate + continue + } + + val, _, err := el.prog.Eval(vars) + if val != nil { + vars[el.identifier] = val + } else if err != nil { + return nil, nil, err + } + } + + act, err := interpreter.NewActivation(vars) + if err != nil { + return nil, nil, err + } + + return e.ctx.getEffectiveEnv(e.env), act, nil +} + +// typeOption implements optioner for loading a set of types defined by a protobuf file descriptor set. +type typeOption struct { + path string + fds *descpb.FileDescriptorSet +} + +func (o *typeOption) String() string { + return fmt.Sprintf("%%load_descriptors '%s'", o.path) +} + +func (o *typeOption) Option() cel.EnvOption { + return cel.TypeDescs(o.fds) +} + +type containerOption struct { + container string +} + +func (o *containerOption) String() string { + return fmt.Sprintf("%%option --container '%s'", o.container) +} + +func (o *containerOption) Option() cel.EnvOption { + return cel.Container(o.container) +} + +// setOption sets a number of options on the environment. returns an error if +// any of them fail. +func (e *Evaluator) setOption(args []string) error { + var issues []string + for idx := 0; idx < len(args); { + arg := args[idx] + idx++ + if arg == "--container" { + if idx >= len(args) { + issues = append(issues, "not enough args for container") + } + container := args[idx] + idx++ + err := e.AddOption(&containerOption{container: container}) + if err != nil { + issues = append(issues, fmt.Sprintf("container: %v", err)) + } + } else { + issues = append(issues, fmt.Sprintf("unsupported option '%s'", arg)) + } + } + if len(issues) > 0 { + return errors.New(strings.Join(issues, "\n")) + } + return nil +} + +func loadFileDescriptorSet(path string, textfmt bool) (*descpb.FileDescriptorSet, error) { + data, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + + var fds descpb.FileDescriptorSet + + if textfmt { + err = prototext.Unmarshal(data, &fds) + } else { + // binary pb + err = proto.Unmarshal(data, &fds) + } + if err != nil { + return nil, err + } + + return &fds, nil +} + +func (e *Evaluator) loadDescriptors(args []string) error { + if len(args) < 1 { + return errors.New("expected path for load descriptors") + } + flag := "" + if len(args) > 1 { + flag = args[0] + } + + textfmt := true + if flag == "--binarypb" { + textfmt = false + } + + p := args[len(args)-1] + fds, err := loadFileDescriptorSet(p, textfmt) + if err != nil { + return fmt.Errorf("error loading file: %v", err) + } + + return e.AddOption(&typeOption{path: p, fds: fds}) +} + +func (e *Evaluator) Process(cmd Cmder) (string, bool, error) { + switch cmd := cmd.(type) { + case *evalCmd: + val, resultT, err := e.Evaluate(cmd.expr) + if err != nil { + return "", false, fmt.Errorf("expr failed:\n%v", err) + } + if val != nil { + return fmt.Sprintf("%v : %s", val.Value(), UnparseType(resultT)), false, nil + } + case *letVarCmd: + var err error + if cmd.src != "" { + err = e.AddLetVar(cmd.identifier, cmd.src, cmd.typeHint) + } else { + // declare only + err = e.AddDeclVar(cmd.identifier, cmd.typeHint) + } + if err != nil { + return "", false, fmt.Errorf("adding variable failed:\n%v", err) + } + case *letFnCmd: + err := errors.New("declare not yet implemented") + if cmd.src != "" { + err = e.AddLetFn(cmd.identifier, cmd.params, cmd.resultType, cmd.src) + } + if err != nil { + return "", false, fmt.Errorf("adding function failed:\n%v", err) + } + case *delCmd: + err := e.DelLetVar(cmd.identifier) + if err != nil { + return "", false, fmt.Errorf("deleting declaration failed:\n%v", err) + } + err = e.DelLetFn(cmd.identifier) + if err != nil { + return "", false, fmt.Errorf("deleting declaration failed:\n%v", err) + } + + case *simpleCmd: + switch cmd.Cmd() { + case "exit": + return "", true, nil + case "null": + return "", false, nil + case "status": + return e.Status(), false, nil + case "load_descriptors": + return "", false, e.loadDescriptors(cmd.args) + case "option": + return "", false, e.setOption(cmd.args) + case "reset": + e.ctx = EvaluationContext{} + return "", false, nil + default: + return "", false, fmt.Errorf("unsupported command: %v", cmd.Cmd()) + } + default: + return "", false, fmt.Errorf("unsupported command: %v", cmd.Cmd()) + } + return "", false, nil +} + +// Evaluate sets up a CEL evaluation using the current evaluation context. +func (e *Evaluator) Evaluate(expr string) (ref.Val, *exprpb.Type, error) { + env, act, err := e.applyContext() + if err != nil { + return nil, nil, err + } + + ast, iss := env.Compile(expr) + if iss != nil { + return nil, nil, iss.Err() + } + + p, err := env.Program(ast, e.ctx.programOptions()) + if err != nil { + return nil, nil, err + } + + val, _, err := p.Eval(act) + // expression can be well-formed and result in an error + return val, ast.ResultType(), err +} diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/evaluator_test.go golang-github-google-cel-go-0.12.5+ds/repl/evaluator_test.go --- golang-github-google-cel-go-0.11.4+ds/repl/evaluator_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/evaluator_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,672 @@ +// Copyright 2022 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 +// +// https://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 repl + +import ( + "testing" + + "github.com/google/cel-go/cel" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +var testTextDescriptorFile string = "testdata/attribute_context_fds.textproto" + +func mustParseType(t testing.TB, name string) *exprpb.Type { + t.Helper() + ty, err := ParseType(name) + if err != nil { + t.Fatalf("ParseType(%s) failed", name) + } + return ty +} + +func TestEvalSimple(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + _, _, err = eval.Evaluate("[1, 2, 3]") + + if err != nil { + t.Errorf("eval.Evaluate('[1, 2, 3]') got %v, wanted non-error", err) + } +} + +func TestEvalSingleLetVar(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + err = eval.AddLetVar("x", "2 + 2", nil) + if err != nil { + t.Errorf("eval.AddLetVar('x', '2 + 2') got %v, wanted non-error", err) + } + + _, _, err = eval.Evaluate("[1, 2, 3, x]") + + if err != nil { + t.Errorf("eval.Evaluate('[1, 2, 3, x]') got %v, wanted non-error", err) + } +} + +func TestEvalMultiLet(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + eval.AddLetVar("x", "20/5", nil) + eval.AddLetVar("y", "x * 3", nil) + eval.AddLetVar("x", "20", nil) + + _, _, err = eval.Evaluate("[1, 2, 3, x, y]") + if err != nil { + t.Errorf("eval.Evaluate('[1, 2, 3, x, y]') got %v, wanted non-error", err) + } +} + +func TestEvalError(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + eval.AddLetVar("x", "1", nil) + eval.AddLetVar("y", "0", nil) + + _, _, err = eval.Evaluate("x / y") + if err == nil { + t.Errorf("eval.Evaluate('x / y') got non-error, wanted division by zero") + } +} + +func TestLetError(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + err = eval.AddLetVar("y", "z + 1", nil) + if err == nil { + t.Errorf("eval.AddLetVar('y', 'z + 1') got %v, wanted error", err) + } + + result, _, err := eval.Evaluate("y") + if err == nil { + t.Errorf("eval.Evaluate('y') got result %v, wanted error", result.Value()) + } +} + +func TestLetTypeHintError(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + err = eval.AddLetVar("y", "10u", mustParseType(t, "int")) + if err == nil { + t.Errorf("eval.AddLetVar('y', '10u') got %v, wanted error", err) + } + + result, _, err := eval.Evaluate("y") + if err == nil { + t.Errorf("eval.Evaluate('y') got result %v, wanted error", result) + } +} + +func TestDeclareError(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + eval.AddDeclVar("z", mustParseType(t, "double")) + eval.AddLetVar("y", "z + 10.0", nil) + err = eval.AddLetVar("z", "'2.0'", nil) + if err == nil { + t.Errorf("eval.AddLetVar('z', '\"2.0\"') got %v, wanted error", err) + } + + err = eval.AddDeclVar("z", mustParseType(t, "string")) + if err == nil { + t.Errorf("eval.AddDeclVar('z', string) got %v, wanted error", err) + } +} + +func TestDelError(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + eval.AddLetVar("z", "41", nil) + eval.AddLetVar("y", "z + 1", nil) + + err = eval.DelLetVar("z") + if err == nil { + t.Errorf("eval.DelLetVar('z') got %v, wanted error", err) + } + + val, _, err := eval.Evaluate("y") + if err != nil { + t.Errorf("eval.Evaluate('y') failed %v, wanted non-error", err) + } else if val.Value().(int64) != 42 { + t.Errorf("eval.Evaluate('y') got %v, wanted 42", val.Value()) + } + +} + +func TestAddLetFn(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + eval.AddLetFn("fn", []letFunctionParam{ + {identifier: "x", typeHint: mustParseType(t, "int")}, + {identifier: "y", typeHint: mustParseType(t, "int")}}, + mustParseType(t, "int"), + "x * x - y * y") + + eval.AddLetVar("testcases", "[[1, 2], [2, 3], [3, 4], [10, 20]]", mustParseType(t, "list(list(int))")) + + result, _, err := eval.Evaluate("testcases.all(e, fn(e[0], e[1]) == (e[0] - e[1]) * (e[0] + e[1]))") + + if err != nil { + t.Errorf("eval.Evaluate() got error %v wanted nil", err) + } else if !result.Value().(bool) { + t.Errorf("eval.Evaluate() got %v wanted true", result.Value()) + } +} + +func TestAddLetFnComposed(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + err = eval.AddLetFn("square", []letFunctionParam{{ + identifier: "x", + typeHint: mustParseType(t, "int"), + }}, mustParseType(t, "int"), "x * x") + + if err != nil { + t.Errorf("eval.AddLetFn(square x -> int) got error %v expected nil", err) + } + + err = eval.AddLetFn("squareDiff", []letFunctionParam{ + { + identifier: "x", + typeHint: mustParseType(t, "int"), + }, + { + identifier: "y", + typeHint: mustParseType(t, "int"), + }}, mustParseType(t, "int"), "square(x) - square(y)") + + if err != nil { + t.Errorf("eval.AddLetFn(squareDiff x, y -> int) got error %v expected nil", err) + } + + result, _, err := eval.Evaluate("squareDiff(4, 3)") + + if err != nil { + t.Errorf("eval.Evaluate() got error %v wanted nil", err) + } else if result.Value().(int64) != 7 { + t.Errorf("eval.Evaluate() got %v wanted true", result.Value()) + } +} + +func TestAddLetFnErrorOnTypeChange(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + err = eval.AddLetFn("square", []letFunctionParam{ + {identifier: "x", typeHint: mustParseType(t, "int")}}, + mustParseType(t, "int"), + "x * x") + + if err != nil { + t.Errorf("eval.AddLetFn('square x -> int') got error %v expected nil", err) + } + + eval.AddLetVar("y", "square(1) + 1", nil) + + // Overloads not yet supported + err = eval.AddLetFn("square", []letFunctionParam{ + {identifier: "x", typeHint: mustParseType(t, "double")}}, + mustParseType(t, "double"), + "x * x") + + if err == nil { + t.Error("eval.AddLetFn('square x -> double') got nil, expected error") + } + + result, _, err := eval.Evaluate("y") + + if err != nil { + t.Errorf("eval.Evaluate() got error %v wanted nil", err) + } else if result.Value().(int64) != 2 { + t.Errorf("eval.Evaluate() got %v wanted true", result.Value()) + } +} + +func TestAddLetFnErrorTypeMismatch(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + err = eval.AddLetFn("fn", []letFunctionParam{ + {identifier: "x", typeHint: mustParseType(t, "int")}, + {identifier: "y", typeHint: mustParseType(t, "int")}}, + mustParseType(t, "double"), + "x * x - y * y") + + if err == nil { + t.Error("eval.AddLetFn('fn x : int, y : int -> double') got nil expected error") + } +} + +func TestAddLetFnErrorBadExpr(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + err = eval.AddLetFn("fn", []letFunctionParam{ + {identifier: "y", typeHint: mustParseType(t, "string")}}, + mustParseType(t, "int"), + "2 - y") + + if err == nil { + t.Error("eval.AddLetFn('fn y : string -> int = 2 - y') got nil wanted error") + } +} + +func TestAddDeclFn(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + err = eval.AddDeclFn("fn", []letFunctionParam{ + {identifier: "x", typeHint: mustParseType(t, "int")}, + {identifier: "y", typeHint: mustParseType(t, "int")}}, + mustParseType(t, "int")) + + if err != nil { + t.Errorf("eval.AddDeclFn('fn(x:int, y:int): int') got error %v wanted nil", err) + } + + err = eval.AddLetVar("z", "fn(1, 2)", nil) + + if err != nil { + t.Errorf("eval.AddLetVar('z = fn(1, 2)') got error %v wanted nil", err) + } +} + +func TestAddDeclFnError(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + err = eval.AddDeclFn("fn", []letFunctionParam{ + {identifier: "x", typeHint: mustParseType(t, "int")}, + {identifier: "y", typeHint: mustParseType(t, "int")}}, + mustParseType(t, "int")) + + if err != nil { + t.Errorf("eval.AddDeclFn('fn(x:int, y:int): int') got error %v wanted nil", err) + } + + err = eval.AddLetVar("z", "fn(1, 2)", nil) + + if err != nil { + t.Errorf("eval.AddLetVar('z = fn(1, 2)') got error %v wanted nil", err) + } + + err = eval.AddDeclFn("fn", []letFunctionParam{ + {identifier: "x", typeHint: mustParseType(t, "string")}, + {identifier: "y", typeHint: mustParseType(t, "string")}}, + mustParseType(t, "int")) + + if err == nil { + t.Errorf("eval.AddDeclFn('fn(x:string, y:string): int') got nil wanted error") + } + +} + +func TestDelLetFn(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + err = eval.AddLetFn("fn", []letFunctionParam{ + {identifier: "y", typeHint: mustParseType(t, "int")}}, + mustParseType(t, "int"), + "2 - y") + + if err != nil { + t.Fatalf("eval.AddLetFn('fn (y : string): int -> 2 - y') failed: %s", err) + } + + err = eval.DelLetFn("fn") + if err != nil { + t.Errorf("eval.DelLetFn('fn') got error %s, wanted nil", err) + } + + err = eval.AddLetVar("x", "fn(2)", nil) + if err == nil { + t.Error("eval.AddLetVar('fn(2)') got nil, wanted error") + } +} + +func TestDelLetFnError(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + err = eval.AddLetFn("fn", []letFunctionParam{ + {identifier: "y", typeHint: mustParseType(t, "int")}}, + mustParseType(t, "int"), + "2 - y") + + if err != nil { + t.Fatalf("eval.AddLetFn('fn (y : string): int -> 2 - y') failed: %s", err) + } + + err = eval.AddLetVar("x", "fn(2)", nil) + if err != nil { + t.Errorf("eval.AddLetVar('fn(2)') got error %s, wanted nil", err) + } + + err = eval.DelLetFn("fn") + if err == nil { + t.Error("eval.DelLetFn('fn') got nil, wanted error") + } +} + +func TestInstanceFunction(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + err = eval.AddLetFn("int.plus", []letFunctionParam{ + {identifier: "y", typeHint: mustParseType(t, "int")}}, + mustParseType(t, "int"), + "this + y") + + if err != nil { + t.Fatalf("eval.AddLetFn('int.plus(y : int): int -> this + y') failed: %s", err) + } + + val, _, err := eval.Evaluate("40.plus(2)") + if err != nil { + t.Errorf("eval.Eval('40.plus(2)') got error %v, wanted nil", err) + } + if val.Value().(int64) != 42 { + t.Errorf("eval.Eval('40.plus(2)') got %s, wanted 42", val) + } +} + +type testContainerOption struct { + container string +} + +func (o *testContainerOption) String() string { + return o.container +} + +func (o *testContainerOption) Option() cel.EnvOption { + return cel.Container(o.container) +} + +func TestSetOption(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + err = eval.AddOption(&testContainerOption{container: "google.protobuf"}) + if err != nil { + t.Errorf("eval.AddOption() got error: %v, wanted nil", err) + } + + val, _, err := eval.Evaluate("Int64Value{value: 42} == 42") + if err != nil { + t.Errorf("eval.Evaluate() got error: %v, expected nil", err) + } + + if !val.Value().(bool) { + t.Error("eval.Evaluate() got false expected true") + } +} + +func TestSetOptionError(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator() failed with: %v", err) + } + + err = eval.AddOption(&testContainerOption{container: "google.protobuf"}) + if err != nil { + t.Errorf("eval.AddOption() got error: %v, wanted nil", err) + } + + err = eval.AddLetVar("x", "Int64Value{value: 42} == 42", nil) + if err != nil { + t.Errorf("eval.Evaluate() got error: %v, expected nil", err) + } + + err = eval.AddOption(&testContainerOption{container: ""}) + if err == nil { + t.Error("eval.AddOption() got nil expected error") + } +} + +func TestProcess(t *testing.T) { + var testCases = []struct { + name string + commands []Cmder + wantText string + wantExit bool + wantError bool + }{ + { + name: "OptionBasic", + commands: []Cmder{ + &simpleCmd{ + cmd: "option", + args: []string{ + "--container", + "google.protobuf", + }, + }, + }, + wantText: "", + wantExit: false, + wantError: false, + }, + { + name: "OptionContainer", + commands: []Cmder{ + &simpleCmd{ + cmd: "option", + args: []string{ + "--container", + "google.protobuf", + }, + }, + &evalCmd{ + expr: "Int64Value{value: 20}", + }, + }, + wantText: "20 : wrapper(int)", + wantExit: false, + wantError: false, + }, + { + name: "LoadDescriptorsError", + commands: []Cmder{ + &simpleCmd{ + cmd: "load_descriptors", + args: []string{ + "", + }, + }, + }, + wantText: "", + wantExit: false, + wantError: true, + }, + { + name: "LoadDescriptorsAddsTypes", + commands: []Cmder{ + &simpleCmd{ + cmd: "load_descriptors", + args: []string{ + testTextDescriptorFile, + }, + }, + &simpleCmd{ + cmd: "option", + args: []string{ + "--container", + "google.rpc.context", + }, + }, + &evalCmd{ + expr: "AttributeContext.Request{host: 'www.example.com'}", + }, + }, + wantText: `host:"www.example.com" : google.rpc.context.AttributeContext.Request`, + wantExit: false, + wantError: false, + }, + { + name: "Status", + commands: []Cmder{ + &simpleCmd{ + cmd: "option", + args: []string{ + "--container", + "google", + }, + }, + &letVarCmd{ + identifier: "x", + typeHint: mustParseType(t, "int"), + src: "1", + }, + &letFnCmd{ + identifier: "fn", + src: "2", + resultType: mustParseType(t, "int"), + params: nil, + }, + &simpleCmd{ + cmd: "status", + args: []string{}, + }, + }, + wantText: `// Options +%option --container 'google' + +// Functions +%let fn() : int -> 2 + +// Variables +%let x = 1 +`, + wantExit: false, + wantError: false, + }, + { + name: "Reset", + commands: []Cmder{ + &simpleCmd{ + cmd: "option", + args: []string{ + "--container", + "google", + }, + }, + &letVarCmd{ + identifier: "x", + typeHint: mustParseType(t, "int"), + src: "1", + }, + &letFnCmd{ + identifier: "fn", + src: "2", + resultType: mustParseType(t, "int"), + params: nil, + }, + &simpleCmd{ + cmd: "reset", + args: nil, + }, + &simpleCmd{ + cmd: "status", + args: []string{}, + }, + }, + wantText: `// Options + +// Functions + +// Variables +`, + wantExit: false, + wantError: false, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + eval, err := NewEvaluator() + if err != nil { + t.Fatalf("NewEvaluator returned error: %v, wanted nil", err) + } + n := len(tc.commands) + for _, cmd := range tc.commands[:n-1] { + // only need output of last command + eval.Process(cmd) + } + text, exit, err := eval.Process(tc.commands[n-1]) + + gotErr := false + if err != nil { + gotErr = true + } + + if text != tc.wantText || exit != tc.wantExit || (gotErr != tc.wantError) { + t.Errorf("For command %s got (output: '%s' exit: %v err: %v (%v)) wanted (output: '%s' exit: %v err: %v)", + tc.commands[n-1], text, exit, gotErr, err, tc.wantText, tc.wantExit, tc.wantError) + } + }) + } +} diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/go.mod golang-github-google-cel-go-0.12.5+ds/repl/go.mod --- golang-github-google-cel-go-0.11.4+ds/repl/go.mod 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/go.mod 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,19 @@ +module github.com/google/cel-go/repl + +go 1.17 + +require ( + github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed + github.com/chzyer/readline v1.5.0 + github.com/google/cel-go v0.11.4 + google.golang.org/genproto v0.0.0-20220614165028-45ed7f3ff16e + google.golang.org/protobuf v1.28.0 +) + +require ( + github.com/stoewer/go-strcase v1.2.0 // indirect + golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 // indirect + golang.org/x/text v0.3.7 // indirect +) + +replace github.com/google/cel-go => ../. diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/go.sum golang-github-google-cel-go-0.12.5+ds/repl/go.sum --- golang-github-google-cel-go-0.11.4+ds/repl/go.sum 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/go.sum 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,153 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed h1:ue9pVfIcP+QMEjfgo/Ez4ZjNZfonGgR6NgjMaJMu1Cg= +github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.2.0 h1:+eqR0HfOetur4tgnC8ftU5imRnhi4te+BadWS95c5AM= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= +github.com/chzyer/readline v1.5.0 h1:lSwwFrbNviGePhkewF1az4oLmcwqCZijQ2/Wi3BGHAI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23 h1:dZ0/VyGgQdVGAss6Ju0dt5P0QltE0SFY5Woh6hbIfiQ= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 h1:y/woIyUBFbpQGKS0u1aHF/40WUDnek3fPOyD08H5Vng= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 h1:hrbNEivu7Zn1pxvHk6MBrq9iE22woVILTHqexqBxe6I= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220614165028-45ed7f3ff16e h1:ubR4JUtqN3ffdFjpKylv8scWk/mZstGmzXbgYSkuMl0= +google.golang.org/genproto v0.0.0-20220614165028-45ed7f3ff16e/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/main/BUILD.bazel golang-github-google-cel-go-0.12.5+ds/repl/main/BUILD.bazel --- golang-github-google-cel-go-0.11.4+ds/repl/main/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/main/BUILD.bazel 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,37 @@ +# Copyright 2022 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 +# +# https://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. + +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") + +package( + licenses = ["notice"], # Apache 2.0 +) + +go_binary( + name = "main", + embed = [":go_default_library"], + importpath = "github.com/google/cel-go/repl/main", + visibility = ["//visibility:public"], +) + +go_library( + name = "go_default_library", + srcs = ["main.go"], + importpath = "github.com/google/cel-go/repl/main", + visibility = ["//visibility:private"], + deps = [ + "//repl:go_default_library", + "@com_github_chzyer_readline//:go_default_library", + ], +) diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/main/main.go golang-github-google-cel-go-0.12.5+ds/repl/main/main.go --- golang-github-google-cel-go-0.11.4+ds/repl/main/main.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/main/main.go 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,101 @@ +// Copyright 2022 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 +// +// https://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 main provides a CLI REPL session for CEL. +// +// introduces commands for manipulating evaluation context to simulate a realistic host +// environment for evaluating expresions. +// +// example session: +// +// ``` +// $ go run . +// CEL REPL +// %exit or EOF to quit. + +// cel-repl> %let x = 42 +// cel-repl> %let y = {'a': x, 'b': y} +// Adding let failed: +// Error updating y = {'a': x, 'b': y} +// ERROR: :1:15: undeclared reference to 'y' (in container '') +// | {'a': x, 'b': y} +// | ..............^ +// cel-repl> %let z = 41 +// cel-repl> %let y = {'a': x, 'b': z} +// cel-repl> y.map(key, y[key]).filter(x, x > 41) +// [42] (list_type:{elem_type:{primitive:INT64}}) +// ``` +package main + +import ( + "fmt" + "os" + + "github.com/google/cel-go/repl" + + "github.com/chzyer/readline" +) + +func main() { + var c readline.Config + c.Prompt = "cel-repl> " + + err := c.Init() + if err != nil { + fmt.Fprintf(os.Stderr, "Init readline failed: %v\n", err) + os.Exit(1) + } + + rl, err := readline.NewEx(&c) + if err != nil { + fmt.Fprintf(os.Stderr, "NewEx readline failed: %v\n", err) + os.Exit(1) + } + + defer rl.Close() + + fmt.Println("CEL REPL") + fmt.Printf("%%exit or EOF to quit.\n\n") + + eval, err := repl.NewEvaluator() + if err != nil { + fmt.Fprintf(os.Stderr, "NewEvaluator failed: %v\n", err) + os.Exit(1) + } + +PromptLoop: + for { + line, err := rl.Readline() + if err != nil { + // Likely eof or interrupt so exit. + break + } + + cmd, err := repl.Parse(line) + if err != nil { + fmt.Fprintf(os.Stderr, "invalid command: %v\n", err) + continue + } + status, exit, err := eval.Process(cmd) + if exit { + break PromptLoop + } + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err.Error()) + } + if status != "" { + fmt.Println(status) + } + } +} diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/main/README.md golang-github-google-cel-go-0.12.5+ds/repl/main/README.md --- golang-github-google-cel-go-0.11.4+ds/repl/main/README.md 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/main/README.md 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,168 @@ +# CEL REPL + +This is a simple tool for experimenting with CEL expressions and learning the +syntax. + +## Usage +The REPL (Read Evaluate Print Loop) is implemented as a command line tool. + +By default, the the input will be interpreted as a cel expression to evaluate. + +Special commands (prefixed with '%') are used to update the evaluation +environment. + +An example session: + +``` +# from a cel-go clone +$ cd ./repl/main + +$ go run . +CEL REPL +%exit or EOF to quit. + +cel-repl> %let x = 10 +cel-repl> %let y = {'abc': {'def': [1, 2, 3]}} +cel-repl> y.abc.def.filter(el, el < x) +[1 2 3] : list(int) +cel-repl> %delete x +cel-repl> y.abc.def.filter(el, el < x) +Expr failed: +ERROR: :1:27: undeclared reference to 'x' (in container '') + | y.abc.def.filter(el, el < x) + | ..........................^ +cel-repl> %declare x : int +cel-repl> y.abc.def.filter(el, el < x) +Expr failed: +no such attribute: id: 8, names: [x] +no such attribute: id: 8, names: [x] : list(int) +cel-repl> y.abc.def.filter(el, el < x || el > 0) +[1 2 3] : list(int) +cel-repl> %exit +``` + +### Commands + +#### let +`%let` introduces or update a variable or function declaration and provide a +definition (as another CEL expression). A type hint is optionally provided to +check that the provided expression has the expected type. + +`%let (: )? = ` + +Example: + +`%let y = 42` + +For functions, result types are mandatory: + +`%let ( : , ...) : -> ` + +Example: + +`%let oracle(x : int) : bool -> x == 42` + +Instance functions are declared as `.(...): ` and may +reference `this` as the receiver instance. + +Example: + +``` +> %let int.oracle() : bool -> this == 42 +> 42.oracle() +true : bool +> 41.oracle() +false : bool +``` + +#### declare + +`%declare` introduces or updates a variable or function declaration with no +definition. + +`%declare : ` + +`%declare ( : , ...) : ` + +#### delete +`%delete` deletes a variable declaration + +`%delete ` + +#### eval +`%eval` evaluate an expression: + +`%eval ` or simply `` + +#### status + +`%status` prints a list of existing lets in the evaluation context. + +#### load_descriptors + +`%load_descriptors` loads a file descriptor set from file into the context. +Message types from the file are available for use in later expressions as +CEL structs. + +Accepts an argument for the filedescriptor file format: `--textproto` or +`--binarypb`. + +example: + +`%load_descriptors --textproto "./testdata/attribute_context_fds.textproto"` + +#### option + +`%option` sets an environment option. Options are specified with flags that +may take string arguments. + +`--container ` sets the expression container for name resolution. + +example: + +`%option --container 'google.protobuf'` + +#### reset + +`%reset` drops all options and let expressions, returning the evaluator to a +starting empty state. + +### Evaluation Model + +The evaluator considers the let expressions and declarations in order, with +functions defined before variables. Let expressions may refer to earlier +expressions, but the reverse is not true. To prevent breaking dependant +expressions, updates will fail if removing or changing a let prevents a later +let expression from compiling. Let expressions are compiled when declared and +evaluated before the expression in an `%eval` command. + +Functions are implicitly defined before variables: let variables may refer to +functions, but functions cannot refer to let variables. + +Using curly-braces to indicate scopes, this looks like: +``` +let sum (x : int, y : int) : int -> x + y +{ + let x = sum(2, 4) + { + let y = sum(x, 30) + { + eval sum(x, y) == 42 + // (x) + (x + 30) + // (2 + 4) + ((2 + 4) + 30) + } + } +} +``` + +## Installing + +To build and install as a standalone binary: + +``` +$ git clone git@github.com:google/cel-go.git ./cel-go +$ cd ./cel-go/repl/main +$ go build . +# e.g. to your $PATH +$ mv ./repl +``` \ No newline at end of file diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/parser/BUILD.bazel golang-github-google-cel-go-0.12.5+ds/repl/parser/BUILD.bazel --- golang-github-google-cel-go-0.11.4+ds/repl/parser/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/parser/BUILD.bazel 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,37 @@ +# Copyright 2022 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 +# +# https://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. + +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +package( + default_visibility = ["//repl:__subpackages__"], + licenses = ["notice"], # Apache 2.0 +) + +go_library( + name = "go_default_library", + srcs = glob(["*.go"], exclude=["*_test.go"]), + data = glob(["*.tokens"]), + importpath = "github.com/google/cel-go/repl/parser", + deps = [ + "@com_github_antlr_antlr4_runtime_go_antlr//:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = ["commands_test.go"], + embed = [":go_default_library"], + deps = ["@com_github_antlr_antlr4_runtime_go_antlr//:go_default_library"], +) diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/parser/commands_base_listener.go golang-github-google-cel-go-0.12.5+ds/repl/parser/commands_base_listener.go --- golang-github-google-cel-go-0.11.4+ds/repl/parser/commands_base_listener.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/parser/commands_base_listener.go 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,291 @@ +// Code generated from ./Commands.g4 by ANTLR 4.10.1. DO NOT EDIT. + +package parser // Commands +import "github.com/antlr/antlr4/runtime/Go/antlr" + +// BaseCommandsListener is a complete listener for a parse tree produced by CommandsParser. +type BaseCommandsListener struct{} + +var _ CommandsListener = &BaseCommandsListener{} + +// VisitTerminal is called when a terminal node is visited. +func (s *BaseCommandsListener) VisitTerminal(node antlr.TerminalNode) {} + +// VisitErrorNode is called when an error node is visited. +func (s *BaseCommandsListener) VisitErrorNode(node antlr.ErrorNode) {} + +// EnterEveryRule is called when any rule is entered. +func (s *BaseCommandsListener) EnterEveryRule(ctx antlr.ParserRuleContext) {} + +// ExitEveryRule is called when any rule is exited. +func (s *BaseCommandsListener) ExitEveryRule(ctx antlr.ParserRuleContext) {} + +// EnterStartCommand is called when production startCommand is entered. +func (s *BaseCommandsListener) EnterStartCommand(ctx *StartCommandContext) {} + +// ExitStartCommand is called when production startCommand is exited. +func (s *BaseCommandsListener) ExitStartCommand(ctx *StartCommandContext) {} + +// EnterCommand is called when production command is entered. +func (s *BaseCommandsListener) EnterCommand(ctx *CommandContext) {} + +// ExitCommand is called when production command is exited. +func (s *BaseCommandsListener) ExitCommand(ctx *CommandContext) {} + +// EnterLet is called when production let is entered. +func (s *BaseCommandsListener) EnterLet(ctx *LetContext) {} + +// ExitLet is called when production let is exited. +func (s *BaseCommandsListener) ExitLet(ctx *LetContext) {} + +// EnterDeclare is called when production declare is entered. +func (s *BaseCommandsListener) EnterDeclare(ctx *DeclareContext) {} + +// ExitDeclare is called when production declare is exited. +func (s *BaseCommandsListener) ExitDeclare(ctx *DeclareContext) {} + +// EnterVarDecl is called when production varDecl is entered. +func (s *BaseCommandsListener) EnterVarDecl(ctx *VarDeclContext) {} + +// ExitVarDecl is called when production varDecl is exited. +func (s *BaseCommandsListener) ExitVarDecl(ctx *VarDeclContext) {} + +// EnterFnDecl is called when production fnDecl is entered. +func (s *BaseCommandsListener) EnterFnDecl(ctx *FnDeclContext) {} + +// ExitFnDecl is called when production fnDecl is exited. +func (s *BaseCommandsListener) ExitFnDecl(ctx *FnDeclContext) {} + +// EnterParam is called when production param is entered. +func (s *BaseCommandsListener) EnterParam(ctx *ParamContext) {} + +// ExitParam is called when production param is exited. +func (s *BaseCommandsListener) ExitParam(ctx *ParamContext) {} + +// EnterDelete is called when production delete is entered. +func (s *BaseCommandsListener) EnterDelete(ctx *DeleteContext) {} + +// ExitDelete is called when production delete is exited. +func (s *BaseCommandsListener) ExitDelete(ctx *DeleteContext) {} + +// EnterSimple is called when production simple is entered. +func (s *BaseCommandsListener) EnterSimple(ctx *SimpleContext) {} + +// ExitSimple is called when production simple is exited. +func (s *BaseCommandsListener) ExitSimple(ctx *SimpleContext) {} + +// EnterEmpty is called when production empty is entered. +func (s *BaseCommandsListener) EnterEmpty(ctx *EmptyContext) {} + +// ExitEmpty is called when production empty is exited. +func (s *BaseCommandsListener) ExitEmpty(ctx *EmptyContext) {} + +// EnterExprCmd is called when production exprCmd is entered. +func (s *BaseCommandsListener) EnterExprCmd(ctx *ExprCmdContext) {} + +// ExitExprCmd is called when production exprCmd is exited. +func (s *BaseCommandsListener) ExitExprCmd(ctx *ExprCmdContext) {} + +// EnterQualId is called when production qualId is entered. +func (s *BaseCommandsListener) EnterQualId(ctx *QualIdContext) {} + +// ExitQualId is called when production qualId is exited. +func (s *BaseCommandsListener) ExitQualId(ctx *QualIdContext) {} + +// EnterStartType is called when production startType is entered. +func (s *BaseCommandsListener) EnterStartType(ctx *StartTypeContext) {} + +// ExitStartType is called when production startType is exited. +func (s *BaseCommandsListener) ExitStartType(ctx *StartTypeContext) {} + +// EnterType is called when production type is entered. +func (s *BaseCommandsListener) EnterType(ctx *TypeContext) {} + +// ExitType is called when production type is exited. +func (s *BaseCommandsListener) ExitType(ctx *TypeContext) {} + +// EnterTypeId is called when production typeId is entered. +func (s *BaseCommandsListener) EnterTypeId(ctx *TypeIdContext) {} + +// ExitTypeId is called when production typeId is exited. +func (s *BaseCommandsListener) ExitTypeId(ctx *TypeIdContext) {} + +// EnterTypeParamList is called when production typeParamList is entered. +func (s *BaseCommandsListener) EnterTypeParamList(ctx *TypeParamListContext) {} + +// ExitTypeParamList is called when production typeParamList is exited. +func (s *BaseCommandsListener) ExitTypeParamList(ctx *TypeParamListContext) {} + +// EnterStart is called when production start is entered. +func (s *BaseCommandsListener) EnterStart(ctx *StartContext) {} + +// ExitStart is called when production start is exited. +func (s *BaseCommandsListener) ExitStart(ctx *StartContext) {} + +// EnterExpr is called when production expr is entered. +func (s *BaseCommandsListener) EnterExpr(ctx *ExprContext) {} + +// ExitExpr is called when production expr is exited. +func (s *BaseCommandsListener) ExitExpr(ctx *ExprContext) {} + +// EnterConditionalOr is called when production conditionalOr is entered. +func (s *BaseCommandsListener) EnterConditionalOr(ctx *ConditionalOrContext) {} + +// ExitConditionalOr is called when production conditionalOr is exited. +func (s *BaseCommandsListener) ExitConditionalOr(ctx *ConditionalOrContext) {} + +// EnterConditionalAnd is called when production conditionalAnd is entered. +func (s *BaseCommandsListener) EnterConditionalAnd(ctx *ConditionalAndContext) {} + +// ExitConditionalAnd is called when production conditionalAnd is exited. +func (s *BaseCommandsListener) ExitConditionalAnd(ctx *ConditionalAndContext) {} + +// EnterRelation is called when production relation is entered. +func (s *BaseCommandsListener) EnterRelation(ctx *RelationContext) {} + +// ExitRelation is called when production relation is exited. +func (s *BaseCommandsListener) ExitRelation(ctx *RelationContext) {} + +// EnterCalc is called when production calc is entered. +func (s *BaseCommandsListener) EnterCalc(ctx *CalcContext) {} + +// ExitCalc is called when production calc is exited. +func (s *BaseCommandsListener) ExitCalc(ctx *CalcContext) {} + +// EnterMemberExpr is called when production MemberExpr is entered. +func (s *BaseCommandsListener) EnterMemberExpr(ctx *MemberExprContext) {} + +// ExitMemberExpr is called when production MemberExpr is exited. +func (s *BaseCommandsListener) ExitMemberExpr(ctx *MemberExprContext) {} + +// EnterLogicalNot is called when production LogicalNot is entered. +func (s *BaseCommandsListener) EnterLogicalNot(ctx *LogicalNotContext) {} + +// ExitLogicalNot is called when production LogicalNot is exited. +func (s *BaseCommandsListener) ExitLogicalNot(ctx *LogicalNotContext) {} + +// EnterNegate is called when production Negate is entered. +func (s *BaseCommandsListener) EnterNegate(ctx *NegateContext) {} + +// ExitNegate is called when production Negate is exited. +func (s *BaseCommandsListener) ExitNegate(ctx *NegateContext) {} + +// EnterSelectOrCall is called when production SelectOrCall is entered. +func (s *BaseCommandsListener) EnterSelectOrCall(ctx *SelectOrCallContext) {} + +// ExitSelectOrCall is called when production SelectOrCall is exited. +func (s *BaseCommandsListener) ExitSelectOrCall(ctx *SelectOrCallContext) {} + +// EnterPrimaryExpr is called when production PrimaryExpr is entered. +func (s *BaseCommandsListener) EnterPrimaryExpr(ctx *PrimaryExprContext) {} + +// ExitPrimaryExpr is called when production PrimaryExpr is exited. +func (s *BaseCommandsListener) ExitPrimaryExpr(ctx *PrimaryExprContext) {} + +// EnterIndex is called when production Index is entered. +func (s *BaseCommandsListener) EnterIndex(ctx *IndexContext) {} + +// ExitIndex is called when production Index is exited. +func (s *BaseCommandsListener) ExitIndex(ctx *IndexContext) {} + +// EnterCreateMessage is called when production CreateMessage is entered. +func (s *BaseCommandsListener) EnterCreateMessage(ctx *CreateMessageContext) {} + +// ExitCreateMessage is called when production CreateMessage is exited. +func (s *BaseCommandsListener) ExitCreateMessage(ctx *CreateMessageContext) {} + +// EnterIdentOrGlobalCall is called when production IdentOrGlobalCall is entered. +func (s *BaseCommandsListener) EnterIdentOrGlobalCall(ctx *IdentOrGlobalCallContext) {} + +// ExitIdentOrGlobalCall is called when production IdentOrGlobalCall is exited. +func (s *BaseCommandsListener) ExitIdentOrGlobalCall(ctx *IdentOrGlobalCallContext) {} + +// EnterNested is called when production Nested is entered. +func (s *BaseCommandsListener) EnterNested(ctx *NestedContext) {} + +// ExitNested is called when production Nested is exited. +func (s *BaseCommandsListener) ExitNested(ctx *NestedContext) {} + +// EnterCreateList is called when production CreateList is entered. +func (s *BaseCommandsListener) EnterCreateList(ctx *CreateListContext) {} + +// ExitCreateList is called when production CreateList is exited. +func (s *BaseCommandsListener) ExitCreateList(ctx *CreateListContext) {} + +// EnterCreateStruct is called when production CreateStruct is entered. +func (s *BaseCommandsListener) EnterCreateStruct(ctx *CreateStructContext) {} + +// ExitCreateStruct is called when production CreateStruct is exited. +func (s *BaseCommandsListener) ExitCreateStruct(ctx *CreateStructContext) {} + +// EnterConstantLiteral is called when production ConstantLiteral is entered. +func (s *BaseCommandsListener) EnterConstantLiteral(ctx *ConstantLiteralContext) {} + +// ExitConstantLiteral is called when production ConstantLiteral is exited. +func (s *BaseCommandsListener) ExitConstantLiteral(ctx *ConstantLiteralContext) {} + +// EnterExprList is called when production exprList is entered. +func (s *BaseCommandsListener) EnterExprList(ctx *ExprListContext) {} + +// ExitExprList is called when production exprList is exited. +func (s *BaseCommandsListener) ExitExprList(ctx *ExprListContext) {} + +// EnterFieldInitializerList is called when production fieldInitializerList is entered. +func (s *BaseCommandsListener) EnterFieldInitializerList(ctx *FieldInitializerListContext) {} + +// ExitFieldInitializerList is called when production fieldInitializerList is exited. +func (s *BaseCommandsListener) ExitFieldInitializerList(ctx *FieldInitializerListContext) {} + +// EnterMapInitializerList is called when production mapInitializerList is entered. +func (s *BaseCommandsListener) EnterMapInitializerList(ctx *MapInitializerListContext) {} + +// ExitMapInitializerList is called when production mapInitializerList is exited. +func (s *BaseCommandsListener) ExitMapInitializerList(ctx *MapInitializerListContext) {} + +// EnterInt is called when production Int is entered. +func (s *BaseCommandsListener) EnterInt(ctx *IntContext) {} + +// ExitInt is called when production Int is exited. +func (s *BaseCommandsListener) ExitInt(ctx *IntContext) {} + +// EnterUint is called when production Uint is entered. +func (s *BaseCommandsListener) EnterUint(ctx *UintContext) {} + +// ExitUint is called when production Uint is exited. +func (s *BaseCommandsListener) ExitUint(ctx *UintContext) {} + +// EnterDouble is called when production Double is entered. +func (s *BaseCommandsListener) EnterDouble(ctx *DoubleContext) {} + +// ExitDouble is called when production Double is exited. +func (s *BaseCommandsListener) ExitDouble(ctx *DoubleContext) {} + +// EnterString is called when production String is entered. +func (s *BaseCommandsListener) EnterString(ctx *StringContext) {} + +// ExitString is called when production String is exited. +func (s *BaseCommandsListener) ExitString(ctx *StringContext) {} + +// EnterBytes is called when production Bytes is entered. +func (s *BaseCommandsListener) EnterBytes(ctx *BytesContext) {} + +// ExitBytes is called when production Bytes is exited. +func (s *BaseCommandsListener) ExitBytes(ctx *BytesContext) {} + +// EnterBoolTrue is called when production BoolTrue is entered. +func (s *BaseCommandsListener) EnterBoolTrue(ctx *BoolTrueContext) {} + +// ExitBoolTrue is called when production BoolTrue is exited. +func (s *BaseCommandsListener) ExitBoolTrue(ctx *BoolTrueContext) {} + +// EnterBoolFalse is called when production BoolFalse is entered. +func (s *BaseCommandsListener) EnterBoolFalse(ctx *BoolFalseContext) {} + +// ExitBoolFalse is called when production BoolFalse is exited. +func (s *BaseCommandsListener) ExitBoolFalse(ctx *BoolFalseContext) {} + +// EnterNull is called when production Null is entered. +func (s *BaseCommandsListener) EnterNull(ctx *NullContext) {} + +// ExitNull is called when production Null is exited. +func (s *BaseCommandsListener) ExitNull(ctx *NullContext) {} diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/parser/commands_base_visitor.go golang-github-google-cel-go-0.12.5+ds/repl/parser/commands_base_visitor.go --- golang-github-google-cel-go-0.11.4+ds/repl/parser/commands_base_visitor.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/parser/commands_base_visitor.go 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,188 @@ +// Code generated from ./Commands.g4 by ANTLR 4.10.1. DO NOT EDIT. + +package parser // Commands +import "github.com/antlr/antlr4/runtime/Go/antlr" + +type BaseCommandsVisitor struct { + *antlr.BaseParseTreeVisitor +} + +func (v *BaseCommandsVisitor) VisitStartCommand(ctx *StartCommandContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitCommand(ctx *CommandContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitLet(ctx *LetContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitDeclare(ctx *DeclareContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitVarDecl(ctx *VarDeclContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitFnDecl(ctx *FnDeclContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitParam(ctx *ParamContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitDelete(ctx *DeleteContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitSimple(ctx *SimpleContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitEmpty(ctx *EmptyContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitExprCmd(ctx *ExprCmdContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitQualId(ctx *QualIdContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitStartType(ctx *StartTypeContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitType(ctx *TypeContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitTypeId(ctx *TypeIdContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitTypeParamList(ctx *TypeParamListContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitStart(ctx *StartContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitExpr(ctx *ExprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitConditionalOr(ctx *ConditionalOrContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitConditionalAnd(ctx *ConditionalAndContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitRelation(ctx *RelationContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitCalc(ctx *CalcContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitMemberExpr(ctx *MemberExprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitLogicalNot(ctx *LogicalNotContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitNegate(ctx *NegateContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitSelectOrCall(ctx *SelectOrCallContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitPrimaryExpr(ctx *PrimaryExprContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitIndex(ctx *IndexContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitCreateMessage(ctx *CreateMessageContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitIdentOrGlobalCall(ctx *IdentOrGlobalCallContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitNested(ctx *NestedContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitCreateList(ctx *CreateListContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitCreateStruct(ctx *CreateStructContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitConstantLiteral(ctx *ConstantLiteralContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitExprList(ctx *ExprListContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitFieldInitializerList(ctx *FieldInitializerListContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitMapInitializerList(ctx *MapInitializerListContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitInt(ctx *IntContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitUint(ctx *UintContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitDouble(ctx *DoubleContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitString(ctx *StringContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitBytes(ctx *BytesContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitBoolTrue(ctx *BoolTrueContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitBoolFalse(ctx *BoolFalseContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BaseCommandsVisitor) VisitNull(ctx *NullContext) interface{} { + return v.VisitChildren(ctx) +} diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/parser/Commands.g4 golang-github-google-cel-go-0.12.5+ds/repl/parser/Commands.g4 --- golang-github-google-cel-go-0.11.4+ds/repl/parser/Commands.g4 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/parser/Commands.g4 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,66 @@ +// Copyright 2022 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 +// +// https://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. + +grammar Commands; + +import CEL; + +// parser rules: +startCommand: command EOF; + +command: let | + declare | + delete | + simple | + exprCmd | + empty; + +let: '%let' ( (var=varDecl '=') | (fn=fnDecl '->') ) e=expr; + +declare: '%declare' (var=varDecl | fn=fnDecl); + +varDecl: id=qualId (':' t=type)?; + +fnDecl: id=qualId '(' (params+=param (',' params+=param)*)? ')' ':' rType=type; + +param: pid=IDENTIFIER ':' t=type; + +delete: '%delete' (var=varDecl | fn=fnDecl); + +simple: cmd=COMMAND (args+=FLAG | args+=STRING)*; + +empty: ; + +exprCmd: '%eval'? e=expr; + +qualId: leadingDot='.'? rid=IDENTIFIER ('.' qualifiers+=IDENTIFIER)*; + +// type sublanguage +startType : t=type EOF; + +type : + id=typeId params=typeParamList? ; + +typeId : + leadingDot='.'? id=(IDENTIFIER|NUL) ('.' qualifiers+=IDENTIFIER )* ; + +typeParamList: + '(' types+=type (',' types+=type)* ')' ; + +// lexer rules: +COMMAND: '%' IDENTIFIER; +FLAG: '-'? '-' IDENTIFIER; +ARROW: '->'; +EQUAL_ASSIGN: '='; + diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/parser/Commands.interp golang-github-google-cel-go-0.12.5+ds/repl/parser/Commands.interp --- golang-github-google-cel-go-0.11.4+ds/repl/parser/Commands.interp 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/parser/Commands.interp 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,128 @@ +token literal names: +null +'%let' +'%declare' +'%delete' +'%eval' +null +null +'->' +'=' +'==' +'!=' +'in' +'<' +'<=' +'>=' +'>' +'&&' +'||' +'[' +']' +'{' +'}' +'(' +')' +'.' +',' +'-' +'!' +'?' +':' +'+' +'*' +'/' +'%' +'true' +'false' +'null' +null +null +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +null +COMMAND +FLAG +ARROW +EQUAL_ASSIGN +EQUALS +NOT_EQUALS +IN +LESS +LESS_EQUALS +GREATER_EQUALS +GREATER +LOGICAL_AND +LOGICAL_OR +LBRACKET +RPRACKET +LBRACE +RBRACE +LPAREN +RPAREN +DOT +COMMA +MINUS +EXCLAM +QUESTIONMARK +COLON +PLUS +STAR +SLASH +PERCENT +CEL_TRUE +CEL_FALSE +NUL +WHITESPACE +COMMENT +NUM_FLOAT +NUM_INT +NUM_UINT +STRING +BYTES +IDENTIFIER + +rule names: +startCommand +command +let +declare +varDecl +fnDecl +param +delete +simple +empty +exprCmd +qualId +startType +type +typeId +typeParamList +start +expr +conditionalOr +conditionalAnd +relation +calc +unary +member +primary +exprList +fieldInitializerList +mapInitializerList +literal + + +atn: +[4, 1, 44, 353, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 68, 8, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 77, 8, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 3, 3, 84, 8, 3, 1, 4, 1, 4, 1, 4, 3, 4, 89, 8, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 96, 8, 5, 10, 5, 12, 5, 99, 9, 5, 3, 5, 101, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 3, 7, 114, 8, 7, 1, 8, 1, 8, 1, 8, 5, 8, 119, 8, 8, 10, 8, 12, 8, 122, 9, 8, 1, 9, 1, 9, 1, 10, 3, 10, 127, 8, 10, 1, 10, 1, 10, 1, 11, 3, 11, 132, 8, 11, 1, 11, 1, 11, 1, 11, 5, 11, 137, 8, 11, 10, 11, 12, 11, 140, 9, 11, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 3, 13, 147, 8, 13, 1, 14, 3, 14, 150, 8, 14, 1, 14, 1, 14, 1, 14, 5, 14, 155, 8, 14, 10, 14, 12, 14, 158, 9, 14, 1, 15, 1, 15, 1, 15, 1, 15, 5, 15, 164, 8, 15, 10, 15, 12, 15, 167, 9, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 3, 17, 180, 8, 17, 1, 18, 1, 18, 1, 18, 5, 18, 185, 8, 18, 10, 18, 12, 18, 188, 9, 18, 1, 19, 1, 19, 1, 19, 5, 19, 193, 8, 19, 10, 19, 12, 19, 196, 9, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 5, 20, 204, 8, 20, 10, 20, 12, 20, 207, 9, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 5, 21, 218, 8, 21, 10, 21, 12, 21, 221, 9, 21, 1, 22, 1, 22, 4, 22, 225, 8, 22, 11, 22, 12, 22, 226, 1, 22, 1, 22, 4, 22, 231, 8, 22, 11, 22, 12, 22, 232, 1, 22, 3, 22, 236, 8, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 3, 23, 246, 8, 23, 1, 23, 3, 23, 249, 8, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 3, 23, 259, 8, 23, 1, 23, 3, 23, 262, 8, 23, 1, 23, 5, 23, 265, 8, 23, 10, 23, 12, 23, 268, 9, 23, 1, 24, 3, 24, 271, 8, 24, 1, 24, 1, 24, 1, 24, 3, 24, 276, 8, 24, 1, 24, 3, 24, 279, 8, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 3, 24, 287, 8, 24, 1, 24, 3, 24, 290, 8, 24, 1, 24, 1, 24, 1, 24, 3, 24, 295, 8, 24, 1, 24, 3, 24, 298, 8, 24, 1, 24, 1, 24, 3, 24, 302, 8, 24, 1, 25, 1, 25, 1, 25, 5, 25, 307, 8, 25, 10, 25, 12, 25, 310, 9, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 5, 26, 319, 8, 26, 10, 26, 12, 26, 322, 9, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 5, 27, 332, 8, 27, 10, 27, 12, 27, 335, 9, 27, 1, 28, 3, 28, 338, 8, 28, 1, 28, 1, 28, 1, 28, 3, 28, 343, 8, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 3, 28, 351, 8, 28, 1, 28, 0, 3, 40, 42, 46, 29, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 0, 4, 2, 0, 36, 36, 44, 44, 1, 0, 9, 15, 1, 0, 31, 33, 2, 0, 26, 26, 30, 30, 383, 0, 58, 1, 0, 0, 0, 2, 67, 1, 0, 0, 0, 4, 69, 1, 0, 0, 0, 6, 80, 1, 0, 0, 0, 8, 85, 1, 0, 0, 0, 10, 90, 1, 0, 0, 0, 12, 106, 1, 0, 0, 0, 14, 110, 1, 0, 0, 0, 16, 115, 1, 0, 0, 0, 18, 123, 1, 0, 0, 0, 20, 126, 1, 0, 0, 0, 22, 131, 1, 0, 0, 0, 24, 141, 1, 0, 0, 0, 26, 144, 1, 0, 0, 0, 28, 149, 1, 0, 0, 0, 30, 159, 1, 0, 0, 0, 32, 170, 1, 0, 0, 0, 34, 173, 1, 0, 0, 0, 36, 181, 1, 0, 0, 0, 38, 189, 1, 0, 0, 0, 40, 197, 1, 0, 0, 0, 42, 208, 1, 0, 0, 0, 44, 235, 1, 0, 0, 0, 46, 237, 1, 0, 0, 0, 48, 301, 1, 0, 0, 0, 50, 303, 1, 0, 0, 0, 52, 311, 1, 0, 0, 0, 54, 323, 1, 0, 0, 0, 56, 350, 1, 0, 0, 0, 58, 59, 3, 2, 1, 0, 59, 60, 5, 0, 0, 1, 60, 1, 1, 0, 0, 0, 61, 68, 3, 4, 2, 0, 62, 68, 3, 6, 3, 0, 63, 68, 3, 14, 7, 0, 64, 68, 3, 16, 8, 0, 65, 68, 3, 20, 10, 0, 66, 68, 3, 18, 9, 0, 67, 61, 1, 0, 0, 0, 67, 62, 1, 0, 0, 0, 67, 63, 1, 0, 0, 0, 67, 64, 1, 0, 0, 0, 67, 65, 1, 0, 0, 0, 67, 66, 1, 0, 0, 0, 68, 3, 1, 0, 0, 0, 69, 76, 5, 1, 0, 0, 70, 71, 3, 8, 4, 0, 71, 72, 5, 8, 0, 0, 72, 77, 1, 0, 0, 0, 73, 74, 3, 10, 5, 0, 74, 75, 5, 7, 0, 0, 75, 77, 1, 0, 0, 0, 76, 70, 1, 0, 0, 0, 76, 73, 1, 0, 0, 0, 77, 78, 1, 0, 0, 0, 78, 79, 3, 34, 17, 0, 79, 5, 1, 0, 0, 0, 80, 83, 5, 2, 0, 0, 81, 84, 3, 8, 4, 0, 82, 84, 3, 10, 5, 0, 83, 81, 1, 0, 0, 0, 83, 82, 1, 0, 0, 0, 84, 7, 1, 0, 0, 0, 85, 88, 3, 22, 11, 0, 86, 87, 5, 29, 0, 0, 87, 89, 3, 26, 13, 0, 88, 86, 1, 0, 0, 0, 88, 89, 1, 0, 0, 0, 89, 9, 1, 0, 0, 0, 90, 91, 3, 22, 11, 0, 91, 100, 5, 22, 0, 0, 92, 97, 3, 12, 6, 0, 93, 94, 5, 25, 0, 0, 94, 96, 3, 12, 6, 0, 95, 93, 1, 0, 0, 0, 96, 99, 1, 0, 0, 0, 97, 95, 1, 0, 0, 0, 97, 98, 1, 0, 0, 0, 98, 101, 1, 0, 0, 0, 99, 97, 1, 0, 0, 0, 100, 92, 1, 0, 0, 0, 100, 101, 1, 0, 0, 0, 101, 102, 1, 0, 0, 0, 102, 103, 5, 23, 0, 0, 103, 104, 5, 29, 0, 0, 104, 105, 3, 26, 13, 0, 105, 11, 1, 0, 0, 0, 106, 107, 5, 44, 0, 0, 107, 108, 5, 29, 0, 0, 108, 109, 3, 26, 13, 0, 109, 13, 1, 0, 0, 0, 110, 113, 5, 3, 0, 0, 111, 114, 3, 8, 4, 0, 112, 114, 3, 10, 5, 0, 113, 111, 1, 0, 0, 0, 113, 112, 1, 0, 0, 0, 114, 15, 1, 0, 0, 0, 115, 120, 5, 5, 0, 0, 116, 119, 5, 6, 0, 0, 117, 119, 5, 42, 0, 0, 118, 116, 1, 0, 0, 0, 118, 117, 1, 0, 0, 0, 119, 122, 1, 0, 0, 0, 120, 118, 1, 0, 0, 0, 120, 121, 1, 0, 0, 0, 121, 17, 1, 0, 0, 0, 122, 120, 1, 0, 0, 0, 123, 124, 1, 0, 0, 0, 124, 19, 1, 0, 0, 0, 125, 127, 5, 4, 0, 0, 126, 125, 1, 0, 0, 0, 126, 127, 1, 0, 0, 0, 127, 128, 1, 0, 0, 0, 128, 129, 3, 34, 17, 0, 129, 21, 1, 0, 0, 0, 130, 132, 5, 24, 0, 0, 131, 130, 1, 0, 0, 0, 131, 132, 1, 0, 0, 0, 132, 133, 1, 0, 0, 0, 133, 138, 5, 44, 0, 0, 134, 135, 5, 24, 0, 0, 135, 137, 5, 44, 0, 0, 136, 134, 1, 0, 0, 0, 137, 140, 1, 0, 0, 0, 138, 136, 1, 0, 0, 0, 138, 139, 1, 0, 0, 0, 139, 23, 1, 0, 0, 0, 140, 138, 1, 0, 0, 0, 141, 142, 3, 26, 13, 0, 142, 143, 5, 0, 0, 1, 143, 25, 1, 0, 0, 0, 144, 146, 3, 28, 14, 0, 145, 147, 3, 30, 15, 0, 146, 145, 1, 0, 0, 0, 146, 147, 1, 0, 0, 0, 147, 27, 1, 0, 0, 0, 148, 150, 5, 24, 0, 0, 149, 148, 1, 0, 0, 0, 149, 150, 1, 0, 0, 0, 150, 151, 1, 0, 0, 0, 151, 156, 7, 0, 0, 0, 152, 153, 5, 24, 0, 0, 153, 155, 5, 44, 0, 0, 154, 152, 1, 0, 0, 0, 155, 158, 1, 0, 0, 0, 156, 154, 1, 0, 0, 0, 156, 157, 1, 0, 0, 0, 157, 29, 1, 0, 0, 0, 158, 156, 1, 0, 0, 0, 159, 160, 5, 22, 0, 0, 160, 165, 3, 26, 13, 0, 161, 162, 5, 25, 0, 0, 162, 164, 3, 26, 13, 0, 163, 161, 1, 0, 0, 0, 164, 167, 1, 0, 0, 0, 165, 163, 1, 0, 0, 0, 165, 166, 1, 0, 0, 0, 166, 168, 1, 0, 0, 0, 167, 165, 1, 0, 0, 0, 168, 169, 5, 23, 0, 0, 169, 31, 1, 0, 0, 0, 170, 171, 3, 34, 17, 0, 171, 172, 5, 0, 0, 1, 172, 33, 1, 0, 0, 0, 173, 179, 3, 36, 18, 0, 174, 175, 5, 28, 0, 0, 175, 176, 3, 36, 18, 0, 176, 177, 5, 29, 0, 0, 177, 178, 3, 34, 17, 0, 178, 180, 1, 0, 0, 0, 179, 174, 1, 0, 0, 0, 179, 180, 1, 0, 0, 0, 180, 35, 1, 0, 0, 0, 181, 186, 3, 38, 19, 0, 182, 183, 5, 17, 0, 0, 183, 185, 3, 38, 19, 0, 184, 182, 1, 0, 0, 0, 185, 188, 1, 0, 0, 0, 186, 184, 1, 0, 0, 0, 186, 187, 1, 0, 0, 0, 187, 37, 1, 0, 0, 0, 188, 186, 1, 0, 0, 0, 189, 194, 3, 40, 20, 0, 190, 191, 5, 16, 0, 0, 191, 193, 3, 40, 20, 0, 192, 190, 1, 0, 0, 0, 193, 196, 1, 0, 0, 0, 194, 192, 1, 0, 0, 0, 194, 195, 1, 0, 0, 0, 195, 39, 1, 0, 0, 0, 196, 194, 1, 0, 0, 0, 197, 198, 6, 20, -1, 0, 198, 199, 3, 42, 21, 0, 199, 205, 1, 0, 0, 0, 200, 201, 10, 1, 0, 0, 201, 202, 7, 1, 0, 0, 202, 204, 3, 40, 20, 2, 203, 200, 1, 0, 0, 0, 204, 207, 1, 0, 0, 0, 205, 203, 1, 0, 0, 0, 205, 206, 1, 0, 0, 0, 206, 41, 1, 0, 0, 0, 207, 205, 1, 0, 0, 0, 208, 209, 6, 21, -1, 0, 209, 210, 3, 44, 22, 0, 210, 219, 1, 0, 0, 0, 211, 212, 10, 2, 0, 0, 212, 213, 7, 2, 0, 0, 213, 218, 3, 42, 21, 3, 214, 215, 10, 1, 0, 0, 215, 216, 7, 3, 0, 0, 216, 218, 3, 42, 21, 2, 217, 211, 1, 0, 0, 0, 217, 214, 1, 0, 0, 0, 218, 221, 1, 0, 0, 0, 219, 217, 1, 0, 0, 0, 219, 220, 1, 0, 0, 0, 220, 43, 1, 0, 0, 0, 221, 219, 1, 0, 0, 0, 222, 236, 3, 46, 23, 0, 223, 225, 5, 27, 0, 0, 224, 223, 1, 0, 0, 0, 225, 226, 1, 0, 0, 0, 226, 224, 1, 0, 0, 0, 226, 227, 1, 0, 0, 0, 227, 228, 1, 0, 0, 0, 228, 236, 3, 46, 23, 0, 229, 231, 5, 26, 0, 0, 230, 229, 1, 0, 0, 0, 231, 232, 1, 0, 0, 0, 232, 230, 1, 0, 0, 0, 232, 233, 1, 0, 0, 0, 233, 234, 1, 0, 0, 0, 234, 236, 3, 46, 23, 0, 235, 222, 1, 0, 0, 0, 235, 224, 1, 0, 0, 0, 235, 230, 1, 0, 0, 0, 236, 45, 1, 0, 0, 0, 237, 238, 6, 23, -1, 0, 238, 239, 3, 48, 24, 0, 239, 266, 1, 0, 0, 0, 240, 241, 10, 3, 0, 0, 241, 242, 5, 24, 0, 0, 242, 248, 5, 44, 0, 0, 243, 245, 5, 22, 0, 0, 244, 246, 3, 50, 25, 0, 245, 244, 1, 0, 0, 0, 245, 246, 1, 0, 0, 0, 246, 247, 1, 0, 0, 0, 247, 249, 5, 23, 0, 0, 248, 243, 1, 0, 0, 0, 248, 249, 1, 0, 0, 0, 249, 265, 1, 0, 0, 0, 250, 251, 10, 2, 0, 0, 251, 252, 5, 18, 0, 0, 252, 253, 3, 34, 17, 0, 253, 254, 5, 19, 0, 0, 254, 265, 1, 0, 0, 0, 255, 256, 10, 1, 0, 0, 256, 258, 5, 20, 0, 0, 257, 259, 3, 52, 26, 0, 258, 257, 1, 0, 0, 0, 258, 259, 1, 0, 0, 0, 259, 261, 1, 0, 0, 0, 260, 262, 5, 25, 0, 0, 261, 260, 1, 0, 0, 0, 261, 262, 1, 0, 0, 0, 262, 263, 1, 0, 0, 0, 263, 265, 5, 21, 0, 0, 264, 240, 1, 0, 0, 0, 264, 250, 1, 0, 0, 0, 264, 255, 1, 0, 0, 0, 265, 268, 1, 0, 0, 0, 266, 264, 1, 0, 0, 0, 266, 267, 1, 0, 0, 0, 267, 47, 1, 0, 0, 0, 268, 266, 1, 0, 0, 0, 269, 271, 5, 24, 0, 0, 270, 269, 1, 0, 0, 0, 270, 271, 1, 0, 0, 0, 271, 272, 1, 0, 0, 0, 272, 278, 5, 44, 0, 0, 273, 275, 5, 22, 0, 0, 274, 276, 3, 50, 25, 0, 275, 274, 1, 0, 0, 0, 275, 276, 1, 0, 0, 0, 276, 277, 1, 0, 0, 0, 277, 279, 5, 23, 0, 0, 278, 273, 1, 0, 0, 0, 278, 279, 1, 0, 0, 0, 279, 302, 1, 0, 0, 0, 280, 281, 5, 22, 0, 0, 281, 282, 3, 34, 17, 0, 282, 283, 5, 23, 0, 0, 283, 302, 1, 0, 0, 0, 284, 286, 5, 18, 0, 0, 285, 287, 3, 50, 25, 0, 286, 285, 1, 0, 0, 0, 286, 287, 1, 0, 0, 0, 287, 289, 1, 0, 0, 0, 288, 290, 5, 25, 0, 0, 289, 288, 1, 0, 0, 0, 289, 290, 1, 0, 0, 0, 290, 291, 1, 0, 0, 0, 291, 302, 5, 19, 0, 0, 292, 294, 5, 20, 0, 0, 293, 295, 3, 54, 27, 0, 294, 293, 1, 0, 0, 0, 294, 295, 1, 0, 0, 0, 295, 297, 1, 0, 0, 0, 296, 298, 5, 25, 0, 0, 297, 296, 1, 0, 0, 0, 297, 298, 1, 0, 0, 0, 298, 299, 1, 0, 0, 0, 299, 302, 5, 21, 0, 0, 300, 302, 3, 56, 28, 0, 301, 270, 1, 0, 0, 0, 301, 280, 1, 0, 0, 0, 301, 284, 1, 0, 0, 0, 301, 292, 1, 0, 0, 0, 301, 300, 1, 0, 0, 0, 302, 49, 1, 0, 0, 0, 303, 308, 3, 34, 17, 0, 304, 305, 5, 25, 0, 0, 305, 307, 3, 34, 17, 0, 306, 304, 1, 0, 0, 0, 307, 310, 1, 0, 0, 0, 308, 306, 1, 0, 0, 0, 308, 309, 1, 0, 0, 0, 309, 51, 1, 0, 0, 0, 310, 308, 1, 0, 0, 0, 311, 312, 5, 44, 0, 0, 312, 313, 5, 29, 0, 0, 313, 320, 3, 34, 17, 0, 314, 315, 5, 25, 0, 0, 315, 316, 5, 44, 0, 0, 316, 317, 5, 29, 0, 0, 317, 319, 3, 34, 17, 0, 318, 314, 1, 0, 0, 0, 319, 322, 1, 0, 0, 0, 320, 318, 1, 0, 0, 0, 320, 321, 1, 0, 0, 0, 321, 53, 1, 0, 0, 0, 322, 320, 1, 0, 0, 0, 323, 324, 3, 34, 17, 0, 324, 325, 5, 29, 0, 0, 325, 333, 3, 34, 17, 0, 326, 327, 5, 25, 0, 0, 327, 328, 3, 34, 17, 0, 328, 329, 5, 29, 0, 0, 329, 330, 3, 34, 17, 0, 330, 332, 1, 0, 0, 0, 331, 326, 1, 0, 0, 0, 332, 335, 1, 0, 0, 0, 333, 331, 1, 0, 0, 0, 333, 334, 1, 0, 0, 0, 334, 55, 1, 0, 0, 0, 335, 333, 1, 0, 0, 0, 336, 338, 5, 26, 0, 0, 337, 336, 1, 0, 0, 0, 337, 338, 1, 0, 0, 0, 338, 339, 1, 0, 0, 0, 339, 351, 5, 40, 0, 0, 340, 351, 5, 41, 0, 0, 341, 343, 5, 26, 0, 0, 342, 341, 1, 0, 0, 0, 342, 343, 1, 0, 0, 0, 343, 344, 1, 0, 0, 0, 344, 351, 5, 39, 0, 0, 345, 351, 5, 42, 0, 0, 346, 351, 5, 43, 0, 0, 347, 351, 5, 34, 0, 0, 348, 351, 5, 35, 0, 0, 349, 351, 5, 36, 0, 0, 350, 337, 1, 0, 0, 0, 350, 340, 1, 0, 0, 0, 350, 342, 1, 0, 0, 0, 350, 345, 1, 0, 0, 0, 350, 346, 1, 0, 0, 0, 350, 347, 1, 0, 0, 0, 350, 348, 1, 0, 0, 0, 350, 349, 1, 0, 0, 0, 351, 57, 1, 0, 0, 0, 45, 67, 76, 83, 88, 97, 100, 113, 118, 120, 126, 131, 138, 146, 149, 156, 165, 179, 186, 194, 205, 217, 219, 226, 232, 235, 245, 248, 258, 261, 264, 266, 270, 275, 278, 286, 289, 294, 297, 301, 308, 320, 333, 337, 342, 350] \ No newline at end of file diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/parser/commands_lexer.go golang-github-google-cel-go-0.12.5+ds/repl/parser/commands_lexer.go --- golang-github-google-cel-go-0.11.4+ds/repl/parser/commands_lexer.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/parser/commands_lexer.go 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,382 @@ +// Code generated from ./Commands.g4 by ANTLR 4.10.1. DO NOT EDIT. + +package parser + +import ( + "fmt" + "sync" + "unicode" + + "github.com/antlr/antlr4/runtime/Go/antlr" +) + +// Suppress unused import error +var _ = fmt.Printf +var _ = sync.Once{} +var _ = unicode.IsLetter + +type CommandsLexer struct { + *antlr.BaseLexer + channelNames []string + modeNames []string + // TODO: EOF string +} + +var commandslexerLexerStaticData struct { + once sync.Once + serializedATN []int32 + channelNames []string + modeNames []string + literalNames []string + symbolicNames []string + ruleNames []string + predictionContextCache *antlr.PredictionContextCache + atn *antlr.ATN + decisionToDFA []*antlr.DFA +} + +func commandslexerLexerInit() { + staticData := &commandslexerLexerStaticData + staticData.channelNames = []string{ + "DEFAULT_TOKEN_CHANNEL", "HIDDEN", + } + staticData.modeNames = []string{ + "DEFAULT_MODE", + } + staticData.literalNames = []string{ + "", "'%let'", "'%declare'", "'%delete'", "'%eval'", "", "", "'->'", + "'='", "'=='", "'!='", "'in'", "'<'", "'<='", "'>='", "'>'", "'&&'", + "'||'", "'['", "']'", "'{'", "'}'", "'('", "')'", "'.'", "','", "'-'", + "'!'", "'?'", "':'", "'+'", "'*'", "'/'", "'%'", "'true'", "'false'", + "'null'", + } + staticData.symbolicNames = []string{ + "", "", "", "", "", "COMMAND", "FLAG", "ARROW", "EQUAL_ASSIGN", "EQUALS", + "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", "GREATER_EQUALS", "GREATER", + "LOGICAL_AND", "LOGICAL_OR", "LBRACKET", "RPRACKET", "LBRACE", "RBRACE", + "LPAREN", "RPAREN", "DOT", "COMMA", "MINUS", "EXCLAM", "QUESTIONMARK", + "COLON", "PLUS", "STAR", "SLASH", "PERCENT", "CEL_TRUE", "CEL_FALSE", + "NUL", "WHITESPACE", "COMMENT", "NUM_FLOAT", "NUM_INT", "NUM_UINT", + "STRING", "BYTES", "IDENTIFIER", + } + staticData.ruleNames = []string{ + "T__0", "T__1", "T__2", "T__3", "COMMAND", "FLAG", "ARROW", "EQUAL_ASSIGN", + "EQUALS", "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", "GREATER_EQUALS", + "GREATER", "LOGICAL_AND", "LOGICAL_OR", "LBRACKET", "RPRACKET", "LBRACE", + "RBRACE", "LPAREN", "RPAREN", "DOT", "COMMA", "MINUS", "EXCLAM", "QUESTIONMARK", + "COLON", "PLUS", "STAR", "SLASH", "PERCENT", "CEL_TRUE", "CEL_FALSE", + "NUL", "BACKSLASH", "LETTER", "DIGIT", "EXPONENT", "HEXDIGIT", "RAW", + "ESC_SEQ", "ESC_CHAR_SEQ", "ESC_OCT_SEQ", "ESC_BYTE_SEQ", "ESC_UNI_SEQ", + "WHITESPACE", "COMMENT", "NUM_FLOAT", "NUM_INT", "NUM_UINT", "STRING", + "BYTES", "IDENTIFIER", + } + staticData.predictionContextCache = antlr.NewPredictionContextCache() + staticData.serializedATN = []int32{ + 4, 0, 44, 481, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, + 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, + 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, + 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, + 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, + 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, + 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, + 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, + 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, + 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, + 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, + 4, 1, 4, 1, 5, 3, 5, 144, 8, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, + 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 11, + 1, 11, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, + 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, + 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, + 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, + 1, 30, 1, 31, 1, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, + 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, + 1, 36, 1, 36, 1, 37, 1, 37, 1, 38, 1, 38, 1, 39, 1, 39, 3, 39, 235, 8, + 39, 1, 39, 4, 39, 238, 8, 39, 11, 39, 12, 39, 239, 1, 40, 1, 40, 1, 41, + 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 3, 42, 250, 8, 42, 1, 43, 1, 43, 1, + 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, + 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, + 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 3, 46, 283, 8, 46, + 1, 47, 4, 47, 286, 8, 47, 11, 47, 12, 47, 287, 1, 47, 1, 47, 1, 48, 1, + 48, 1, 48, 1, 48, 5, 48, 296, 8, 48, 10, 48, 12, 48, 299, 9, 48, 1, 48, + 1, 48, 1, 49, 4, 49, 304, 8, 49, 11, 49, 12, 49, 305, 1, 49, 1, 49, 4, + 49, 310, 8, 49, 11, 49, 12, 49, 311, 1, 49, 3, 49, 315, 8, 49, 1, 49, 4, + 49, 318, 8, 49, 11, 49, 12, 49, 319, 1, 49, 1, 49, 1, 49, 1, 49, 4, 49, + 326, 8, 49, 11, 49, 12, 49, 327, 1, 49, 3, 49, 331, 8, 49, 3, 49, 333, + 8, 49, 1, 50, 4, 50, 336, 8, 50, 11, 50, 12, 50, 337, 1, 50, 1, 50, 1, + 50, 1, 50, 4, 50, 344, 8, 50, 11, 50, 12, 50, 345, 3, 50, 348, 8, 50, 1, + 51, 4, 51, 351, 8, 51, 11, 51, 12, 51, 352, 1, 51, 1, 51, 1, 51, 1, 51, + 1, 51, 1, 51, 4, 51, 361, 8, 51, 11, 51, 12, 51, 362, 1, 51, 1, 51, 3, + 51, 367, 8, 51, 1, 52, 1, 52, 1, 52, 5, 52, 372, 8, 52, 10, 52, 12, 52, + 375, 9, 52, 1, 52, 1, 52, 1, 52, 1, 52, 5, 52, 381, 8, 52, 10, 52, 12, + 52, 384, 9, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 5, 52, + 393, 8, 52, 10, 52, 12, 52, 396, 9, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, + 52, 1, 52, 1, 52, 1, 52, 1, 52, 5, 52, 407, 8, 52, 10, 52, 12, 52, 410, + 9, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 5, 52, 418, 8, 52, 10, + 52, 12, 52, 421, 9, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 5, 52, 428, + 8, 52, 10, 52, 12, 52, 431, 9, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, + 52, 1, 52, 1, 52, 5, 52, 441, 8, 52, 10, 52, 12, 52, 444, 9, 52, 1, 52, + 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 5, 52, 456, + 8, 52, 10, 52, 12, 52, 459, 9, 52, 1, 52, 1, 52, 1, 52, 1, 52, 3, 52, 465, + 8, 52, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 3, 54, 472, 8, 54, 1, 54, 1, + 54, 1, 54, 5, 54, 477, 8, 54, 10, 54, 12, 54, 480, 9, 54, 4, 394, 408, + 442, 457, 0, 55, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, + 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, + 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, + 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, + 36, 73, 0, 75, 0, 77, 0, 79, 0, 81, 0, 83, 0, 85, 0, 87, 0, 89, 0, 91, + 0, 93, 0, 95, 37, 97, 38, 99, 39, 101, 40, 103, 41, 105, 42, 107, 43, 109, + 44, 1, 0, 16, 2, 0, 65, 90, 97, 122, 2, 0, 69, 69, 101, 101, 2, 0, 43, + 43, 45, 45, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 82, 82, 114, 114, 10, + 0, 34, 34, 39, 39, 63, 63, 92, 92, 96, 98, 102, 102, 110, 110, 114, 114, + 116, 116, 118, 118, 2, 0, 88, 88, 120, 120, 3, 0, 9, 10, 12, 13, 32, 32, + 1, 0, 10, 10, 2, 0, 85, 85, 117, 117, 4, 0, 10, 10, 13, 13, 34, 34, 92, + 92, 4, 0, 10, 10, 13, 13, 39, 39, 92, 92, 1, 0, 92, 92, 3, 0, 10, 10, 13, + 13, 34, 34, 3, 0, 10, 10, 13, 13, 39, 39, 2, 0, 66, 66, 98, 98, 515, 0, + 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, + 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, + 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, + 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, + 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, + 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, + 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, + 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, + 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, + 0, 0, 71, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, + 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 105, 1, 0, 0, 0, 0, 107, + 1, 0, 0, 0, 0, 109, 1, 0, 0, 0, 1, 111, 1, 0, 0, 0, 3, 116, 1, 0, 0, 0, + 5, 125, 1, 0, 0, 0, 7, 133, 1, 0, 0, 0, 9, 139, 1, 0, 0, 0, 11, 143, 1, + 0, 0, 0, 13, 148, 1, 0, 0, 0, 15, 151, 1, 0, 0, 0, 17, 153, 1, 0, 0, 0, + 19, 156, 1, 0, 0, 0, 21, 159, 1, 0, 0, 0, 23, 162, 1, 0, 0, 0, 25, 164, + 1, 0, 0, 0, 27, 167, 1, 0, 0, 0, 29, 170, 1, 0, 0, 0, 31, 172, 1, 0, 0, + 0, 33, 175, 1, 0, 0, 0, 35, 178, 1, 0, 0, 0, 37, 180, 1, 0, 0, 0, 39, 182, + 1, 0, 0, 0, 41, 184, 1, 0, 0, 0, 43, 186, 1, 0, 0, 0, 45, 188, 1, 0, 0, + 0, 47, 190, 1, 0, 0, 0, 49, 192, 1, 0, 0, 0, 51, 194, 1, 0, 0, 0, 53, 196, + 1, 0, 0, 0, 55, 198, 1, 0, 0, 0, 57, 200, 1, 0, 0, 0, 59, 202, 1, 0, 0, + 0, 61, 204, 1, 0, 0, 0, 63, 206, 1, 0, 0, 0, 65, 208, 1, 0, 0, 0, 67, 210, + 1, 0, 0, 0, 69, 215, 1, 0, 0, 0, 71, 221, 1, 0, 0, 0, 73, 226, 1, 0, 0, + 0, 75, 228, 1, 0, 0, 0, 77, 230, 1, 0, 0, 0, 79, 232, 1, 0, 0, 0, 81, 241, + 1, 0, 0, 0, 83, 243, 1, 0, 0, 0, 85, 249, 1, 0, 0, 0, 87, 251, 1, 0, 0, + 0, 89, 254, 1, 0, 0, 0, 91, 259, 1, 0, 0, 0, 93, 282, 1, 0, 0, 0, 95, 285, + 1, 0, 0, 0, 97, 291, 1, 0, 0, 0, 99, 332, 1, 0, 0, 0, 101, 347, 1, 0, 0, + 0, 103, 366, 1, 0, 0, 0, 105, 464, 1, 0, 0, 0, 107, 466, 1, 0, 0, 0, 109, + 471, 1, 0, 0, 0, 111, 112, 5, 37, 0, 0, 112, 113, 5, 108, 0, 0, 113, 114, + 5, 101, 0, 0, 114, 115, 5, 116, 0, 0, 115, 2, 1, 0, 0, 0, 116, 117, 5, + 37, 0, 0, 117, 118, 5, 100, 0, 0, 118, 119, 5, 101, 0, 0, 119, 120, 5, + 99, 0, 0, 120, 121, 5, 108, 0, 0, 121, 122, 5, 97, 0, 0, 122, 123, 5, 114, + 0, 0, 123, 124, 5, 101, 0, 0, 124, 4, 1, 0, 0, 0, 125, 126, 5, 37, 0, 0, + 126, 127, 5, 100, 0, 0, 127, 128, 5, 101, 0, 0, 128, 129, 5, 108, 0, 0, + 129, 130, 5, 101, 0, 0, 130, 131, 5, 116, 0, 0, 131, 132, 5, 101, 0, 0, + 132, 6, 1, 0, 0, 0, 133, 134, 5, 37, 0, 0, 134, 135, 5, 101, 0, 0, 135, + 136, 5, 118, 0, 0, 136, 137, 5, 97, 0, 0, 137, 138, 5, 108, 0, 0, 138, + 8, 1, 0, 0, 0, 139, 140, 5, 37, 0, 0, 140, 141, 3, 109, 54, 0, 141, 10, + 1, 0, 0, 0, 142, 144, 5, 45, 0, 0, 143, 142, 1, 0, 0, 0, 143, 144, 1, 0, + 0, 0, 144, 145, 1, 0, 0, 0, 145, 146, 5, 45, 0, 0, 146, 147, 3, 109, 54, + 0, 147, 12, 1, 0, 0, 0, 148, 149, 5, 45, 0, 0, 149, 150, 5, 62, 0, 0, 150, + 14, 1, 0, 0, 0, 151, 152, 5, 61, 0, 0, 152, 16, 1, 0, 0, 0, 153, 154, 5, + 61, 0, 0, 154, 155, 5, 61, 0, 0, 155, 18, 1, 0, 0, 0, 156, 157, 5, 33, + 0, 0, 157, 158, 5, 61, 0, 0, 158, 20, 1, 0, 0, 0, 159, 160, 5, 105, 0, + 0, 160, 161, 5, 110, 0, 0, 161, 22, 1, 0, 0, 0, 162, 163, 5, 60, 0, 0, + 163, 24, 1, 0, 0, 0, 164, 165, 5, 60, 0, 0, 165, 166, 5, 61, 0, 0, 166, + 26, 1, 0, 0, 0, 167, 168, 5, 62, 0, 0, 168, 169, 5, 61, 0, 0, 169, 28, + 1, 0, 0, 0, 170, 171, 5, 62, 0, 0, 171, 30, 1, 0, 0, 0, 172, 173, 5, 38, + 0, 0, 173, 174, 5, 38, 0, 0, 174, 32, 1, 0, 0, 0, 175, 176, 5, 124, 0, + 0, 176, 177, 5, 124, 0, 0, 177, 34, 1, 0, 0, 0, 178, 179, 5, 91, 0, 0, + 179, 36, 1, 0, 0, 0, 180, 181, 5, 93, 0, 0, 181, 38, 1, 0, 0, 0, 182, 183, + 5, 123, 0, 0, 183, 40, 1, 0, 0, 0, 184, 185, 5, 125, 0, 0, 185, 42, 1, + 0, 0, 0, 186, 187, 5, 40, 0, 0, 187, 44, 1, 0, 0, 0, 188, 189, 5, 41, 0, + 0, 189, 46, 1, 0, 0, 0, 190, 191, 5, 46, 0, 0, 191, 48, 1, 0, 0, 0, 192, + 193, 5, 44, 0, 0, 193, 50, 1, 0, 0, 0, 194, 195, 5, 45, 0, 0, 195, 52, + 1, 0, 0, 0, 196, 197, 5, 33, 0, 0, 197, 54, 1, 0, 0, 0, 198, 199, 5, 63, + 0, 0, 199, 56, 1, 0, 0, 0, 200, 201, 5, 58, 0, 0, 201, 58, 1, 0, 0, 0, + 202, 203, 5, 43, 0, 0, 203, 60, 1, 0, 0, 0, 204, 205, 5, 42, 0, 0, 205, + 62, 1, 0, 0, 0, 206, 207, 5, 47, 0, 0, 207, 64, 1, 0, 0, 0, 208, 209, 5, + 37, 0, 0, 209, 66, 1, 0, 0, 0, 210, 211, 5, 116, 0, 0, 211, 212, 5, 114, + 0, 0, 212, 213, 5, 117, 0, 0, 213, 214, 5, 101, 0, 0, 214, 68, 1, 0, 0, + 0, 215, 216, 5, 102, 0, 0, 216, 217, 5, 97, 0, 0, 217, 218, 5, 108, 0, + 0, 218, 219, 5, 115, 0, 0, 219, 220, 5, 101, 0, 0, 220, 70, 1, 0, 0, 0, + 221, 222, 5, 110, 0, 0, 222, 223, 5, 117, 0, 0, 223, 224, 5, 108, 0, 0, + 224, 225, 5, 108, 0, 0, 225, 72, 1, 0, 0, 0, 226, 227, 5, 92, 0, 0, 227, + 74, 1, 0, 0, 0, 228, 229, 7, 0, 0, 0, 229, 76, 1, 0, 0, 0, 230, 231, 2, + 48, 57, 0, 231, 78, 1, 0, 0, 0, 232, 234, 7, 1, 0, 0, 233, 235, 7, 2, 0, + 0, 234, 233, 1, 0, 0, 0, 234, 235, 1, 0, 0, 0, 235, 237, 1, 0, 0, 0, 236, + 238, 3, 77, 38, 0, 237, 236, 1, 0, 0, 0, 238, 239, 1, 0, 0, 0, 239, 237, + 1, 0, 0, 0, 239, 240, 1, 0, 0, 0, 240, 80, 1, 0, 0, 0, 241, 242, 7, 3, + 0, 0, 242, 82, 1, 0, 0, 0, 243, 244, 7, 4, 0, 0, 244, 84, 1, 0, 0, 0, 245, + 250, 3, 87, 43, 0, 246, 250, 3, 91, 45, 0, 247, 250, 3, 93, 46, 0, 248, + 250, 3, 89, 44, 0, 249, 245, 1, 0, 0, 0, 249, 246, 1, 0, 0, 0, 249, 247, + 1, 0, 0, 0, 249, 248, 1, 0, 0, 0, 250, 86, 1, 0, 0, 0, 251, 252, 3, 73, + 36, 0, 252, 253, 7, 5, 0, 0, 253, 88, 1, 0, 0, 0, 254, 255, 3, 73, 36, + 0, 255, 256, 2, 48, 51, 0, 256, 257, 2, 48, 55, 0, 257, 258, 2, 48, 55, + 0, 258, 90, 1, 0, 0, 0, 259, 260, 3, 73, 36, 0, 260, 261, 7, 6, 0, 0, 261, + 262, 3, 81, 40, 0, 262, 263, 3, 81, 40, 0, 263, 92, 1, 0, 0, 0, 264, 265, + 3, 73, 36, 0, 265, 266, 5, 117, 0, 0, 266, 267, 3, 81, 40, 0, 267, 268, + 3, 81, 40, 0, 268, 269, 3, 81, 40, 0, 269, 270, 3, 81, 40, 0, 270, 283, + 1, 0, 0, 0, 271, 272, 3, 73, 36, 0, 272, 273, 5, 85, 0, 0, 273, 274, 3, + 81, 40, 0, 274, 275, 3, 81, 40, 0, 275, 276, 3, 81, 40, 0, 276, 277, 3, + 81, 40, 0, 277, 278, 3, 81, 40, 0, 278, 279, 3, 81, 40, 0, 279, 280, 3, + 81, 40, 0, 280, 281, 3, 81, 40, 0, 281, 283, 1, 0, 0, 0, 282, 264, 1, 0, + 0, 0, 282, 271, 1, 0, 0, 0, 283, 94, 1, 0, 0, 0, 284, 286, 7, 7, 0, 0, + 285, 284, 1, 0, 0, 0, 286, 287, 1, 0, 0, 0, 287, 285, 1, 0, 0, 0, 287, + 288, 1, 0, 0, 0, 288, 289, 1, 0, 0, 0, 289, 290, 6, 47, 0, 0, 290, 96, + 1, 0, 0, 0, 291, 292, 5, 47, 0, 0, 292, 293, 5, 47, 0, 0, 293, 297, 1, + 0, 0, 0, 294, 296, 8, 8, 0, 0, 295, 294, 1, 0, 0, 0, 296, 299, 1, 0, 0, + 0, 297, 295, 1, 0, 0, 0, 297, 298, 1, 0, 0, 0, 298, 300, 1, 0, 0, 0, 299, + 297, 1, 0, 0, 0, 300, 301, 6, 48, 0, 0, 301, 98, 1, 0, 0, 0, 302, 304, + 3, 77, 38, 0, 303, 302, 1, 0, 0, 0, 304, 305, 1, 0, 0, 0, 305, 303, 1, + 0, 0, 0, 305, 306, 1, 0, 0, 0, 306, 307, 1, 0, 0, 0, 307, 309, 5, 46, 0, + 0, 308, 310, 3, 77, 38, 0, 309, 308, 1, 0, 0, 0, 310, 311, 1, 0, 0, 0, + 311, 309, 1, 0, 0, 0, 311, 312, 1, 0, 0, 0, 312, 314, 1, 0, 0, 0, 313, + 315, 3, 79, 39, 0, 314, 313, 1, 0, 0, 0, 314, 315, 1, 0, 0, 0, 315, 333, + 1, 0, 0, 0, 316, 318, 3, 77, 38, 0, 317, 316, 1, 0, 0, 0, 318, 319, 1, + 0, 0, 0, 319, 317, 1, 0, 0, 0, 319, 320, 1, 0, 0, 0, 320, 321, 1, 0, 0, + 0, 321, 322, 3, 79, 39, 0, 322, 333, 1, 0, 0, 0, 323, 325, 5, 46, 0, 0, + 324, 326, 3, 77, 38, 0, 325, 324, 1, 0, 0, 0, 326, 327, 1, 0, 0, 0, 327, + 325, 1, 0, 0, 0, 327, 328, 1, 0, 0, 0, 328, 330, 1, 0, 0, 0, 329, 331, + 3, 79, 39, 0, 330, 329, 1, 0, 0, 0, 330, 331, 1, 0, 0, 0, 331, 333, 1, + 0, 0, 0, 332, 303, 1, 0, 0, 0, 332, 317, 1, 0, 0, 0, 332, 323, 1, 0, 0, + 0, 333, 100, 1, 0, 0, 0, 334, 336, 3, 77, 38, 0, 335, 334, 1, 0, 0, 0, + 336, 337, 1, 0, 0, 0, 337, 335, 1, 0, 0, 0, 337, 338, 1, 0, 0, 0, 338, + 348, 1, 0, 0, 0, 339, 340, 5, 48, 0, 0, 340, 341, 5, 120, 0, 0, 341, 343, + 1, 0, 0, 0, 342, 344, 3, 81, 40, 0, 343, 342, 1, 0, 0, 0, 344, 345, 1, + 0, 0, 0, 345, 343, 1, 0, 0, 0, 345, 346, 1, 0, 0, 0, 346, 348, 1, 0, 0, + 0, 347, 335, 1, 0, 0, 0, 347, 339, 1, 0, 0, 0, 348, 102, 1, 0, 0, 0, 349, + 351, 3, 77, 38, 0, 350, 349, 1, 0, 0, 0, 351, 352, 1, 0, 0, 0, 352, 350, + 1, 0, 0, 0, 352, 353, 1, 0, 0, 0, 353, 354, 1, 0, 0, 0, 354, 355, 7, 9, + 0, 0, 355, 367, 1, 0, 0, 0, 356, 357, 5, 48, 0, 0, 357, 358, 5, 120, 0, + 0, 358, 360, 1, 0, 0, 0, 359, 361, 3, 81, 40, 0, 360, 359, 1, 0, 0, 0, + 361, 362, 1, 0, 0, 0, 362, 360, 1, 0, 0, 0, 362, 363, 1, 0, 0, 0, 363, + 364, 1, 0, 0, 0, 364, 365, 7, 9, 0, 0, 365, 367, 1, 0, 0, 0, 366, 350, + 1, 0, 0, 0, 366, 356, 1, 0, 0, 0, 367, 104, 1, 0, 0, 0, 368, 373, 5, 34, + 0, 0, 369, 372, 3, 85, 42, 0, 370, 372, 8, 10, 0, 0, 371, 369, 1, 0, 0, + 0, 371, 370, 1, 0, 0, 0, 372, 375, 1, 0, 0, 0, 373, 371, 1, 0, 0, 0, 373, + 374, 1, 0, 0, 0, 374, 376, 1, 0, 0, 0, 375, 373, 1, 0, 0, 0, 376, 465, + 5, 34, 0, 0, 377, 382, 5, 39, 0, 0, 378, 381, 3, 85, 42, 0, 379, 381, 8, + 11, 0, 0, 380, 378, 1, 0, 0, 0, 380, 379, 1, 0, 0, 0, 381, 384, 1, 0, 0, + 0, 382, 380, 1, 0, 0, 0, 382, 383, 1, 0, 0, 0, 383, 385, 1, 0, 0, 0, 384, + 382, 1, 0, 0, 0, 385, 465, 5, 39, 0, 0, 386, 387, 5, 34, 0, 0, 387, 388, + 5, 34, 0, 0, 388, 389, 5, 34, 0, 0, 389, 394, 1, 0, 0, 0, 390, 393, 3, + 85, 42, 0, 391, 393, 8, 12, 0, 0, 392, 390, 1, 0, 0, 0, 392, 391, 1, 0, + 0, 0, 393, 396, 1, 0, 0, 0, 394, 395, 1, 0, 0, 0, 394, 392, 1, 0, 0, 0, + 395, 397, 1, 0, 0, 0, 396, 394, 1, 0, 0, 0, 397, 398, 5, 34, 0, 0, 398, + 399, 5, 34, 0, 0, 399, 465, 5, 34, 0, 0, 400, 401, 5, 39, 0, 0, 401, 402, + 5, 39, 0, 0, 402, 403, 5, 39, 0, 0, 403, 408, 1, 0, 0, 0, 404, 407, 3, + 85, 42, 0, 405, 407, 8, 12, 0, 0, 406, 404, 1, 0, 0, 0, 406, 405, 1, 0, + 0, 0, 407, 410, 1, 0, 0, 0, 408, 409, 1, 0, 0, 0, 408, 406, 1, 0, 0, 0, + 409, 411, 1, 0, 0, 0, 410, 408, 1, 0, 0, 0, 411, 412, 5, 39, 0, 0, 412, + 413, 5, 39, 0, 0, 413, 465, 5, 39, 0, 0, 414, 415, 3, 83, 41, 0, 415, 419, + 5, 34, 0, 0, 416, 418, 8, 13, 0, 0, 417, 416, 1, 0, 0, 0, 418, 421, 1, + 0, 0, 0, 419, 417, 1, 0, 0, 0, 419, 420, 1, 0, 0, 0, 420, 422, 1, 0, 0, + 0, 421, 419, 1, 0, 0, 0, 422, 423, 5, 34, 0, 0, 423, 465, 1, 0, 0, 0, 424, + 425, 3, 83, 41, 0, 425, 429, 5, 39, 0, 0, 426, 428, 8, 14, 0, 0, 427, 426, + 1, 0, 0, 0, 428, 431, 1, 0, 0, 0, 429, 427, 1, 0, 0, 0, 429, 430, 1, 0, + 0, 0, 430, 432, 1, 0, 0, 0, 431, 429, 1, 0, 0, 0, 432, 433, 5, 39, 0, 0, + 433, 465, 1, 0, 0, 0, 434, 435, 3, 83, 41, 0, 435, 436, 5, 34, 0, 0, 436, + 437, 5, 34, 0, 0, 437, 438, 5, 34, 0, 0, 438, 442, 1, 0, 0, 0, 439, 441, + 9, 0, 0, 0, 440, 439, 1, 0, 0, 0, 441, 444, 1, 0, 0, 0, 442, 443, 1, 0, + 0, 0, 442, 440, 1, 0, 0, 0, 443, 445, 1, 0, 0, 0, 444, 442, 1, 0, 0, 0, + 445, 446, 5, 34, 0, 0, 446, 447, 5, 34, 0, 0, 447, 448, 5, 34, 0, 0, 448, + 465, 1, 0, 0, 0, 449, 450, 3, 83, 41, 0, 450, 451, 5, 39, 0, 0, 451, 452, + 5, 39, 0, 0, 452, 453, 5, 39, 0, 0, 453, 457, 1, 0, 0, 0, 454, 456, 9, + 0, 0, 0, 455, 454, 1, 0, 0, 0, 456, 459, 1, 0, 0, 0, 457, 458, 1, 0, 0, + 0, 457, 455, 1, 0, 0, 0, 458, 460, 1, 0, 0, 0, 459, 457, 1, 0, 0, 0, 460, + 461, 5, 39, 0, 0, 461, 462, 5, 39, 0, 0, 462, 463, 5, 39, 0, 0, 463, 465, + 1, 0, 0, 0, 464, 368, 1, 0, 0, 0, 464, 377, 1, 0, 0, 0, 464, 386, 1, 0, + 0, 0, 464, 400, 1, 0, 0, 0, 464, 414, 1, 0, 0, 0, 464, 424, 1, 0, 0, 0, + 464, 434, 1, 0, 0, 0, 464, 449, 1, 0, 0, 0, 465, 106, 1, 0, 0, 0, 466, + 467, 7, 15, 0, 0, 467, 468, 3, 105, 52, 0, 468, 108, 1, 0, 0, 0, 469, 472, + 3, 75, 37, 0, 470, 472, 5, 95, 0, 0, 471, 469, 1, 0, 0, 0, 471, 470, 1, + 0, 0, 0, 472, 478, 1, 0, 0, 0, 473, 477, 3, 75, 37, 0, 474, 477, 3, 77, + 38, 0, 475, 477, 5, 95, 0, 0, 476, 473, 1, 0, 0, 0, 476, 474, 1, 0, 0, + 0, 476, 475, 1, 0, 0, 0, 477, 480, 1, 0, 0, 0, 478, 476, 1, 0, 0, 0, 478, + 479, 1, 0, 0, 0, 479, 110, 1, 0, 0, 0, 480, 478, 1, 0, 0, 0, 37, 0, 143, + 234, 239, 249, 282, 287, 297, 305, 311, 314, 319, 327, 330, 332, 337, 345, + 347, 352, 362, 366, 371, 373, 380, 382, 392, 394, 406, 408, 419, 429, 442, + 457, 464, 471, 476, 478, 1, 0, 1, 0, + } + deserializer := antlr.NewATNDeserializer(nil) + staticData.atn = deserializer.Deserialize(staticData.serializedATN) + atn := staticData.atn + staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState)) + decisionToDFA := staticData.decisionToDFA + for index, state := range atn.DecisionToState { + decisionToDFA[index] = antlr.NewDFA(state, index) + } +} + +// CommandsLexerInit initializes any static state used to implement CommandsLexer. By default the +// static state used to implement the lexer is lazily initialized during the first call to +// NewCommandsLexer(). You can call this function if you wish to initialize the static state ahead +// of time. +func CommandsLexerInit() { + staticData := &commandslexerLexerStaticData + staticData.once.Do(commandslexerLexerInit) +} + +// NewCommandsLexer produces a new lexer instance for the optional input antlr.CharStream. +func NewCommandsLexer(input antlr.CharStream) *CommandsLexer { + CommandsLexerInit() + l := new(CommandsLexer) + l.BaseLexer = antlr.NewBaseLexer(input) + staticData := &commandslexerLexerStaticData + l.Interpreter = antlr.NewLexerATNSimulator(l, staticData.atn, staticData.decisionToDFA, staticData.predictionContextCache) + l.channelNames = staticData.channelNames + l.modeNames = staticData.modeNames + l.RuleNames = staticData.ruleNames + l.LiteralNames = staticData.literalNames + l.SymbolicNames = staticData.symbolicNames + l.GrammarFileName = "Commands.g4" + // TODO: l.EOF = antlr.TokenEOF + + return l +} + +// CommandsLexer tokens. +const ( + CommandsLexerT__0 = 1 + CommandsLexerT__1 = 2 + CommandsLexerT__2 = 3 + CommandsLexerT__3 = 4 + CommandsLexerCOMMAND = 5 + CommandsLexerFLAG = 6 + CommandsLexerARROW = 7 + CommandsLexerEQUAL_ASSIGN = 8 + CommandsLexerEQUALS = 9 + CommandsLexerNOT_EQUALS = 10 + CommandsLexerIN = 11 + CommandsLexerLESS = 12 + CommandsLexerLESS_EQUALS = 13 + CommandsLexerGREATER_EQUALS = 14 + CommandsLexerGREATER = 15 + CommandsLexerLOGICAL_AND = 16 + CommandsLexerLOGICAL_OR = 17 + CommandsLexerLBRACKET = 18 + CommandsLexerRPRACKET = 19 + CommandsLexerLBRACE = 20 + CommandsLexerRBRACE = 21 + CommandsLexerLPAREN = 22 + CommandsLexerRPAREN = 23 + CommandsLexerDOT = 24 + CommandsLexerCOMMA = 25 + CommandsLexerMINUS = 26 + CommandsLexerEXCLAM = 27 + CommandsLexerQUESTIONMARK = 28 + CommandsLexerCOLON = 29 + CommandsLexerPLUS = 30 + CommandsLexerSTAR = 31 + CommandsLexerSLASH = 32 + CommandsLexerPERCENT = 33 + CommandsLexerCEL_TRUE = 34 + CommandsLexerCEL_FALSE = 35 + CommandsLexerNUL = 36 + CommandsLexerWHITESPACE = 37 + CommandsLexerCOMMENT = 38 + CommandsLexerNUM_FLOAT = 39 + CommandsLexerNUM_INT = 40 + CommandsLexerNUM_UINT = 41 + CommandsLexerSTRING = 42 + CommandsLexerBYTES = 43 + CommandsLexerIDENTIFIER = 44 +) diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/parser/CommandsLexer.interp golang-github-google-cel-go-0.12.5+ds/repl/parser/CommandsLexer.interp --- golang-github-google-cel-go-0.11.4+ds/repl/parser/CommandsLexer.interp 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/parser/CommandsLexer.interp 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,160 @@ +token literal names: +null +'%let' +'%declare' +'%delete' +'%eval' +null +null +'->' +'=' +'==' +'!=' +'in' +'<' +'<=' +'>=' +'>' +'&&' +'||' +'[' +']' +'{' +'}' +'(' +')' +'.' +',' +'-' +'!' +'?' +':' +'+' +'*' +'/' +'%' +'true' +'false' +'null' +null +null +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +null +COMMAND +FLAG +ARROW +EQUAL_ASSIGN +EQUALS +NOT_EQUALS +IN +LESS +LESS_EQUALS +GREATER_EQUALS +GREATER +LOGICAL_AND +LOGICAL_OR +LBRACKET +RPRACKET +LBRACE +RBRACE +LPAREN +RPAREN +DOT +COMMA +MINUS +EXCLAM +QUESTIONMARK +COLON +PLUS +STAR +SLASH +PERCENT +CEL_TRUE +CEL_FALSE +NUL +WHITESPACE +COMMENT +NUM_FLOAT +NUM_INT +NUM_UINT +STRING +BYTES +IDENTIFIER + +rule names: +T__0 +T__1 +T__2 +T__3 +COMMAND +FLAG +ARROW +EQUAL_ASSIGN +EQUALS +NOT_EQUALS +IN +LESS +LESS_EQUALS +GREATER_EQUALS +GREATER +LOGICAL_AND +LOGICAL_OR +LBRACKET +RPRACKET +LBRACE +RBRACE +LPAREN +RPAREN +DOT +COMMA +MINUS +EXCLAM +QUESTIONMARK +COLON +PLUS +STAR +SLASH +PERCENT +CEL_TRUE +CEL_FALSE +NUL +BACKSLASH +LETTER +DIGIT +EXPONENT +HEXDIGIT +RAW +ESC_SEQ +ESC_CHAR_SEQ +ESC_OCT_SEQ +ESC_BYTE_SEQ +ESC_UNI_SEQ +WHITESPACE +COMMENT +NUM_FLOAT +NUM_INT +NUM_UINT +STRING +BYTES +IDENTIFIER + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[4, 0, 44, 481, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 5, 3, 5, 144, 8, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, 1, 30, 1, 31, 1, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 37, 1, 37, 1, 38, 1, 38, 1, 39, 1, 39, 3, 39, 235, 8, 39, 1, 39, 4, 39, 238, 8, 39, 11, 39, 12, 39, 239, 1, 40, 1, 40, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 3, 42, 250, 8, 42, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 3, 46, 283, 8, 46, 1, 47, 4, 47, 286, 8, 47, 11, 47, 12, 47, 287, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 48, 5, 48, 296, 8, 48, 10, 48, 12, 48, 299, 9, 48, 1, 48, 1, 48, 1, 49, 4, 49, 304, 8, 49, 11, 49, 12, 49, 305, 1, 49, 1, 49, 4, 49, 310, 8, 49, 11, 49, 12, 49, 311, 1, 49, 3, 49, 315, 8, 49, 1, 49, 4, 49, 318, 8, 49, 11, 49, 12, 49, 319, 1, 49, 1, 49, 1, 49, 1, 49, 4, 49, 326, 8, 49, 11, 49, 12, 49, 327, 1, 49, 3, 49, 331, 8, 49, 3, 49, 333, 8, 49, 1, 50, 4, 50, 336, 8, 50, 11, 50, 12, 50, 337, 1, 50, 1, 50, 1, 50, 1, 50, 4, 50, 344, 8, 50, 11, 50, 12, 50, 345, 3, 50, 348, 8, 50, 1, 51, 4, 51, 351, 8, 51, 11, 51, 12, 51, 352, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 4, 51, 361, 8, 51, 11, 51, 12, 51, 362, 1, 51, 1, 51, 3, 51, 367, 8, 51, 1, 52, 1, 52, 1, 52, 5, 52, 372, 8, 52, 10, 52, 12, 52, 375, 9, 52, 1, 52, 1, 52, 1, 52, 1, 52, 5, 52, 381, 8, 52, 10, 52, 12, 52, 384, 9, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 5, 52, 393, 8, 52, 10, 52, 12, 52, 396, 9, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 5, 52, 407, 8, 52, 10, 52, 12, 52, 410, 9, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 5, 52, 418, 8, 52, 10, 52, 12, 52, 421, 9, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 5, 52, 428, 8, 52, 10, 52, 12, 52, 431, 9, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 5, 52, 441, 8, 52, 10, 52, 12, 52, 444, 9, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 5, 52, 456, 8, 52, 10, 52, 12, 52, 459, 9, 52, 1, 52, 1, 52, 1, 52, 1, 52, 3, 52, 465, 8, 52, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 3, 54, 472, 8, 54, 1, 54, 1, 54, 1, 54, 5, 54, 477, 8, 54, 10, 54, 12, 54, 480, 9, 54, 4, 394, 408, 442, 457, 0, 55, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 0, 75, 0, 77, 0, 79, 0, 81, 0, 83, 0, 85, 0, 87, 0, 89, 0, 91, 0, 93, 0, 95, 37, 97, 38, 99, 39, 101, 40, 103, 41, 105, 42, 107, 43, 109, 44, 1, 0, 16, 2, 0, 65, 90, 97, 122, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 82, 82, 114, 114, 10, 0, 34, 34, 39, 39, 63, 63, 92, 92, 96, 98, 102, 102, 110, 110, 114, 114, 116, 116, 118, 118, 2, 0, 88, 88, 120, 120, 3, 0, 9, 10, 12, 13, 32, 32, 1, 0, 10, 10, 2, 0, 85, 85, 117, 117, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 4, 0, 10, 10, 13, 13, 39, 39, 92, 92, 1, 0, 92, 92, 3, 0, 10, 10, 13, 13, 34, 34, 3, 0, 10, 10, 13, 13, 39, 39, 2, 0, 66, 66, 98, 98, 515, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 105, 1, 0, 0, 0, 0, 107, 1, 0, 0, 0, 0, 109, 1, 0, 0, 0, 1, 111, 1, 0, 0, 0, 3, 116, 1, 0, 0, 0, 5, 125, 1, 0, 0, 0, 7, 133, 1, 0, 0, 0, 9, 139, 1, 0, 0, 0, 11, 143, 1, 0, 0, 0, 13, 148, 1, 0, 0, 0, 15, 151, 1, 0, 0, 0, 17, 153, 1, 0, 0, 0, 19, 156, 1, 0, 0, 0, 21, 159, 1, 0, 0, 0, 23, 162, 1, 0, 0, 0, 25, 164, 1, 0, 0, 0, 27, 167, 1, 0, 0, 0, 29, 170, 1, 0, 0, 0, 31, 172, 1, 0, 0, 0, 33, 175, 1, 0, 0, 0, 35, 178, 1, 0, 0, 0, 37, 180, 1, 0, 0, 0, 39, 182, 1, 0, 0, 0, 41, 184, 1, 0, 0, 0, 43, 186, 1, 0, 0, 0, 45, 188, 1, 0, 0, 0, 47, 190, 1, 0, 0, 0, 49, 192, 1, 0, 0, 0, 51, 194, 1, 0, 0, 0, 53, 196, 1, 0, 0, 0, 55, 198, 1, 0, 0, 0, 57, 200, 1, 0, 0, 0, 59, 202, 1, 0, 0, 0, 61, 204, 1, 0, 0, 0, 63, 206, 1, 0, 0, 0, 65, 208, 1, 0, 0, 0, 67, 210, 1, 0, 0, 0, 69, 215, 1, 0, 0, 0, 71, 221, 1, 0, 0, 0, 73, 226, 1, 0, 0, 0, 75, 228, 1, 0, 0, 0, 77, 230, 1, 0, 0, 0, 79, 232, 1, 0, 0, 0, 81, 241, 1, 0, 0, 0, 83, 243, 1, 0, 0, 0, 85, 249, 1, 0, 0, 0, 87, 251, 1, 0, 0, 0, 89, 254, 1, 0, 0, 0, 91, 259, 1, 0, 0, 0, 93, 282, 1, 0, 0, 0, 95, 285, 1, 0, 0, 0, 97, 291, 1, 0, 0, 0, 99, 332, 1, 0, 0, 0, 101, 347, 1, 0, 0, 0, 103, 366, 1, 0, 0, 0, 105, 464, 1, 0, 0, 0, 107, 466, 1, 0, 0, 0, 109, 471, 1, 0, 0, 0, 111, 112, 5, 37, 0, 0, 112, 113, 5, 108, 0, 0, 113, 114, 5, 101, 0, 0, 114, 115, 5, 116, 0, 0, 115, 2, 1, 0, 0, 0, 116, 117, 5, 37, 0, 0, 117, 118, 5, 100, 0, 0, 118, 119, 5, 101, 0, 0, 119, 120, 5, 99, 0, 0, 120, 121, 5, 108, 0, 0, 121, 122, 5, 97, 0, 0, 122, 123, 5, 114, 0, 0, 123, 124, 5, 101, 0, 0, 124, 4, 1, 0, 0, 0, 125, 126, 5, 37, 0, 0, 126, 127, 5, 100, 0, 0, 127, 128, 5, 101, 0, 0, 128, 129, 5, 108, 0, 0, 129, 130, 5, 101, 0, 0, 130, 131, 5, 116, 0, 0, 131, 132, 5, 101, 0, 0, 132, 6, 1, 0, 0, 0, 133, 134, 5, 37, 0, 0, 134, 135, 5, 101, 0, 0, 135, 136, 5, 118, 0, 0, 136, 137, 5, 97, 0, 0, 137, 138, 5, 108, 0, 0, 138, 8, 1, 0, 0, 0, 139, 140, 5, 37, 0, 0, 140, 141, 3, 109, 54, 0, 141, 10, 1, 0, 0, 0, 142, 144, 5, 45, 0, 0, 143, 142, 1, 0, 0, 0, 143, 144, 1, 0, 0, 0, 144, 145, 1, 0, 0, 0, 145, 146, 5, 45, 0, 0, 146, 147, 3, 109, 54, 0, 147, 12, 1, 0, 0, 0, 148, 149, 5, 45, 0, 0, 149, 150, 5, 62, 0, 0, 150, 14, 1, 0, 0, 0, 151, 152, 5, 61, 0, 0, 152, 16, 1, 0, 0, 0, 153, 154, 5, 61, 0, 0, 154, 155, 5, 61, 0, 0, 155, 18, 1, 0, 0, 0, 156, 157, 5, 33, 0, 0, 157, 158, 5, 61, 0, 0, 158, 20, 1, 0, 0, 0, 159, 160, 5, 105, 0, 0, 160, 161, 5, 110, 0, 0, 161, 22, 1, 0, 0, 0, 162, 163, 5, 60, 0, 0, 163, 24, 1, 0, 0, 0, 164, 165, 5, 60, 0, 0, 165, 166, 5, 61, 0, 0, 166, 26, 1, 0, 0, 0, 167, 168, 5, 62, 0, 0, 168, 169, 5, 61, 0, 0, 169, 28, 1, 0, 0, 0, 170, 171, 5, 62, 0, 0, 171, 30, 1, 0, 0, 0, 172, 173, 5, 38, 0, 0, 173, 174, 5, 38, 0, 0, 174, 32, 1, 0, 0, 0, 175, 176, 5, 124, 0, 0, 176, 177, 5, 124, 0, 0, 177, 34, 1, 0, 0, 0, 178, 179, 5, 91, 0, 0, 179, 36, 1, 0, 0, 0, 180, 181, 5, 93, 0, 0, 181, 38, 1, 0, 0, 0, 182, 183, 5, 123, 0, 0, 183, 40, 1, 0, 0, 0, 184, 185, 5, 125, 0, 0, 185, 42, 1, 0, 0, 0, 186, 187, 5, 40, 0, 0, 187, 44, 1, 0, 0, 0, 188, 189, 5, 41, 0, 0, 189, 46, 1, 0, 0, 0, 190, 191, 5, 46, 0, 0, 191, 48, 1, 0, 0, 0, 192, 193, 5, 44, 0, 0, 193, 50, 1, 0, 0, 0, 194, 195, 5, 45, 0, 0, 195, 52, 1, 0, 0, 0, 196, 197, 5, 33, 0, 0, 197, 54, 1, 0, 0, 0, 198, 199, 5, 63, 0, 0, 199, 56, 1, 0, 0, 0, 200, 201, 5, 58, 0, 0, 201, 58, 1, 0, 0, 0, 202, 203, 5, 43, 0, 0, 203, 60, 1, 0, 0, 0, 204, 205, 5, 42, 0, 0, 205, 62, 1, 0, 0, 0, 206, 207, 5, 47, 0, 0, 207, 64, 1, 0, 0, 0, 208, 209, 5, 37, 0, 0, 209, 66, 1, 0, 0, 0, 210, 211, 5, 116, 0, 0, 211, 212, 5, 114, 0, 0, 212, 213, 5, 117, 0, 0, 213, 214, 5, 101, 0, 0, 214, 68, 1, 0, 0, 0, 215, 216, 5, 102, 0, 0, 216, 217, 5, 97, 0, 0, 217, 218, 5, 108, 0, 0, 218, 219, 5, 115, 0, 0, 219, 220, 5, 101, 0, 0, 220, 70, 1, 0, 0, 0, 221, 222, 5, 110, 0, 0, 222, 223, 5, 117, 0, 0, 223, 224, 5, 108, 0, 0, 224, 225, 5, 108, 0, 0, 225, 72, 1, 0, 0, 0, 226, 227, 5, 92, 0, 0, 227, 74, 1, 0, 0, 0, 228, 229, 7, 0, 0, 0, 229, 76, 1, 0, 0, 0, 230, 231, 2, 48, 57, 0, 231, 78, 1, 0, 0, 0, 232, 234, 7, 1, 0, 0, 233, 235, 7, 2, 0, 0, 234, 233, 1, 0, 0, 0, 234, 235, 1, 0, 0, 0, 235, 237, 1, 0, 0, 0, 236, 238, 3, 77, 38, 0, 237, 236, 1, 0, 0, 0, 238, 239, 1, 0, 0, 0, 239, 237, 1, 0, 0, 0, 239, 240, 1, 0, 0, 0, 240, 80, 1, 0, 0, 0, 241, 242, 7, 3, 0, 0, 242, 82, 1, 0, 0, 0, 243, 244, 7, 4, 0, 0, 244, 84, 1, 0, 0, 0, 245, 250, 3, 87, 43, 0, 246, 250, 3, 91, 45, 0, 247, 250, 3, 93, 46, 0, 248, 250, 3, 89, 44, 0, 249, 245, 1, 0, 0, 0, 249, 246, 1, 0, 0, 0, 249, 247, 1, 0, 0, 0, 249, 248, 1, 0, 0, 0, 250, 86, 1, 0, 0, 0, 251, 252, 3, 73, 36, 0, 252, 253, 7, 5, 0, 0, 253, 88, 1, 0, 0, 0, 254, 255, 3, 73, 36, 0, 255, 256, 2, 48, 51, 0, 256, 257, 2, 48, 55, 0, 257, 258, 2, 48, 55, 0, 258, 90, 1, 0, 0, 0, 259, 260, 3, 73, 36, 0, 260, 261, 7, 6, 0, 0, 261, 262, 3, 81, 40, 0, 262, 263, 3, 81, 40, 0, 263, 92, 1, 0, 0, 0, 264, 265, 3, 73, 36, 0, 265, 266, 5, 117, 0, 0, 266, 267, 3, 81, 40, 0, 267, 268, 3, 81, 40, 0, 268, 269, 3, 81, 40, 0, 269, 270, 3, 81, 40, 0, 270, 283, 1, 0, 0, 0, 271, 272, 3, 73, 36, 0, 272, 273, 5, 85, 0, 0, 273, 274, 3, 81, 40, 0, 274, 275, 3, 81, 40, 0, 275, 276, 3, 81, 40, 0, 276, 277, 3, 81, 40, 0, 277, 278, 3, 81, 40, 0, 278, 279, 3, 81, 40, 0, 279, 280, 3, 81, 40, 0, 280, 281, 3, 81, 40, 0, 281, 283, 1, 0, 0, 0, 282, 264, 1, 0, 0, 0, 282, 271, 1, 0, 0, 0, 283, 94, 1, 0, 0, 0, 284, 286, 7, 7, 0, 0, 285, 284, 1, 0, 0, 0, 286, 287, 1, 0, 0, 0, 287, 285, 1, 0, 0, 0, 287, 288, 1, 0, 0, 0, 288, 289, 1, 0, 0, 0, 289, 290, 6, 47, 0, 0, 290, 96, 1, 0, 0, 0, 291, 292, 5, 47, 0, 0, 292, 293, 5, 47, 0, 0, 293, 297, 1, 0, 0, 0, 294, 296, 8, 8, 0, 0, 295, 294, 1, 0, 0, 0, 296, 299, 1, 0, 0, 0, 297, 295, 1, 0, 0, 0, 297, 298, 1, 0, 0, 0, 298, 300, 1, 0, 0, 0, 299, 297, 1, 0, 0, 0, 300, 301, 6, 48, 0, 0, 301, 98, 1, 0, 0, 0, 302, 304, 3, 77, 38, 0, 303, 302, 1, 0, 0, 0, 304, 305, 1, 0, 0, 0, 305, 303, 1, 0, 0, 0, 305, 306, 1, 0, 0, 0, 306, 307, 1, 0, 0, 0, 307, 309, 5, 46, 0, 0, 308, 310, 3, 77, 38, 0, 309, 308, 1, 0, 0, 0, 310, 311, 1, 0, 0, 0, 311, 309, 1, 0, 0, 0, 311, 312, 1, 0, 0, 0, 312, 314, 1, 0, 0, 0, 313, 315, 3, 79, 39, 0, 314, 313, 1, 0, 0, 0, 314, 315, 1, 0, 0, 0, 315, 333, 1, 0, 0, 0, 316, 318, 3, 77, 38, 0, 317, 316, 1, 0, 0, 0, 318, 319, 1, 0, 0, 0, 319, 317, 1, 0, 0, 0, 319, 320, 1, 0, 0, 0, 320, 321, 1, 0, 0, 0, 321, 322, 3, 79, 39, 0, 322, 333, 1, 0, 0, 0, 323, 325, 5, 46, 0, 0, 324, 326, 3, 77, 38, 0, 325, 324, 1, 0, 0, 0, 326, 327, 1, 0, 0, 0, 327, 325, 1, 0, 0, 0, 327, 328, 1, 0, 0, 0, 328, 330, 1, 0, 0, 0, 329, 331, 3, 79, 39, 0, 330, 329, 1, 0, 0, 0, 330, 331, 1, 0, 0, 0, 331, 333, 1, 0, 0, 0, 332, 303, 1, 0, 0, 0, 332, 317, 1, 0, 0, 0, 332, 323, 1, 0, 0, 0, 333, 100, 1, 0, 0, 0, 334, 336, 3, 77, 38, 0, 335, 334, 1, 0, 0, 0, 336, 337, 1, 0, 0, 0, 337, 335, 1, 0, 0, 0, 337, 338, 1, 0, 0, 0, 338, 348, 1, 0, 0, 0, 339, 340, 5, 48, 0, 0, 340, 341, 5, 120, 0, 0, 341, 343, 1, 0, 0, 0, 342, 344, 3, 81, 40, 0, 343, 342, 1, 0, 0, 0, 344, 345, 1, 0, 0, 0, 345, 343, 1, 0, 0, 0, 345, 346, 1, 0, 0, 0, 346, 348, 1, 0, 0, 0, 347, 335, 1, 0, 0, 0, 347, 339, 1, 0, 0, 0, 348, 102, 1, 0, 0, 0, 349, 351, 3, 77, 38, 0, 350, 349, 1, 0, 0, 0, 351, 352, 1, 0, 0, 0, 352, 350, 1, 0, 0, 0, 352, 353, 1, 0, 0, 0, 353, 354, 1, 0, 0, 0, 354, 355, 7, 9, 0, 0, 355, 367, 1, 0, 0, 0, 356, 357, 5, 48, 0, 0, 357, 358, 5, 120, 0, 0, 358, 360, 1, 0, 0, 0, 359, 361, 3, 81, 40, 0, 360, 359, 1, 0, 0, 0, 361, 362, 1, 0, 0, 0, 362, 360, 1, 0, 0, 0, 362, 363, 1, 0, 0, 0, 363, 364, 1, 0, 0, 0, 364, 365, 7, 9, 0, 0, 365, 367, 1, 0, 0, 0, 366, 350, 1, 0, 0, 0, 366, 356, 1, 0, 0, 0, 367, 104, 1, 0, 0, 0, 368, 373, 5, 34, 0, 0, 369, 372, 3, 85, 42, 0, 370, 372, 8, 10, 0, 0, 371, 369, 1, 0, 0, 0, 371, 370, 1, 0, 0, 0, 372, 375, 1, 0, 0, 0, 373, 371, 1, 0, 0, 0, 373, 374, 1, 0, 0, 0, 374, 376, 1, 0, 0, 0, 375, 373, 1, 0, 0, 0, 376, 465, 5, 34, 0, 0, 377, 382, 5, 39, 0, 0, 378, 381, 3, 85, 42, 0, 379, 381, 8, 11, 0, 0, 380, 378, 1, 0, 0, 0, 380, 379, 1, 0, 0, 0, 381, 384, 1, 0, 0, 0, 382, 380, 1, 0, 0, 0, 382, 383, 1, 0, 0, 0, 383, 385, 1, 0, 0, 0, 384, 382, 1, 0, 0, 0, 385, 465, 5, 39, 0, 0, 386, 387, 5, 34, 0, 0, 387, 388, 5, 34, 0, 0, 388, 389, 5, 34, 0, 0, 389, 394, 1, 0, 0, 0, 390, 393, 3, 85, 42, 0, 391, 393, 8, 12, 0, 0, 392, 390, 1, 0, 0, 0, 392, 391, 1, 0, 0, 0, 393, 396, 1, 0, 0, 0, 394, 395, 1, 0, 0, 0, 394, 392, 1, 0, 0, 0, 395, 397, 1, 0, 0, 0, 396, 394, 1, 0, 0, 0, 397, 398, 5, 34, 0, 0, 398, 399, 5, 34, 0, 0, 399, 465, 5, 34, 0, 0, 400, 401, 5, 39, 0, 0, 401, 402, 5, 39, 0, 0, 402, 403, 5, 39, 0, 0, 403, 408, 1, 0, 0, 0, 404, 407, 3, 85, 42, 0, 405, 407, 8, 12, 0, 0, 406, 404, 1, 0, 0, 0, 406, 405, 1, 0, 0, 0, 407, 410, 1, 0, 0, 0, 408, 409, 1, 0, 0, 0, 408, 406, 1, 0, 0, 0, 409, 411, 1, 0, 0, 0, 410, 408, 1, 0, 0, 0, 411, 412, 5, 39, 0, 0, 412, 413, 5, 39, 0, 0, 413, 465, 5, 39, 0, 0, 414, 415, 3, 83, 41, 0, 415, 419, 5, 34, 0, 0, 416, 418, 8, 13, 0, 0, 417, 416, 1, 0, 0, 0, 418, 421, 1, 0, 0, 0, 419, 417, 1, 0, 0, 0, 419, 420, 1, 0, 0, 0, 420, 422, 1, 0, 0, 0, 421, 419, 1, 0, 0, 0, 422, 423, 5, 34, 0, 0, 423, 465, 1, 0, 0, 0, 424, 425, 3, 83, 41, 0, 425, 429, 5, 39, 0, 0, 426, 428, 8, 14, 0, 0, 427, 426, 1, 0, 0, 0, 428, 431, 1, 0, 0, 0, 429, 427, 1, 0, 0, 0, 429, 430, 1, 0, 0, 0, 430, 432, 1, 0, 0, 0, 431, 429, 1, 0, 0, 0, 432, 433, 5, 39, 0, 0, 433, 465, 1, 0, 0, 0, 434, 435, 3, 83, 41, 0, 435, 436, 5, 34, 0, 0, 436, 437, 5, 34, 0, 0, 437, 438, 5, 34, 0, 0, 438, 442, 1, 0, 0, 0, 439, 441, 9, 0, 0, 0, 440, 439, 1, 0, 0, 0, 441, 444, 1, 0, 0, 0, 442, 443, 1, 0, 0, 0, 442, 440, 1, 0, 0, 0, 443, 445, 1, 0, 0, 0, 444, 442, 1, 0, 0, 0, 445, 446, 5, 34, 0, 0, 446, 447, 5, 34, 0, 0, 447, 448, 5, 34, 0, 0, 448, 465, 1, 0, 0, 0, 449, 450, 3, 83, 41, 0, 450, 451, 5, 39, 0, 0, 451, 452, 5, 39, 0, 0, 452, 453, 5, 39, 0, 0, 453, 457, 1, 0, 0, 0, 454, 456, 9, 0, 0, 0, 455, 454, 1, 0, 0, 0, 456, 459, 1, 0, 0, 0, 457, 458, 1, 0, 0, 0, 457, 455, 1, 0, 0, 0, 458, 460, 1, 0, 0, 0, 459, 457, 1, 0, 0, 0, 460, 461, 5, 39, 0, 0, 461, 462, 5, 39, 0, 0, 462, 463, 5, 39, 0, 0, 463, 465, 1, 0, 0, 0, 464, 368, 1, 0, 0, 0, 464, 377, 1, 0, 0, 0, 464, 386, 1, 0, 0, 0, 464, 400, 1, 0, 0, 0, 464, 414, 1, 0, 0, 0, 464, 424, 1, 0, 0, 0, 464, 434, 1, 0, 0, 0, 464, 449, 1, 0, 0, 0, 465, 106, 1, 0, 0, 0, 466, 467, 7, 15, 0, 0, 467, 468, 3, 105, 52, 0, 468, 108, 1, 0, 0, 0, 469, 472, 3, 75, 37, 0, 470, 472, 5, 95, 0, 0, 471, 469, 1, 0, 0, 0, 471, 470, 1, 0, 0, 0, 472, 478, 1, 0, 0, 0, 473, 477, 3, 75, 37, 0, 474, 477, 3, 77, 38, 0, 475, 477, 5, 95, 0, 0, 476, 473, 1, 0, 0, 0, 476, 474, 1, 0, 0, 0, 476, 475, 1, 0, 0, 0, 477, 480, 1, 0, 0, 0, 478, 476, 1, 0, 0, 0, 478, 479, 1, 0, 0, 0, 479, 110, 1, 0, 0, 0, 480, 478, 1, 0, 0, 0, 37, 0, 143, 234, 239, 249, 282, 287, 297, 305, 311, 314, 319, 327, 330, 332, 337, 345, 347, 352, 362, 366, 371, 373, 380, 382, 392, 394, 406, 408, 419, 429, 442, 457, 464, 471, 476, 478, 1, 0, 1, 0] \ No newline at end of file diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/parser/CommandsLexer.tokens golang-github-google-cel-go-0.12.5+ds/repl/parser/CommandsLexer.tokens --- golang-github-google-cel-go-0.11.4+ds/repl/parser/CommandsLexer.tokens 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/parser/CommandsLexer.tokens 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,78 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +COMMAND=5 +FLAG=6 +ARROW=7 +EQUAL_ASSIGN=8 +EQUALS=9 +NOT_EQUALS=10 +IN=11 +LESS=12 +LESS_EQUALS=13 +GREATER_EQUALS=14 +GREATER=15 +LOGICAL_AND=16 +LOGICAL_OR=17 +LBRACKET=18 +RPRACKET=19 +LBRACE=20 +RBRACE=21 +LPAREN=22 +RPAREN=23 +DOT=24 +COMMA=25 +MINUS=26 +EXCLAM=27 +QUESTIONMARK=28 +COLON=29 +PLUS=30 +STAR=31 +SLASH=32 +PERCENT=33 +CEL_TRUE=34 +CEL_FALSE=35 +NUL=36 +WHITESPACE=37 +COMMENT=38 +NUM_FLOAT=39 +NUM_INT=40 +NUM_UINT=41 +STRING=42 +BYTES=43 +IDENTIFIER=44 +'%let'=1 +'%declare'=2 +'%delete'=3 +'%eval'=4 +'->'=7 +'='=8 +'=='=9 +'!='=10 +'in'=11 +'<'=12 +'<='=13 +'>='=14 +'>'=15 +'&&'=16 +'||'=17 +'['=18 +']'=19 +'{'=20 +'}'=21 +'('=22 +')'=23 +'.'=24 +','=25 +'-'=26 +'!'=27 +'?'=28 +':'=29 +'+'=30 +'*'=31 +'/'=32 +'%'=33 +'true'=34 +'false'=35 +'null'=36 diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/parser/commands_listener.go golang-github-google-cel-go-0.12.5+ds/repl/parser/commands_listener.go --- golang-github-google-cel-go-0.11.4+ds/repl/parser/commands_listener.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/parser/commands_listener.go 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,279 @@ +// Code generated from ./Commands.g4 by ANTLR 4.10.1. DO NOT EDIT. + +package parser // Commands +import "github.com/antlr/antlr4/runtime/Go/antlr" + +// CommandsListener is a complete listener for a parse tree produced by CommandsParser. +type CommandsListener interface { + antlr.ParseTreeListener + + // EnterStartCommand is called when entering the startCommand production. + EnterStartCommand(c *StartCommandContext) + + // EnterCommand is called when entering the command production. + EnterCommand(c *CommandContext) + + // EnterLet is called when entering the let production. + EnterLet(c *LetContext) + + // EnterDeclare is called when entering the declare production. + EnterDeclare(c *DeclareContext) + + // EnterVarDecl is called when entering the varDecl production. + EnterVarDecl(c *VarDeclContext) + + // EnterFnDecl is called when entering the fnDecl production. + EnterFnDecl(c *FnDeclContext) + + // EnterParam is called when entering the param production. + EnterParam(c *ParamContext) + + // EnterDelete is called when entering the delete production. + EnterDelete(c *DeleteContext) + + // EnterSimple is called when entering the simple production. + EnterSimple(c *SimpleContext) + + // EnterEmpty is called when entering the empty production. + EnterEmpty(c *EmptyContext) + + // EnterExprCmd is called when entering the exprCmd production. + EnterExprCmd(c *ExprCmdContext) + + // EnterQualId is called when entering the qualId production. + EnterQualId(c *QualIdContext) + + // EnterStartType is called when entering the startType production. + EnterStartType(c *StartTypeContext) + + // EnterType is called when entering the type production. + EnterType(c *TypeContext) + + // EnterTypeId is called when entering the typeId production. + EnterTypeId(c *TypeIdContext) + + // EnterTypeParamList is called when entering the typeParamList production. + EnterTypeParamList(c *TypeParamListContext) + + // 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) + + // ExitStartCommand is called when exiting the startCommand production. + ExitStartCommand(c *StartCommandContext) + + // ExitCommand is called when exiting the command production. + ExitCommand(c *CommandContext) + + // ExitLet is called when exiting the let production. + ExitLet(c *LetContext) + + // ExitDeclare is called when exiting the declare production. + ExitDeclare(c *DeclareContext) + + // ExitVarDecl is called when exiting the varDecl production. + ExitVarDecl(c *VarDeclContext) + + // ExitFnDecl is called when exiting the fnDecl production. + ExitFnDecl(c *FnDeclContext) + + // ExitParam is called when exiting the param production. + ExitParam(c *ParamContext) + + // ExitDelete is called when exiting the delete production. + ExitDelete(c *DeleteContext) + + // ExitSimple is called when exiting the simple production. + ExitSimple(c *SimpleContext) + + // ExitEmpty is called when exiting the empty production. + ExitEmpty(c *EmptyContext) + + // ExitExprCmd is called when exiting the exprCmd production. + ExitExprCmd(c *ExprCmdContext) + + // ExitQualId is called when exiting the qualId production. + ExitQualId(c *QualIdContext) + + // ExitStartType is called when exiting the startType production. + ExitStartType(c *StartTypeContext) + + // ExitType is called when exiting the type production. + ExitType(c *TypeContext) + + // ExitTypeId is called when exiting the typeId production. + ExitTypeId(c *TypeIdContext) + + // ExitTypeParamList is called when exiting the typeParamList production. + ExitTypeParamList(c *TypeParamListContext) + + // 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 -Nru golang-github-google-cel-go-0.11.4+ds/repl/parser/commands_parser.go golang-github-google-cel-go-0.12.5+ds/repl/parser/commands_parser.go --- golang-github-google-cel-go-0.11.4+ds/repl/parser/commands_parser.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/parser/commands_parser.go 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,7704 @@ +// Code generated from ./Commands.g4 by ANTLR 4.10.1. DO NOT EDIT. + +package parser // Commands +import ( + "fmt" + "strconv" + "sync" + + "github.com/antlr/antlr4/runtime/Go/antlr" +) + +// Suppress unused import errors +var _ = fmt.Printf +var _ = strconv.Itoa +var _ = sync.Once{} + +type CommandsParser struct { + *antlr.BaseParser +} + +var commandsParserStaticData struct { + once sync.Once + serializedATN []int32 + literalNames []string + symbolicNames []string + ruleNames []string + predictionContextCache *antlr.PredictionContextCache + atn *antlr.ATN + decisionToDFA []*antlr.DFA +} + +func commandsParserInit() { + staticData := &commandsParserStaticData + staticData.literalNames = []string{ + "", "'%let'", "'%declare'", "'%delete'", "'%eval'", "", "", "'->'", + "'='", "'=='", "'!='", "'in'", "'<'", "'<='", "'>='", "'>'", "'&&'", + "'||'", "'['", "']'", "'{'", "'}'", "'('", "')'", "'.'", "','", "'-'", + "'!'", "'?'", "':'", "'+'", "'*'", "'/'", "'%'", "'true'", "'false'", + "'null'", + } + staticData.symbolicNames = []string{ + "", "", "", "", "", "COMMAND", "FLAG", "ARROW", "EQUAL_ASSIGN", "EQUALS", + "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", "GREATER_EQUALS", "GREATER", + "LOGICAL_AND", "LOGICAL_OR", "LBRACKET", "RPRACKET", "LBRACE", "RBRACE", + "LPAREN", "RPAREN", "DOT", "COMMA", "MINUS", "EXCLAM", "QUESTIONMARK", + "COLON", "PLUS", "STAR", "SLASH", "PERCENT", "CEL_TRUE", "CEL_FALSE", + "NUL", "WHITESPACE", "COMMENT", "NUM_FLOAT", "NUM_INT", "NUM_UINT", + "STRING", "BYTES", "IDENTIFIER", + } + staticData.ruleNames = []string{ + "startCommand", "command", "let", "declare", "varDecl", "fnDecl", "param", + "delete", "simple", "empty", "exprCmd", "qualId", "startType", "type", + "typeId", "typeParamList", "start", "expr", "conditionalOr", "conditionalAnd", + "relation", "calc", "unary", "member", "primary", "exprList", "fieldInitializerList", + "mapInitializerList", "literal", + } + staticData.predictionContextCache = antlr.NewPredictionContextCache() + staticData.serializedATN = []int32{ + 4, 1, 44, 353, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, + 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, + 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, + 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, + 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, + 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 1, 68, 8, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, + 2, 3, 2, 77, 8, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 3, 3, 84, 8, 3, 1, 4, + 1, 4, 1, 4, 3, 4, 89, 8, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 96, 8, + 5, 10, 5, 12, 5, 99, 9, 5, 3, 5, 101, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, + 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 3, 7, 114, 8, 7, 1, 8, 1, 8, 1, + 8, 5, 8, 119, 8, 8, 10, 8, 12, 8, 122, 9, 8, 1, 9, 1, 9, 1, 10, 3, 10, + 127, 8, 10, 1, 10, 1, 10, 1, 11, 3, 11, 132, 8, 11, 1, 11, 1, 11, 1, 11, + 5, 11, 137, 8, 11, 10, 11, 12, 11, 140, 9, 11, 1, 12, 1, 12, 1, 12, 1, + 13, 1, 13, 3, 13, 147, 8, 13, 1, 14, 3, 14, 150, 8, 14, 1, 14, 1, 14, 1, + 14, 5, 14, 155, 8, 14, 10, 14, 12, 14, 158, 9, 14, 1, 15, 1, 15, 1, 15, + 1, 15, 5, 15, 164, 8, 15, 10, 15, 12, 15, 167, 9, 15, 1, 15, 1, 15, 1, + 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 3, 17, 180, + 8, 17, 1, 18, 1, 18, 1, 18, 5, 18, 185, 8, 18, 10, 18, 12, 18, 188, 9, + 18, 1, 19, 1, 19, 1, 19, 5, 19, 193, 8, 19, 10, 19, 12, 19, 196, 9, 19, + 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 5, 20, 204, 8, 20, 10, 20, 12, + 20, 207, 9, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, + 1, 21, 5, 21, 218, 8, 21, 10, 21, 12, 21, 221, 9, 21, 1, 22, 1, 22, 4, + 22, 225, 8, 22, 11, 22, 12, 22, 226, 1, 22, 1, 22, 4, 22, 231, 8, 22, 11, + 22, 12, 22, 232, 1, 22, 3, 22, 236, 8, 22, 1, 23, 1, 23, 1, 23, 1, 23, + 1, 23, 1, 23, 1, 23, 1, 23, 3, 23, 246, 8, 23, 1, 23, 3, 23, 249, 8, 23, + 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 3, 23, 259, 8, + 23, 1, 23, 3, 23, 262, 8, 23, 1, 23, 5, 23, 265, 8, 23, 10, 23, 12, 23, + 268, 9, 23, 1, 24, 3, 24, 271, 8, 24, 1, 24, 1, 24, 1, 24, 3, 24, 276, + 8, 24, 1, 24, 3, 24, 279, 8, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, + 24, 3, 24, 287, 8, 24, 1, 24, 3, 24, 290, 8, 24, 1, 24, 1, 24, 1, 24, 3, + 24, 295, 8, 24, 1, 24, 3, 24, 298, 8, 24, 1, 24, 1, 24, 3, 24, 302, 8, + 24, 1, 25, 1, 25, 1, 25, 5, 25, 307, 8, 25, 10, 25, 12, 25, 310, 9, 25, + 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 5, 26, 319, 8, 26, 10, + 26, 12, 26, 322, 9, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, + 1, 27, 5, 27, 332, 8, 27, 10, 27, 12, 27, 335, 9, 27, 1, 28, 3, 28, 338, + 8, 28, 1, 28, 1, 28, 1, 28, 3, 28, 343, 8, 28, 1, 28, 1, 28, 1, 28, 1, + 28, 1, 28, 1, 28, 3, 28, 351, 8, 28, 1, 28, 0, 3, 40, 42, 46, 29, 0, 2, + 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, + 42, 44, 46, 48, 50, 52, 54, 56, 0, 4, 2, 0, 36, 36, 44, 44, 1, 0, 9, 15, + 1, 0, 31, 33, 2, 0, 26, 26, 30, 30, 383, 0, 58, 1, 0, 0, 0, 2, 67, 1, 0, + 0, 0, 4, 69, 1, 0, 0, 0, 6, 80, 1, 0, 0, 0, 8, 85, 1, 0, 0, 0, 10, 90, + 1, 0, 0, 0, 12, 106, 1, 0, 0, 0, 14, 110, 1, 0, 0, 0, 16, 115, 1, 0, 0, + 0, 18, 123, 1, 0, 0, 0, 20, 126, 1, 0, 0, 0, 22, 131, 1, 0, 0, 0, 24, 141, + 1, 0, 0, 0, 26, 144, 1, 0, 0, 0, 28, 149, 1, 0, 0, 0, 30, 159, 1, 0, 0, + 0, 32, 170, 1, 0, 0, 0, 34, 173, 1, 0, 0, 0, 36, 181, 1, 0, 0, 0, 38, 189, + 1, 0, 0, 0, 40, 197, 1, 0, 0, 0, 42, 208, 1, 0, 0, 0, 44, 235, 1, 0, 0, + 0, 46, 237, 1, 0, 0, 0, 48, 301, 1, 0, 0, 0, 50, 303, 1, 0, 0, 0, 52, 311, + 1, 0, 0, 0, 54, 323, 1, 0, 0, 0, 56, 350, 1, 0, 0, 0, 58, 59, 3, 2, 1, + 0, 59, 60, 5, 0, 0, 1, 60, 1, 1, 0, 0, 0, 61, 68, 3, 4, 2, 0, 62, 68, 3, + 6, 3, 0, 63, 68, 3, 14, 7, 0, 64, 68, 3, 16, 8, 0, 65, 68, 3, 20, 10, 0, + 66, 68, 3, 18, 9, 0, 67, 61, 1, 0, 0, 0, 67, 62, 1, 0, 0, 0, 67, 63, 1, + 0, 0, 0, 67, 64, 1, 0, 0, 0, 67, 65, 1, 0, 0, 0, 67, 66, 1, 0, 0, 0, 68, + 3, 1, 0, 0, 0, 69, 76, 5, 1, 0, 0, 70, 71, 3, 8, 4, 0, 71, 72, 5, 8, 0, + 0, 72, 77, 1, 0, 0, 0, 73, 74, 3, 10, 5, 0, 74, 75, 5, 7, 0, 0, 75, 77, + 1, 0, 0, 0, 76, 70, 1, 0, 0, 0, 76, 73, 1, 0, 0, 0, 77, 78, 1, 0, 0, 0, + 78, 79, 3, 34, 17, 0, 79, 5, 1, 0, 0, 0, 80, 83, 5, 2, 0, 0, 81, 84, 3, + 8, 4, 0, 82, 84, 3, 10, 5, 0, 83, 81, 1, 0, 0, 0, 83, 82, 1, 0, 0, 0, 84, + 7, 1, 0, 0, 0, 85, 88, 3, 22, 11, 0, 86, 87, 5, 29, 0, 0, 87, 89, 3, 26, + 13, 0, 88, 86, 1, 0, 0, 0, 88, 89, 1, 0, 0, 0, 89, 9, 1, 0, 0, 0, 90, 91, + 3, 22, 11, 0, 91, 100, 5, 22, 0, 0, 92, 97, 3, 12, 6, 0, 93, 94, 5, 25, + 0, 0, 94, 96, 3, 12, 6, 0, 95, 93, 1, 0, 0, 0, 96, 99, 1, 0, 0, 0, 97, + 95, 1, 0, 0, 0, 97, 98, 1, 0, 0, 0, 98, 101, 1, 0, 0, 0, 99, 97, 1, 0, + 0, 0, 100, 92, 1, 0, 0, 0, 100, 101, 1, 0, 0, 0, 101, 102, 1, 0, 0, 0, + 102, 103, 5, 23, 0, 0, 103, 104, 5, 29, 0, 0, 104, 105, 3, 26, 13, 0, 105, + 11, 1, 0, 0, 0, 106, 107, 5, 44, 0, 0, 107, 108, 5, 29, 0, 0, 108, 109, + 3, 26, 13, 0, 109, 13, 1, 0, 0, 0, 110, 113, 5, 3, 0, 0, 111, 114, 3, 8, + 4, 0, 112, 114, 3, 10, 5, 0, 113, 111, 1, 0, 0, 0, 113, 112, 1, 0, 0, 0, + 114, 15, 1, 0, 0, 0, 115, 120, 5, 5, 0, 0, 116, 119, 5, 6, 0, 0, 117, 119, + 5, 42, 0, 0, 118, 116, 1, 0, 0, 0, 118, 117, 1, 0, 0, 0, 119, 122, 1, 0, + 0, 0, 120, 118, 1, 0, 0, 0, 120, 121, 1, 0, 0, 0, 121, 17, 1, 0, 0, 0, + 122, 120, 1, 0, 0, 0, 123, 124, 1, 0, 0, 0, 124, 19, 1, 0, 0, 0, 125, 127, + 5, 4, 0, 0, 126, 125, 1, 0, 0, 0, 126, 127, 1, 0, 0, 0, 127, 128, 1, 0, + 0, 0, 128, 129, 3, 34, 17, 0, 129, 21, 1, 0, 0, 0, 130, 132, 5, 24, 0, + 0, 131, 130, 1, 0, 0, 0, 131, 132, 1, 0, 0, 0, 132, 133, 1, 0, 0, 0, 133, + 138, 5, 44, 0, 0, 134, 135, 5, 24, 0, 0, 135, 137, 5, 44, 0, 0, 136, 134, + 1, 0, 0, 0, 137, 140, 1, 0, 0, 0, 138, 136, 1, 0, 0, 0, 138, 139, 1, 0, + 0, 0, 139, 23, 1, 0, 0, 0, 140, 138, 1, 0, 0, 0, 141, 142, 3, 26, 13, 0, + 142, 143, 5, 0, 0, 1, 143, 25, 1, 0, 0, 0, 144, 146, 3, 28, 14, 0, 145, + 147, 3, 30, 15, 0, 146, 145, 1, 0, 0, 0, 146, 147, 1, 0, 0, 0, 147, 27, + 1, 0, 0, 0, 148, 150, 5, 24, 0, 0, 149, 148, 1, 0, 0, 0, 149, 150, 1, 0, + 0, 0, 150, 151, 1, 0, 0, 0, 151, 156, 7, 0, 0, 0, 152, 153, 5, 24, 0, 0, + 153, 155, 5, 44, 0, 0, 154, 152, 1, 0, 0, 0, 155, 158, 1, 0, 0, 0, 156, + 154, 1, 0, 0, 0, 156, 157, 1, 0, 0, 0, 157, 29, 1, 0, 0, 0, 158, 156, 1, + 0, 0, 0, 159, 160, 5, 22, 0, 0, 160, 165, 3, 26, 13, 0, 161, 162, 5, 25, + 0, 0, 162, 164, 3, 26, 13, 0, 163, 161, 1, 0, 0, 0, 164, 167, 1, 0, 0, + 0, 165, 163, 1, 0, 0, 0, 165, 166, 1, 0, 0, 0, 166, 168, 1, 0, 0, 0, 167, + 165, 1, 0, 0, 0, 168, 169, 5, 23, 0, 0, 169, 31, 1, 0, 0, 0, 170, 171, + 3, 34, 17, 0, 171, 172, 5, 0, 0, 1, 172, 33, 1, 0, 0, 0, 173, 179, 3, 36, + 18, 0, 174, 175, 5, 28, 0, 0, 175, 176, 3, 36, 18, 0, 176, 177, 5, 29, + 0, 0, 177, 178, 3, 34, 17, 0, 178, 180, 1, 0, 0, 0, 179, 174, 1, 0, 0, + 0, 179, 180, 1, 0, 0, 0, 180, 35, 1, 0, 0, 0, 181, 186, 3, 38, 19, 0, 182, + 183, 5, 17, 0, 0, 183, 185, 3, 38, 19, 0, 184, 182, 1, 0, 0, 0, 185, 188, + 1, 0, 0, 0, 186, 184, 1, 0, 0, 0, 186, 187, 1, 0, 0, 0, 187, 37, 1, 0, + 0, 0, 188, 186, 1, 0, 0, 0, 189, 194, 3, 40, 20, 0, 190, 191, 5, 16, 0, + 0, 191, 193, 3, 40, 20, 0, 192, 190, 1, 0, 0, 0, 193, 196, 1, 0, 0, 0, + 194, 192, 1, 0, 0, 0, 194, 195, 1, 0, 0, 0, 195, 39, 1, 0, 0, 0, 196, 194, + 1, 0, 0, 0, 197, 198, 6, 20, -1, 0, 198, 199, 3, 42, 21, 0, 199, 205, 1, + 0, 0, 0, 200, 201, 10, 1, 0, 0, 201, 202, 7, 1, 0, 0, 202, 204, 3, 40, + 20, 2, 203, 200, 1, 0, 0, 0, 204, 207, 1, 0, 0, 0, 205, 203, 1, 0, 0, 0, + 205, 206, 1, 0, 0, 0, 206, 41, 1, 0, 0, 0, 207, 205, 1, 0, 0, 0, 208, 209, + 6, 21, -1, 0, 209, 210, 3, 44, 22, 0, 210, 219, 1, 0, 0, 0, 211, 212, 10, + 2, 0, 0, 212, 213, 7, 2, 0, 0, 213, 218, 3, 42, 21, 3, 214, 215, 10, 1, + 0, 0, 215, 216, 7, 3, 0, 0, 216, 218, 3, 42, 21, 2, 217, 211, 1, 0, 0, + 0, 217, 214, 1, 0, 0, 0, 218, 221, 1, 0, 0, 0, 219, 217, 1, 0, 0, 0, 219, + 220, 1, 0, 0, 0, 220, 43, 1, 0, 0, 0, 221, 219, 1, 0, 0, 0, 222, 236, 3, + 46, 23, 0, 223, 225, 5, 27, 0, 0, 224, 223, 1, 0, 0, 0, 225, 226, 1, 0, + 0, 0, 226, 224, 1, 0, 0, 0, 226, 227, 1, 0, 0, 0, 227, 228, 1, 0, 0, 0, + 228, 236, 3, 46, 23, 0, 229, 231, 5, 26, 0, 0, 230, 229, 1, 0, 0, 0, 231, + 232, 1, 0, 0, 0, 232, 230, 1, 0, 0, 0, 232, 233, 1, 0, 0, 0, 233, 234, + 1, 0, 0, 0, 234, 236, 3, 46, 23, 0, 235, 222, 1, 0, 0, 0, 235, 224, 1, + 0, 0, 0, 235, 230, 1, 0, 0, 0, 236, 45, 1, 0, 0, 0, 237, 238, 6, 23, -1, + 0, 238, 239, 3, 48, 24, 0, 239, 266, 1, 0, 0, 0, 240, 241, 10, 3, 0, 0, + 241, 242, 5, 24, 0, 0, 242, 248, 5, 44, 0, 0, 243, 245, 5, 22, 0, 0, 244, + 246, 3, 50, 25, 0, 245, 244, 1, 0, 0, 0, 245, 246, 1, 0, 0, 0, 246, 247, + 1, 0, 0, 0, 247, 249, 5, 23, 0, 0, 248, 243, 1, 0, 0, 0, 248, 249, 1, 0, + 0, 0, 249, 265, 1, 0, 0, 0, 250, 251, 10, 2, 0, 0, 251, 252, 5, 18, 0, + 0, 252, 253, 3, 34, 17, 0, 253, 254, 5, 19, 0, 0, 254, 265, 1, 0, 0, 0, + 255, 256, 10, 1, 0, 0, 256, 258, 5, 20, 0, 0, 257, 259, 3, 52, 26, 0, 258, + 257, 1, 0, 0, 0, 258, 259, 1, 0, 0, 0, 259, 261, 1, 0, 0, 0, 260, 262, + 5, 25, 0, 0, 261, 260, 1, 0, 0, 0, 261, 262, 1, 0, 0, 0, 262, 263, 1, 0, + 0, 0, 263, 265, 5, 21, 0, 0, 264, 240, 1, 0, 0, 0, 264, 250, 1, 0, 0, 0, + 264, 255, 1, 0, 0, 0, 265, 268, 1, 0, 0, 0, 266, 264, 1, 0, 0, 0, 266, + 267, 1, 0, 0, 0, 267, 47, 1, 0, 0, 0, 268, 266, 1, 0, 0, 0, 269, 271, 5, + 24, 0, 0, 270, 269, 1, 0, 0, 0, 270, 271, 1, 0, 0, 0, 271, 272, 1, 0, 0, + 0, 272, 278, 5, 44, 0, 0, 273, 275, 5, 22, 0, 0, 274, 276, 3, 50, 25, 0, + 275, 274, 1, 0, 0, 0, 275, 276, 1, 0, 0, 0, 276, 277, 1, 0, 0, 0, 277, + 279, 5, 23, 0, 0, 278, 273, 1, 0, 0, 0, 278, 279, 1, 0, 0, 0, 279, 302, + 1, 0, 0, 0, 280, 281, 5, 22, 0, 0, 281, 282, 3, 34, 17, 0, 282, 283, 5, + 23, 0, 0, 283, 302, 1, 0, 0, 0, 284, 286, 5, 18, 0, 0, 285, 287, 3, 50, + 25, 0, 286, 285, 1, 0, 0, 0, 286, 287, 1, 0, 0, 0, 287, 289, 1, 0, 0, 0, + 288, 290, 5, 25, 0, 0, 289, 288, 1, 0, 0, 0, 289, 290, 1, 0, 0, 0, 290, + 291, 1, 0, 0, 0, 291, 302, 5, 19, 0, 0, 292, 294, 5, 20, 0, 0, 293, 295, + 3, 54, 27, 0, 294, 293, 1, 0, 0, 0, 294, 295, 1, 0, 0, 0, 295, 297, 1, + 0, 0, 0, 296, 298, 5, 25, 0, 0, 297, 296, 1, 0, 0, 0, 297, 298, 1, 0, 0, + 0, 298, 299, 1, 0, 0, 0, 299, 302, 5, 21, 0, 0, 300, 302, 3, 56, 28, 0, + 301, 270, 1, 0, 0, 0, 301, 280, 1, 0, 0, 0, 301, 284, 1, 0, 0, 0, 301, + 292, 1, 0, 0, 0, 301, 300, 1, 0, 0, 0, 302, 49, 1, 0, 0, 0, 303, 308, 3, + 34, 17, 0, 304, 305, 5, 25, 0, 0, 305, 307, 3, 34, 17, 0, 306, 304, 1, + 0, 0, 0, 307, 310, 1, 0, 0, 0, 308, 306, 1, 0, 0, 0, 308, 309, 1, 0, 0, + 0, 309, 51, 1, 0, 0, 0, 310, 308, 1, 0, 0, 0, 311, 312, 5, 44, 0, 0, 312, + 313, 5, 29, 0, 0, 313, 320, 3, 34, 17, 0, 314, 315, 5, 25, 0, 0, 315, 316, + 5, 44, 0, 0, 316, 317, 5, 29, 0, 0, 317, 319, 3, 34, 17, 0, 318, 314, 1, + 0, 0, 0, 319, 322, 1, 0, 0, 0, 320, 318, 1, 0, 0, 0, 320, 321, 1, 0, 0, + 0, 321, 53, 1, 0, 0, 0, 322, 320, 1, 0, 0, 0, 323, 324, 3, 34, 17, 0, 324, + 325, 5, 29, 0, 0, 325, 333, 3, 34, 17, 0, 326, 327, 5, 25, 0, 0, 327, 328, + 3, 34, 17, 0, 328, 329, 5, 29, 0, 0, 329, 330, 3, 34, 17, 0, 330, 332, + 1, 0, 0, 0, 331, 326, 1, 0, 0, 0, 332, 335, 1, 0, 0, 0, 333, 331, 1, 0, + 0, 0, 333, 334, 1, 0, 0, 0, 334, 55, 1, 0, 0, 0, 335, 333, 1, 0, 0, 0, + 336, 338, 5, 26, 0, 0, 337, 336, 1, 0, 0, 0, 337, 338, 1, 0, 0, 0, 338, + 339, 1, 0, 0, 0, 339, 351, 5, 40, 0, 0, 340, 351, 5, 41, 0, 0, 341, 343, + 5, 26, 0, 0, 342, 341, 1, 0, 0, 0, 342, 343, 1, 0, 0, 0, 343, 344, 1, 0, + 0, 0, 344, 351, 5, 39, 0, 0, 345, 351, 5, 42, 0, 0, 346, 351, 5, 43, 0, + 0, 347, 351, 5, 34, 0, 0, 348, 351, 5, 35, 0, 0, 349, 351, 5, 36, 0, 0, + 350, 337, 1, 0, 0, 0, 350, 340, 1, 0, 0, 0, 350, 342, 1, 0, 0, 0, 350, + 345, 1, 0, 0, 0, 350, 346, 1, 0, 0, 0, 350, 347, 1, 0, 0, 0, 350, 348, + 1, 0, 0, 0, 350, 349, 1, 0, 0, 0, 351, 57, 1, 0, 0, 0, 45, 67, 76, 83, + 88, 97, 100, 113, 118, 120, 126, 131, 138, 146, 149, 156, 165, 179, 186, + 194, 205, 217, 219, 226, 232, 235, 245, 248, 258, 261, 264, 266, 270, 275, + 278, 286, 289, 294, 297, 301, 308, 320, 333, 337, 342, 350, + } + deserializer := antlr.NewATNDeserializer(nil) + staticData.atn = deserializer.Deserialize(staticData.serializedATN) + atn := staticData.atn + staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState)) + decisionToDFA := staticData.decisionToDFA + for index, state := range atn.DecisionToState { + decisionToDFA[index] = antlr.NewDFA(state, index) + } +} + +// CommandsParserInit initializes any static state used to implement CommandsParser. By default the +// static state used to implement the parser is lazily initialized during the first call to +// NewCommandsParser(). You can call this function if you wish to initialize the static state ahead +// of time. +func CommandsParserInit() { + staticData := &commandsParserStaticData + staticData.once.Do(commandsParserInit) +} + +// NewCommandsParser produces a new parser instance for the optional input antlr.TokenStream. +func NewCommandsParser(input antlr.TokenStream) *CommandsParser { + CommandsParserInit() + this := new(CommandsParser) + this.BaseParser = antlr.NewBaseParser(input) + staticData := &commandsParserStaticData + this.Interpreter = antlr.NewParserATNSimulator(this, staticData.atn, staticData.decisionToDFA, staticData.predictionContextCache) + this.RuleNames = staticData.ruleNames + this.LiteralNames = staticData.literalNames + this.SymbolicNames = staticData.symbolicNames + this.GrammarFileName = "Commands.g4" + + return this +} + +// CommandsParser tokens. +const ( + CommandsParserEOF = antlr.TokenEOF + CommandsParserT__0 = 1 + CommandsParserT__1 = 2 + CommandsParserT__2 = 3 + CommandsParserT__3 = 4 + CommandsParserCOMMAND = 5 + CommandsParserFLAG = 6 + CommandsParserARROW = 7 + CommandsParserEQUAL_ASSIGN = 8 + CommandsParserEQUALS = 9 + CommandsParserNOT_EQUALS = 10 + CommandsParserIN = 11 + CommandsParserLESS = 12 + CommandsParserLESS_EQUALS = 13 + CommandsParserGREATER_EQUALS = 14 + CommandsParserGREATER = 15 + CommandsParserLOGICAL_AND = 16 + CommandsParserLOGICAL_OR = 17 + CommandsParserLBRACKET = 18 + CommandsParserRPRACKET = 19 + CommandsParserLBRACE = 20 + CommandsParserRBRACE = 21 + CommandsParserLPAREN = 22 + CommandsParserRPAREN = 23 + CommandsParserDOT = 24 + CommandsParserCOMMA = 25 + CommandsParserMINUS = 26 + CommandsParserEXCLAM = 27 + CommandsParserQUESTIONMARK = 28 + CommandsParserCOLON = 29 + CommandsParserPLUS = 30 + CommandsParserSTAR = 31 + CommandsParserSLASH = 32 + CommandsParserPERCENT = 33 + CommandsParserCEL_TRUE = 34 + CommandsParserCEL_FALSE = 35 + CommandsParserNUL = 36 + CommandsParserWHITESPACE = 37 + CommandsParserCOMMENT = 38 + CommandsParserNUM_FLOAT = 39 + CommandsParserNUM_INT = 40 + CommandsParserNUM_UINT = 41 + CommandsParserSTRING = 42 + CommandsParserBYTES = 43 + CommandsParserIDENTIFIER = 44 +) + +// CommandsParser rules. +const ( + CommandsParserRULE_startCommand = 0 + CommandsParserRULE_command = 1 + CommandsParserRULE_let = 2 + CommandsParserRULE_declare = 3 + CommandsParserRULE_varDecl = 4 + CommandsParserRULE_fnDecl = 5 + CommandsParserRULE_param = 6 + CommandsParserRULE_delete = 7 + CommandsParserRULE_simple = 8 + CommandsParserRULE_empty = 9 + CommandsParserRULE_exprCmd = 10 + CommandsParserRULE_qualId = 11 + CommandsParserRULE_startType = 12 + CommandsParserRULE_type = 13 + CommandsParserRULE_typeId = 14 + CommandsParserRULE_typeParamList = 15 + CommandsParserRULE_start = 16 + CommandsParserRULE_expr = 17 + CommandsParserRULE_conditionalOr = 18 + CommandsParserRULE_conditionalAnd = 19 + CommandsParserRULE_relation = 20 + CommandsParserRULE_calc = 21 + CommandsParserRULE_unary = 22 + CommandsParserRULE_member = 23 + CommandsParserRULE_primary = 24 + CommandsParserRULE_exprList = 25 + CommandsParserRULE_fieldInitializerList = 26 + CommandsParserRULE_mapInitializerList = 27 + CommandsParserRULE_literal = 28 +) + +// IStartCommandContext is an interface to support dynamic dispatch. +type IStartCommandContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // IsStartCommandContext differentiates from other interfaces. + IsStartCommandContext() +} + +type StartCommandContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyStartCommandContext() *StartCommandContext { + var p = new(StartCommandContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_startCommand + return p +} + +func (*StartCommandContext) IsStartCommandContext() {} + +func NewStartCommandContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *StartCommandContext { + var p = new(StartCommandContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CommandsParserRULE_startCommand + + return p +} + +func (s *StartCommandContext) GetParser() antlr.Parser { return s.parser } + +func (s *StartCommandContext) Command() ICommandContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ICommandContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ICommandContext) +} + +func (s *StartCommandContext) EOF() antlr.TerminalNode { + return s.GetToken(CommandsParserEOF, 0) +} + +func (s *StartCommandContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *StartCommandContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *StartCommandContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.EnterStartCommand(s) + } +} + +func (s *StartCommandContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitStartCommand(s) + } +} + +func (s *StartCommandContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitStartCommand(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) StartCommand() (localctx IStartCommandContext) { + this := p + _ = this + + localctx = NewStartCommandContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 0, CommandsParserRULE_startCommand) + + 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(58) + p.Command() + } + { + p.SetState(59) + p.Match(CommandsParserEOF) + } + + return localctx +} + +// ICommandContext is an interface to support dynamic dispatch. +type ICommandContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // IsCommandContext differentiates from other interfaces. + IsCommandContext() +} + +type CommandContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyCommandContext() *CommandContext { + var p = new(CommandContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_command + return p +} + +func (*CommandContext) IsCommandContext() {} + +func NewCommandContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CommandContext { + var p = new(CommandContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CommandsParserRULE_command + + return p +} + +func (s *CommandContext) GetParser() antlr.Parser { return s.parser } + +func (s *CommandContext) Let() ILetContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ILetContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ILetContext) +} + +func (s *CommandContext) Declare() IDeclareContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IDeclareContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IDeclareContext) +} + +func (s *CommandContext) Delete() IDeleteContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IDeleteContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IDeleteContext) +} + +func (s *CommandContext) Simple() ISimpleContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ISimpleContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ISimpleContext) +} + +func (s *CommandContext) ExprCmd() IExprCmdContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprCmdContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IExprCmdContext) +} + +func (s *CommandContext) Empty() IEmptyContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IEmptyContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IEmptyContext) +} + +func (s *CommandContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *CommandContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *CommandContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.EnterCommand(s) + } +} + +func (s *CommandContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitCommand(s) + } +} + +func (s *CommandContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitCommand(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) Command() (localctx ICommandContext) { + this := p + _ = this + + localctx = NewCommandContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 2, CommandsParserRULE_command) + + 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.SetState(67) + p.GetErrorHandler().Sync(p) + + switch p.GetTokenStream().LA(1) { + case CommandsParserT__0: + p.EnterOuterAlt(localctx, 1) + { + p.SetState(61) + p.Let() + } + + case CommandsParserT__1: + p.EnterOuterAlt(localctx, 2) + { + p.SetState(62) + p.Declare() + } + + case CommandsParserT__2: + p.EnterOuterAlt(localctx, 3) + { + p.SetState(63) + p.Delete() + } + + case CommandsParserCOMMAND: + p.EnterOuterAlt(localctx, 4) + { + p.SetState(64) + p.Simple() + } + + case CommandsParserT__3, CommandsParserLBRACKET, CommandsParserLBRACE, CommandsParserLPAREN, CommandsParserDOT, CommandsParserMINUS, CommandsParserEXCLAM, CommandsParserCEL_TRUE, CommandsParserCEL_FALSE, CommandsParserNUL, CommandsParserNUM_FLOAT, CommandsParserNUM_INT, CommandsParserNUM_UINT, CommandsParserSTRING, CommandsParserBYTES, CommandsParserIDENTIFIER: + p.EnterOuterAlt(localctx, 5) + { + p.SetState(65) + p.ExprCmd() + } + + case CommandsParserEOF: + p.EnterOuterAlt(localctx, 6) + { + p.SetState(66) + p.Empty() + } + + default: + panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + } + + return localctx +} + +// ILetContext is an interface to support dynamic dispatch. +type ILetContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetVar returns the var rule contexts. + GetVar() IVarDeclContext + + // GetFn returns the fn rule contexts. + GetFn() IFnDeclContext + + // GetE returns the e rule contexts. + GetE() IExprContext + + // SetVar sets the var rule contexts. + SetVar(IVarDeclContext) + + // SetFn sets the fn rule contexts. + SetFn(IFnDeclContext) + + // SetE sets the e rule contexts. + SetE(IExprContext) + + // IsLetContext differentiates from other interfaces. + IsLetContext() +} + +type LetContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + var_ IVarDeclContext + fn IFnDeclContext + e IExprContext +} + +func NewEmptyLetContext() *LetContext { + var p = new(LetContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_let + return p +} + +func (*LetContext) IsLetContext() {} + +func NewLetContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *LetContext { + var p = new(LetContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CommandsParserRULE_let + + return p +} + +func (s *LetContext) GetParser() antlr.Parser { return s.parser } + +func (s *LetContext) GetVar() IVarDeclContext { return s.var_ } + +func (s *LetContext) GetFn() IFnDeclContext { return s.fn } + +func (s *LetContext) GetE() IExprContext { return s.e } + +func (s *LetContext) SetVar(v IVarDeclContext) { s.var_ = v } + +func (s *LetContext) SetFn(v IFnDeclContext) { s.fn = v } + +func (s *LetContext) SetE(v IExprContext) { s.e = v } + +func (s *LetContext) Expr() IExprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *LetContext) EQUAL_ASSIGN() antlr.TerminalNode { + return s.GetToken(CommandsParserEQUAL_ASSIGN, 0) +} + +func (s *LetContext) ARROW() antlr.TerminalNode { + return s.GetToken(CommandsParserARROW, 0) +} + +func (s *LetContext) VarDecl() IVarDeclContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IVarDeclContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IVarDeclContext) +} + +func (s *LetContext) FnDecl() IFnDeclContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IFnDeclContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IFnDeclContext) +} + +func (s *LetContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *LetContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *LetContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.EnterLet(s) + } +} + +func (s *LetContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitLet(s) + } +} + +func (s *LetContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitLet(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) Let() (localctx ILetContext) { + this := p + _ = this + + localctx = NewLetContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 4, CommandsParserRULE_let) + + 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(69) + p.Match(CommandsParserT__0) + } + p.SetState(76) + p.GetErrorHandler().Sync(p) + switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 1, p.GetParserRuleContext()) { + case 1: + { + p.SetState(70) + + var _x = p.VarDecl() + + localctx.(*LetContext).var_ = _x + } + { + p.SetState(71) + p.Match(CommandsParserEQUAL_ASSIGN) + } + + case 2: + { + p.SetState(73) + + var _x = p.FnDecl() + + localctx.(*LetContext).fn = _x + } + { + p.SetState(74) + p.Match(CommandsParserARROW) + } + + } + { + p.SetState(78) + + var _x = p.Expr() + + localctx.(*LetContext).e = _x + } + + return localctx +} + +// IDeclareContext is an interface to support dynamic dispatch. +type IDeclareContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetVar returns the var rule contexts. + GetVar() IVarDeclContext + + // GetFn returns the fn rule contexts. + GetFn() IFnDeclContext + + // SetVar sets the var rule contexts. + SetVar(IVarDeclContext) + + // SetFn sets the fn rule contexts. + SetFn(IFnDeclContext) + + // IsDeclareContext differentiates from other interfaces. + IsDeclareContext() +} + +type DeclareContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + var_ IVarDeclContext + fn IFnDeclContext +} + +func NewEmptyDeclareContext() *DeclareContext { + var p = new(DeclareContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_declare + return p +} + +func (*DeclareContext) IsDeclareContext() {} + +func NewDeclareContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *DeclareContext { + var p = new(DeclareContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CommandsParserRULE_declare + + return p +} + +func (s *DeclareContext) GetParser() antlr.Parser { return s.parser } + +func (s *DeclareContext) GetVar() IVarDeclContext { return s.var_ } + +func (s *DeclareContext) GetFn() IFnDeclContext { return s.fn } + +func (s *DeclareContext) SetVar(v IVarDeclContext) { s.var_ = v } + +func (s *DeclareContext) SetFn(v IFnDeclContext) { s.fn = v } + +func (s *DeclareContext) VarDecl() IVarDeclContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IVarDeclContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IVarDeclContext) +} + +func (s *DeclareContext) FnDecl() IFnDeclContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IFnDeclContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IFnDeclContext) +} + +func (s *DeclareContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *DeclareContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *DeclareContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.EnterDeclare(s) + } +} + +func (s *DeclareContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitDeclare(s) + } +} + +func (s *DeclareContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitDeclare(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) Declare() (localctx IDeclareContext) { + this := p + _ = this + + localctx = NewDeclareContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 6, CommandsParserRULE_declare) + + 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(80) + p.Match(CommandsParserT__1) + } + p.SetState(83) + p.GetErrorHandler().Sync(p) + switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 2, p.GetParserRuleContext()) { + case 1: + { + p.SetState(81) + + var _x = p.VarDecl() + + localctx.(*DeclareContext).var_ = _x + } + + case 2: + { + p.SetState(82) + + var _x = p.FnDecl() + + localctx.(*DeclareContext).fn = _x + } + + } + + return localctx +} + +// IVarDeclContext is an interface to support dynamic dispatch. +type IVarDeclContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetId returns the id rule contexts. + GetId() IQualIdContext + + // GetT returns the t rule contexts. + GetT() ITypeContext + + // SetId sets the id rule contexts. + SetId(IQualIdContext) + + // SetT sets the t rule contexts. + SetT(ITypeContext) + + // IsVarDeclContext differentiates from other interfaces. + IsVarDeclContext() +} + +type VarDeclContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + id IQualIdContext + t ITypeContext +} + +func NewEmptyVarDeclContext() *VarDeclContext { + var p = new(VarDeclContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_varDecl + return p +} + +func (*VarDeclContext) IsVarDeclContext() {} + +func NewVarDeclContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *VarDeclContext { + var p = new(VarDeclContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CommandsParserRULE_varDecl + + return p +} + +func (s *VarDeclContext) GetParser() antlr.Parser { return s.parser } + +func (s *VarDeclContext) GetId() IQualIdContext { return s.id } + +func (s *VarDeclContext) GetT() ITypeContext { return s.t } + +func (s *VarDeclContext) SetId(v IQualIdContext) { s.id = v } + +func (s *VarDeclContext) SetT(v ITypeContext) { s.t = v } + +func (s *VarDeclContext) QualId() IQualIdContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IQualIdContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IQualIdContext) +} + +func (s *VarDeclContext) COLON() antlr.TerminalNode { + return s.GetToken(CommandsParserCOLON, 0) +} + +func (s *VarDeclContext) Type() ITypeContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITypeContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ITypeContext) +} + +func (s *VarDeclContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *VarDeclContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *VarDeclContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.EnterVarDecl(s) + } +} + +func (s *VarDeclContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitVarDecl(s) + } +} + +func (s *VarDeclContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitVarDecl(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) VarDecl() (localctx IVarDeclContext) { + this := p + _ = this + + localctx = NewVarDeclContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 8, CommandsParserRULE_varDecl) + 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(85) + + var _x = p.QualId() + + localctx.(*VarDeclContext).id = _x + } + p.SetState(88) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + if _la == CommandsParserCOLON { + { + p.SetState(86) + p.Match(CommandsParserCOLON) + } + { + p.SetState(87) + + var _x = p.Type() + + localctx.(*VarDeclContext).t = _x + } + + } + + return localctx +} + +// IFnDeclContext is an interface to support dynamic dispatch. +type IFnDeclContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetId returns the id rule contexts. + GetId() IQualIdContext + + // Get_param returns the _param rule contexts. + Get_param() IParamContext + + // GetRType returns the rType rule contexts. + GetRType() ITypeContext + + // SetId sets the id rule contexts. + SetId(IQualIdContext) + + // Set_param sets the _param rule contexts. + Set_param(IParamContext) + + // SetRType sets the rType rule contexts. + SetRType(ITypeContext) + + // GetParams returns the params rule context list. + GetParams() []IParamContext + + // SetParams sets the params rule context list. + SetParams([]IParamContext) + + // IsFnDeclContext differentiates from other interfaces. + IsFnDeclContext() +} + +type FnDeclContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + id IQualIdContext + _param IParamContext + params []IParamContext + rType ITypeContext +} + +func NewEmptyFnDeclContext() *FnDeclContext { + var p = new(FnDeclContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_fnDecl + return p +} + +func (*FnDeclContext) IsFnDeclContext() {} + +func NewFnDeclContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *FnDeclContext { + var p = new(FnDeclContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CommandsParserRULE_fnDecl + + return p +} + +func (s *FnDeclContext) GetParser() antlr.Parser { return s.parser } + +func (s *FnDeclContext) GetId() IQualIdContext { return s.id } + +func (s *FnDeclContext) Get_param() IParamContext { return s._param } + +func (s *FnDeclContext) GetRType() ITypeContext { return s.rType } + +func (s *FnDeclContext) SetId(v IQualIdContext) { s.id = v } + +func (s *FnDeclContext) Set_param(v IParamContext) { s._param = v } + +func (s *FnDeclContext) SetRType(v ITypeContext) { s.rType = v } + +func (s *FnDeclContext) GetParams() []IParamContext { return s.params } + +func (s *FnDeclContext) SetParams(v []IParamContext) { s.params = v } + +func (s *FnDeclContext) LPAREN() antlr.TerminalNode { + return s.GetToken(CommandsParserLPAREN, 0) +} + +func (s *FnDeclContext) RPAREN() antlr.TerminalNode { + return s.GetToken(CommandsParserRPAREN, 0) +} + +func (s *FnDeclContext) COLON() antlr.TerminalNode { + return s.GetToken(CommandsParserCOLON, 0) +} + +func (s *FnDeclContext) QualId() IQualIdContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IQualIdContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IQualIdContext) +} + +func (s *FnDeclContext) Type() ITypeContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITypeContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ITypeContext) +} + +func (s *FnDeclContext) AllParam() []IParamContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IParamContext); ok { + len++ + } + } + + tst := make([]IParamContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IParamContext); ok { + tst[i] = t.(IParamContext) + i++ + } + } + + return tst +} + +func (s *FnDeclContext) Param(i int) IParamContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IParamContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IParamContext) +} + +func (s *FnDeclContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(CommandsParserCOMMA) +} + +func (s *FnDeclContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(CommandsParserCOMMA, i) +} + +func (s *FnDeclContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *FnDeclContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *FnDeclContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.EnterFnDecl(s) + } +} + +func (s *FnDeclContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitFnDecl(s) + } +} + +func (s *FnDeclContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitFnDecl(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) FnDecl() (localctx IFnDeclContext) { + this := p + _ = this + + localctx = NewFnDeclContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 10, CommandsParserRULE_fnDecl) + 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(90) + + var _x = p.QualId() + + localctx.(*FnDeclContext).id = _x + } + { + p.SetState(91) + p.Match(CommandsParserLPAREN) + } + p.SetState(100) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + if _la == CommandsParserIDENTIFIER { + { + p.SetState(92) + + var _x = p.Param() + + localctx.(*FnDeclContext)._param = _x + } + localctx.(*FnDeclContext).params = append(localctx.(*FnDeclContext).params, localctx.(*FnDeclContext)._param) + p.SetState(97) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + for _la == CommandsParserCOMMA { + { + p.SetState(93) + p.Match(CommandsParserCOMMA) + } + { + p.SetState(94) + + var _x = p.Param() + + localctx.(*FnDeclContext)._param = _x + } + localctx.(*FnDeclContext).params = append(localctx.(*FnDeclContext).params, localctx.(*FnDeclContext)._param) + + p.SetState(99) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + } + + } + { + p.SetState(102) + p.Match(CommandsParserRPAREN) + } + { + p.SetState(103) + p.Match(CommandsParserCOLON) + } + { + p.SetState(104) + + var _x = p.Type() + + localctx.(*FnDeclContext).rType = _x + } + + return localctx +} + +// IParamContext is an interface to support dynamic dispatch. +type IParamContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetPid returns the pid token. + GetPid() antlr.Token + + // SetPid sets the pid token. + SetPid(antlr.Token) + + // GetT returns the t rule contexts. + GetT() ITypeContext + + // SetT sets the t rule contexts. + SetT(ITypeContext) + + // IsParamContext differentiates from other interfaces. + IsParamContext() +} + +type ParamContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + pid antlr.Token + t ITypeContext +} + +func NewEmptyParamContext() *ParamContext { + var p = new(ParamContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_param + return p +} + +func (*ParamContext) IsParamContext() {} + +func NewParamContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ParamContext { + var p = new(ParamContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CommandsParserRULE_param + + return p +} + +func (s *ParamContext) GetParser() antlr.Parser { return s.parser } + +func (s *ParamContext) GetPid() antlr.Token { return s.pid } + +func (s *ParamContext) SetPid(v antlr.Token) { s.pid = v } + +func (s *ParamContext) GetT() ITypeContext { return s.t } + +func (s *ParamContext) SetT(v ITypeContext) { s.t = v } + +func (s *ParamContext) COLON() antlr.TerminalNode { + return s.GetToken(CommandsParserCOLON, 0) +} + +func (s *ParamContext) IDENTIFIER() antlr.TerminalNode { + return s.GetToken(CommandsParserIDENTIFIER, 0) +} + +func (s *ParamContext) Type() ITypeContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITypeContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ITypeContext) +} + +func (s *ParamContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *ParamContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *ParamContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.EnterParam(s) + } +} + +func (s *ParamContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitParam(s) + } +} + +func (s *ParamContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitParam(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) Param() (localctx IParamContext) { + this := p + _ = this + + localctx = NewParamContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 12, CommandsParserRULE_param) + + 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(106) + + var _m = p.Match(CommandsParserIDENTIFIER) + + localctx.(*ParamContext).pid = _m + } + { + p.SetState(107) + p.Match(CommandsParserCOLON) + } + { + p.SetState(108) + + var _x = p.Type() + + localctx.(*ParamContext).t = _x + } + + return localctx +} + +// IDeleteContext is an interface to support dynamic dispatch. +type IDeleteContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetVar returns the var rule contexts. + GetVar() IVarDeclContext + + // GetFn returns the fn rule contexts. + GetFn() IFnDeclContext + + // SetVar sets the var rule contexts. + SetVar(IVarDeclContext) + + // SetFn sets the fn rule contexts. + SetFn(IFnDeclContext) + + // IsDeleteContext differentiates from other interfaces. + IsDeleteContext() +} + +type DeleteContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + var_ IVarDeclContext + fn IFnDeclContext +} + +func NewEmptyDeleteContext() *DeleteContext { + var p = new(DeleteContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_delete + return p +} + +func (*DeleteContext) IsDeleteContext() {} + +func NewDeleteContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *DeleteContext { + var p = new(DeleteContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CommandsParserRULE_delete + + return p +} + +func (s *DeleteContext) GetParser() antlr.Parser { return s.parser } + +func (s *DeleteContext) GetVar() IVarDeclContext { return s.var_ } + +func (s *DeleteContext) GetFn() IFnDeclContext { return s.fn } + +func (s *DeleteContext) SetVar(v IVarDeclContext) { s.var_ = v } + +func (s *DeleteContext) SetFn(v IFnDeclContext) { s.fn = v } + +func (s *DeleteContext) VarDecl() IVarDeclContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IVarDeclContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IVarDeclContext) +} + +func (s *DeleteContext) FnDecl() IFnDeclContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IFnDeclContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IFnDeclContext) +} + +func (s *DeleteContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *DeleteContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *DeleteContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.EnterDelete(s) + } +} + +func (s *DeleteContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitDelete(s) + } +} + +func (s *DeleteContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitDelete(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) Delete() (localctx IDeleteContext) { + this := p + _ = this + + localctx = NewDeleteContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 14, CommandsParserRULE_delete) + + 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(110) + p.Match(CommandsParserT__2) + } + p.SetState(113) + p.GetErrorHandler().Sync(p) + switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 6, p.GetParserRuleContext()) { + case 1: + { + p.SetState(111) + + var _x = p.VarDecl() + + localctx.(*DeleteContext).var_ = _x + } + + case 2: + { + p.SetState(112) + + var _x = p.FnDecl() + + localctx.(*DeleteContext).fn = _x + } + + } + + return localctx +} + +// ISimpleContext is an interface to support dynamic dispatch. +type ISimpleContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetCmd returns the cmd token. + GetCmd() antlr.Token + + // Get_FLAG returns the _FLAG token. + Get_FLAG() antlr.Token + + // Get_STRING returns the _STRING token. + Get_STRING() antlr.Token + + // SetCmd sets the cmd token. + SetCmd(antlr.Token) + + // Set_FLAG sets the _FLAG token. + Set_FLAG(antlr.Token) + + // Set_STRING sets the _STRING token. + Set_STRING(antlr.Token) + + // GetArgs returns the args token list. + GetArgs() []antlr.Token + + // SetArgs sets the args token list. + SetArgs([]antlr.Token) + + // IsSimpleContext differentiates from other interfaces. + IsSimpleContext() +} + +type SimpleContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + cmd antlr.Token + _FLAG antlr.Token + args []antlr.Token + _STRING antlr.Token +} + +func NewEmptySimpleContext() *SimpleContext { + var p = new(SimpleContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_simple + return p +} + +func (*SimpleContext) IsSimpleContext() {} + +func NewSimpleContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SimpleContext { + var p = new(SimpleContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CommandsParserRULE_simple + + return p +} + +func (s *SimpleContext) GetParser() antlr.Parser { return s.parser } + +func (s *SimpleContext) GetCmd() antlr.Token { return s.cmd } + +func (s *SimpleContext) Get_FLAG() antlr.Token { return s._FLAG } + +func (s *SimpleContext) Get_STRING() antlr.Token { return s._STRING } + +func (s *SimpleContext) SetCmd(v antlr.Token) { s.cmd = v } + +func (s *SimpleContext) Set_FLAG(v antlr.Token) { s._FLAG = v } + +func (s *SimpleContext) Set_STRING(v antlr.Token) { s._STRING = v } + +func (s *SimpleContext) GetArgs() []antlr.Token { return s.args } + +func (s *SimpleContext) SetArgs(v []antlr.Token) { s.args = v } + +func (s *SimpleContext) COMMAND() antlr.TerminalNode { + return s.GetToken(CommandsParserCOMMAND, 0) +} + +func (s *SimpleContext) AllFLAG() []antlr.TerminalNode { + return s.GetTokens(CommandsParserFLAG) +} + +func (s *SimpleContext) FLAG(i int) antlr.TerminalNode { + return s.GetToken(CommandsParserFLAG, i) +} + +func (s *SimpleContext) AllSTRING() []antlr.TerminalNode { + return s.GetTokens(CommandsParserSTRING) +} + +func (s *SimpleContext) STRING(i int) antlr.TerminalNode { + return s.GetToken(CommandsParserSTRING, i) +} + +func (s *SimpleContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *SimpleContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *SimpleContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.EnterSimple(s) + } +} + +func (s *SimpleContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitSimple(s) + } +} + +func (s *SimpleContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitSimple(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) Simple() (localctx ISimpleContext) { + this := p + _ = this + + localctx = NewSimpleContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 16, CommandsParserRULE_simple) + 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(115) + + var _m = p.Match(CommandsParserCOMMAND) + + localctx.(*SimpleContext).cmd = _m + } + p.SetState(120) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + for _la == CommandsParserFLAG || _la == CommandsParserSTRING { + p.SetState(118) + p.GetErrorHandler().Sync(p) + + switch p.GetTokenStream().LA(1) { + case CommandsParserFLAG: + { + p.SetState(116) + + var _m = p.Match(CommandsParserFLAG) + + localctx.(*SimpleContext)._FLAG = _m + } + localctx.(*SimpleContext).args = append(localctx.(*SimpleContext).args, localctx.(*SimpleContext)._FLAG) + + case CommandsParserSTRING: + { + p.SetState(117) + + var _m = p.Match(CommandsParserSTRING) + + localctx.(*SimpleContext)._STRING = _m + } + localctx.(*SimpleContext).args = append(localctx.(*SimpleContext).args, localctx.(*SimpleContext)._STRING) + + default: + panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + } + + p.SetState(122) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + } + + return localctx +} + +// IEmptyContext is an interface to support dynamic dispatch. +type IEmptyContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // IsEmptyContext differentiates from other interfaces. + IsEmptyContext() +} + +type EmptyContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyEmptyContext() *EmptyContext { + var p = new(EmptyContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_empty + return p +} + +func (*EmptyContext) IsEmptyContext() {} + +func NewEmptyContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *EmptyContext { + var p = new(EmptyContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CommandsParserRULE_empty + + return p +} + +func (s *EmptyContext) GetParser() antlr.Parser { return s.parser } +func (s *EmptyContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *EmptyContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *EmptyContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.EnterEmpty(s) + } +} + +func (s *EmptyContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitEmpty(s) + } +} + +func (s *EmptyContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitEmpty(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) Empty() (localctx IEmptyContext) { + this := p + _ = this + + localctx = NewEmptyContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 18, CommandsParserRULE_empty) + + 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) + + return localctx +} + +// IExprCmdContext is an interface to support dynamic dispatch. +type IExprCmdContext 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) + + // IsExprCmdContext differentiates from other interfaces. + IsExprCmdContext() +} + +type ExprCmdContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + e IExprContext +} + +func NewEmptyExprCmdContext() *ExprCmdContext { + var p = new(ExprCmdContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_exprCmd + return p +} + +func (*ExprCmdContext) IsExprCmdContext() {} + +func NewExprCmdContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ExprCmdContext { + var p = new(ExprCmdContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CommandsParserRULE_exprCmd + + return p +} + +func (s *ExprCmdContext) GetParser() antlr.Parser { return s.parser } + +func (s *ExprCmdContext) GetE() IExprContext { return s.e } + +func (s *ExprCmdContext) SetE(v IExprContext) { s.e = v } + +func (s *ExprCmdContext) Expr() IExprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *ExprCmdContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *ExprCmdContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *ExprCmdContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.EnterExprCmd(s) + } +} + +func (s *ExprCmdContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitExprCmd(s) + } +} + +func (s *ExprCmdContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitExprCmd(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) ExprCmd() (localctx IExprCmdContext) { + this := p + _ = this + + localctx = NewExprCmdContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 20, CommandsParserRULE_exprCmd) + 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(126) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + if _la == CommandsParserT__3 { + { + p.SetState(125) + p.Match(CommandsParserT__3) + } + + } + { + p.SetState(128) + + var _x = p.Expr() + + localctx.(*ExprCmdContext).e = _x + } + + return localctx +} + +// IQualIdContext is an interface to support dynamic dispatch. +type IQualIdContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetLeadingDot returns the leadingDot token. + GetLeadingDot() antlr.Token + + // GetRid returns the rid token. + GetRid() antlr.Token + + // Get_IDENTIFIER returns the _IDENTIFIER token. + Get_IDENTIFIER() antlr.Token + + // SetLeadingDot sets the leadingDot token. + SetLeadingDot(antlr.Token) + + // SetRid sets the rid token. + SetRid(antlr.Token) + + // Set_IDENTIFIER sets the _IDENTIFIER token. + Set_IDENTIFIER(antlr.Token) + + // GetQualifiers returns the qualifiers token list. + GetQualifiers() []antlr.Token + + // SetQualifiers sets the qualifiers token list. + SetQualifiers([]antlr.Token) + + // IsQualIdContext differentiates from other interfaces. + IsQualIdContext() +} + +type QualIdContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + leadingDot antlr.Token + rid antlr.Token + _IDENTIFIER antlr.Token + qualifiers []antlr.Token +} + +func NewEmptyQualIdContext() *QualIdContext { + var p = new(QualIdContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_qualId + return p +} + +func (*QualIdContext) IsQualIdContext() {} + +func NewQualIdContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *QualIdContext { + var p = new(QualIdContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CommandsParserRULE_qualId + + return p +} + +func (s *QualIdContext) GetParser() antlr.Parser { return s.parser } + +func (s *QualIdContext) GetLeadingDot() antlr.Token { return s.leadingDot } + +func (s *QualIdContext) GetRid() antlr.Token { return s.rid } + +func (s *QualIdContext) Get_IDENTIFIER() antlr.Token { return s._IDENTIFIER } + +func (s *QualIdContext) SetLeadingDot(v antlr.Token) { s.leadingDot = v } + +func (s *QualIdContext) SetRid(v antlr.Token) { s.rid = v } + +func (s *QualIdContext) Set_IDENTIFIER(v antlr.Token) { s._IDENTIFIER = v } + +func (s *QualIdContext) GetQualifiers() []antlr.Token { return s.qualifiers } + +func (s *QualIdContext) SetQualifiers(v []antlr.Token) { s.qualifiers = v } + +func (s *QualIdContext) AllIDENTIFIER() []antlr.TerminalNode { + return s.GetTokens(CommandsParserIDENTIFIER) +} + +func (s *QualIdContext) IDENTIFIER(i int) antlr.TerminalNode { + return s.GetToken(CommandsParserIDENTIFIER, i) +} + +func (s *QualIdContext) AllDOT() []antlr.TerminalNode { + return s.GetTokens(CommandsParserDOT) +} + +func (s *QualIdContext) DOT(i int) antlr.TerminalNode { + return s.GetToken(CommandsParserDOT, i) +} + +func (s *QualIdContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *QualIdContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *QualIdContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.EnterQualId(s) + } +} + +func (s *QualIdContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitQualId(s) + } +} + +func (s *QualIdContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitQualId(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) QualId() (localctx IQualIdContext) { + this := p + _ = this + + localctx = NewQualIdContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 22, CommandsParserRULE_qualId) + 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(131) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + if _la == CommandsParserDOT { + { + p.SetState(130) + + var _m = p.Match(CommandsParserDOT) + + localctx.(*QualIdContext).leadingDot = _m + } + + } + { + p.SetState(133) + + var _m = p.Match(CommandsParserIDENTIFIER) + + localctx.(*QualIdContext).rid = _m + } + p.SetState(138) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + for _la == CommandsParserDOT { + { + p.SetState(134) + p.Match(CommandsParserDOT) + } + { + p.SetState(135) + + var _m = p.Match(CommandsParserIDENTIFIER) + + localctx.(*QualIdContext)._IDENTIFIER = _m + } + localctx.(*QualIdContext).qualifiers = append(localctx.(*QualIdContext).qualifiers, localctx.(*QualIdContext)._IDENTIFIER) + + p.SetState(140) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + } + + return localctx +} + +// IStartTypeContext is an interface to support dynamic dispatch. +type IStartTypeContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetT returns the t rule contexts. + GetT() ITypeContext + + // SetT sets the t rule contexts. + SetT(ITypeContext) + + // IsStartTypeContext differentiates from other interfaces. + IsStartTypeContext() +} + +type StartTypeContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + t ITypeContext +} + +func NewEmptyStartTypeContext() *StartTypeContext { + var p = new(StartTypeContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_startType + return p +} + +func (*StartTypeContext) IsStartTypeContext() {} + +func NewStartTypeContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *StartTypeContext { + var p = new(StartTypeContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CommandsParserRULE_startType + + return p +} + +func (s *StartTypeContext) GetParser() antlr.Parser { return s.parser } + +func (s *StartTypeContext) GetT() ITypeContext { return s.t } + +func (s *StartTypeContext) SetT(v ITypeContext) { s.t = v } + +func (s *StartTypeContext) EOF() antlr.TerminalNode { + return s.GetToken(CommandsParserEOF, 0) +} + +func (s *StartTypeContext) Type() ITypeContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITypeContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ITypeContext) +} + +func (s *StartTypeContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *StartTypeContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *StartTypeContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.EnterStartType(s) + } +} + +func (s *StartTypeContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitStartType(s) + } +} + +func (s *StartTypeContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitStartType(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) StartType() (localctx IStartTypeContext) { + this := p + _ = this + + localctx = NewStartTypeContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 24, CommandsParserRULE_startType) + + 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(141) + + var _x = p.Type() + + localctx.(*StartTypeContext).t = _x + } + { + p.SetState(142) + p.Match(CommandsParserEOF) + } + + return localctx +} + +// ITypeContext is an interface to support dynamic dispatch. +type ITypeContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetId returns the id rule contexts. + GetId() ITypeIdContext + + // GetParams returns the params rule contexts. + GetParams() ITypeParamListContext + + // SetId sets the id rule contexts. + SetId(ITypeIdContext) + + // SetParams sets the params rule contexts. + SetParams(ITypeParamListContext) + + // IsTypeContext differentiates from other interfaces. + IsTypeContext() +} + +type TypeContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + id ITypeIdContext + params ITypeParamListContext +} + +func NewEmptyTypeContext() *TypeContext { + var p = new(TypeContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_type + return p +} + +func (*TypeContext) IsTypeContext() {} + +func NewTypeContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *TypeContext { + var p = new(TypeContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CommandsParserRULE_type + + return p +} + +func (s *TypeContext) GetParser() antlr.Parser { return s.parser } + +func (s *TypeContext) GetId() ITypeIdContext { return s.id } + +func (s *TypeContext) GetParams() ITypeParamListContext { return s.params } + +func (s *TypeContext) SetId(v ITypeIdContext) { s.id = v } + +func (s *TypeContext) SetParams(v ITypeParamListContext) { s.params = v } + +func (s *TypeContext) TypeId() ITypeIdContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITypeIdContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ITypeIdContext) +} + +func (s *TypeContext) TypeParamList() ITypeParamListContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITypeParamListContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ITypeParamListContext) +} + +func (s *TypeContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *TypeContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *TypeContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.EnterType(s) + } +} + +func (s *TypeContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitType(s) + } +} + +func (s *TypeContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitType(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) Type() (localctx ITypeContext) { + this := p + _ = this + + localctx = NewTypeContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 26, CommandsParserRULE_type) + 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(144) + + var _x = p.TypeId() + + localctx.(*TypeContext).id = _x + } + p.SetState(146) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + if _la == CommandsParserLPAREN { + { + p.SetState(145) + + var _x = p.TypeParamList() + + localctx.(*TypeContext).params = _x + } + + } + + return localctx +} + +// ITypeIdContext is an interface to support dynamic dispatch. +type ITypeIdContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetLeadingDot returns the leadingDot token. + GetLeadingDot() antlr.Token + + // GetId returns the id token. + GetId() antlr.Token + + // Get_IDENTIFIER returns the _IDENTIFIER token. + Get_IDENTIFIER() antlr.Token + + // SetLeadingDot sets the leadingDot token. + SetLeadingDot(antlr.Token) + + // SetId sets the id token. + SetId(antlr.Token) + + // Set_IDENTIFIER sets the _IDENTIFIER token. + Set_IDENTIFIER(antlr.Token) + + // GetQualifiers returns the qualifiers token list. + GetQualifiers() []antlr.Token + + // SetQualifiers sets the qualifiers token list. + SetQualifiers([]antlr.Token) + + // IsTypeIdContext differentiates from other interfaces. + IsTypeIdContext() +} + +type TypeIdContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + leadingDot antlr.Token + id antlr.Token + _IDENTIFIER antlr.Token + qualifiers []antlr.Token +} + +func NewEmptyTypeIdContext() *TypeIdContext { + var p = new(TypeIdContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_typeId + return p +} + +func (*TypeIdContext) IsTypeIdContext() {} + +func NewTypeIdContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *TypeIdContext { + var p = new(TypeIdContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CommandsParserRULE_typeId + + return p +} + +func (s *TypeIdContext) GetParser() antlr.Parser { return s.parser } + +func (s *TypeIdContext) GetLeadingDot() antlr.Token { return s.leadingDot } + +func (s *TypeIdContext) GetId() antlr.Token { return s.id } + +func (s *TypeIdContext) Get_IDENTIFIER() antlr.Token { return s._IDENTIFIER } + +func (s *TypeIdContext) SetLeadingDot(v antlr.Token) { s.leadingDot = v } + +func (s *TypeIdContext) SetId(v antlr.Token) { s.id = v } + +func (s *TypeIdContext) Set_IDENTIFIER(v antlr.Token) { s._IDENTIFIER = v } + +func (s *TypeIdContext) GetQualifiers() []antlr.Token { return s.qualifiers } + +func (s *TypeIdContext) SetQualifiers(v []antlr.Token) { s.qualifiers = v } + +func (s *TypeIdContext) AllIDENTIFIER() []antlr.TerminalNode { + return s.GetTokens(CommandsParserIDENTIFIER) +} + +func (s *TypeIdContext) IDENTIFIER(i int) antlr.TerminalNode { + return s.GetToken(CommandsParserIDENTIFIER, i) +} + +func (s *TypeIdContext) NUL() antlr.TerminalNode { + return s.GetToken(CommandsParserNUL, 0) +} + +func (s *TypeIdContext) AllDOT() []antlr.TerminalNode { + return s.GetTokens(CommandsParserDOT) +} + +func (s *TypeIdContext) DOT(i int) antlr.TerminalNode { + return s.GetToken(CommandsParserDOT, i) +} + +func (s *TypeIdContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *TypeIdContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *TypeIdContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.EnterTypeId(s) + } +} + +func (s *TypeIdContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitTypeId(s) + } +} + +func (s *TypeIdContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitTypeId(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) TypeId() (localctx ITypeIdContext) { + this := p + _ = this + + localctx = NewTypeIdContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 28, CommandsParserRULE_typeId) + 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(149) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + if _la == CommandsParserDOT { + { + p.SetState(148) + + var _m = p.Match(CommandsParserDOT) + + localctx.(*TypeIdContext).leadingDot = _m + } + + } + { + p.SetState(151) + + var _lt = p.GetTokenStream().LT(1) + + localctx.(*TypeIdContext).id = _lt + + _la = p.GetTokenStream().LA(1) + + if !(_la == CommandsParserNUL || _la == CommandsParserIDENTIFIER) { + var _ri = p.GetErrorHandler().RecoverInline(p) + + localctx.(*TypeIdContext).id = _ri + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + p.SetState(156) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + for _la == CommandsParserDOT { + { + p.SetState(152) + p.Match(CommandsParserDOT) + } + { + p.SetState(153) + + var _m = p.Match(CommandsParserIDENTIFIER) + + localctx.(*TypeIdContext)._IDENTIFIER = _m + } + localctx.(*TypeIdContext).qualifiers = append(localctx.(*TypeIdContext).qualifiers, localctx.(*TypeIdContext)._IDENTIFIER) + + p.SetState(158) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + } + + return localctx +} + +// ITypeParamListContext is an interface to support dynamic dispatch. +type ITypeParamListContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Get_type returns the _type rule contexts. + Get_type() ITypeContext + + // Set_type sets the _type rule contexts. + Set_type(ITypeContext) + + // GetTypes returns the types rule context list. + GetTypes() []ITypeContext + + // SetTypes sets the types rule context list. + SetTypes([]ITypeContext) + + // IsTypeParamListContext differentiates from other interfaces. + IsTypeParamListContext() +} + +type TypeParamListContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + _type ITypeContext + types []ITypeContext +} + +func NewEmptyTypeParamListContext() *TypeParamListContext { + var p = new(TypeParamListContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_typeParamList + return p +} + +func (*TypeParamListContext) IsTypeParamListContext() {} + +func NewTypeParamListContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *TypeParamListContext { + var p = new(TypeParamListContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CommandsParserRULE_typeParamList + + return p +} + +func (s *TypeParamListContext) GetParser() antlr.Parser { return s.parser } + +func (s *TypeParamListContext) Get_type() ITypeContext { return s._type } + +func (s *TypeParamListContext) Set_type(v ITypeContext) { s._type = v } + +func (s *TypeParamListContext) GetTypes() []ITypeContext { return s.types } + +func (s *TypeParamListContext) SetTypes(v []ITypeContext) { s.types = v } + +func (s *TypeParamListContext) LPAREN() antlr.TerminalNode { + return s.GetToken(CommandsParserLPAREN, 0) +} + +func (s *TypeParamListContext) RPAREN() antlr.TerminalNode { + return s.GetToken(CommandsParserRPAREN, 0) +} + +func (s *TypeParamListContext) AllType() []ITypeContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ITypeContext); ok { + len++ + } + } + + tst := make([]ITypeContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ITypeContext); ok { + tst[i] = t.(ITypeContext) + i++ + } + } + + return tst +} + +func (s *TypeParamListContext) Type(i int) ITypeContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITypeContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(ITypeContext) +} + +func (s *TypeParamListContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(CommandsParserCOMMA) +} + +func (s *TypeParamListContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(CommandsParserCOMMA, i) +} + +func (s *TypeParamListContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *TypeParamListContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *TypeParamListContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.EnterTypeParamList(s) + } +} + +func (s *TypeParamListContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitTypeParamList(s) + } +} + +func (s *TypeParamListContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitTypeParamList(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) TypeParamList() (localctx ITypeParamListContext) { + this := p + _ = this + + localctx = NewTypeParamListContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 30, CommandsParserRULE_typeParamList) + 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(159) + p.Match(CommandsParserLPAREN) + } + { + p.SetState(160) + + var _x = p.Type() + + localctx.(*TypeParamListContext)._type = _x + } + localctx.(*TypeParamListContext).types = append(localctx.(*TypeParamListContext).types, localctx.(*TypeParamListContext)._type) + p.SetState(165) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + for _la == CommandsParserCOMMA { + { + p.SetState(161) + p.Match(CommandsParserCOMMA) + } + { + p.SetState(162) + + var _x = p.Type() + + localctx.(*TypeParamListContext)._type = _x + } + localctx.(*TypeParamListContext).types = append(localctx.(*TypeParamListContext).types, localctx.(*TypeParamListContext)._type) + + p.SetState(167) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + } + { + p.SetState(168) + p.Match(CommandsParserRPAREN) + } + + return localctx +} + +// 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 = CommandsParserRULE_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 = CommandsParserRULE_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(CommandsParserEOF, 0) +} + +func (s *StartContext) Expr() IExprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + 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.(CommandsListener); ok { + listenerT.EnterStart(s) + } +} + +func (s *StartContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitStart(s) + } +} + +func (s *StartContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitStart(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) Start() (localctx IStartContext) { + this := p + _ = this + + localctx = NewStartContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 32, CommandsParserRULE_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(170) + + var _x = p.Expr() + + localctx.(*StartContext).e = _x + } + { + p.SetState(171) + p.Match(CommandsParserEOF) + } + + 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 = CommandsParserRULE_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 = CommandsParserRULE_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 { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IConditionalOrContext); ok { + len++ + } + } + + tst := make([]IConditionalOrContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IConditionalOrContext); ok { + tst[i] = t.(IConditionalOrContext) + i++ + } + } + + return tst +} + +func (s *ExprContext) ConditionalOr(i int) IConditionalOrContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IConditionalOrContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IConditionalOrContext) +} + +func (s *ExprContext) COLON() antlr.TerminalNode { + return s.GetToken(CommandsParserCOLON, 0) +} + +func (s *ExprContext) QUESTIONMARK() antlr.TerminalNode { + return s.GetToken(CommandsParserQUESTIONMARK, 0) +} + +func (s *ExprContext) Expr() IExprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + 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.(CommandsListener); ok { + listenerT.EnterExpr(s) + } +} + +func (s *ExprContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitExpr(s) + } +} + +func (s *ExprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitExpr(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) Expr() (localctx IExprContext) { + this := p + _ = this + + localctx = NewExprContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 34, CommandsParserRULE_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(173) + + var _x = p.ConditionalOr() + + localctx.(*ExprContext).e = _x + } + p.SetState(179) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + if _la == CommandsParserQUESTIONMARK { + { + p.SetState(174) + + var _m = p.Match(CommandsParserQUESTIONMARK) + + localctx.(*ExprContext).op = _m + } + { + p.SetState(175) + + var _x = p.ConditionalOr() + + localctx.(*ExprContext).e1 = _x + } + { + p.SetState(176) + p.Match(CommandsParserCOLON) + } + { + p.SetState(177) + + 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 + + // GetS17 returns the s17 token. + GetS17() antlr.Token + + // SetS17 sets the s17 token. + SetS17(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 + s17 antlr.Token + ops []antlr.Token + _conditionalAnd IConditionalAndContext + e1 []IConditionalAndContext +} + +func NewEmptyConditionalOrContext() *ConditionalOrContext { + var p = new(ConditionalOrContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_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 = CommandsParserRULE_conditionalOr + + return p +} + +func (s *ConditionalOrContext) GetParser() antlr.Parser { return s.parser } + +func (s *ConditionalOrContext) GetS17() antlr.Token { return s.s17 } + +func (s *ConditionalOrContext) SetS17(v antlr.Token) { s.s17 = 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 { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IConditionalAndContext); ok { + len++ + } + } + + tst := make([]IConditionalAndContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IConditionalAndContext); ok { + tst[i] = t.(IConditionalAndContext) + i++ + } + } + + return tst +} + +func (s *ConditionalOrContext) ConditionalAnd(i int) IConditionalAndContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IConditionalAndContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IConditionalAndContext) +} + +func (s *ConditionalOrContext) AllLOGICAL_OR() []antlr.TerminalNode { + return s.GetTokens(CommandsParserLOGICAL_OR) +} + +func (s *ConditionalOrContext) LOGICAL_OR(i int) antlr.TerminalNode { + return s.GetToken(CommandsParserLOGICAL_OR, i) +} + +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.(CommandsListener); ok { + listenerT.EnterConditionalOr(s) + } +} + +func (s *ConditionalOrContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitConditionalOr(s) + } +} + +func (s *ConditionalOrContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitConditionalOr(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) ConditionalOr() (localctx IConditionalOrContext) { + this := p + _ = this + + localctx = NewConditionalOrContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 36, CommandsParserRULE_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(181) + + var _x = p.ConditionalAnd() + + localctx.(*ConditionalOrContext).e = _x + } + p.SetState(186) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + for _la == CommandsParserLOGICAL_OR { + { + p.SetState(182) + + var _m = p.Match(CommandsParserLOGICAL_OR) + + localctx.(*ConditionalOrContext).s17 = _m + } + localctx.(*ConditionalOrContext).ops = append(localctx.(*ConditionalOrContext).ops, localctx.(*ConditionalOrContext).s17) + { + p.SetState(183) + + var _x = p.ConditionalAnd() + + localctx.(*ConditionalOrContext)._conditionalAnd = _x + } + localctx.(*ConditionalOrContext).e1 = append(localctx.(*ConditionalOrContext).e1, localctx.(*ConditionalOrContext)._conditionalAnd) + + p.SetState(188) + 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 + + // GetS16 returns the s16 token. + GetS16() antlr.Token + + // SetS16 sets the s16 token. + SetS16(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 + s16 antlr.Token + ops []antlr.Token + _relation IRelationContext + e1 []IRelationContext +} + +func NewEmptyConditionalAndContext() *ConditionalAndContext { + var p = new(ConditionalAndContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CommandsParserRULE_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 = CommandsParserRULE_conditionalAnd + + return p +} + +func (s *ConditionalAndContext) GetParser() antlr.Parser { return s.parser } + +func (s *ConditionalAndContext) GetS16() antlr.Token { return s.s16 } + +func (s *ConditionalAndContext) SetS16(v antlr.Token) { s.s16 = 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 { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IRelationContext); ok { + len++ + } + } + + tst := make([]IRelationContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IRelationContext); ok { + tst[i] = t.(IRelationContext) + i++ + } + } + + return tst +} + +func (s *ConditionalAndContext) Relation(i int) IRelationContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IRelationContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IRelationContext) +} + +func (s *ConditionalAndContext) AllLOGICAL_AND() []antlr.TerminalNode { + return s.GetTokens(CommandsParserLOGICAL_AND) +} + +func (s *ConditionalAndContext) LOGICAL_AND(i int) antlr.TerminalNode { + return s.GetToken(CommandsParserLOGICAL_AND, i) +} + +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.(CommandsListener); ok { + listenerT.EnterConditionalAnd(s) + } +} + +func (s *ConditionalAndContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitConditionalAnd(s) + } +} + +func (s *ConditionalAndContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitConditionalAnd(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) ConditionalAnd() (localctx IConditionalAndContext) { + this := p + _ = this + + localctx = NewConditionalAndContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 38, CommandsParserRULE_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(189) + + var _x = p.relation(0) + + localctx.(*ConditionalAndContext).e = _x + } + p.SetState(194) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + for _la == CommandsParserLOGICAL_AND { + { + p.SetState(190) + + var _m = p.Match(CommandsParserLOGICAL_AND) + + localctx.(*ConditionalAndContext).s16 = _m + } + localctx.(*ConditionalAndContext).ops = append(localctx.(*ConditionalAndContext).ops, localctx.(*ConditionalAndContext).s16) + { + p.SetState(191) + + var _x = p.relation(0) + + localctx.(*ConditionalAndContext)._relation = _x + } + localctx.(*ConditionalAndContext).e1 = append(localctx.(*ConditionalAndContext).e1, localctx.(*ConditionalAndContext)._relation) + + p.SetState(196) + 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 = CommandsParserRULE_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 = CommandsParserRULE_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 antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ICalcContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ICalcContext) +} + +func (s *RelationContext) AllRelation() []IRelationContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IRelationContext); ok { + len++ + } + } + + tst := make([]IRelationContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IRelationContext); ok { + tst[i] = t.(IRelationContext) + i++ + } + } + + return tst +} + +func (s *RelationContext) Relation(i int) IRelationContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IRelationContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IRelationContext) +} + +func (s *RelationContext) LESS() antlr.TerminalNode { + return s.GetToken(CommandsParserLESS, 0) +} + +func (s *RelationContext) LESS_EQUALS() antlr.TerminalNode { + return s.GetToken(CommandsParserLESS_EQUALS, 0) +} + +func (s *RelationContext) GREATER_EQUALS() antlr.TerminalNode { + return s.GetToken(CommandsParserGREATER_EQUALS, 0) +} + +func (s *RelationContext) GREATER() antlr.TerminalNode { + return s.GetToken(CommandsParserGREATER, 0) +} + +func (s *RelationContext) EQUALS() antlr.TerminalNode { + return s.GetToken(CommandsParserEQUALS, 0) +} + +func (s *RelationContext) NOT_EQUALS() antlr.TerminalNode { + return s.GetToken(CommandsParserNOT_EQUALS, 0) +} + +func (s *RelationContext) IN() antlr.TerminalNode { + return s.GetToken(CommandsParserIN, 0) +} + +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.(CommandsListener); ok { + listenerT.EnterRelation(s) + } +} + +func (s *RelationContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CommandsListener); ok { + listenerT.ExitRelation(s) + } +} + +func (s *RelationContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case CommandsVisitor: + return t.VisitRelation(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *CommandsParser) Relation() (localctx IRelationContext) { + return p.relation(0) +} + +func (p *CommandsParser) relation(_p int) (localctx IRelationContext) { + this := p + _ = this + + 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 := 40 + p.EnterRecursionRule(localctx, 40, CommandsParserRULE_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(198) + p.calc(0) + } + + p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) + p.SetState(205) + p.GetErrorHandler().Sync(p) + _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 19, 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, CommandsParserRULE_relation) + p.SetState(200) + + if !(p.Precpred(p.GetParserRuleContext(), 1)) { + panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 1)", "")) + } + { + p.SetState(201) + + var _lt = p.GetTokenStream().LT(1) + + localctx.(*RelationContext).op = _lt + + _la = p.GetTokenStream().LA(1) + + if !(((_la)&-(0x1f+1)) == 0 && ((1< y + 10", + "%let fn () : int -> 10", + "%let fn (x:int, y : int) : int -> x + y", + "%let fn (x:int, y : int) : int -> x + y", + "%let com.google.fn (x:int, y : int) : int -> x + y", + "%let int.plus (x: int) : int -> this + x", + "%delete id", + "%delete com.google.id", + "%delete int.fn(x:int): int", + "%declare x : int", + "%declare fn (x : int) : int", + "%declare x", // accepted by grammar, but business logic will error + "x + 2", // also an expr + } + for _, tc := range testCases { + err := tryParse(t, tc) + if err != nil { + t.Errorf("parse %s:\ngot %v\nexpected nil", tc, err) + } + + } +} + +func TestReject(t *testing.T) { + var testCases = []string{ + "%declare 1", + "%let 1 = 2", + "%1badid", + "%let fn x : int : int -> x + 2", // parens required + "%let fn (x : int) -> x + 2", // return type required + "x{{", // won't parse as CEL expr + "%declare fn (x: int)", // return type required + "%declare fn (x) : int", // arg type required + } + for _, tc := range testCases { + err := tryParse(t, tc) + if err == nil { + t.Errorf("parse %s got nil, expected error", tc) + } + + } +} diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/parser/Commands.tokens golang-github-google-cel-go-0.12.5+ds/repl/parser/Commands.tokens --- golang-github-google-cel-go-0.11.4+ds/repl/parser/Commands.tokens 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/parser/Commands.tokens 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,78 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +COMMAND=5 +FLAG=6 +ARROW=7 +EQUAL_ASSIGN=8 +EQUALS=9 +NOT_EQUALS=10 +IN=11 +LESS=12 +LESS_EQUALS=13 +GREATER_EQUALS=14 +GREATER=15 +LOGICAL_AND=16 +LOGICAL_OR=17 +LBRACKET=18 +RPRACKET=19 +LBRACE=20 +RBRACE=21 +LPAREN=22 +RPAREN=23 +DOT=24 +COMMA=25 +MINUS=26 +EXCLAM=27 +QUESTIONMARK=28 +COLON=29 +PLUS=30 +STAR=31 +SLASH=32 +PERCENT=33 +CEL_TRUE=34 +CEL_FALSE=35 +NUL=36 +WHITESPACE=37 +COMMENT=38 +NUM_FLOAT=39 +NUM_INT=40 +NUM_UINT=41 +STRING=42 +BYTES=43 +IDENTIFIER=44 +'%let'=1 +'%declare'=2 +'%delete'=3 +'%eval'=4 +'->'=7 +'='=8 +'=='=9 +'!='=10 +'in'=11 +'<'=12 +'<='=13 +'>='=14 +'>'=15 +'&&'=16 +'||'=17 +'['=18 +']'=19 +'{'=20 +'}'=21 +'('=22 +')'=23 +'.'=24 +','=25 +'-'=26 +'!'=27 +'?'=28 +':'=29 +'+'=30 +'*'=31 +'/'=32 +'%'=33 +'true'=34 +'false'=35 +'null'=36 diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/parser/commands_visitor.go golang-github-google-cel-go-0.12.5+ds/repl/parser/commands_visitor.go --- golang-github-google-cel-go-0.11.4+ds/repl/parser/commands_visitor.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/parser/commands_visitor.go 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,144 @@ +// Code generated from ./Commands.g4 by ANTLR 4.10.1. DO NOT EDIT. + +package parser // Commands +import "github.com/antlr/antlr4/runtime/Go/antlr" + +// A complete Visitor for a parse tree produced by CommandsParser. +type CommandsVisitor interface { + antlr.ParseTreeVisitor + + // Visit a parse tree produced by CommandsParser#startCommand. + VisitStartCommand(ctx *StartCommandContext) interface{} + + // Visit a parse tree produced by CommandsParser#command. + VisitCommand(ctx *CommandContext) interface{} + + // Visit a parse tree produced by CommandsParser#let. + VisitLet(ctx *LetContext) interface{} + + // Visit a parse tree produced by CommandsParser#declare. + VisitDeclare(ctx *DeclareContext) interface{} + + // Visit a parse tree produced by CommandsParser#varDecl. + VisitVarDecl(ctx *VarDeclContext) interface{} + + // Visit a parse tree produced by CommandsParser#fnDecl. + VisitFnDecl(ctx *FnDeclContext) interface{} + + // Visit a parse tree produced by CommandsParser#param. + VisitParam(ctx *ParamContext) interface{} + + // Visit a parse tree produced by CommandsParser#delete. + VisitDelete(ctx *DeleteContext) interface{} + + // Visit a parse tree produced by CommandsParser#simple. + VisitSimple(ctx *SimpleContext) interface{} + + // Visit a parse tree produced by CommandsParser#empty. + VisitEmpty(ctx *EmptyContext) interface{} + + // Visit a parse tree produced by CommandsParser#exprCmd. + VisitExprCmd(ctx *ExprCmdContext) interface{} + + // Visit a parse tree produced by CommandsParser#qualId. + VisitQualId(ctx *QualIdContext) interface{} + + // Visit a parse tree produced by CommandsParser#startType. + VisitStartType(ctx *StartTypeContext) interface{} + + // Visit a parse tree produced by CommandsParser#type. + VisitType(ctx *TypeContext) interface{} + + // Visit a parse tree produced by CommandsParser#typeId. + VisitTypeId(ctx *TypeIdContext) interface{} + + // Visit a parse tree produced by CommandsParser#typeParamList. + VisitTypeParamList(ctx *TypeParamListContext) interface{} + + // Visit a parse tree produced by CommandsParser#start. + VisitStart(ctx *StartContext) interface{} + + // Visit a parse tree produced by CommandsParser#expr. + VisitExpr(ctx *ExprContext) interface{} + + // Visit a parse tree produced by CommandsParser#conditionalOr. + VisitConditionalOr(ctx *ConditionalOrContext) interface{} + + // Visit a parse tree produced by CommandsParser#conditionalAnd. + VisitConditionalAnd(ctx *ConditionalAndContext) interface{} + + // Visit a parse tree produced by CommandsParser#relation. + VisitRelation(ctx *RelationContext) interface{} + + // Visit a parse tree produced by CommandsParser#calc. + VisitCalc(ctx *CalcContext) interface{} + + // Visit a parse tree produced by CommandsParser#MemberExpr. + VisitMemberExpr(ctx *MemberExprContext) interface{} + + // Visit a parse tree produced by CommandsParser#LogicalNot. + VisitLogicalNot(ctx *LogicalNotContext) interface{} + + // Visit a parse tree produced by CommandsParser#Negate. + VisitNegate(ctx *NegateContext) interface{} + + // Visit a parse tree produced by CommandsParser#SelectOrCall. + VisitSelectOrCall(ctx *SelectOrCallContext) interface{} + + // Visit a parse tree produced by CommandsParser#PrimaryExpr. + VisitPrimaryExpr(ctx *PrimaryExprContext) interface{} + + // Visit a parse tree produced by CommandsParser#Index. + VisitIndex(ctx *IndexContext) interface{} + + // Visit a parse tree produced by CommandsParser#CreateMessage. + VisitCreateMessage(ctx *CreateMessageContext) interface{} + + // Visit a parse tree produced by CommandsParser#IdentOrGlobalCall. + VisitIdentOrGlobalCall(ctx *IdentOrGlobalCallContext) interface{} + + // Visit a parse tree produced by CommandsParser#Nested. + VisitNested(ctx *NestedContext) interface{} + + // Visit a parse tree produced by CommandsParser#CreateList. + VisitCreateList(ctx *CreateListContext) interface{} + + // Visit a parse tree produced by CommandsParser#CreateStruct. + VisitCreateStruct(ctx *CreateStructContext) interface{} + + // Visit a parse tree produced by CommandsParser#ConstantLiteral. + VisitConstantLiteral(ctx *ConstantLiteralContext) interface{} + + // Visit a parse tree produced by CommandsParser#exprList. + VisitExprList(ctx *ExprListContext) interface{} + + // Visit a parse tree produced by CommandsParser#fieldInitializerList. + VisitFieldInitializerList(ctx *FieldInitializerListContext) interface{} + + // Visit a parse tree produced by CommandsParser#mapInitializerList. + VisitMapInitializerList(ctx *MapInitializerListContext) interface{} + + // Visit a parse tree produced by CommandsParser#Int. + VisitInt(ctx *IntContext) interface{} + + // Visit a parse tree produced by CommandsParser#Uint. + VisitUint(ctx *UintContext) interface{} + + // Visit a parse tree produced by CommandsParser#Double. + VisitDouble(ctx *DoubleContext) interface{} + + // Visit a parse tree produced by CommandsParser#String. + VisitString(ctx *StringContext) interface{} + + // Visit a parse tree produced by CommandsParser#Bytes. + VisitBytes(ctx *BytesContext) interface{} + + // Visit a parse tree produced by CommandsParser#BoolTrue. + VisitBoolTrue(ctx *BoolTrueContext) interface{} + + // Visit a parse tree produced by CommandsParser#BoolFalse. + VisitBoolFalse(ctx *BoolFalseContext) interface{} + + // Visit a parse tree produced by CommandsParser#Null. + VisitNull(ctx *NullContext) interface{} +} diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/parser/regen.sh golang-github-google-cel-go-0.12.5+ds/repl/parser/regen.sh --- golang-github-google-cel-go-0.11.4+ds/repl/parser/regen.sh 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/parser/regen.sh 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,12 @@ +#!/bin/sh + +ANTLR_JAR="$HOME/bin/antlr-4.10.1-complete.jar" +export CLASSPATH=".:$ANTLR_JAR:$CLASSPATH" +antlr4="java -Xmx500M -cp \"$ANTLR_JAR:$CLASSPATH\" org.antlr.v4.Tool" + +$antlr4 \ + -Dlanguage=Go \ + -lib ../../parser/gen \ + -package parser \ + -visitor \ + ./Commands.g4 diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/testdata/attribute_context_fds.textproto golang-github-google-cel-go-0.12.5+ds/repl/testdata/attribute_context_fds.textproto --- golang-github-google-cel-go-0.11.4+ds/repl/testdata/attribute_context_fds.textproto 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/testdata/attribute_context_fds.textproto 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,751 @@ +file { + name: "google/protobuf/any.proto" + package: "google.protobuf" + message_type { + name: "Any" + field { + name: "type_url" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + options { + ctype: STRING_PIECE + } + json_name: "typeUrl" + } + field { + name: "value" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_BYTES + options { + ctype: CORD + } + json_name: "value" + } + } + options { + java_package: "com.google.protobuf" + java_outer_classname: "AnyProto" + java_multiple_files: true + go_package: "google.golang.org/protobuf/types/known/anypb" + objc_class_prefix: "GPB" + csharp_namespace: "Google.Protobuf.WellKnownTypes" + } + syntax: "proto3" +} +file { + name: "google/protobuf/duration.proto" + package: "google.protobuf" + message_type { + name: "Duration" + field { + name: "seconds" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT64 + json_name: "seconds" + } + field { + name: "nanos" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_INT32 + json_name: "nanos" + } + } + options { + java_package: "com.google.protobuf" + java_outer_classname: "DurationProto" + java_multiple_files: true + go_package: "google.golang.org/protobuf/types/known/durationpb" + cc_enable_arenas: true + objc_class_prefix: "GPB" + csharp_namespace: "Google.Protobuf.WellKnownTypes" + } + syntax: "proto3" +} +file { + name: "google/protobuf/struct.proto" + package: "google.protobuf" + message_type { + name: "Struct" + field { + name: "fields" + number: 1 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".google.protobuf.Struct.FieldsEntry" + json_name: "fields" + } + nested_type { + name: "FieldsEntry" + field { + name: "key" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "key" + } + field { + name: "value" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.protobuf.Value" + json_name: "value" + } + options { + map_entry: true + } + } + } + message_type { + name: "Value" + field { + name: "null_value" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_ENUM + type_name: ".google.protobuf.NullValue" + oneof_index: 0 + json_name: "nullValue" + } + field { + name: "number_value" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_DOUBLE + oneof_index: 0 + json_name: "numberValue" + } + field { + name: "string_value" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_STRING + oneof_index: 0 + json_name: "stringValue" + } + field { + name: "bool_value" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_BOOL + oneof_index: 0 + json_name: "boolValue" + } + field { + name: "struct_value" + number: 5 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.protobuf.Struct" + oneof_index: 0 + json_name: "structValue" + } + field { + name: "list_value" + number: 6 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.protobuf.ListValue" + oneof_index: 0 + json_name: "listValue" + } + oneof_decl { + name: "kind" + } + } + message_type { + name: "ListValue" + field { + name: "values" + number: 1 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".google.protobuf.Value" + json_name: "values" + } + } + enum_type { + name: "NullValue" + value { + name: "NULL_VALUE" + number: 0 + } + } + options { + java_package: "com.google.protobuf" + java_outer_classname: "StructProto" + java_multiple_files: true + go_package: "google.golang.org/protobuf/types/known/structpb" + cc_enable_arenas: true + objc_class_prefix: "GPB" + csharp_namespace: "Google.Protobuf.WellKnownTypes" + } + syntax: "proto3" +} +file { + name: "google/protobuf/timestamp.proto" + package: "google.protobuf" + message_type { + name: "Timestamp" + field { + name: "seconds" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT64 + json_name: "seconds" + } + field { + name: "nanos" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_INT32 + json_name: "nanos" + } + } + options { + java_package: "com.google.protobuf" + java_outer_classname: "TimestampProto" + java_multiple_files: true + go_package: "google.golang.org/protobuf/types/known/timestamppb" + cc_enable_arenas: true + objc_class_prefix: "GPB" + csharp_namespace: "Google.Protobuf.WellKnownTypes" + } + syntax: "proto3" +} +file { + name: "google/rpc/context/attribute_context.proto" + package: "google.rpc.context" + dependency: "google/protobuf/any.proto" + dependency: "google/protobuf/duration.proto" + dependency: "google/protobuf/struct.proto" + dependency: "google/protobuf/timestamp.proto" + message_type { + name: "AttributeContext" + field { + name: "origin" + number: 7 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.rpc.context.AttributeContext.Peer" + json_name: "origin" + } + field { + name: "source" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.rpc.context.AttributeContext.Peer" + json_name: "source" + } + field { + name: "destination" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.rpc.context.AttributeContext.Peer" + json_name: "destination" + } + field { + name: "request" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.rpc.context.AttributeContext.Request" + json_name: "request" + } + field { + name: "response" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.rpc.context.AttributeContext.Response" + json_name: "response" + } + field { + name: "resource" + number: 5 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.rpc.context.AttributeContext.Resource" + json_name: "resource" + } + field { + name: "api" + number: 6 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.rpc.context.AttributeContext.Api" + json_name: "api" + } + field { + name: "extensions" + number: 8 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".google.protobuf.Any" + json_name: "extensions" + } + nested_type { + name: "Peer" + field { + name: "ip" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "ip" + } + field { + name: "port" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_INT64 + json_name: "port" + } + field { + name: "labels" + number: 6 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".google.rpc.context.AttributeContext.Peer.LabelsEntry" + json_name: "labels" + } + field { + name: "principal" + number: 7 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "principal" + } + field { + name: "region_code" + number: 8 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "regionCode" + } + nested_type { + name: "LabelsEntry" + field { + name: "key" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "key" + } + field { + name: "value" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "value" + } + options { + map_entry: true + } + } + reserved_range { + start: 3 + end: 4 + } + reserved_range { + start: 4 + end: 5 + } + reserved_range { + start: 5 + end: 6 + } + } + nested_type { + name: "Api" + field { + name: "service" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "service" + } + field { + name: "operation" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "operation" + } + field { + name: "protocol" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "protocol" + } + field { + name: "version" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "version" + } + } + nested_type { + name: "Auth" + field { + name: "principal" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "principal" + } + field { + name: "audiences" + number: 2 + label: LABEL_REPEATED + type: TYPE_STRING + json_name: "audiences" + } + field { + name: "presenter" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "presenter" + } + field { + name: "claims" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.protobuf.Struct" + json_name: "claims" + } + field { + name: "access_levels" + number: 5 + label: LABEL_REPEATED + type: TYPE_STRING + json_name: "accessLevels" + } + } + nested_type { + name: "Request" + field { + name: "id" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "id" + } + field { + name: "method" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "method" + } + field { + name: "headers" + number: 3 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".google.rpc.context.AttributeContext.Request.HeadersEntry" + json_name: "headers" + } + field { + name: "path" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "path" + } + field { + name: "host" + number: 5 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "host" + } + field { + name: "scheme" + number: 6 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "scheme" + } + field { + name: "query" + number: 7 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "query" + } + field { + name: "time" + number: 9 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.protobuf.Timestamp" + json_name: "time" + } + field { + name: "size" + number: 10 + label: LABEL_OPTIONAL + type: TYPE_INT64 + json_name: "size" + } + field { + name: "protocol" + number: 11 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "protocol" + } + field { + name: "reason" + number: 12 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "reason" + } + field { + name: "auth" + number: 13 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.rpc.context.AttributeContext.Auth" + json_name: "auth" + } + nested_type { + name: "HeadersEntry" + field { + name: "key" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "key" + } + field { + name: "value" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "value" + } + options { + map_entry: true + } + } + reserved_range { + start: 8 + end: 9 + } + } + nested_type { + name: "Response" + field { + name: "code" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT64 + json_name: "code" + } + field { + name: "size" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_INT64 + json_name: "size" + } + field { + name: "headers" + number: 3 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".google.rpc.context.AttributeContext.Response.HeadersEntry" + json_name: "headers" + } + field { + name: "time" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.protobuf.Timestamp" + json_name: "time" + } + field { + name: "backend_latency" + number: 5 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.protobuf.Duration" + json_name: "backendLatency" + } + nested_type { + name: "HeadersEntry" + field { + name: "key" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "key" + } + field { + name: "value" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "value" + } + options { + map_entry: true + } + } + } + nested_type { + name: "Resource" + field { + name: "service" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "service" + } + field { + name: "name" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "name" + } + field { + name: "type" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "type" + } + field { + name: "labels" + number: 4 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".google.rpc.context.AttributeContext.Resource.LabelsEntry" + json_name: "labels" + } + field { + name: "uid" + number: 5 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "uid" + } + field { + name: "annotations" + number: 6 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".google.rpc.context.AttributeContext.Resource.AnnotationsEntry" + json_name: "annotations" + } + field { + name: "display_name" + number: 7 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "displayName" + } + field { + name: "create_time" + number: 8 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.protobuf.Timestamp" + json_name: "createTime" + } + field { + name: "update_time" + number: 9 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.protobuf.Timestamp" + json_name: "updateTime" + } + field { + name: "delete_time" + number: 10 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.protobuf.Timestamp" + json_name: "deleteTime" + } + field { + name: "etag" + number: 11 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "etag" + } + field { + name: "location" + number: 12 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "location" + } + nested_type { + name: "LabelsEntry" + field { + name: "key" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "key" + } + field { + name: "value" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "value" + } + options { + map_entry: true + } + } + nested_type { + name: "AnnotationsEntry" + field { + name: "key" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "key" + } + field { + name: "value" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "value" + } + options { + map_entry: true + } + } + } + } + options { + java_package: "com.google.rpc.context" + java_outer_classname: "AttributeContextProto" + java_multiple_files: true + go_package: "google.golang.org/genproto/googleapis/rpc/context/attribute_context;attribute_context" + cc_enable_arenas: true + } + syntax: "proto3" +} + diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/typefmt.go golang-github-google-cel-go-0.12.5+ds/repl/typefmt.go --- golang-github-google-cel-go-0.11.4+ds/repl/typefmt.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/typefmt.go 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,318 @@ +// Copyright 2022 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 +// +// https://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 repl + +import ( + "fmt" + "strings" + + "github.com/antlr/antlr4/runtime/Go/antlr" + "github.com/google/cel-go/repl/parser" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +func formatTypeArgs(ts []*exprpb.Type) string { + s := make([]string, len(ts)) + for i, t := range ts { + s[i] = UnparseType(t) + } + return fmt.Sprintf("(%s)", strings.Join(s, ", ")) +} + +func formatFn(t *exprpb.Type_FunctionType) string { + return fmt.Sprintf("%s -> %s", formatTypeArgs(t.GetArgTypes()), UnparseType(t.GetResultType())) +} + +func formatPrimitive(t exprpb.Type_PrimitiveType) string { + switch t { + case exprpb.Type_BOOL: + return "bool" + case exprpb.Type_STRING: + return "string" + case exprpb.Type_BYTES: + return "bytes" + case exprpb.Type_INT64: + return "int" + case exprpb.Type_UINT64: + return "uint" + case exprpb.Type_DOUBLE: + return "double" + } + return "" +} + +func formatWellKnown(t exprpb.Type_WellKnownType) string { + switch t { + case exprpb.Type_ANY: + return "any" + case exprpb.Type_DURATION: + return "google.protobuf.Duration" + case exprpb.Type_TIMESTAMP: + return "google.protobuf.Timestamp" + } + return "" +} + +// UnparseType pretty-prints a type for the REPL. +// +// TODO(issue/538): This is slightly different from core CEL's built-in formatter. Should +// converge if possible. +func UnparseType(t *exprpb.Type) string { + if t == nil { + return "" + } + switch t.TypeKind.(type) { + case *exprpb.Type_Dyn: + return "dyn" + case *exprpb.Type_Null: + return "null" + case *exprpb.Type_Primitive: + return formatPrimitive(t.GetPrimitive()) + case *exprpb.Type_WellKnown: + return formatWellKnown(t.GetWellKnown()) + case *exprpb.Type_ListType_: + return fmt.Sprintf("list(%s)", UnparseType(t.GetListType().GetElemType())) + case *exprpb.Type_MapType_: + return fmt.Sprintf("map(%s, %s)", UnparseType(t.GetMapType().GetKeyType()), UnparseType(t.GetMapType().GetValueType())) + case *exprpb.Type_Type: + return fmt.Sprintf("type(%s)", UnparseType(t.GetType())) + case *exprpb.Type_Wrapper: + return fmt.Sprintf("wrapper(%s)", formatPrimitive(t.GetWrapper())) + case *exprpb.Type_Error: + return "*error*" + case *exprpb.Type_MessageType: + return t.GetMessageType() + case *exprpb.Type_TypeParam: + return t.GetTypeParam() + case *exprpb.Type_Function: + return formatFn(t.GetFunction()) + case *exprpb.Type_AbstractType_: + if len(t.GetAbstractType().GetParameterTypes()) > 0 { + return t.GetAbstractType().GetName() + formatTypeArgs(t.GetAbstractType().GetParameterTypes()) + } + return t.GetAbstractType().GetName() + } + return "" +} + +type errorListener struct { + *antlr.DefaultErrorListener + errs []error +} + +func (l *errorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) { + l.errs = append(l.errs, fmt.Errorf("type parse error: %s", msg)) + l.DefaultErrorListener.SyntaxError(recognizer, offendingSymbol, line, column, msg, e) +} + +type typesVisitor struct { + parser.BaseCommandsVisitor + + errs []error +} + +var _ parser.CommandsVisitor = &typesVisitor{} + +type typeParams []*exprpb.Type + +func (t *typesVisitor) Visit(tree antlr.ParseTree) interface{} { + switch ctx := tree.(type) { + case *parser.StartTypeContext: + return t.VisitStartType(ctx) + case *parser.TypeContext: + return t.VisitType(ctx) + case *parser.TypeIdContext: + return t.VisitTypeId(ctx) + case *parser.TypeParamListContext: + return t.VisitTypeParamList(ctx) + default: + t.errs = append(t.errs, fmt.Errorf("unhandled parse node kind")) + return nil + } + +} + +func (t *typesVisitor) VisitStartType(ctx *parser.StartTypeContext) interface{} { + return t.Visit(ctx.GetT()) +} + +func (t *typesVisitor) expectUnparameterized(p typeParams, id string) { + if p != nil { + t.errs = append(t.errs, fmt.Errorf("unexpected type params for %s", id)) + } +} + +func checkWellKnown(name string) *exprpb.Type { + switch name { + case "google.protobuf.Timestamp", ".google.protobuf.Timestamp": + return &exprpb.Type{TypeKind: &exprpb.Type_WellKnown{WellKnown: exprpb.Type_TIMESTAMP}} + case "google.protobuf.Duration", ".google.protobuf.Duration": + return &exprpb.Type{TypeKind: &exprpb.Type_WellKnown{WellKnown: exprpb.Type_DURATION}} + case "any": + return &exprpb.Type{TypeKind: &exprpb.Type_WellKnown{WellKnown: exprpb.Type_ANY}} + } + return nil +} + +func (t *typesVisitor) VisitTypeId(ctx *parser.TypeIdContext) interface{} { + id := "" + if ctx.GetLeadingDot() != nil { + id += "." + } + tl := ctx.GetId() + if tl == nil { + return nil + } + id += tl.GetText() + for _, tok := range ctx.GetQualifiers() { + id += "." + tok.GetText() + } + return id +} + +func (t *typesVisitor) VisitTypeParamList(ctx *parser.TypeParamListContext) interface{} { + var params typeParams + for _, ty := range ctx.GetTypes() { + p := t.Visit(ty) + params = append(params, p.(*exprpb.Type)) + } + return params +} + +func (t *typesVisitor) VisitType(ctx *parser.TypeContext) interface{} { + emptyType := &exprpb.Type{} + + r := t.Visit(ctx.GetId()) + if r == nil { + return emptyType + } + + typeID := r.(string) + + paramsCtx := ctx.GetParams() + + var params typeParams + if paramsCtx != nil { + r = t.Visit(paramsCtx) + if r == nil { + return emptyType + } + params = r.(typeParams) + } + + switch typeID { + case "int": + t.expectUnparameterized(params, typeID) + return &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_INT64}} + case "uint": + t.expectUnparameterized(params, typeID) + return &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_UINT64}} + case "double": + t.expectUnparameterized(params, typeID) + return &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_DOUBLE}} + case "bytes": + t.expectUnparameterized(params, typeID) + return &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_BYTES}} + case "string": + t.expectUnparameterized(params, typeID) + return &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_STRING}} + case "bool": + t.expectUnparameterized(params, typeID) + return &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_BOOL}} + case "dyn": + t.expectUnparameterized(params, typeID) + return &exprpb.Type{TypeKind: &exprpb.Type_Dyn{}} + case "null": + t.expectUnparameterized(params, typeID) + return &exprpb.Type{TypeKind: &exprpb.Type_Null{}} + case "wrapper": + if params == nil || len(params) != 1 { + t.errs = append(t.errs, fmt.Errorf("expected exactly one parameter for wrapper")) + return emptyType + } + p := params[0] + if p.GetPrimitive() == exprpb.Type_PRIMITIVE_TYPE_UNSPECIFIED { + t.errs = append(t.errs, fmt.Errorf("expected primitive param for wrapper")) + } + return &exprpb.Type{TypeKind: &exprpb.Type_Wrapper{Wrapper: p.GetPrimitive()}} + case "list": + if params == nil || len(params) != 1 { + t.errs = append(t.errs, fmt.Errorf("expected exactly one parameter for list")) + return emptyType + } + p := params[0] + return &exprpb.Type{TypeKind: &exprpb.Type_ListType_{ListType: &exprpb.Type_ListType{ElemType: p}}} + case "map": + if params == nil || len(params) != 2 { + t.errs = append(t.errs, fmt.Errorf("expected exactly two parameters for map")) + return emptyType + } + k, v := params[0], params[1] + return &exprpb.Type{TypeKind: &exprpb.Type_MapType_{ + MapType: &exprpb.Type_MapType{ + KeyType: k, + ValueType: v, + }}} + case "type": + if params == nil || len(params) != 1 { + t.errs = append(t.errs, fmt.Errorf("expected exactly one parameter for type")) + return emptyType + } + p := params[0] + return &exprpb.Type{TypeKind: &exprpb.Type_Type{Type: p}} + default: + // TODO(issue/538): need a way to distinguish message from abstract type + t.expectUnparameterized(params, typeID) + wkt := checkWellKnown(typeID) + if wkt != nil { + return wkt + } + return &exprpb.Type{TypeKind: &exprpb.Type_MessageType{MessageType: typeID}} + } +} + +// ParseType parses a human readable type string into the protobuf representation. +// TODO(issue/538): add support for abstract types and validating message types. +func ParseType(t string) (*exprpb.Type, error) { + var errListener errorListener + visitor := &typesVisitor{} + is := antlr.NewInputStream(t) + lexer := parser.NewCommandsLexer(is) + lexer.RemoveErrorListeners() + lexer.AddErrorListener(&errListener) + p := parser.NewCommandsParser(antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)) + p.RemoveErrorListeners() + p.AddErrorListener(&errListener) + + var result *exprpb.Type + s := visitor.Visit(p.StartType()) + if s != nil { + result = s.(*exprpb.Type) + } + + errs := append(errListener.errs, visitor.errs...) + var err error = nil + + if len(errs) > 0 { + msgs := make([]string, len(errs)) + for i, e := range errs { + msgs[i] = e.Error() + } + err = fmt.Errorf("errors parsing type:\n" + strings.Join(msgs, "\n")) + } + + return result, err +} diff -Nru golang-github-google-cel-go-0.11.4+ds/repl/typefmt_test.go golang-github-google-cel-go-0.12.5+ds/repl/typefmt_test.go --- golang-github-google-cel-go-0.11.4+ds/repl/typefmt_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/repl/typefmt_test.go 2022-12-20 15:30:36.000000000 +0000 @@ -0,0 +1,356 @@ +// Copyright 2022 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 +// +// https://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 repl + +import ( + "testing" + + "google.golang.org/protobuf/proto" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +func TestUnparseType(t *testing.T) { + var testCases = []struct { + exprType *exprpb.Type + wantFmt string + }{ + { + exprType: &exprpb.Type{}, + wantFmt: "", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_Dyn{}}, + wantFmt: "dyn", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_Null{}}, + wantFmt: "null", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_BOOL}}, + wantFmt: "bool", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_INT64}}, + wantFmt: "int", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_UINT64}}, + wantFmt: "uint", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_DOUBLE}}, + wantFmt: "double", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_STRING}}, + wantFmt: "string", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_BYTES}}, + wantFmt: "bytes", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_PRIMITIVE_TYPE_UNSPECIFIED}}, + wantFmt: "", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_WellKnown{WellKnown: exprpb.Type_DURATION}}, + wantFmt: "google.protobuf.Duration", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_WellKnown{WellKnown: exprpb.Type_TIMESTAMP}}, + wantFmt: "google.protobuf.Timestamp", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_WellKnown{WellKnown: exprpb.Type_ANY}}, + wantFmt: "any", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_WellKnown{WellKnown: exprpb.Type_WELL_KNOWN_TYPE_UNSPECIFIED}}, + wantFmt: "", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_MapType_{MapType: &exprpb.Type_MapType{ + KeyType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_STRING}}, + ValueType: &exprpb.Type{TypeKind: &exprpb.Type_WellKnown{WellKnown: exprpb.Type_TIMESTAMP}}, + }}}, + wantFmt: "map(string, google.protobuf.Timestamp)", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_ListType_{ + ListType: &exprpb.Type_ListType{ElemType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_DOUBLE}}}}}, + wantFmt: "list(double)", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_Type{ + Type: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_DOUBLE}}}}, + wantFmt: "type(double)", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_Wrapper{ + Wrapper: exprpb.Type_UINT64}}, + wantFmt: "wrapper(uint)", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_Error{}}, + wantFmt: "*error*", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_MessageType{ + MessageType: "com.example.Message", + }}, + wantFmt: "com.example.Message", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_TypeParam{ + TypeParam: "T", + }}, + wantFmt: "T", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_Function{ + Function: &exprpb.Type_FunctionType{ + ResultType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_DOUBLE}}, + ArgTypes: []*exprpb.Type{ + {TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_DOUBLE}}, + {TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_DOUBLE}}, + }, + }, + }}, + wantFmt: "(double, double) -> double", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_AbstractType_{ + AbstractType: &exprpb.Type_AbstractType{ + Name: "MyAbstractParamType", + ParameterTypes: []*exprpb.Type{ + {TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_DOUBLE}}, + {TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_STRING}}, + }, + }, + }}, + wantFmt: "MyAbstractParamType(double, string)", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_AbstractType_{ + AbstractType: &exprpb.Type_AbstractType{ + Name: "MyAbstractType", + }, + }}, + wantFmt: "MyAbstractType", + }, + { + exprType: &exprpb.Type{TypeKind: &exprpb.Type_MapType_{MapType: &exprpb.Type_MapType{ + KeyType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_STRING}}, + ValueType: &exprpb.Type{TypeKind: &exprpb.Type_ListType_{ + ListType: &exprpb.Type_ListType{ElemType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_DOUBLE}}}}}, + }}}, + wantFmt: "map(string, list(double))", + }, + } + + for _, tc := range testCases { + fmt := UnparseType(tc.exprType) + if fmt != tc.wantFmt { + t.Errorf("expected: %s got: %s for type: %v", tc.wantFmt, fmt, tc.exprType) + } + } + +} + +func TestParseType(t *testing.T) { + var testCases = []struct { + fmt string + wantExprType *exprpb.Type + }{ + { + fmt: "int", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_INT64}}, + }, + { + fmt: "uint", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_UINT64}}, + }, + { + fmt: "double", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_DOUBLE}}, + }, + { + fmt: "string", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_STRING}}, + }, + { + fmt: "bytes", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_BYTES}}, + }, + { + fmt: "bool", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_BOOL}}, + }, + { + fmt: "wrapper(int)", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_Wrapper{Wrapper: exprpb.Type_INT64}}, + }, + { + fmt: "wrapper(uint)", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_Wrapper{Wrapper: exprpb.Type_UINT64}}, + }, + { + fmt: "wrapper(double)", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_Wrapper{Wrapper: exprpb.Type_DOUBLE}}, + }, + { + fmt: "wrapper(string)", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_Wrapper{Wrapper: exprpb.Type_STRING}}, + }, + { + fmt: "wrapper(bytes)", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_Wrapper{Wrapper: exprpb.Type_BYTES}}, + }, + { + fmt: "wrapper(bool)", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_Wrapper{Wrapper: exprpb.Type_BOOL}}, + }, + { + fmt: "dyn", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_Dyn{}}, + }, + { + fmt: "null", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_Null{}}, + }, + { + fmt: "any", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_WellKnown{WellKnown: exprpb.Type_ANY}}, + }, + { + fmt: "google.protobuf.Timestamp", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_WellKnown{WellKnown: exprpb.Type_TIMESTAMP}}, + }, + { + fmt: "google.protobuf.Duration", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_WellKnown{WellKnown: exprpb.Type_DURATION}}, + }, + { + fmt: "map(string, int)", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_MapType_{ + MapType: &exprpb.Type_MapType{ + KeyType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_STRING}}, + ValueType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_INT64}}, + }}}, + }, + { + fmt: "map(string, map(string, int))", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_MapType_{ + MapType: &exprpb.Type_MapType{ + KeyType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_STRING}}, + ValueType: &exprpb.Type{TypeKind: &exprpb.Type_MapType_{ + MapType: &exprpb.Type_MapType{ + KeyType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_STRING}}, + ValueType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_INT64}}, + }}}, + }}}, + }, + + { + fmt: "list(int)", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_ListType_{ + ListType: &exprpb.Type_ListType{ElemType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_INT64}}}}}, + }, + { + fmt: "list(list(int))", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_ListType_{ + ListType: &exprpb.Type_ListType{ElemType: &exprpb.Type{TypeKind: &exprpb.Type_ListType_{ + ListType: &exprpb.Type_ListType{ElemType: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_INT64}}}}}}}}, + }, + { + fmt: ".com.example.Message", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_MessageType{MessageType: ".com.example.Message"}}, + }, + { + fmt: "type(int)", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_Type{ + Type: &exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: exprpb.Type_INT64}}}}, + }, + { + fmt: "type(type(wrapper(int)))", + wantExprType: &exprpb.Type{TypeKind: &exprpb.Type_Type{ + Type: &exprpb.Type{TypeKind: &exprpb.Type_Type{ + Type: &exprpb.Type{TypeKind: &exprpb.Type_Wrapper{Wrapper: exprpb.Type_INT64}}}}}}, + }, + } + + for _, tc := range testCases { + exprType, err := ParseType(tc.fmt) + if err != nil { + t.Fatalf("ParseType(%s) failed: %v", tc.fmt, err) + } + if !proto.Equal(exprType, tc.wantExprType) { + t.Errorf("ParseType(%s) got %s, wanted %s", tc.fmt, exprType, tc.wantExprType) + } + } +} + +func TestParseTypeErrors(t *testing.T) { + var testCases = []struct { + fmt string + }{{ + fmt: "list()", + }, + { + fmt: "list(int", + }, + { + fmt: "list", + }, + { + fmt: "list(int, int)", + }, + { + fmt: "wrapper(int, double)", + }, + { + fmt: "wrapper(map(int, int))", + }, + { + fmt: "in", + }, + { + fmt: "x?", + }, + { + fmt: "map(int)", + }, + { + fmt: "map", + }, + { + fmt: "map(string, )", + }, + { + fmt: "map(string, int", + }, + } + + for _, tc := range testCases { + exprType, err := ParseType(tc.fmt) + if err == nil { + t.Errorf("ParseType(%s) got %s, wanted error", tc.fmt, exprType) + } + } + +} diff -Nru golang-github-google-cel-go-0.11.4+ds/server/server.go golang-github-google-cel-go-0.12.5+ds/server/server.go --- golang-github-google-cel-go-0.11.4+ds/server/server.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/server/server.go 2022-12-20 15:30:36.000000000 +0000 @@ -100,7 +100,7 @@ env, _ := evalEnv.Extend(cel.Container(in.Container)) var prg cel.Program var err error - switch in.ExprKind.(type) { + switch in.GetExprKind().(type) { case *confpb.EvalRequest_ParsedExpr: ast := cel.ParsedExprToAst(in.GetParsedExpr()) prg, err = env.Program(ast) diff -Nru golang-github-google-cel-go-0.11.4+ds/test/compare.go golang-github-google-cel-go-0.12.5+ds/test/compare.go --- golang-github-google-cel-go-0.11.4+ds/test/compare.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/test/compare.go 2022-12-20 15:30:36.000000000 +0000 @@ -22,18 +22,17 @@ // Compare compares two strings, a for actual, e for expected, and returns true or false. The comparison is done, // by filtering out whitespace (i.e. space, tabs and newline). func Compare(a string, e string) bool { - a = strings.Replace(a, " ", "", -1) - a = strings.Replace(a, "\n", "", -1) - a = strings.Replace(a, "\t", "", -1) - - e = strings.Replace(e, " ", "", -1) - e = strings.Replace(e, "\n", "", -1) - e = strings.Replace(e, "\t", "", -1) - - return a == e + return stripWhitespace(a) == stripWhitespace(e) } // DiffMessage creates a diff dump message for test failures. func DiffMessage(context string, actual interface{}, expected interface{}) string { - return fmt.Sprintf("%s: \ngot %q, \nwanted %q", context, actual, expected) + return fmt.Sprintf("%s: \ngot %v, \nwanted %v", context, actual, expected) +} + +func stripWhitespace(a string) string { + a = strings.Replace(a, " ", "", -1) + a = strings.Replace(a, "\n", "", -1) + a = strings.Replace(a, "\t", "", -1) + return strings.Replace(a, "\r", "", -1) } diff -Nru golang-github-google-cel-go-0.11.4+ds/test/proto2pb/test_all_types.pb.go golang-github-google-cel-go-0.12.5+ds/test/proto2pb/test_all_types.pb.go --- golang-github-google-cel-go-0.11.4+ds/test/proto2pb/test_all_types.pb.go 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/test/proto2pb/test_all_types.pb.go 2022-12-20 15:30:36.000000000 +0000 @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.22.0 -// protoc v3.11.4 +// protoc-gen-go v1.25.0 +// protoc v3.13.0 // source: test/proto2pb/test_all_types.proto package google_expr_proto2_test @@ -153,36 +153,37 @@ sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - SingleInt32 *int32 `protobuf:"varint,1,opt,name=single_int32,json=singleInt32,def=-32" json:"single_int32,omitempty"` - SingleInt64 *int64 `protobuf:"varint,2,opt,name=single_int64,json=singleInt64,def=-64" json:"single_int64,omitempty"` - SingleUint32 *uint32 `protobuf:"varint,3,opt,name=single_uint32,json=singleUint32,def=32" json:"single_uint32,omitempty"` - SingleUint64 *uint64 `protobuf:"varint,4,opt,name=single_uint64,json=singleUint64,def=64" json:"single_uint64,omitempty"` - SingleSint32 *int32 `protobuf:"zigzag32,5,opt,name=single_sint32,json=singleSint32" json:"single_sint32,omitempty"` - SingleSint64 *int64 `protobuf:"zigzag64,6,opt,name=single_sint64,json=singleSint64" json:"single_sint64,omitempty"` - SingleFixed32 *uint32 `protobuf:"fixed32,7,opt,name=single_fixed32,json=singleFixed32" json:"single_fixed32,omitempty"` - SingleFixed64 *uint64 `protobuf:"fixed64,8,opt,name=single_fixed64,json=singleFixed64" json:"single_fixed64,omitempty"` - SingleSfixed32 *int32 `protobuf:"fixed32,9,opt,name=single_sfixed32,json=singleSfixed32" json:"single_sfixed32,omitempty"` - SingleSfixed64 *int64 `protobuf:"fixed64,10,opt,name=single_sfixed64,json=singleSfixed64" json:"single_sfixed64,omitempty"` - SingleFloat *float32 `protobuf:"fixed32,11,opt,name=single_float,json=singleFloat,def=3" json:"single_float,omitempty"` - SingleDouble *float64 `protobuf:"fixed64,12,opt,name=single_double,json=singleDouble,def=6.4" json:"single_double,omitempty"` - SingleBool *bool `protobuf:"varint,13,opt,name=single_bool,json=singleBool,def=1" json:"single_bool,omitempty"` - SingleString *string `protobuf:"bytes,14,opt,name=single_string,json=singleString,def=empty" json:"single_string,omitempty"` - SingleBytes []byte `protobuf:"bytes,15,opt,name=single_bytes,json=singleBytes,def=none" json:"single_bytes,omitempty"` - StandaloneEnum *TestAllTypes_NestedEnum `protobuf:"varint,22,opt,name=standalone_enum,json=standaloneEnum,enum=google.expr.proto2.test.TestAllTypes_NestedEnum" json:"standalone_enum,omitempty"` - SingleAny *any.Any `protobuf:"bytes,100,opt,name=single_any,json=singleAny" json:"single_any,omitempty"` - SingleDuration *duration.Duration `protobuf:"bytes,101,opt,name=single_duration,json=singleDuration" json:"single_duration,omitempty"` - SingleTimestamp *timestamp.Timestamp `protobuf:"bytes,102,opt,name=single_timestamp,json=singleTimestamp" json:"single_timestamp,omitempty"` - SingleStruct *_struct.Struct `protobuf:"bytes,103,opt,name=single_struct,json=singleStruct" json:"single_struct,omitempty"` - SingleValue *_struct.Value `protobuf:"bytes,104,opt,name=single_value,json=singleValue" json:"single_value,omitempty"` - SingleInt64Wrapper *wrappers.Int64Value `protobuf:"bytes,105,opt,name=single_int64_wrapper,json=singleInt64Wrapper" json:"single_int64_wrapper,omitempty"` - SingleInt32Wrapper *wrappers.Int32Value `protobuf:"bytes,106,opt,name=single_int32_wrapper,json=singleInt32Wrapper" json:"single_int32_wrapper,omitempty"` - SingleDoubleWrapper *wrappers.DoubleValue `protobuf:"bytes,107,opt,name=single_double_wrapper,json=singleDoubleWrapper" json:"single_double_wrapper,omitempty"` - SingleFloatWrapper *wrappers.FloatValue `protobuf:"bytes,108,opt,name=single_float_wrapper,json=singleFloatWrapper" json:"single_float_wrapper,omitempty"` - SingleUint64Wrapper *wrappers.UInt64Value `protobuf:"bytes,109,opt,name=single_uint64_wrapper,json=singleUint64Wrapper" json:"single_uint64_wrapper,omitempty"` - SingleUint32Wrapper *wrappers.UInt32Value `protobuf:"bytes,110,opt,name=single_uint32_wrapper,json=singleUint32Wrapper" json:"single_uint32_wrapper,omitempty"` - SingleStringWrapper *wrappers.StringValue `protobuf:"bytes,111,opt,name=single_string_wrapper,json=singleStringWrapper" json:"single_string_wrapper,omitempty"` - SingleBoolWrapper *wrappers.BoolValue `protobuf:"bytes,112,opt,name=single_bool_wrapper,json=singleBoolWrapper" json:"single_bool_wrapper,omitempty"` - SingleBytesWrapper *wrappers.BytesValue `protobuf:"bytes,113,opt,name=single_bytes_wrapper,json=singleBytesWrapper" json:"single_bytes_wrapper,omitempty"` + SingleInt32 *int32 `protobuf:"varint,1,opt,name=single_int32,json=singleInt32,def=-32" json:"single_int32,omitempty"` + SingleInt64 *int64 `protobuf:"varint,2,opt,name=single_int64,json=singleInt64,def=-64" json:"single_int64,omitempty"` + SingleUint32 *uint32 `protobuf:"varint,3,opt,name=single_uint32,json=singleUint32,def=32" json:"single_uint32,omitempty"` + SingleUint64 *uint64 `protobuf:"varint,4,opt,name=single_uint64,json=singleUint64,def=64" json:"single_uint64,omitempty"` + SingleSint32 *int32 `protobuf:"zigzag32,5,opt,name=single_sint32,json=singleSint32" json:"single_sint32,omitempty"` + SingleSint64 *int64 `protobuf:"zigzag64,6,opt,name=single_sint64,json=singleSint64" json:"single_sint64,omitempty"` + SingleFixed32 *uint32 `protobuf:"fixed32,7,opt,name=single_fixed32,json=singleFixed32" json:"single_fixed32,omitempty"` + SingleFixed64 *uint64 `protobuf:"fixed64,8,opt,name=single_fixed64,json=singleFixed64" json:"single_fixed64,omitempty"` + SingleSfixed32 *int32 `protobuf:"fixed32,9,opt,name=single_sfixed32,json=singleSfixed32" json:"single_sfixed32,omitempty"` + SingleSfixed64 *int64 `protobuf:"fixed64,10,opt,name=single_sfixed64,json=singleSfixed64" json:"single_sfixed64,omitempty"` + SingleFloat *float32 `protobuf:"fixed32,11,opt,name=single_float,json=singleFloat,def=3" json:"single_float,omitempty"` + SingleDouble *float64 `protobuf:"fixed64,12,opt,name=single_double,json=singleDouble,def=6.4" json:"single_double,omitempty"` + SingleBool *bool `protobuf:"varint,13,opt,name=single_bool,json=singleBool,def=1" json:"single_bool,omitempty"` + SingleString *string `protobuf:"bytes,14,opt,name=single_string,json=singleString,def=empty" json:"single_string,omitempty"` + SingleBytes []byte `protobuf:"bytes,15,opt,name=single_bytes,json=singleBytes,def=none" json:"single_bytes,omitempty"` + StandaloneEnum *TestAllTypes_NestedEnum `protobuf:"varint,22,opt,name=standalone_enum,json=standaloneEnum,enum=google.expr.proto2.test.TestAllTypes_NestedEnum" json:"standalone_enum,omitempty"` + Nestedgroup *TestAllTypes_NestedGroup `protobuf:"group,23,opt,name=NestedGroup,json=nestedgroup" json:"nestedgroup,omitempty"` + SingleAny *any.Any `protobuf:"bytes,100,opt,name=single_any,json=singleAny" json:"single_any,omitempty"` + SingleDuration *duration.Duration `protobuf:"bytes,101,opt,name=single_duration,json=singleDuration" json:"single_duration,omitempty"` + SingleTimestamp *timestamp.Timestamp `protobuf:"bytes,102,opt,name=single_timestamp,json=singleTimestamp" json:"single_timestamp,omitempty"` + SingleStruct *_struct.Struct `protobuf:"bytes,103,opt,name=single_struct,json=singleStruct" json:"single_struct,omitempty"` + SingleValue *_struct.Value `protobuf:"bytes,104,opt,name=single_value,json=singleValue" json:"single_value,omitempty"` + SingleInt64Wrapper *wrappers.Int64Value `protobuf:"bytes,105,opt,name=single_int64_wrapper,json=singleInt64Wrapper" json:"single_int64_wrapper,omitempty"` + SingleInt32Wrapper *wrappers.Int32Value `protobuf:"bytes,106,opt,name=single_int32_wrapper,json=singleInt32Wrapper" json:"single_int32_wrapper,omitempty"` + SingleDoubleWrapper *wrappers.DoubleValue `protobuf:"bytes,107,opt,name=single_double_wrapper,json=singleDoubleWrapper" json:"single_double_wrapper,omitempty"` + SingleFloatWrapper *wrappers.FloatValue `protobuf:"bytes,108,opt,name=single_float_wrapper,json=singleFloatWrapper" json:"single_float_wrapper,omitempty"` + SingleUint64Wrapper *wrappers.UInt64Value `protobuf:"bytes,109,opt,name=single_uint64_wrapper,json=singleUint64Wrapper" json:"single_uint64_wrapper,omitempty"` + SingleUint32Wrapper *wrappers.UInt32Value `protobuf:"bytes,110,opt,name=single_uint32_wrapper,json=singleUint32Wrapper" json:"single_uint32_wrapper,omitempty"` + SingleStringWrapper *wrappers.StringValue `protobuf:"bytes,111,opt,name=single_string_wrapper,json=singleStringWrapper" json:"single_string_wrapper,omitempty"` + SingleBoolWrapper *wrappers.BoolValue `protobuf:"bytes,112,opt,name=single_bool_wrapper,json=singleBoolWrapper" json:"single_bool_wrapper,omitempty"` + SingleBytesWrapper *wrappers.BytesValue `protobuf:"bytes,113,opt,name=single_bytes_wrapper,json=singleBytesWrapper" json:"single_bytes_wrapper,omitempty"` // Types that are assignable to NestedType: // *TestAllTypes_SingleNestedMessage // *TestAllTypes_SingleNestedEnum @@ -373,6 +374,13 @@ return TestAllTypes_FOO } +func (x *TestAllTypes) GetNestedgroup() *TestAllTypes_NestedGroup { + if x != nil { + return x.Nestedgroup + } + return nil +} + func (x *TestAllTypes) GetSingleAny() *any.Any { if x != nil { return x.SingleAny @@ -764,6 +772,61 @@ return 0 } +type TestAllTypes_NestedGroup struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NestedId *int32 `protobuf:"varint,24,opt,name=nested_id,json=nestedId" json:"nested_id,omitempty"` + NestedName *string `protobuf:"bytes,25,opt,name=nested_name,json=nestedName" json:"nested_name,omitempty"` +} + +func (x *TestAllTypes_NestedGroup) Reset() { + *x = TestAllTypes_NestedGroup{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto2pb_test_all_types_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TestAllTypes_NestedGroup) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TestAllTypes_NestedGroup) ProtoMessage() {} + +func (x *TestAllTypes_NestedGroup) ProtoReflect() protoreflect.Message { + mi := &file_test_proto2pb_test_all_types_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TestAllTypes_NestedGroup.ProtoReflect.Descriptor instead. +func (*TestAllTypes_NestedGroup) Descriptor() ([]byte, []int) { + return file_test_proto2pb_test_all_types_proto_rawDescGZIP(), []int{0, 1} +} + +func (x *TestAllTypes_NestedGroup) GetNestedId() int32 { + if x != nil && x.NestedId != nil { + return *x.NestedId + } + return 0 +} + +func (x *TestAllTypes_NestedGroup) GetNestedName() string { + if x != nil && x.NestedName != nil { + return *x.NestedName + } + return "" +} + var File_test_proto2pb_test_all_types_proto protoreflect.FileDescriptor var file_test_proto2pb_test_all_types_proto_rawDesc = []byte{ @@ -780,7 +843,7 @@ 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8d, 0x1b, 0x0a, 0x0c, 0x54, 0x65, 0x73, 0x74, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xaf, 0x1c, 0x0a, 0x0c, 0x54, 0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0c, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x3a, 0x03, 0x2d, 0x33, 0x32, 0x52, 0x0b, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x49, 0x6e, 0x74, 0x33, 0x32, @@ -824,192 +887,202 @@ 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x0e, 0x73, 0x74, 0x61, - 0x6e, 0x64, 0x61, 0x6c, 0x6f, 0x6e, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x33, 0x0a, 0x0a, 0x73, - 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x61, 0x6e, 0x79, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x09, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x41, 0x6e, 0x79, - 0x12, 0x42, 0x0a, 0x0f, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x44, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x10, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x66, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x6e, 0x64, 0x61, 0x6c, 0x6f, 0x6e, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x53, 0x0a, 0x0b, 0x6e, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0a, + 0x32, 0x31, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x41, + 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x52, 0x0b, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x12, 0x33, 0x0a, 0x0a, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x61, 0x6e, 0x79, 0x18, 0x64, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x09, 0x73, 0x69, 0x6e, 0x67, + 0x6c, 0x65, 0x41, 0x6e, 0x79, 0x12, 0x42, 0x0a, 0x0f, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, + 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0f, 0x73, 0x69, 0x6e, 0x67, - 0x6c, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3c, 0x0a, 0x0d, 0x73, - 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x18, 0x67, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0c, 0x73, 0x69, 0x6e, - 0x67, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, 0x39, 0x0a, 0x0c, 0x73, 0x69, 0x6e, - 0x67, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x68, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4d, 0x0a, 0x14, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x69, - 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x18, 0x69, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, - 0x12, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x57, 0x72, 0x61, 0x70, - 0x70, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x14, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x69, 0x6e, - 0x74, 0x33, 0x32, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x18, 0x6a, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, - 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x57, 0x72, 0x61, 0x70, 0x70, - 0x65, 0x72, 0x12, 0x50, 0x0a, 0x15, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x64, 0x6f, 0x75, - 0x62, 0x6c, 0x65, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x18, 0x6b, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, - 0x13, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x57, 0x72, 0x61, - 0x70, 0x70, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x14, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x66, - 0x6c, 0x6f, 0x61, 0x74, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x18, 0x6c, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, - 0x12, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x57, 0x72, 0x61, 0x70, - 0x70, 0x65, 0x72, 0x12, 0x50, 0x0a, 0x15, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x75, 0x69, - 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x18, 0x6d, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x13, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x55, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x57, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x50, 0x0a, 0x15, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, - 0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x18, 0x6e, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x13, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x55, 0x69, 0x6e, 0x74, 0x33, 0x32, + 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x73, 0x69, 0x6e, 0x67, 0x6c, + 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x10, 0x73, 0x69, 0x6e, + 0x67, 0x6c, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x66, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x0f, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x12, 0x3c, 0x0a, 0x0d, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x18, 0x67, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x52, 0x0c, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, 0x39, + 0x0a, 0x0c, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x68, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x73, 0x69, + 0x6e, 0x67, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4d, 0x0a, 0x14, 0x73, 0x69, 0x6e, + 0x67, 0x6c, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, + 0x72, 0x18, 0x69, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x49, 0x6e, 0x74, 0x36, + 0x34, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x14, 0x73, 0x69, 0x6e, 0x67, + 0x6c, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, + 0x18, 0x6a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x12, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x50, 0x0a, 0x15, 0x73, 0x69, 0x6e, 0x67, 0x6c, - 0x65, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x18, 0x6f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x4a, 0x0a, 0x13, 0x73, 0x69, 0x6e, - 0x67, 0x6c, 0x65, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x18, 0x70, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x11, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x6f, 0x6f, 0x6c, 0x57, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x14, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x18, 0x71, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x12, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x57, 0x72, 0x61, - 0x70, 0x70, 0x65, 0x72, 0x12, 0x69, 0x0a, 0x15, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x6e, - 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x12, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, - 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65, - 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, - 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x13, 0x73, 0x69, 0x6e, 0x67, - 0x6c, 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, - 0x65, 0x0a, 0x12, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, - 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x30, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, - 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x45, 0x6e, 0x75, 0x6d, 0x3a, 0x03, 0x42, - 0x41, 0x52, 0x48, 0x00, 0x52, 0x10, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x4e, 0x65, 0x73, 0x74, - 0x65, 0x64, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x1f, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0d, - 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x12, 0x25, 0x0a, - 0x0e, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, - 0x20, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0d, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x49, - 0x6e, 0x74, 0x36, 0x34, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x5f, 0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x21, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0e, 0x72, - 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x55, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x12, 0x27, 0x0a, - 0x0f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, - 0x18, 0x22, 0x20, 0x03, 0x28, 0x04, 0x52, 0x0e, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x55, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x5f, 0x73, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x23, 0x20, 0x03, 0x28, 0x11, 0x52, - 0x0e, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x12, - 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x69, 0x6e, 0x74, - 0x36, 0x34, 0x18, 0x24, 0x20, 0x03, 0x28, 0x12, 0x52, 0x0e, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x53, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x70, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x18, 0x25, 0x20, 0x03, - 0x28, 0x07, 0x52, 0x0f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x78, 0x65, - 0x64, 0x33, 0x32, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, - 0x66, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x18, 0x26, 0x20, 0x03, 0x28, 0x06, 0x52, 0x0f, 0x72, - 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x12, 0x2b, - 0x0a, 0x11, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x66, 0x69, 0x78, 0x65, - 0x64, 0x33, 0x32, 0x18, 0x27, 0x20, 0x03, 0x28, 0x0f, 0x52, 0x10, 0x72, 0x65, 0x70, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x53, 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x12, 0x2b, 0x0a, 0x11, 0x72, - 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x66, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, - 0x18, 0x28, 0x20, 0x03, 0x28, 0x10, 0x52, 0x10, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x53, 0x66, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x70, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18, 0x29, 0x20, 0x03, 0x28, 0x02, - 0x52, 0x0d, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x12, - 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x75, 0x62, - 0x6c, 0x65, 0x18, 0x2a, 0x20, 0x03, 0x28, 0x01, 0x52, 0x0e, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x70, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x18, 0x2b, 0x20, 0x03, 0x28, 0x08, 0x52, - 0x0c, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x6f, 0x6f, 0x6c, 0x12, 0x27, 0x0a, - 0x0f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x18, 0x2c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x2d, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0d, - 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x6b, 0x0a, - 0x17, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, - 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x30, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x32, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, - 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x52, 0x15, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4e, 0x65, 0x73, - 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x62, 0x0a, 0x14, 0x72, 0x65, - 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x6e, - 0x75, 0x6d, 0x18, 0x33, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, + 0x18, 0x6b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x44, 0x6f, 0x75, 0x62, + 0x6c, 0x65, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x14, 0x73, 0x69, 0x6e, + 0x67, 0x6c, 0x65, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, + 0x72, 0x18, 0x6c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x46, 0x6c, 0x6f, 0x61, + 0x74, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x50, 0x0a, 0x15, 0x73, 0x69, 0x6e, 0x67, + 0x6c, 0x65, 0x5f, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, + 0x72, 0x18, 0x6d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x55, 0x69, 0x6e, + 0x74, 0x36, 0x34, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x50, 0x0a, 0x15, 0x73, 0x69, + 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x77, 0x72, 0x61, 0x70, + 0x70, 0x65, 0x72, 0x18, 0x6e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, + 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x55, + 0x69, 0x6e, 0x74, 0x33, 0x32, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x50, 0x0a, 0x15, + 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x77, 0x72, + 0x61, 0x70, 0x70, 0x65, 0x72, 0x18, 0x6f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x73, 0x69, 0x6e, 0x67, 0x6c, + 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x4a, + 0x0a, 0x13, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x77, 0x72, + 0x61, 0x70, 0x70, 0x65, 0x72, 0x18, 0x70, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, + 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x11, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, + 0x6f, 0x6f, 0x6c, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x14, 0x73, 0x69, + 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, + 0x65, 0x72, 0x18, 0x71, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x69, 0x0a, 0x15, 0x73, 0x69, 0x6e, + 0x67, 0x6c, 0x65, 0x5f, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x12, 0x72, 0x65, 0x70, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x36, - 0x0a, 0x15, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x5f, 0x70, 0x69, 0x65, 0x63, 0x65, 0x18, 0x36, 0x20, 0x03, 0x28, 0x09, 0x42, 0x02, 0x08, - 0x02, 0x52, 0x13, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x50, 0x69, 0x65, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0d, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x72, 0x64, 0x18, 0x37, 0x20, 0x03, 0x28, 0x09, 0x42, 0x02, 0x08, - 0x01, 0x52, 0x0c, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x72, 0x64, 0x12, - 0x6b, 0x0a, 0x15, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6c, 0x61, 0x7a, 0x79, - 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x39, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x32, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, - 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x42, 0x02, 0x28, 0x01, 0x52, 0x13, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, - 0x64, 0x4c, 0x61, 0x7a, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x66, 0x0a, 0x11, - 0x6d, 0x61, 0x70, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x18, 0x3a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x2e, 0x74, 0x65, 0x73, - 0x74, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, - 0x61, 0x70, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x0f, 0x6d, 0x61, 0x70, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x12, 0x70, 0x0a, 0x15, 0x6d, 0x61, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x36, - 0x34, 0x5f, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x3b, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, + 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, + 0x13, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x65, 0x0a, 0x12, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x6e, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x41, + 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x45, 0x6e, + 0x75, 0x6d, 0x3a, 0x03, 0x42, 0x41, 0x52, 0x48, 0x00, 0x52, 0x10, 0x73, 0x69, 0x6e, 0x67, 0x6c, + 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x25, 0x0a, 0x0e, 0x72, + 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x1f, 0x20, + 0x03, 0x28, 0x05, 0x52, 0x0d, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x49, 0x6e, 0x74, + 0x33, 0x32, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x69, + 0x6e, 0x74, 0x36, 0x34, 0x18, 0x20, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0d, 0x72, 0x65, 0x70, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x70, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x21, 0x20, 0x03, + 0x28, 0x0d, 0x52, 0x0e, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x55, 0x69, 0x6e, 0x74, + 0x33, 0x32, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x75, + 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x22, 0x20, 0x03, 0x28, 0x04, 0x52, 0x0e, 0x72, 0x65, 0x70, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x55, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x27, 0x0a, 0x0f, 0x72, + 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x23, + 0x20, 0x03, 0x28, 0x11, 0x52, 0x0e, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, + 0x6e, 0x74, 0x33, 0x32, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x73, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x24, 0x20, 0x03, 0x28, 0x12, 0x52, 0x0e, 0x72, + 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x29, 0x0a, + 0x10, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, + 0x32, 0x18, 0x25, 0x20, 0x03, 0x28, 0x07, 0x52, 0x0f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x46, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x70, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x18, 0x26, 0x20, 0x03, + 0x28, 0x06, 0x52, 0x0f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x78, 0x65, + 0x64, 0x36, 0x34, 0x12, 0x2b, 0x0a, 0x11, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, + 0x73, 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x18, 0x27, 0x20, 0x03, 0x28, 0x0f, 0x52, 0x10, + 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, + 0x12, 0x2b, 0x0a, 0x11, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x66, 0x69, + 0x78, 0x65, 0x64, 0x36, 0x34, 0x18, 0x28, 0x20, 0x03, 0x28, 0x10, 0x52, 0x10, 0x72, 0x65, 0x70, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x66, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x12, 0x25, 0x0a, + 0x0e, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18, + 0x29, 0x20, 0x03, 0x28, 0x02, 0x52, 0x0d, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x46, + 0x6c, 0x6f, 0x61, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x18, 0x2a, 0x20, 0x03, 0x28, 0x01, 0x52, 0x0e, 0x72, + 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x12, 0x23, 0x0a, + 0x0d, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x18, 0x2b, + 0x20, 0x03, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x6f, + 0x6f, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x2c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x70, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x72, + 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x2d, 0x20, + 0x03, 0x28, 0x0c, 0x52, 0x0d, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x12, 0x6b, 0x0a, 0x17, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6e, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x30, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65, - 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x61, 0x70, 0x49, 0x6e, - 0x74, 0x36, 0x34, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x12, 0x6d, 0x61, 0x70, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x4e, 0x65, 0x73, 0x74, - 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x1f, 0x0a, 0x0d, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x62, 0x62, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x02, 0x62, 0x62, 0x1a, 0x42, 0x0a, 0x14, 0x4d, 0x61, 0x70, 0x53, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x72, 0x0a, 0x17, 0x4d, - 0x61, 0x70, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, - 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x41, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x2e, 0x74, 0x65, 0x73, - 0x74, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, - 0x79, 0x70, 0x65, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0x27, 0x0a, 0x0a, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x07, 0x0a, - 0x03, 0x46, 0x4f, 0x4f, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x42, 0x41, 0x52, 0x10, 0x01, 0x12, - 0x07, 0x0a, 0x03, 0x42, 0x41, 0x5a, 0x10, 0x02, 0x42, 0x0d, 0x0a, 0x0b, 0x6e, 0x65, 0x73, 0x74, - 0x65, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x12, 0x4e, 0x65, 0x73, 0x74, - 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x41, - 0x0a, 0x05, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, + 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, + 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x15, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x62, 0x0a, 0x14, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6e, 0x65, 0x73, 0x74, + 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x33, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x32, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x65, - 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x05, 0x63, 0x68, 0x69, 0x6c, - 0x64, 0x12, 0x3f, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x72, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65, 0x73, - 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, - 0x61, 0x64, 0x2a, 0x27, 0x0a, 0x0a, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x45, 0x6e, 0x75, 0x6d, - 0x12, 0x07, 0x0a, 0x03, 0x47, 0x4f, 0x4f, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x41, 0x52, - 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x41, 0x5a, 0x10, 0x02, + 0x6f, 0x32, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x45, 0x6e, 0x75, 0x6d, 0x52, + 0x12, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x45, + 0x6e, 0x75, 0x6d, 0x12, 0x36, 0x0a, 0x15, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x69, 0x65, 0x63, 0x65, 0x18, 0x36, 0x20, 0x03, + 0x28, 0x09, 0x42, 0x02, 0x08, 0x02, 0x52, 0x13, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x69, 0x65, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0d, 0x72, + 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x72, 0x64, 0x18, 0x37, 0x20, 0x03, + 0x28, 0x09, 0x42, 0x02, 0x08, 0x01, 0x52, 0x0c, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x43, 0x6f, 0x72, 0x64, 0x12, 0x6b, 0x0a, 0x15, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x39, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65, + 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, + 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x02, 0x28, 0x01, 0x52, 0x13, 0x72, 0x65, + 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4c, 0x61, 0x7a, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x66, 0x0a, 0x11, 0x6d, 0x61, 0x70, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x3a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x32, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x61, 0x70, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x6d, 0x61, 0x70, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x70, 0x0a, 0x15, 0x6d, 0x61, 0x70, + 0x5f, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x3b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x4d, 0x61, 0x70, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x79, + 0x70, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x6d, 0x61, 0x70, 0x49, 0x6e, 0x74, 0x36, + 0x34, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x1f, 0x0a, 0x0d, 0x4e, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, + 0x62, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x62, 0x62, 0x1a, 0x4b, 0x0a, 0x0b, + 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x18, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, + 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x65, 0x73, 0x74, + 0x65, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x19, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6e, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x42, 0x0a, 0x14, 0x4d, 0x61, 0x70, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x72, 0x0a, + 0x17, 0x4d, 0x61, 0x70, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, + 0x79, 0x70, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x41, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x41, 0x6c, + 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0x27, 0x0a, 0x0a, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x45, 0x6e, 0x75, 0x6d, 0x12, + 0x07, 0x0a, 0x03, 0x46, 0x4f, 0x4f, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x42, 0x41, 0x52, 0x10, + 0x01, 0x12, 0x07, 0x0a, 0x03, 0x42, 0x41, 0x5a, 0x10, 0x02, 0x42, 0x0d, 0x0a, 0x0b, 0x6e, 0x65, + 0x73, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x12, 0x4e, 0x65, + 0x73, 0x74, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, + 0x12, 0x41, 0x0a, 0x05, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x32, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, + 0x54, 0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x05, 0x63, 0x68, + 0x69, 0x6c, 0x64, 0x12, 0x3f, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, + 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, + 0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x07, 0x70, 0x61, 0x79, + 0x6c, 0x6f, 0x61, 0x64, 0x2a, 0x27, 0x0a, 0x0a, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x45, 0x6e, + 0x75, 0x6d, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x4f, 0x4f, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x47, + 0x41, 0x52, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x41, 0x5a, 0x10, 0x02, } var ( @@ -1025,61 +1098,63 @@ } var file_test_proto2pb_test_all_types_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_test_proto2pb_test_all_types_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_test_proto2pb_test_all_types_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_test_proto2pb_test_all_types_proto_goTypes = []interface{}{ (GlobalEnum)(0), // 0: google.expr.proto2.test.GlobalEnum (TestAllTypes_NestedEnum)(0), // 1: google.expr.proto2.test.TestAllTypes.NestedEnum (*TestAllTypes)(nil), // 2: google.expr.proto2.test.TestAllTypes (*NestedTestAllTypes)(nil), // 3: google.expr.proto2.test.NestedTestAllTypes (*TestAllTypes_NestedMessage)(nil), // 4: google.expr.proto2.test.TestAllTypes.NestedMessage - nil, // 5: google.expr.proto2.test.TestAllTypes.MapStringStringEntry - nil, // 6: google.expr.proto2.test.TestAllTypes.MapInt64NestedTypeEntry - (*any.Any)(nil), // 7: google.protobuf.Any - (*duration.Duration)(nil), // 8: google.protobuf.Duration - (*timestamp.Timestamp)(nil), // 9: google.protobuf.Timestamp - (*_struct.Struct)(nil), // 10: google.protobuf.Struct - (*_struct.Value)(nil), // 11: google.protobuf.Value - (*wrappers.Int64Value)(nil), // 12: google.protobuf.Int64Value - (*wrappers.Int32Value)(nil), // 13: google.protobuf.Int32Value - (*wrappers.DoubleValue)(nil), // 14: google.protobuf.DoubleValue - (*wrappers.FloatValue)(nil), // 15: google.protobuf.FloatValue - (*wrappers.UInt64Value)(nil), // 16: google.protobuf.UInt64Value - (*wrappers.UInt32Value)(nil), // 17: google.protobuf.UInt32Value - (*wrappers.StringValue)(nil), // 18: google.protobuf.StringValue - (*wrappers.BoolValue)(nil), // 19: google.protobuf.BoolValue - (*wrappers.BytesValue)(nil), // 20: google.protobuf.BytesValue + (*TestAllTypes_NestedGroup)(nil), // 5: google.expr.proto2.test.TestAllTypes.NestedGroup + nil, // 6: google.expr.proto2.test.TestAllTypes.MapStringStringEntry + nil, // 7: google.expr.proto2.test.TestAllTypes.MapInt64NestedTypeEntry + (*any.Any)(nil), // 8: google.protobuf.Any + (*duration.Duration)(nil), // 9: google.protobuf.Duration + (*timestamp.Timestamp)(nil), // 10: google.protobuf.Timestamp + (*_struct.Struct)(nil), // 11: google.protobuf.Struct + (*_struct.Value)(nil), // 12: google.protobuf.Value + (*wrappers.Int64Value)(nil), // 13: google.protobuf.Int64Value + (*wrappers.Int32Value)(nil), // 14: google.protobuf.Int32Value + (*wrappers.DoubleValue)(nil), // 15: google.protobuf.DoubleValue + (*wrappers.FloatValue)(nil), // 16: google.protobuf.FloatValue + (*wrappers.UInt64Value)(nil), // 17: google.protobuf.UInt64Value + (*wrappers.UInt32Value)(nil), // 18: google.protobuf.UInt32Value + (*wrappers.StringValue)(nil), // 19: google.protobuf.StringValue + (*wrappers.BoolValue)(nil), // 20: google.protobuf.BoolValue + (*wrappers.BytesValue)(nil), // 21: google.protobuf.BytesValue } var file_test_proto2pb_test_all_types_proto_depIdxs = []int32{ 1, // 0: google.expr.proto2.test.TestAllTypes.standalone_enum:type_name -> google.expr.proto2.test.TestAllTypes.NestedEnum - 7, // 1: google.expr.proto2.test.TestAllTypes.single_any:type_name -> google.protobuf.Any - 8, // 2: google.expr.proto2.test.TestAllTypes.single_duration:type_name -> google.protobuf.Duration - 9, // 3: google.expr.proto2.test.TestAllTypes.single_timestamp:type_name -> google.protobuf.Timestamp - 10, // 4: google.expr.proto2.test.TestAllTypes.single_struct:type_name -> google.protobuf.Struct - 11, // 5: google.expr.proto2.test.TestAllTypes.single_value:type_name -> google.protobuf.Value - 12, // 6: google.expr.proto2.test.TestAllTypes.single_int64_wrapper:type_name -> google.protobuf.Int64Value - 13, // 7: google.expr.proto2.test.TestAllTypes.single_int32_wrapper:type_name -> google.protobuf.Int32Value - 14, // 8: google.expr.proto2.test.TestAllTypes.single_double_wrapper:type_name -> google.protobuf.DoubleValue - 15, // 9: google.expr.proto2.test.TestAllTypes.single_float_wrapper:type_name -> google.protobuf.FloatValue - 16, // 10: google.expr.proto2.test.TestAllTypes.single_uint64_wrapper:type_name -> google.protobuf.UInt64Value - 17, // 11: google.expr.proto2.test.TestAllTypes.single_uint32_wrapper:type_name -> google.protobuf.UInt32Value - 18, // 12: google.expr.proto2.test.TestAllTypes.single_string_wrapper:type_name -> google.protobuf.StringValue - 19, // 13: google.expr.proto2.test.TestAllTypes.single_bool_wrapper:type_name -> google.protobuf.BoolValue - 20, // 14: google.expr.proto2.test.TestAllTypes.single_bytes_wrapper:type_name -> google.protobuf.BytesValue - 4, // 15: google.expr.proto2.test.TestAllTypes.single_nested_message:type_name -> google.expr.proto2.test.TestAllTypes.NestedMessage - 1, // 16: google.expr.proto2.test.TestAllTypes.single_nested_enum:type_name -> google.expr.proto2.test.TestAllTypes.NestedEnum - 4, // 17: google.expr.proto2.test.TestAllTypes.repeated_nested_message:type_name -> google.expr.proto2.test.TestAllTypes.NestedMessage - 1, // 18: google.expr.proto2.test.TestAllTypes.repeated_nested_enum:type_name -> google.expr.proto2.test.TestAllTypes.NestedEnum - 4, // 19: google.expr.proto2.test.TestAllTypes.repeated_lazy_message:type_name -> google.expr.proto2.test.TestAllTypes.NestedMessage - 5, // 20: google.expr.proto2.test.TestAllTypes.map_string_string:type_name -> google.expr.proto2.test.TestAllTypes.MapStringStringEntry - 6, // 21: google.expr.proto2.test.TestAllTypes.map_int64_nested_type:type_name -> google.expr.proto2.test.TestAllTypes.MapInt64NestedTypeEntry - 3, // 22: google.expr.proto2.test.NestedTestAllTypes.child:type_name -> google.expr.proto2.test.NestedTestAllTypes - 2, // 23: google.expr.proto2.test.NestedTestAllTypes.payload:type_name -> google.expr.proto2.test.TestAllTypes - 3, // 24: google.expr.proto2.test.TestAllTypes.MapInt64NestedTypeEntry.value:type_name -> google.expr.proto2.test.NestedTestAllTypes - 25, // [25:25] is the sub-list for method output_type - 25, // [25:25] is the sub-list for method input_type - 25, // [25:25] is the sub-list for extension type_name - 25, // [25:25] is the sub-list for extension extendee - 0, // [0:25] is the sub-list for field type_name + 5, // 1: google.expr.proto2.test.TestAllTypes.nestedgroup:type_name -> google.expr.proto2.test.TestAllTypes.NestedGroup + 8, // 2: google.expr.proto2.test.TestAllTypes.single_any:type_name -> google.protobuf.Any + 9, // 3: google.expr.proto2.test.TestAllTypes.single_duration:type_name -> google.protobuf.Duration + 10, // 4: google.expr.proto2.test.TestAllTypes.single_timestamp:type_name -> google.protobuf.Timestamp + 11, // 5: google.expr.proto2.test.TestAllTypes.single_struct:type_name -> google.protobuf.Struct + 12, // 6: google.expr.proto2.test.TestAllTypes.single_value:type_name -> google.protobuf.Value + 13, // 7: google.expr.proto2.test.TestAllTypes.single_int64_wrapper:type_name -> google.protobuf.Int64Value + 14, // 8: google.expr.proto2.test.TestAllTypes.single_int32_wrapper:type_name -> google.protobuf.Int32Value + 15, // 9: google.expr.proto2.test.TestAllTypes.single_double_wrapper:type_name -> google.protobuf.DoubleValue + 16, // 10: google.expr.proto2.test.TestAllTypes.single_float_wrapper:type_name -> google.protobuf.FloatValue + 17, // 11: google.expr.proto2.test.TestAllTypes.single_uint64_wrapper:type_name -> google.protobuf.UInt64Value + 18, // 12: google.expr.proto2.test.TestAllTypes.single_uint32_wrapper:type_name -> google.protobuf.UInt32Value + 19, // 13: google.expr.proto2.test.TestAllTypes.single_string_wrapper:type_name -> google.protobuf.StringValue + 20, // 14: google.expr.proto2.test.TestAllTypes.single_bool_wrapper:type_name -> google.protobuf.BoolValue + 21, // 15: google.expr.proto2.test.TestAllTypes.single_bytes_wrapper:type_name -> google.protobuf.BytesValue + 4, // 16: google.expr.proto2.test.TestAllTypes.single_nested_message:type_name -> google.expr.proto2.test.TestAllTypes.NestedMessage + 1, // 17: google.expr.proto2.test.TestAllTypes.single_nested_enum:type_name -> google.expr.proto2.test.TestAllTypes.NestedEnum + 4, // 18: google.expr.proto2.test.TestAllTypes.repeated_nested_message:type_name -> google.expr.proto2.test.TestAllTypes.NestedMessage + 1, // 19: google.expr.proto2.test.TestAllTypes.repeated_nested_enum:type_name -> google.expr.proto2.test.TestAllTypes.NestedEnum + 4, // 20: google.expr.proto2.test.TestAllTypes.repeated_lazy_message:type_name -> google.expr.proto2.test.TestAllTypes.NestedMessage + 6, // 21: google.expr.proto2.test.TestAllTypes.map_string_string:type_name -> google.expr.proto2.test.TestAllTypes.MapStringStringEntry + 7, // 22: google.expr.proto2.test.TestAllTypes.map_int64_nested_type:type_name -> google.expr.proto2.test.TestAllTypes.MapInt64NestedTypeEntry + 3, // 23: google.expr.proto2.test.NestedTestAllTypes.child:type_name -> google.expr.proto2.test.NestedTestAllTypes + 2, // 24: google.expr.proto2.test.NestedTestAllTypes.payload:type_name -> google.expr.proto2.test.TestAllTypes + 3, // 25: google.expr.proto2.test.TestAllTypes.MapInt64NestedTypeEntry.value:type_name -> google.expr.proto2.test.NestedTestAllTypes + 26, // [26:26] is the sub-list for method output_type + 26, // [26:26] is the sub-list for method input_type + 26, // [26:26] is the sub-list for extension type_name + 26, // [26:26] is the sub-list for extension extendee + 0, // [0:26] is the sub-list for field type_name } func init() { file_test_proto2pb_test_all_types_proto_init() } @@ -1124,6 +1199,18 @@ return nil } } + file_test_proto2pb_test_all_types_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TestAllTypes_NestedGroup); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_test_proto2pb_test_all_types_proto_msgTypes[0].OneofWrappers = []interface{}{ (*TestAllTypes_SingleNestedMessage)(nil), @@ -1135,7 +1222,7 @@ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_test_proto2pb_test_all_types_proto_rawDesc, NumEnums: 2, - NumMessages: 5, + NumMessages: 6, NumExtensions: 0, NumServices: 0, }, diff -Nru golang-github-google-cel-go-0.11.4+ds/test/proto2pb/test_all_types.proto golang-github-google-cel-go-0.12.5+ds/test/proto2pb/test_all_types.proto --- golang-github-google-cel-go-0.11.4+ds/test/proto2pb/test_all_types.proto 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/test/proto2pb/test_all_types.proto 2022-12-20 15:30:36.000000000 +0000 @@ -43,6 +43,10 @@ optional string single_string = 14 [default = "empty"]; optional bytes single_bytes = 15 [default = "none"]; optional NestedEnum standalone_enum = 22; + optional group NestedGroup = 23 { + optional int32 nested_id = 24; + optional string nested_name = 25; + } // Wellknown. optional google.protobuf.Any single_any = 100; diff -Nru golang-github-google-cel-go-0.11.4+ds/WORKSPACE golang-github-google-cel-go-0.12.5+ds/WORKSPACE --- golang-github-google-cel-go-0.11.4+ds/WORKSPACE 2022-05-13 17:33:50.000000000 +0000 +++ golang-github-google-cel-go-0.12.5+ds/WORKSPACE 2022-12-20 15:30:36.000000000 +0000 @@ -122,6 +122,13 @@ version = "v1.2.0", ) +# Readline for repl +go_repository( + name = "com_github_chzyer_readline", + importpath = "github.com/chzyer/readline", + commit = "62c6fe6193755f722b8b8788aa7357be55a50ff1" # v1.4 +) + # Run the dependencies at the end. These will silently try to import some # of the above repositories but at different versions, so ours must come first. go_rules_dependencies()