diff --git a/docs/cel_expressions.md b/docs/cel_expressions.md index 70a524657..9327d5f2d 100644 --- a/docs/cel_expressions.md +++ b/docs/cel_expressions.md @@ -96,9 +96,35 @@ because there's no automatic conversion. ## cel-go extensions -All the functionality from the cel-go project's [String extension](https://github.com/google/cel-go/tree/master/ext) is available in +All the functionality from the cel-go project's [CEL extension](https://github.com/google/cel-go/tree/master/ext) is available in your CEL expressions. +### cel-go Bytes + +The cel-go project function `base64.decode` returns a [CEL `Bytes`](https://github.com/google/cel-spec/blob/master/doc/langdef.md#string-and-bytes-values) value. + +To compare this to a string, you will need to convert it to a Bytes type: + +``` +base64.decode(body.b64value) == b'hello' # compare to Bytes literal +base64.decode(body.b64value) == bytes('hello') # convert to bytes. +``` + +### Returning Bytes + +Confusingly, if you decode a base64 string with the cel-go base64 decoder, it will +appear in the extension as a base64 encoded string, you will need to explicitly +convert it to a CEL string. + +```yaml +interceptors: + - cel: + overlays: + - key: base64_decoded + expression: "string(base64.decode(body.b64Value))" +``` +This will correctly appear in the extension as the decoded version. + ## List of extensions The body from the `http.Request` value is decoded to JSON and exposed, and the @@ -235,7 +261,7 @@ interceptor.
<string>.decodeb64() -> stringdiff --git a/go.mod b/go.mod index a2d603b99..ec713dce0 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/GoogleCloudPlatform/cloud-builders/gcs-fetcher v0.0.0-20191203181535-308b93ad1f39 github.com/gobuffalo/envy v1.9.0 // indirect github.com/golang/protobuf v1.4.3 - github.com/google/cel-go v0.6.0 + github.com/google/cel-go v0.7.3 github.com/google/go-cmp v0.5.4 github.com/google/go-github/v31 v31.0.0 github.com/google/uuid v1.2.0 diff --git a/go.sum b/go.sum index 4230fe728..f1af9e6aa 100644 --- a/go.sum +++ b/go.sum @@ -373,9 +373,9 @@ github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9/go.mod h1:0EXg4mc1CNP github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b/go.mod h1:Z4GIJBJO3Wa4gD4vbwQxXXZ+WHmW6E9ixmNrwvs0iZs= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/cel-go v0.6.0 h1:Li+angxmgvzlwDsPuFc1/nbqnq3gc4K/X7NrWjOADFI= -github.com/google/cel-go v0.6.0/go.mod h1:rHS68o5G1QcUv/ubiCoZ5nT5LHxRWWfS0qMzTgv42WQ= -github.com/google/cel-spec v0.4.0/go.mod h1:2pBM5cU4UKjbPDXBgwWkiwBsVgnxknuEJ7C5TDWwORQ= +github.com/google/cel-go v0.7.3 h1:8v9BSN0avuGwrHFKNCjfiQ/CE6+D6sW+BDyOVoEeP6o= +github.com/google/cel-go v0.7.3/go.mod h1:4EtyFAHT5xNr0Msu0MJjyGxPUgdr9DlcaPyzLt/kkt8= +github.com/google/cel-spec v0.5.0/go.mod h1:Nwjgxy5CbjlPrtCWjeDjUyKMl8w41YBYGjsyDdqk0xA= 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= @@ -748,6 +748,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= +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/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -764,7 +765,6 @@ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tektoncd/pipeline v0.20.1-0.20210203144343-1b7a37f0d21d h1:JIWiB3J5auMzmFrv/VUzLt88KmYZsrBMwSHOpHJpuEc= github.com/tektoncd/pipeline v0.20.1-0.20210203144343-1b7a37f0d21d/go.mod h1:GwdfGGt/5VhZL8JvJu8kFz8friKufcJ/TJkJmK6uc0U= -github.com/tektoncd/plumbing v0.0.0-20201021153918-6b7e894737b5 h1:Y2Gd3X79zqvCd6AdiWyi/pnSewSkLxKygpvXNFXwscg= github.com/tektoncd/plumbing v0.0.0-20201021153918-6b7e894737b5/go.mod h1:WTWwsg91xgm+jPOKoyKVK/yRYxnVDlUYeDlypB1lDdQ= github.com/tektoncd/plumbing v0.0.0-20210420200944-17170d5e7bc9 h1:ZLPo8/vilaxvpdvvdd9ZgIhhQJPkHyS5GeKK8UH4/Yo= github.com/tektoncd/plumbing v0.0.0-20210420200944-17170d5e7bc9/go.mod h1:WTWwsg91xgm+jPOKoyKVK/yRYxnVDlUYeDlypB1lDdQ= @@ -814,7 +814,6 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4-0.20200608061201-1901b56b9515/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= @@ -1186,7 +1185,6 @@ google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200416231807-8751e049a2a0/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -1201,6 +1199,7 @@ google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200827165113-ac2560b5e952/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201211151036-40ec1c210f7a h1:GnJAhasbD8HiT8DZMvsEx3QLVy/X0icq/MGr0MqRJ2M= diff --git a/pkg/interceptors/cel/cel.go b/pkg/interceptors/cel/cel.go index c7526f8c7..5f05a385c 100644 --- a/pkg/interceptors/cel/cel.go +++ b/pkg/interceptors/cel/cel.go @@ -96,6 +96,7 @@ func makeCelEnv(ns string, k kubernetes.Interface) (*cel.Env, error) { return cel.NewEnv( Triggers(ns, k), celext.Strings(), + celext.Encoders(), cel.Declarations( decls.NewVar("body", mapStrDyn), decls.NewVar("header", mapStrDyn), @@ -165,15 +166,21 @@ func (w *Interceptor) Process(ctx context.Context, r *triggersv1.InterceptorRequ var b []byte switch val.(type) { - case types.String: + // this causes types.Bytes to be rendered as a Base64 string this is + // because the Go JSON Encoder encodes []bytes this way, see + // https://golang.org/pkg/encoding/json/#Marshal + // + // An alternative might be to return " + val + " for types.Bytes to + // simulate the the JSON encoding. + case types.String, types.Bytes: raw, err = val.ConvertToNative(structType) if err == nil { - b, err = json.Marshal(raw.(*structpb.Value).GetStringValue()) + b, err = raw.(*structpb.Value).MarshalJSON() } case types.Double, types.Int: raw, err = val.ConvertToNative(structType) if err == nil { - b, err = json.Marshal(raw.(*structpb.Value).GetNumberValue()) + b, err = raw.(*structpb.Value).MarshalJSON() } case traits.Lister: raw, err = val.ConvertToNative(listType) @@ -212,7 +219,6 @@ func (w *Interceptor) Process(ctx context.Context, r *triggersv1.InterceptorRequ extensions = []byte("{}") } extensions, err = sjson.SetRawBytes(extensions, u.Key, b) - if err != nil { return interceptors.Failf(codes.Internal, "failed to sjson for key '%s' to '%s': %v", u.Key, val, err) } @@ -228,7 +234,6 @@ func (w *Interceptor) Process(ctx context.Context, r *triggersv1.InterceptorRequ if err := json.Unmarshal(extensions, &extensionsMap); err != nil { return interceptors.Failf(codes.Internal, "failed to unmarshal extensions into map: %v", err) } - return &triggersv1.InterceptorResponse{ Continue: true, Extensions: extensionsMap, diff --git a/pkg/interceptors/cel/cel_test.go b/pkg/interceptors/cel/cel_test.go index bd5351250..4cfdeb3bb 100644 --- a/pkg/interceptors/cel/cel_test.go +++ b/pkg/interceptors/cel/cel_test.go @@ -156,7 +156,7 @@ func TestInterceptor_Process(t *testing.T) { }, }, body: json.RawMessage(`{"value":"test"}`), - // TODO: Fix extensions iff key contains ., use sjson to m erge + // TODO: Fix extensions if key contains ., use sjson to merge wantExtensions: map[string]interface{}{ "test": map[string]interface{}{ "two": "test", @@ -259,8 +259,23 @@ func TestInterceptor_Process(t *testing.T) { wantExtensions: map[string]interface{}{ "one": "bar", }, - }, - } + }, { + name: "decode with cel extension to a field", + CEL: &triggersv1.CELInterceptor{ + Overlays: []triggersv1.CELOverlay{ + {Key: "value", Expression: "base64.decode(body.b64value) == b'hello'"}, + {Key: "compare_string", Expression: "base64.decode(body.b64value) == bytes('hello')"}, + {Key: "decoded", Expression: "base64.decode(body.b64value)"}, + {Key: "decoded_string", Expression: "string(base64.decode(body.b64value))"}, + }, + }, + body: json.RawMessage(`{"b64value":"aGVsbG8=","test":"hello"}`), + wantExtensions: map[string]interface{}{ + "value": true, + "compare_string": true, + "decoded": "aGVsbG8=", + "decoded_string": "hello"}, + }} for _, tt := range tests { t.Run(tt.name, func(rt *testing.T) { logger := zaptest.NewLogger(t) @@ -432,7 +447,10 @@ func TestInterceptor_Process_InvalidParams(t *testing.T) { } func TestExpressionEvaluation(t *testing.T) { - reg := types.NewRegistry() + reg, err := types.NewRegistry() + if err != nil { + t.Fatal(err) + } testSHA := "ec26c3e57ca3a959ca5aad62de7213c562f8c821" testRef := "refs/heads/master" jsonMap := map[string]interface{}{ @@ -496,12 +514,12 @@ func TestExpressionEvaluation(t *testing.T) { { name: "split a string on a character", expr: "body.ref.split('/')", - want: types.NewStringList(types.NewRegistry(), refParts), + want: types.NewStringList(reg, refParts), }, { name: "extract a branch from a non refs string", expr: "body.value.split('/')", - want: types.NewStringList(types.NewRegistry(), []string{"testing"}), + want: types.NewStringList(reg, []string{"testing"}), }, { name: "combine split and truncate", @@ -591,13 +609,25 @@ func TestExpressionEvaluation(t *testing.T) { expr: "body.jsonArray.marshalJSON()", want: types.String(`["one","two"]`), }, + { + name: "extension base64 decoding", + expr: "base64.decode(body.b64value)", + want: types.Bytes("example"), + }, + { + name: "extension base64 encoding", + expr: "base64.encode(b'example')", + want: types.String("ZXhhbXBsZQ=="), + }, } for _, tt := range tests { t.Run(tt.name, func(rt *testing.T) { ctx, _ := rtesting.SetupFakeContext(rt) kubeClient := fakekubeclient.Get(ctx) if tt.secret != nil { - if _, err := kubeClient.CoreV1().Secrets(tt.secret.ObjectMeta.Namespace).Create(ctx, tt.secret, metav1.CreateOptions{}); err != nil { + if _, err := kubeClient.CoreV1(). + Secrets(tt.secret.ObjectMeta.Namespace). + Create(ctx, tt.secret, metav1.CreateOptions{}); err != nil { rt.Error(err) } } @@ -615,7 +645,11 @@ func TestExpressionEvaluation(t *testing.T) { rt.Errorf("error evaluating expression: %s", got) return } - if !got.Equal(tt.want).(types.Bool) { + v, ok := got.Equal(tt.want).(types.Bool) + if !ok { + rt.Errorf("failed to compare got %v, want %v", got, tt.want) + } + if ok && v != types.True { rt.Errorf("evaluate() = %s, wantMsg %s", got, tt.want) } }) diff --git a/pkg/interceptors/cel/triggers.go b/pkg/interceptors/cel/triggers.go index ae89c1737..623e7993b 100644 --- a/pkg/interceptors/cel/triggers.go +++ b/pkg/interceptors/cel/triggers.go @@ -344,7 +344,11 @@ func parseJSONString(val ref.Val) ref.Val { if err != nil { return types.NewErr("failed to decode '%v' in parseJSON: %w", str, err) } - return types.NewDynamicMap(types.NewRegistry(), decodedVal) + r, err := types.NewRegistry() + if err != nil { + return types.NewErr("failed to create a new registry in parseJSON: %w", err) + } + return types.NewDynamicMap(r, decodedVal) } func parseYAMLString(val ref.Val) ref.Val { @@ -357,7 +361,11 @@ func parseYAMLString(val ref.Val) ref.Val { if err != nil { return types.NewErr("failed to decode '%v' in parseYAML: %w", str, err) } - return types.NewDynamicMap(types.NewRegistry(), decodedVal) + r, err := types.NewRegistry() + if err != nil { + return types.NewErr("failed to create a new registry in parseJSON: %w", err) + } + return types.NewDynamicMap(r, decodedVal) } func parseURLString(val ref.Val) ref.Val { @@ -370,8 +378,11 @@ func parseURLString(val ref.Val) ref.Val { if err != nil { return types.NewErr("failed to decode '%v' in parseURL: %w", str, err) } - - return types.NewDynamicMap(types.NewRegistry(), urlToMap(parsed)) + r, err := types.NewRegistry() + if err != nil { + return types.NewErr("failed to create a new registry in parseJSON: %w", err) + } + return types.NewDynamicMap(r, urlToMap(parsed)) } func marshalJSON(val ref.Val) ref.Val { diff --git a/vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go b/vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go deleted file mode 100644 index 16686a655..000000000 --- a/vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go +++ /dev/null @@ -1,62 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: github.com/golang/protobuf/ptypes/empty/empty.proto - -package empty - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - emptypb "google.golang.org/protobuf/types/known/emptypb" - reflect "reflect" -) - -// Symbols defined in public import of google/protobuf/empty.proto. - -type Empty = emptypb.Empty - -var File_github_com_golang_protobuf_ptypes_empty_empty_proto protoreflect.FileDescriptor - -var file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc = []byte{ - 0x0a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x3b, 0x65, 0x6d, - 0x70, 0x74, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes = []interface{}{} -var file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_golang_protobuf_ptypes_empty_empty_proto_init() } -func file_github_com_golang_protobuf_ptypes_empty_empty_proto_init() { - if File_github_com_golang_protobuf_ptypes_empty_empty_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes, - DependencyIndexes: file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs, - }.Build() - File_github_com_golang_protobuf_ptypes_empty_empty_proto = out.File - file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc = nil - file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes = nil - file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs = nil -} diff --git a/vendor/github.com/google/cel-go/cel/BUILD.bazel b/vendor/github.com/google/cel-go/cel/BUILD.bazel index 3be11d73d..0c740dd89 100644 --- a/vendor/github.com/google/cel-go/cel/BUILD.bazel +++ b/vendor/github.com/google/cel-go/cel/BUILD.bazel @@ -25,8 +25,12 @@ go_library( "//interpreter:go_default_library", "//interpreter/functions:go_default_library", "//parser:go_default_library", - "@com_github_golang_protobuf//proto:go_default_library", - "@io_bazel_rules_go//proto/wkt:descriptor_go_proto", + "@org_golang_google_protobuf//proto:go_default_library", + "@org_golang_google_protobuf//reflect/protodesc:go_default_library", + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//reflect/protoregistry:go_default_library", + "@org_golang_google_protobuf//types/descriptorpb:go_default_library", + "@org_golang_google_protobuf//types/dynamicpb:go_default_library", "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", ], importpath = "github.com/google/cel-go/cel", diff --git a/vendor/github.com/google/cel-go/cel/env.go b/vendor/github.com/google/cel-go/cel/env.go index 322e8c31c..0f97696fa 100644 --- a/vendor/github.com/google/cel-go/cel/env.go +++ b/vendor/github.com/google/cel-go/cel/env.go @@ -75,6 +75,11 @@ func (ast *Ast) Source() Source { return ast.source } +// FormatType converts a type message into a string representation. +func FormatType(t *exprpb.Type) string { + return checker.FormatCheckedType(t) +} + // Env encapsulates the context necessary to perform parsing, type checking, or generation of // evaluable programs for different expressions. type Env struct { @@ -115,7 +120,10 @@ func NewEnv(opts ...EnvOption) (*Env, error) { // See the EnvOption helper functions for the options that can be used to configure the // environment. func NewCustomEnv(opts ...EnvOption) (*Env, error) { - registry := types.NewRegistry() + registry, err := types.NewRegistry() + if err != nil { + return nil, err + } return (&Env{ declarations: []*exprpb.Decl{}, macros: []parser.Macro{}, diff --git a/vendor/github.com/google/cel-go/cel/io.go b/vendor/github.com/google/cel-go/cel/io.go index 31b8a563b..b6cf58d92 100644 --- a/vendor/github.com/google/cel-go/cel/io.go +++ b/vendor/github.com/google/cel-go/cel/io.go @@ -25,12 +25,20 @@ import ( // CheckedExprToAst converts a checked expression proto message to an Ast. func CheckedExprToAst(checkedExpr *exprpb.CheckedExpr) *Ast { + refMap := checkedExpr.GetReferenceMap() + if refMap == nil { + refMap = map[int64]*exprpb.Reference{} + } + typeMap := checkedExpr.GetTypeMap() + if typeMap == nil { + typeMap = map[int64]*exprpb.Type{} + } return &Ast{ expr: checkedExpr.GetExpr(), info: checkedExpr.GetSourceInfo(), source: common.NewInfoSource(checkedExpr.GetSourceInfo()), - refMap: checkedExpr.GetReferenceMap(), - typeMap: checkedExpr.GetTypeMap(), + refMap: refMap, + typeMap: typeMap, } } diff --git a/vendor/github.com/google/cel-go/cel/options.go b/vendor/github.com/google/cel-go/cel/options.go index f56b954d4..1da6ecd79 100644 --- a/vendor/github.com/google/cel-go/cel/options.go +++ b/vendor/github.com/google/cel-go/cel/options.go @@ -17,7 +17,6 @@ package cel import ( "fmt" - "github.com/golang/protobuf/proto" "github.com/google/cel-go/common/containers" "github.com/google/cel-go/common/types/pb" "github.com/google/cel-go/common/types/ref" @@ -25,8 +24,13 @@ import ( "github.com/google/cel-go/interpreter/functions" "github.com/google/cel-go/parser" - descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protodesc" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + descpb "google.golang.org/protobuf/types/descriptorpb" ) // These constants beginning with "Feature" enable optional behavior in @@ -205,12 +209,9 @@ func Types(addTypes ...interface{}) EnvOption { for _, t := range addTypes { switch v := t.(type) { case proto.Message: - fds, err := pb.CollectFileDescriptorSet(v) - if err != nil { - return nil, err - } - for _, fd := range fds.GetFile() { - err = reg.RegisterDescriptor(fd) + fdMap := pb.CollectFileDescriptorSet(v) + for _, fd := range fdMap { + err := reg.RegisterDescriptor(fd) if err != nil { return nil, err } @@ -228,30 +229,56 @@ func Types(addTypes ...interface{}) EnvOption { } } -// TypeDescs adds type declarations for one or more protocol buffer -// FileDescriptorProtos or FileDescriptorSets. Note that types added -// via descriptor will not be able to instantiate messages, and so are -// only useful for Check() operations. +// TypeDescs adds type declarations from any protoreflect.FileDescriptor, protoregistry.Files, +// google.protobuf.FileDescriptorProto or google.protobuf.FileDescriptorSet provided. +// +// Note that messages instantiated from these descriptors will be *dynamicpb.Message values +// rather than the concrete message type. +// +// TypeDescs are hermetic to a single Env object, but may be copied to other Env values via +// extension or by re-using the same EnvOption with another NewEnv() call. func TypeDescs(descs ...interface{}) EnvOption { return func(e *Env) (*Env, error) { reg, isReg := e.provider.(ref.TypeRegistry) if !isReg { return nil, fmt.Errorf("custom types not supported by provider: %T", e.provider) } + // Scan the input descriptors for FileDescriptorProto messages and accumulate them into a + // synthetic FileDescriptorSet as the FileDescriptorProto messages may refer to each other + // and will not resolve properly unless they are part of the same set. + var fds *descpb.FileDescriptorSet for _, d := range descs { - switch p := d.(type) { - case *descpb.FileDescriptorSet: - for _, fd := range p.File { - err := reg.RegisterDescriptor(fd) - if err != nil { - return nil, err + switch f := d.(type) { + case *descpb.FileDescriptorProto: + if fds == nil { + fds = &descpb.FileDescriptorSet{ + File: []*descpb.FileDescriptorProto{}, } } - case *descpb.FileDescriptorProto: - err := reg.RegisterDescriptor(p) - if err != nil { + fds.File = append(fds.File, f) + } + } + if fds != nil { + if err := registerFileSet(reg, fds); err != nil { + return nil, err + } + } + for _, d := range descs { + switch f := d.(type) { + case *protoregistry.Files: + if err := registerFiles(reg, f); err != nil { return nil, err } + case protoreflect.FileDescriptor: + if err := reg.RegisterDescriptor(f); err != nil { + return nil, err + } + case *descpb.FileDescriptorSet: + if err := registerFileSet(reg, f); err != nil { + return nil, err + } + case *descpb.FileDescriptorProto: + // skip, handled as a synthetic file descriptor set. default: return nil, fmt.Errorf("unsupported type descriptor: %T", d) } @@ -260,6 +287,23 @@ func TypeDescs(descs ...interface{}) EnvOption { } } +func registerFileSet(reg ref.TypeRegistry, fileSet *descpb.FileDescriptorSet) error { + files, err := protodesc.NewFiles(fileSet) + if err != nil { + return fmt.Errorf("protodesc.NewFiles(%v) failed: %v", fileSet, err) + } + return registerFiles(reg, files) +} + +func registerFiles(reg ref.TypeRegistry, files *protoregistry.Files) error { + var err error + files.RangeFiles(func(fd protoreflect.FileDescriptor) bool { + err = reg.RegisterDescriptor(fd) + return err == nil + }) + return err +} + // ProgramOption is a functional interface for configuring evaluation bindings and behaviors. type ProgramOption func(p *prog) (*prog, error) diff --git a/vendor/github.com/google/cel-go/cel/program.go b/vendor/github.com/google/cel-go/cel/program.go index 3c74796b9..3ceaace24 100644 --- a/vendor/github.com/google/cel-go/cel/program.go +++ b/vendor/github.com/google/cel-go/cel/program.go @@ -256,7 +256,7 @@ func (p *prog) Eval(input interface{}) (v ref.Val, det *EvalDetails, err error) // translates the CEL value to a Go error response. This interface does not quite match the // RPC signature which allows for multiple errors to be returned, but should be sufficient. if types.IsError(v) { - err = v.Value().(error) + err = v.(*types.Err) } return } diff --git a/vendor/github.com/google/cel-go/checker/BUILD.bazel b/vendor/github.com/google/cel-go/checker/BUILD.bazel index 84ad6858b..4fdc03458 100644 --- a/vendor/github.com/google/cel-go/checker/BUILD.bazel +++ b/vendor/github.com/google/cel-go/checker/BUILD.bazel @@ -26,9 +26,9 @@ go_library( "//common/types/ref:go_default_library", "//common/types/pb:go_default_library", "//parser:go_default_library", - "@com_github_golang_protobuf//proto:go_default_library", - "@io_bazel_rules_go//proto/wkt:empty_go_proto", - "@io_bazel_rules_go//proto/wkt:struct_go_proto", + "@org_golang_google_protobuf//proto:go_default_library", + "@org_golang_google_protobuf//types/known/emptypb:go_default_library", + "@org_golang_google_protobuf//types/known/structpb:go_default_library", "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", ], importpath = "github.com/google/cel-go/checker", @@ -52,7 +52,7 @@ go_test( "//test:go_default_library", "//test/proto2pb:go_default_library", "//test/proto3pb:go_default_library", - "@com_github_golang_protobuf//proto:go_default_library", + "@org_golang_google_protobuf//proto:go_default_library", "@com_github_antlr//runtime/Go/antlr:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/checker/checker.go b/vendor/github.com/google/cel-go/checker/checker.go index a216e6328..2394d2dcd 100644 --- a/vendor/github.com/google/cel-go/checker/checker.go +++ b/vendor/github.com/google/cel-go/checker/checker.go @@ -20,12 +20,13 @@ import ( "fmt" "reflect" - "github.com/golang/protobuf/proto" "github.com/google/cel-go/checker/decls" "github.com/google/cel-go/common" "github.com/google/cel-go/common/containers" "github.com/google/cel-go/common/types/ref" + "google.golang.org/protobuf/proto" + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) diff --git a/vendor/github.com/google/cel-go/checker/decls/BUILD.bazel b/vendor/github.com/google/cel-go/checker/decls/BUILD.bazel index 433190f1f..a904d09d8 100644 --- a/vendor/github.com/google/cel-go/checker/decls/BUILD.bazel +++ b/vendor/github.com/google/cel-go/checker/decls/BUILD.bazel @@ -12,8 +12,8 @@ go_library( "scopes.go", ], deps = [ - "@io_bazel_rules_go//proto/wkt:empty_go_proto", - "@io_bazel_rules_go//proto/wkt:struct_go_proto", + "@org_golang_google_protobuf//types/known/emptypb:go_default_library", + "@org_golang_google_protobuf//types/known/structpb:go_default_library", "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", ], importpath = "github.com/google/cel-go/checker/decls", diff --git a/vendor/github.com/google/cel-go/checker/decls/decls.go b/vendor/github.com/google/cel-go/checker/decls/decls.go index 0abf68895..88a99282d 100644 --- a/vendor/github.com/google/cel-go/checker/decls/decls.go +++ b/vendor/github.com/google/cel-go/checker/decls/decls.go @@ -16,8 +16,8 @@ package decls import ( - emptypb "github.com/golang/protobuf/ptypes/empty" - structpb "github.com/golang/protobuf/ptypes/struct" + emptypb "google.golang.org/protobuf/types/known/emptypb" + structpb "google.golang.org/protobuf/types/known/structpb" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) diff --git a/vendor/github.com/google/cel-go/checker/types.go b/vendor/github.com/google/cel-go/checker/types.go index a6c31c1fb..05d30aa1b 100644 --- a/vendor/github.com/google/cel-go/checker/types.go +++ b/vendor/github.com/google/cel-go/checker/types.go @@ -18,9 +18,10 @@ import ( "fmt" "strings" - "github.com/golang/protobuf/proto" "github.com/google/cel-go/checker/decls" + "google.golang.org/protobuf/proto" + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) diff --git a/vendor/github.com/google/cel-go/common/source.go b/vendor/github.com/google/cel-go/common/source.go index c4ed80d19..d4fa4bbfc 100644 --- a/vendor/github.com/google/cel-go/common/source.go +++ b/vendor/github.com/google/cel-go/common/source.go @@ -180,24 +180,3 @@ func (s *sourceImpl) findLine(characterOffset int32) (int32, int32) { } return line, s.lineOffsets[line-2] } - -// idOffset returns the raw character offset of an expression within the -// source, or false if the expression cannot be found. -func (s *sourceImpl) idOffset(exprID int64) (int32, bool) { - if offset, found := s.idOffsets[exprID]; found { - return offset, true - } - return -1, false -} - -// idLocation returns a Location for the given expression id, or false if one -// cannot be found. It behaves as the composition of idOffset() and -// offsetLocation(). -func (s *sourceImpl) idLocation(exprID int64) (Location, bool) { - if offset, found := s.idOffset(exprID); found { - if location, found := s.OffsetLocation(offset); found { - return location, true - } - } - return NewLocation(1, 0), false -} diff --git a/vendor/github.com/google/cel-go/common/types/BUILD.bazel b/vendor/github.com/google/cel-go/common/types/BUILD.bazel index a7106689b..e78b31738 100644 --- a/vendor/github.com/google/cel-go/common/types/BUILD.bazel +++ b/vendor/github.com/google/cel-go/common/types/BUILD.bazel @@ -17,8 +17,6 @@ go_library( "int.go", "iterator.go", "json_value.go", - "json_list.go", - "json_struct.go", "list.go", "map.go", "null.go", @@ -37,16 +35,16 @@ go_library( "//common/types/ref:go_default_library", "//common/types/pb:go_default_library", "//common/types/traits:go_default_library", - "@com_github_golang_protobuf//jsonpb:go_default_library", - "@com_github_golang_protobuf//proto:go_default_library", - "@com_github_golang_protobuf//ptypes:go_default_library", - "@io_bazel_rules_go//proto/wkt:any_go_proto", - "@io_bazel_rules_go//proto/wkt:descriptor_go_proto", - "@io_bazel_rules_go//proto/wkt:duration_go_proto", - "@io_bazel_rules_go//proto/wkt:struct_go_proto", - "@io_bazel_rules_go//proto/wkt:timestamp_go_proto", - "@io_bazel_rules_go//proto/wkt:wrappers_go_proto", + "@com_github_stoewer_go_strcase//:go_default_library", "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_protobuf//proto:go_default_library", + "@org_golang_google_protobuf//encoding/protojson:go_default_library", + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//types/known/anypb:go_default_library", + "@org_golang_google_protobuf//types/known/durationpb:go_default_library", + "@org_golang_google_protobuf//types/known/structpb:go_default_library", + "@org_golang_google_protobuf//types/known/timestamppb:go_default_library", + "@org_golang_google_protobuf//types/known/wrapperspb:go_default_library", ], ) @@ -64,7 +62,7 @@ go_test( "map_test.go", "null_test.go", "object_test.go", - "providers_test.go", + "provider_test.go", "string_test.go", "timestamp_test.go", "type_test.go", @@ -75,10 +73,11 @@ go_test( deps = [ "//common/types/ref:go_default_library", "//test:go_default_library", - "@com_github_golang_protobuf//jsonpb:go_default_library", - "@io_bazel_rules_go//proto/wkt:any_go_proto", - "@io_bazel_rules_go//proto/wkt:duration_go_proto", - "@io_bazel_rules_go//proto/wkt:timestamp_go_proto", + "//test/proto3pb:test_all_types_go_proto", + "@org_golang_google_protobuf//encoding/protojson:go_default_library", + "@org_golang_google_protobuf//types/known/anypb:go_default_library", + "@org_golang_google_protobuf//types/known/durationpb:go_default_library", + "@org_golang_google_protobuf//types/known/timestamppb:go_default_library", "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/common/types/any_value.go b/vendor/github.com/google/cel-go/common/types/any_value.go index 8272ca006..cda0f13ac 100644 --- a/vendor/github.com/google/cel-go/common/types/any_value.go +++ b/vendor/github.com/google/cel-go/common/types/any_value.go @@ -17,7 +17,7 @@ package types import ( "reflect" - anypb "github.com/golang/protobuf/ptypes/any" + anypb "google.golang.org/protobuf/types/known/anypb" ) // anyValueType constant representing the reflected type of google.protobuf.Any. diff --git a/vendor/github.com/google/cel-go/common/types/bool.go b/vendor/github.com/google/cel-go/common/types/bool.go index 44649c78d..16214c257 100644 --- a/vendor/github.com/google/cel-go/common/types/bool.go +++ b/vendor/github.com/google/cel-go/common/types/bool.go @@ -19,13 +19,12 @@ import ( "reflect" "strconv" - "github.com/golang/protobuf/ptypes" - "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/common/types/traits" - structpb "github.com/golang/protobuf/ptypes/struct" - wrapperspb "github.com/golang/protobuf/ptypes/wrappers" + anypb "google.golang.org/protobuf/types/known/anypb" + structpb "google.golang.org/protobuf/types/known/structpb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" ) // Bool type that implements ref.Val and supports comparison and negation. @@ -66,19 +65,18 @@ func (b Bool) Compare(other ref.Val) ref.Val { func (b Bool) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { switch typeDesc.Kind() { case reflect.Bool: - return bool(b), nil + return reflect.ValueOf(b).Convert(typeDesc).Interface(), nil case reflect.Ptr: switch typeDesc { case anyValueType: - // Primitives must be wrapped before being set on an Any field. - return ptypes.MarshalAny(&wrapperspb.BoolValue{Value: bool(b)}) + // Primitives must be wrapped to a wrapperspb.BoolValue before being packed into an Any. + return anypb.New(wrapperspb.Bool(bool(b))) case boolWrapperType: - // Convert the bool to a protobuf.BoolValue. - return &wrapperspb.BoolValue{Value: bool(b)}, nil + // Convert the bool to a wrapperspb.BoolValue. + return wrapperspb.Bool(bool(b)), nil case jsonValueType: - return &structpb.Value{ - Kind: &structpb.Value_BoolValue{BoolValue: bool(b)}, - }, nil + // Return the bool as a new structpb.Value. + return structpb.NewBoolValue(bool(b)), nil default: if typeDesc.Elem().Kind() == reflect.Bool { p := bool(b) @@ -86,6 +84,10 @@ func (b Bool) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { } } case reflect.Interface: + bv := b.Value() + if reflect.TypeOf(bv).Implements(typeDesc) { + return bv, nil + } if reflect.TypeOf(b).Implements(typeDesc) { return b, nil } @@ -132,11 +134,11 @@ func (b Bool) Value() interface{} { // IsBool returns whether the input ref.Val or ref.Type is equal to BoolType. func IsBool(elem interface{}) bool { - switch elem.(type) { + switch elem := elem.(type) { case ref.Type: return elem == BoolType case ref.Val: - return IsBool(elem.(ref.Val).Type()) + return IsBool(elem.Type()) } return false } diff --git a/vendor/github.com/google/cel-go/common/types/bytes.go b/vendor/github.com/google/cel-go/common/types/bytes.go index f7181ee1a..5ef367f02 100644 --- a/vendor/github.com/google/cel-go/common/types/bytes.go +++ b/vendor/github.com/google/cel-go/common/types/bytes.go @@ -21,13 +21,12 @@ import ( "reflect" "unicode/utf8" - "github.com/golang/protobuf/ptypes" - "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/common/types/traits" - structpb "github.com/golang/protobuf/ptypes/struct" - wrapperspb "github.com/golang/protobuf/ptypes/wrappers" + anypb "google.golang.org/protobuf/types/known/anypb" + structpb "google.golang.org/protobuf/types/known/structpb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" ) // Bytes type that implements ref.Val and supports add, compare, and size @@ -67,27 +66,27 @@ func (b Bytes) Compare(other ref.Val) ref.Val { func (b Bytes) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { switch typeDesc.Kind() { case reflect.Array, reflect.Slice: - if typeDesc.Elem().Kind() == reflect.Uint8 { - return b.Value(), nil - } + return reflect.ValueOf(b).Convert(typeDesc).Interface(), nil case reflect.Ptr: switch typeDesc { case anyValueType: // Primitives must be wrapped before being set on an Any field. - return ptypes.MarshalAny(&wrapperspb.BytesValue{Value: []byte(b)}) + return anypb.New(wrapperspb.Bytes([]byte(b))) case byteWrapperType: - // Convert the bytes to a protobuf.BytesValue. - return &wrapperspb.BytesValue{Value: []byte(b)}, nil + // Convert the bytes to a wrapperspb.BytesValue. + return wrapperspb.Bytes([]byte(b)), nil case jsonValueType: // CEL follows the proto3 to JSON conversion by encoding bytes to a string via base64. // The encoding below matches the golang 'encoding/json' behavior during marshaling, // which uses base64.StdEncoding. str := base64.StdEncoding.EncodeToString([]byte(b)) - return &structpb.Value{ - Kind: &structpb.Value_StringValue{StringValue: str}, - }, nil + return structpb.NewStringValue(str), nil } case reflect.Interface: + bv := b.Value() + if reflect.TypeOf(bv).Implements(typeDesc) { + return bv, nil + } if reflect.TypeOf(b).Implements(typeDesc) { return b, nil } diff --git a/vendor/github.com/google/cel-go/common/types/double.go b/vendor/github.com/google/cel-go/common/types/double.go index 14417bf0e..54c66faa6 100644 --- a/vendor/github.com/google/cel-go/common/types/double.go +++ b/vendor/github.com/google/cel-go/common/types/double.go @@ -22,10 +22,9 @@ import ( "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/common/types/traits" - "github.com/golang/protobuf/ptypes" - - structpb "github.com/golang/protobuf/ptypes/struct" - wrapperspb "github.com/golang/protobuf/ptypes/wrappers" + anypb "google.golang.org/protobuf/types/known/anypb" + structpb "google.golang.org/protobuf/types/known/structpb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" ) // Double type that implements ref.Val, comparison, and mathematical @@ -86,21 +85,19 @@ func (d Double) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { switch typeDesc { case anyValueType: // Primitives must be wrapped before being set on an Any field. - return ptypes.MarshalAny(&wrapperspb.DoubleValue{Value: float64(d)}) + return anypb.New(wrapperspb.Double(float64(d))) case doubleWrapperType: - // Convert to a protobuf.DoubleValue - return &wrapperspb.DoubleValue{Value: float64(d)}, nil + // Convert to a wrapperspb.DoubleValue + return wrapperspb.Double(float64(d)), nil case floatWrapperType: - // Convert to a protobuf.FloatValue (with truncation). - return &wrapperspb.FloatValue{Value: float32(d)}, nil + // Convert to a wrapperspb.FloatValue (with truncation). + return wrapperspb.Float(float32(d)), nil case jsonValueType: // Note, there are special cases for proto3 to json conversion that // expect the floating point value to be converted to a NaN, // Infinity, or -Infinity string values, but the jsonpb string // marshaling of the protobuf.Value will handle this conversion. - return &structpb.Value{ - Kind: &structpb.Value_NumberValue{NumberValue: float64(d)}, - }, nil + return structpb.NewNumberValue(float64(d)), nil } switch typeDesc.Elem().Kind() { case reflect.Float32: @@ -115,6 +112,10 @@ func (d Double) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { return p.Interface(), nil } case reflect.Interface: + dv := d.Value() + if reflect.TypeOf(dv).Implements(typeDesc) { + return dv, nil + } if reflect.TypeOf(d).Implements(typeDesc) { return d, nil } diff --git a/vendor/github.com/google/cel-go/common/types/duration.go b/vendor/github.com/google/cel-go/common/types/duration.go index 6b0016abd..5a14b024e 100644 --- a/vendor/github.com/google/cel-go/common/types/duration.go +++ b/vendor/github.com/google/cel-go/common/types/duration.go @@ -20,22 +20,20 @@ import ( "strconv" "time" - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" - "github.com/google/cel-go/common/overloads" "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/common/types/traits" - dpb "github.com/golang/protobuf/ptypes/duration" - structpb "github.com/golang/protobuf/ptypes/struct" + anypb "google.golang.org/protobuf/types/known/anypb" + dpb "google.golang.org/protobuf/types/known/durationpb" + structpb "google.golang.org/protobuf/types/known/structpb" ) // Duration type that implements ref.Val and supports add, compare, negate, // and subtract operators. This type is also a receiver which means it can // participate in dispatch to receiver functions. type Duration struct { - *dpb.Duration + time.Duration } var ( @@ -52,29 +50,11 @@ var ( func (d Duration) Add(other ref.Val) ref.Val { switch other.Type() { case DurationType: - dur1, err := ptypes.Duration(d.Duration) - if err != nil { - return &Err{err} - } - dur2, err := ptypes.Duration(other.(Duration).Duration) - if err != nil { - return &Err{err} - } - return Duration{ptypes.DurationProto(dur1 + dur2)} + dur2 := other.(Duration) + return Duration{Duration: d.Duration + dur2.Duration} case TimestampType: - dur, err := ptypes.Duration(d.Duration) - if err != nil { - return &Err{err} - } - ts, err := ptypes.Timestamp(other.(Timestamp).Timestamp) - if err != nil { - return &Err{err} - } - tstamp, err := ptypes.TimestampProto(ts.Add(dur)) - if err != nil { - return &Err{err} - } - return Timestamp{tstamp} + ts := other.(Timestamp).Time + return Timestamp{Time: ts.Add(d.Duration)} } return ValOrErr(other, "no such overload") } @@ -85,15 +65,7 @@ func (d Duration) Compare(other ref.Val) ref.Val { if !ok { return ValOrErr(other, "no such overload") } - dur1, err := ptypes.Duration(d.Duration) - if err != nil { - return &Err{err} - } - dur2, err := ptypes.Duration(otherDur.Duration) - if err != nil { - return &Err{err} - } - dur := dur1 - dur2 + dur := d.Duration - otherDur.Duration if dur < 0 { return IntNegOne } @@ -105,13 +77,20 @@ func (d Duration) Compare(other ref.Val) ref.Val { // ConvertToNative implements ref.Val.ConvertToNative. func (d Duration) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + // If the duration is already assignable to the desired type return it. + if reflect.TypeOf(d.Duration).AssignableTo(typeDesc) { + return d.Duration, nil + } + if reflect.TypeOf(d).AssignableTo(typeDesc) { + return d, nil + } switch typeDesc { case anyValueType: - // Pack the underlying proto value into an Any value. - return ptypes.MarshalAny(d.Value().(*dpb.Duration)) + // Pack the duration as a dpb.Duration into an Any value. + return anypb.New(dpb.New(d.Duration)) case durationValueType: // Unwrap the CEL value to its underlying proto value. - return d.Value(), nil + return dpb.New(d.Duration), nil case jsonValueType: // CEL follows the proto3 to JSON conversion. // Note, using jsonpb would wrap the result in extra double quotes. @@ -119,29 +98,18 @@ func (d Duration) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { if IsError(v) { return nil, v.(*Err) } - return &structpb.Value{ - Kind: &structpb.Value_StringValue{StringValue: string(v.(String))}, - }, nil - } - // If the duration is already assignable to the desired type return it. - if reflect.TypeOf(d).AssignableTo(typeDesc) { - return d, nil + return structpb.NewStringValue(string(v.(String))), nil } - return nil, fmt.Errorf("type conversion error from "+ - "'google.protobuf.Duration' to '%v'", typeDesc) + return nil, fmt.Errorf("type conversion error from 'Duration' to '%v'", typeDesc) } // ConvertToType implements ref.Val.ConvertToType. func (d Duration) ConvertToType(typeVal ref.Type) ref.Val { switch typeVal { case StringType: - if dur, err := ptypes.Duration(d.Duration); err == nil { - return String(strconv.FormatFloat(dur.Seconds(), 'f', -1, 64) + "s") - } + return String(strconv.FormatFloat(d.Seconds(), 'f', -1, 64) + "s") case IntType: - if dur, err := ptypes.Duration(d.Duration); err == nil { - return Int(dur) - } + return Int(d.Duration) case DurationType: return d case TypeType: @@ -156,27 +124,19 @@ func (d Duration) Equal(other ref.Val) ref.Val { if !ok { return ValOrErr(other, "no such overload") } - return Bool(proto.Equal(d.Duration, otherDur.Value().(proto.Message))) + return Bool(d.Duration == otherDur.Duration) } // Negate implements traits.Negater.Negate. func (d Duration) Negate() ref.Val { - dur, err := ptypes.Duration(d.Duration) - if err != nil { - return &Err{err} - } - return Duration{ptypes.DurationProto(-dur)} + return Duration{Duration: -d.Duration} } // Receive implements traits.Receiver.Receive. func (d Duration) Receive(function string, overload string, args []ref.Val) ref.Val { - dur, err := ptypes.Duration(d.Duration) - if err != nil { - return &Err{err} - } if len(args) == 0 { if f, found := durationZeroArgOverloads[function]; found { - return f(dur) + return f(d.Duration) } } return NewErr("no such overload") @@ -215,6 +175,6 @@ var ( return Int(dur.Seconds()) }, overloads.TimeGetMilliseconds: func(dur time.Duration) ref.Val { - return Int(dur.Nanoseconds() / 1000000) + return Int(dur.Milliseconds()) }} ) diff --git a/vendor/github.com/google/cel-go/common/types/err.go b/vendor/github.com/google/cel-go/common/types/err.go index 67386f4e1..5cccb53d0 100644 --- a/vendor/github.com/google/cel-go/common/types/err.go +++ b/vendor/github.com/google/cel-go/common/types/err.go @@ -42,6 +42,12 @@ func NoSuchOverloadErr() ref.Val { return NewErr("no such overload") } +// UnsupportedRefValConversionErr returns a types.NewErr instance with a no such conversion +// message that indicates that the native value could not be converted to a CEL ref.Val. +func UnsupportedRefValConversionErr(val interface{}) ref.Val { + return NewErr("unsupported conversion to ref.Val: (%T)%v", val, val) +} + // MaybeNoSuchOverloadErr returns the error or unknown if the input ref.Val is one of these types, // else a new no such overload error. func MaybeNoSuchOverloadErr(val ref.Val) ref.Val { diff --git a/vendor/github.com/google/cel-go/common/types/int.go b/vendor/github.com/google/cel-go/common/types/int.go index 8c586f592..4b76ce265 100644 --- a/vendor/github.com/google/cel-go/common/types/int.go +++ b/vendor/github.com/google/cel-go/common/types/int.go @@ -16,17 +16,17 @@ package types import ( "fmt" + "math" "reflect" "strconv" "time" - "github.com/golang/protobuf/ptypes" - "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/common/types/traits" - structpb "github.com/golang/protobuf/ptypes/struct" - wrapperspb "github.com/golang/protobuf/ptypes/wrappers" + anypb "google.golang.org/protobuf/types/known/anypb" + structpb "google.golang.org/protobuf/types/known/structpb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" ) // Int type that implements ref.Val as well as comparison and math operators. @@ -64,6 +64,9 @@ func (i Int) Add(other ref.Val) ref.Val { if !ok { return ValOrErr(other, "no such overload") } + if (otherInt > 0 && i > math.MaxInt64-otherInt) || (otherInt < 0 && i < math.MinInt64-otherInt) { + return NewErr("integer overflow") + } return i + otherInt } @@ -95,13 +98,13 @@ func (i Int) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { switch typeDesc { case anyValueType: // Primitives must be wrapped before being set on an Any field. - return ptypes.MarshalAny(&wrapperspb.Int64Value{Value: int64(i)}) + return anypb.New(wrapperspb.Int64(int64(i))) case int32WrapperType: - // Convert the value to a protobuf.Int32Value (with truncation). - return &wrapperspb.Int32Value{Value: int32(i)}, nil + // Convert the value to a wrapperspb.Int32Value (with truncation). + return wrapperspb.Int32(int32(i)), nil case int64WrapperType: - // Convert the value to a protobuf.Int64Value. - return &wrapperspb.Int64Value{Value: int64(i)}, nil + // Convert the value to a wrapperspb.Int64Value. + return wrapperspb.Int64(int64(i)), nil case jsonValueType: // The proto-to-JSON conversion rules would convert all 64-bit integer values to JSON // decimal strings. Because CEL ints might come from the automatic widening of 32-bit @@ -118,17 +121,11 @@ func (i Int) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { // however, it is best to simply stay within the JSON number range when building JSON // objects in CEL. if i.isJSONSafe() { - return &structpb.Value{ - Kind: &structpb.Value_NumberValue{NumberValue: float64(i)}, - }, nil + return structpb.NewNumberValue(float64(i)), nil } // Proto3 to JSON conversion requires string-formatted int64 values // since the conversion to floating point would result in truncation. - return &structpb.Value{ - Kind: &structpb.Value_StringValue{ - StringValue: strconv.FormatInt(int64(i), 10), - }, - }, nil + return structpb.NewStringValue(strconv.FormatInt(int64(i), 10)), nil } switch typeDesc.Elem().Kind() { case reflect.Int32: @@ -143,6 +140,10 @@ func (i Int) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { return p.Interface(), nil } case reflect.Interface: + iv := i.Value() + if reflect.TypeOf(iv).Implements(typeDesc) { + return iv, nil + } if reflect.TypeOf(i).Implements(typeDesc) { return i, nil } @@ -165,12 +166,8 @@ func (i Int) ConvertToType(typeVal ref.Type) ref.Val { case StringType: return String(fmt.Sprintf("%d", int64(i))) case TimestampType: - t := time.Unix(int64(i), 0) - ts, err := ptypes.TimestampProto(t) - if err != nil { - return NewErr(err.Error()) - } - return Timestamp{Timestamp: ts} + t := time.Unix(int64(i), 0).UTC() + return Timestamp{Time: t} case TypeType: return IntType } @@ -186,6 +183,10 @@ func (i Int) Divide(other ref.Val) ref.Val { if otherInt == IntZero { return NewErr("divide by zero") } + // In twos complement, negating MinInt64 would result in a valid of MaxInt64+1. + if i == math.MinInt64 && otherInt == -1 { + return NewErr("integer overflow") + } return i / otherInt } @@ -207,6 +208,10 @@ func (i Int) Modulo(other ref.Val) ref.Val { if otherInt == IntZero { return NewErr("modulus by zero") } + // In twos complement, negating MinInt64 would result in a valid of MaxInt64+1. + if i == math.MinInt64 && otherInt == -1 { + return NewErr("integer overflow") + } return i % otherInt } @@ -216,11 +221,23 @@ func (i Int) Multiply(other ref.Val) ref.Val { if !ok { return ValOrErr(other, "no such overload") } + // Detecting multiplication overflow is more complicated than the others. The first two detect + // attempting to negate MinInt64, which would result in MaxInt64+1. The other four detect normal + // overflow conditions. + if (i == -1 && otherInt == math.MinInt64) || (otherInt == -1 && i == math.MinInt64) || + (i > 0 && otherInt > 0 && i > math.MaxInt64/otherInt) || (i > 0 && otherInt < 0 && otherInt < math.MinInt64/i) || + (i < 0 && otherInt > 0 && i < math.MinInt64/otherInt) || (i < 0 && otherInt < 0 && otherInt < math.MaxInt64/i) { + return NewErr("integer overflow") + } return i * otherInt } // Negate implements traits.Negater.Negate. func (i Int) Negate() ref.Val { + // In twos complement, negating MinInt64 would result in a valid of MaxInt64+1. + if i == math.MinInt64 { + return NewErr("integer overflow") + } return -i } @@ -230,6 +247,9 @@ func (i Int) Subtract(subtrahend ref.Val) ref.Val { if !ok { return ValOrErr(subtrahend, "no such overload") } + if (subtraInt < 0 && i > math.MaxInt64+subtraInt) || (subtraInt > 0 && i < math.MinInt64+subtraInt) { + return NewErr("integer overflow") + } return i - subtraInt } diff --git a/vendor/github.com/google/cel-go/common/types/iterator.go b/vendor/github.com/google/cel-go/common/types/iterator.go index 023fcaf7a..490662778 100644 --- a/vendor/github.com/google/cel-go/common/types/iterator.go +++ b/vendor/github.com/google/cel-go/common/types/iterator.go @@ -34,22 +34,22 @@ var ( // interpreter. type baseIterator struct{} -func (it *baseIterator) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { +func (*baseIterator) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { return nil, fmt.Errorf("type conversion on iterators not supported") } -func (it *baseIterator) ConvertToType(typeVal ref.Type) ref.Val { +func (*baseIterator) ConvertToType(typeVal ref.Type) ref.Val { return NewErr("no such overload") } -func (it *baseIterator) Equal(other ref.Val) ref.Val { +func (*baseIterator) Equal(other ref.Val) ref.Val { return NewErr("no such overload") } -func (it *baseIterator) Type() ref.Type { +func (*baseIterator) Type() ref.Type { return IteratorType } -func (it *baseIterator) Value() interface{} { +func (*baseIterator) Value() interface{} { return nil } diff --git a/vendor/github.com/google/cel-go/common/types/json_list.go b/vendor/github.com/google/cel-go/common/types/json_list.go deleted file mode 100644 index 32e1e7782..000000000 --- a/vendor/github.com/google/cel-go/common/types/json_list.go +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright 2018 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package types - -import ( - "fmt" - "reflect" - - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" - structpb "github.com/golang/protobuf/ptypes/struct" - - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" -) - -var ( - jsonListValueType = reflect.TypeOf(&structpb.ListValue{}) -) - -type jsonListValue struct { - *structpb.ListValue - ref.TypeAdapter -} - -// NewJSONList creates a traits.Lister implementation backed by a JSON list that has been encoded -// in protocol buffer form. -// -// The `adapter` argument provides type adaptation capabilities from proto to CEL. -func NewJSONList(adapter ref.TypeAdapter, l *structpb.ListValue) traits.Lister { - return &jsonListValue{TypeAdapter: adapter, ListValue: l} -} - -// Add implements the traits.Adder interface method. -func (l *jsonListValue) Add(other ref.Val) ref.Val { - if other.Type() != ListType { - return ValOrErr(other, "no such overload") - } - switch other.(type) { - case *jsonListValue: - otherList := other.(*jsonListValue) - concatElems := append(l.GetValues(), otherList.GetValues()...) - return NewJSONList(l.TypeAdapter, &structpb.ListValue{Values: concatElems}) - } - return &concatList{ - TypeAdapter: l.TypeAdapter, - prevList: l, - nextList: other.(traits.Lister)} -} - -// Contains implements the traits.Container interface method. -func (l *jsonListValue) Contains(elem ref.Val) ref.Val { - if IsUnknownOrError(elem) { - return elem - } - var err ref.Val - for i := Int(0); i < l.Size().(Int); i++ { - val := l.Get(i) - cmp := elem.Equal(val) - b, ok := cmp.(Bool) - // When there is an error on the contain check, this is not necessarily terminal. - // The contains call could find the element and return True, just as though the user - // had written a per-element comparison in an exists() macro or logical ||, e.g. - // list.exists(e, e == elem) - if !ok && err == nil { - err = ValOrErr(cmp, "no such overload") - } - if b == True { - return True - } - } - if err != nil { - return err - } - return False -} - -// ConvertToNative implements the ref.Val interface method. -func (l *jsonListValue) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { - switch typeDesc.Kind() { - case reflect.Array, reflect.Slice: - elemCount := int(l.Size().(Int)) - nativeList := reflect.MakeSlice(typeDesc, elemCount, elemCount) - for i := 0; i < elemCount; i++ { - elem := l.Get(Int(i)) - nativeElemVal, err := elem.ConvertToNative(typeDesc.Elem()) - if err != nil { - return nil, err - } - nativeList.Index(i).Set(reflect.ValueOf(nativeElemVal)) - } - return nativeList.Interface(), nil - - case reflect.Ptr: - switch typeDesc { - case anyValueType: - return ptypes.MarshalAny(l.Value().(proto.Message)) - case jsonValueType: - return &structpb.Value{ - Kind: &structpb.Value_ListValue{ListValue: l.ListValue}, - }, nil - case jsonListValueType: - return l.ListValue, nil - } - - case reflect.Interface: - // If the list is already assignable to the desired type return it. - if reflect.TypeOf(l).Implements(typeDesc) { - return l, nil - } - } - return nil, fmt.Errorf("no conversion found from list type to native type."+ - " list elem: google.protobuf.Value, native type: %v", typeDesc) -} - -// ConvertToType implements the ref.Val interface method. -func (l *jsonListValue) ConvertToType(typeVal ref.Type) ref.Val { - switch typeVal { - case ListType: - return l - case TypeType: - return ListType - } - return NewErr("type conversion error from '%s' to '%s'", ListType, typeVal) -} - -// Equal implements the ref.Val interface method. -func (l *jsonListValue) Equal(other ref.Val) ref.Val { - otherList, ok := other.(traits.Lister) - if !ok { - return ValOrErr(other, "no such overload") - } - if l.Size() != otherList.Size() { - return False - } - for i := IntZero; i < l.Size().(Int); i++ { - thisElem := l.Get(i) - otherElem := otherList.Get(i) - elemEq := thisElem.Equal(otherElem) - if elemEq != True { - return elemEq - } - } - return True -} - -// Get implements the traits.Indexer interface method. -func (l *jsonListValue) Get(index ref.Val) ref.Val { - i, ok := index.(Int) - if !ok { - return ValOrErr(index, "unsupported index type: '%v", index.Type()) - } - if i < 0 || i >= l.Size().(Int) { - return NewErr("index '%d' out of range in list size '%d'", i, l.Size()) - } - elem := l.GetValues()[i] - return l.NativeToValue(elem) -} - -// Iterator implements the traits.Iterable interface method. -func (l *jsonListValue) Iterator() traits.Iterator { - return &jsonValueListIterator{ - baseIterator: &baseIterator{}, - TypeAdapter: l.TypeAdapter, - elems: l.GetValues(), - len: len(l.GetValues())} -} - -// Size implements the traits.Sizer interface method. -func (l *jsonListValue) Size() ref.Val { - return Int(len(l.GetValues())) -} - -// Type implements the ref.Val interface method. -func (l *jsonListValue) Type() ref.Type { - return ListType -} - -// Value implements the ref.Val interface method. -func (l *jsonListValue) Value() interface{} { - return l.ListValue -} - -type jsonValueListIterator struct { - *baseIterator - ref.TypeAdapter - cursor int - elems []*structpb.Value - len int -} - -// HasNext implements the traits.Iterator interface method. -func (it *jsonValueListIterator) HasNext() ref.Val { - return Bool(it.cursor < it.len) -} - -// Next implements the traits.Iterator interface method. -func (it *jsonValueListIterator) Next() ref.Val { - if it.HasNext() == True { - index := it.cursor - it.cursor++ - return it.NativeToValue(it.elems[index]) - } - return nil -} diff --git a/vendor/github.com/google/cel-go/common/types/json_struct.go b/vendor/github.com/google/cel-go/common/types/json_struct.go deleted file mode 100644 index 25bea8b6a..000000000 --- a/vendor/github.com/google/cel-go/common/types/json_struct.go +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright 2018 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package types - -import ( - "fmt" - "reflect" - - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" - - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" - - structpb "github.com/golang/protobuf/ptypes/struct" -) - -var ( - jsonStructType = reflect.TypeOf(&structpb.Struct{}) -) - -type jsonStruct struct { - ref.TypeAdapter - *structpb.Struct -} - -// NewJSONStruct creates a traits.Mapper implementation backed by a JSON struct that has been -// encoded in protocol buffer form. -// -// The `adapter` argument provides type adaptation capabilities from proto to CEL. -func NewJSONStruct(adapter ref.TypeAdapter, st *structpb.Struct) traits.Mapper { - return &jsonStruct{TypeAdapter: adapter, Struct: st} -} - -// Contains implements the traits.Container interface method. -func (m *jsonStruct) Contains(index ref.Val) ref.Val { - val, found := m.Find(index) - // When the index is not found and val is non-nil, this is an error or unknown value. - if !found && val != nil && IsUnknownOrError(val) { - return val - } - return Bool(found) -} - -// ConvertToNative implements the ref.Val interface method. -func (m *jsonStruct) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { - switch typeDesc.Kind() { - case reflect.Map: - otherKey := typeDesc.Key() - otherElem := typeDesc.Elem() - if typeDesc.Key().Kind() == reflect.String { - nativeMap := reflect.MakeMapWithSize(typeDesc, int(m.Size().(Int))) - it := m.Iterator() - for it.HasNext() == True { - key := it.Next() - refKeyValue, err := key.ConvertToNative(otherKey) - if err != nil { - return nil, err - } - refElemValue, err := m.Get(key).ConvertToNative(otherElem) - if err != nil { - return nil, err - } - nativeMap.SetMapIndex( - reflect.ValueOf(refKeyValue), - reflect.ValueOf(refElemValue)) - } - return nativeMap.Interface(), nil - } - - case reflect.Ptr: - switch typeDesc { - case anyValueType: - return ptypes.MarshalAny(m.Value().(proto.Message)) - case jsonValueType: - return &structpb.Value{ - Kind: &structpb.Value_StructValue{StructValue: m.Struct}, - }, nil - case jsonStructType: - return m.Struct, nil - } - - case reflect.Interface: - // If the struct is already assignable to the desired type return it. - if reflect.TypeOf(m).Implements(typeDesc) { - return m, nil - } - } - return nil, fmt.Errorf( - "no conversion found from map type to native type."+ - " map type: google.protobuf.Struct, native type: %v", typeDesc) -} - -// ConvertToType implements the ref.Val interface method. -func (m *jsonStruct) ConvertToType(typeVal ref.Type) ref.Val { - switch typeVal { - case MapType: - return m - case TypeType: - return MapType - } - return NewErr("type conversion error from '%s' to '%s'", MapType, typeVal) -} - -// Equal implements the ref.Val interface method. -func (m *jsonStruct) Equal(other ref.Val) ref.Val { - if MapType != other.Type() { - return ValOrErr(other, "no such overload") - } - otherMap := other.(traits.Mapper) - if m.Size() != otherMap.Size() { - return False - } - it := m.Iterator() - for it.HasNext() == True { - key := it.Next() - thisVal, _ := m.Find(key) - otherVal, found := otherMap.Find(key) - if !found { - if otherVal == nil { - return False - } - return ValOrErr(otherVal, "no such overload") - } - valEq := thisVal.Equal(otherVal) - if valEq != True { - return valEq - } - } - return True -} - -// Find implements the traits.Mapper interface method. -func (m *jsonStruct) Find(key ref.Val) (ref.Val, bool) { - strKey, ok := key.(String) - if !ok { - return ValOrErr(key, "no such overload"), false - } - fields := m.Struct.GetFields() - value, found := fields[string(strKey)] - if !found { - return nil, found - } - return m.NativeToValue(value), found -} - -// Get implements the traits.Indexer interface method. -func (m *jsonStruct) Get(key ref.Val) ref.Val { - v, found := m.Find(key) - if !found { - return ValOrErr(v, "no such key: %v", key) - } - return v -} - -// Iterator implements the traits.Iterable interface method. -func (m *jsonStruct) Iterator() traits.Iterator { - f := m.GetFields() - keys := make([]string, len(m.GetFields())) - i := 0 - for k := range f { - keys[i] = k - i++ - } - return &jsonValueMapIterator{ - baseIterator: &baseIterator{}, - len: len(keys), - mapKeys: keys} -} - -// Size implements the traits.Sizer interface method. -func (m *jsonStruct) Size() ref.Val { - return Int(len(m.GetFields())) -} - -// Type implements the ref.Val interface method. -func (m *jsonStruct) Type() ref.Type { - return MapType -} - -// Value implements the ref.Val interface method. -func (m *jsonStruct) Value() interface{} { - return m.Struct -} - -type jsonValueMapIterator struct { - *baseIterator - cursor int - len int - mapKeys []string -} - -// HasNext implements the traits.Iterator interface method. -func (it *jsonValueMapIterator) HasNext() ref.Val { - return Bool(it.cursor < it.len) -} - -// Next implements the traits.Iterator interface method. -func (it *jsonValueMapIterator) Next() ref.Val { - if it.HasNext() == True { - index := it.cursor - it.cursor++ - return String(it.mapKeys[index]) - } - return nil -} diff --git a/vendor/github.com/google/cel-go/common/types/json_value.go b/vendor/github.com/google/cel-go/common/types/json_value.go index e082dc6a2..cf7527884 100644 --- a/vendor/github.com/google/cel-go/common/types/json_value.go +++ b/vendor/github.com/google/cel-go/common/types/json_value.go @@ -17,8 +17,12 @@ package types import ( "reflect" - "github.com/golang/protobuf/ptypes/struct" + "google.golang.org/protobuf/types/known/structpb" ) -// jsonValueType constant representing the reflected type of a protobuf Value. -var jsonValueType = reflect.TypeOf(&structpb.Value{}) +// JSON type constants representing the reflected types of protobuf JSON values. +var ( + jsonValueType = reflect.TypeOf(&structpb.Value{}) + jsonListValueType = reflect.TypeOf(&structpb.ListValue{}) + jsonStructType = reflect.TypeOf(&structpb.Struct{}) +) diff --git a/vendor/github.com/google/cel-go/common/types/list.go b/vendor/github.com/google/cel-go/common/types/list.go index a44795136..fd577e95d 100644 --- a/vendor/github.com/google/cel-go/common/types/list.go +++ b/vendor/github.com/google/cel-go/common/types/list.go @@ -18,13 +18,14 @@ import ( "fmt" "reflect" - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" - "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/common/types/traits" - structpb "github.com/golang/protobuf/ptypes/struct" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + + anypb "google.golang.org/protobuf/types/known/anypb" + structpb "google.golang.org/protobuf/types/known/structpb" ) var ( @@ -41,24 +42,58 @@ var ( // value should be an array of "native" types, i.e. any type that // NativeToValue() can convert to a ref.Val. func NewDynamicList(adapter ref.TypeAdapter, value interface{}) traits.Lister { + refValue := reflect.ValueOf(value) return &baseList{ TypeAdapter: adapter, value: value, - refValue: reflect.ValueOf(value)} + size: refValue.Len(), + get: func(i int) interface{} { + return refValue.Index(i).Interface() + }, + } } // NewStringList returns a traits.Lister containing only strings. func NewStringList(adapter ref.TypeAdapter, elems []string) traits.Lister { - return &stringList{ - baseList: NewDynamicList(adapter, elems).(*baseList), - elems: elems} + return &baseList{ + TypeAdapter: adapter, + value: elems, + size: len(elems), + get: func(i int) interface{} { return elems[i] }, + } +} + +// NewRefValList returns a traits.Lister with ref.Val elements. +// +// This type specialization is used with list literals within CEL expressions. +func NewRefValList(adapter ref.TypeAdapter, elems []ref.Val) traits.Lister { + return &baseList{ + TypeAdapter: adapter, + value: elems, + size: len(elems), + get: func(i int) interface{} { return elems[i] }, + } } -// NewValueList returns a traits.Lister with ref.Val elements. -func NewValueList(adapter ref.TypeAdapter, elems []ref.Val) traits.Lister { - return &valueList{ - baseList: NewDynamicList(adapter, elems).(*baseList), - elems: elems} +// NewProtoList returns a traits.Lister based on a pb.List instance. +func NewProtoList(adapter ref.TypeAdapter, list protoreflect.List) traits.Lister { + return &baseList{ + TypeAdapter: adapter, + value: list, + size: list.Len(), + get: func(i int) interface{} { return list.Get(i).Interface() }, + } +} + +// NewJSONList returns a traits.Lister based on structpb.ListValue instance. +func NewJSONList(adapter ref.TypeAdapter, l *structpb.ListValue) traits.Lister { + vals := l.GetValues() + return &baseList{ + TypeAdapter: adapter, + value: l, + size: len(vals), + get: func(i int) interface{} { return vals[i] }, + } } // baseList points to a list containing elements of any type. @@ -66,15 +101,22 @@ func NewValueList(adapter ref.TypeAdapter, elems []ref.Val) traits.Lister { // The `ref.TypeAdapter` enables native type to CEL type conversions. type baseList struct { ref.TypeAdapter - value interface{} - refValue reflect.Value + value interface{} + + // size indicates the number of elements within the list. + // Since objects are immutable the size of a list is static. + size int + + // get returns a value at the specified integer index. + // The index is guaranteed to be checked against the list index range. + get func(int) interface{} } // Add implements the traits.Adder interface method. func (l *baseList) Add(other ref.Val) ref.Val { otherList, ok := other.(traits.Lister) if !ok { - return ValOrErr(other, "no such overload") + return MaybeNoSuchOverloadErr(other) } if l.Size() == IntZero { return other @@ -94,9 +136,8 @@ func (l *baseList) Contains(elem ref.Val) ref.Val { return elem } var err ref.Val - sz := l.Size().(Int) - for i := Int(0); i < sz; i++ { - val := l.Get(i) + for i := 0; i < l.size; i++ { + val := l.NativeToValue(l.get(i)) cmp := elem.Equal(val) b, ok := cmp.(Bool) // When there is an error on the contain check, this is not necessarily terminal. @@ -118,15 +159,22 @@ func (l *baseList) Contains(elem ref.Val) ref.Val { // ConvertToNative implements the ref.Val interface method. func (l *baseList) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { - // TODO: Add support for conversion to Any - // JSON conversions are a special case since the 'native' type is a proto message. + // If the underlying list value is assignable to the reflected type return it. + if reflect.TypeOf(l.value).AssignableTo(typeDesc) { + return l.value, nil + } + // If the list wrapper is assignable to the desired type return it. + if reflect.TypeOf(l).AssignableTo(typeDesc) { + return l, nil + } + // Attempt to convert the list to a set of well known protobuf types. switch typeDesc { case anyValueType: json, err := l.ConvertToNative(jsonListValueType) if err != nil { return nil, err } - return ptypes.MarshalAny(json.(proto.Message)) + return anypb.New(json.(proto.Message)) case jsonValueType, jsonListValueType: jsonValues, err := l.ConvertToNative(reflect.TypeOf([]*structpb.Value{})) @@ -137,35 +185,21 @@ func (l *baseList) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { if typeDesc == jsonListValueType { return jsonList, nil } - return &structpb.Value{Kind: &structpb.Value_ListValue{ListValue: jsonList}}, nil + return structpb.NewListValue(jsonList), nil } - // Non-list conversion. if typeDesc.Kind() != reflect.Slice && typeDesc.Kind() != reflect.Array { return nil, fmt.Errorf("type conversion error from list to '%v'", typeDesc) } - // If the list is already assignable to the desired type return it. - if reflect.TypeOf(l).AssignableTo(typeDesc) { - return l, nil - } - // List conversion. - thisType := l.refValue.Type() - thisElem := thisType.Elem() - thisElemKind := thisElem.Kind() - - otherElem := typeDesc.Elem() - otherElemKind := otherElem.Kind() - if otherElemKind == thisElemKind { - return l.value, nil - } // Allow the element ConvertToNative() function to determine whether conversion is possible. - elemCount := int(l.Size().(Int)) + otherElemType := typeDesc.Elem() + elemCount := l.size nativeList := reflect.MakeSlice(typeDesc, elemCount, elemCount) for i := 0; i < elemCount; i++ { - elem := l.Get(Int(i)) - nativeElemVal, err := elem.ConvertToNative(otherElem) + elem := l.NativeToValue(l.get(i)) + nativeElemVal, err := elem.ConvertToNative(otherElemType) if err != nil { return nil, err } @@ -189,7 +223,7 @@ func (l *baseList) ConvertToType(typeVal ref.Type) ref.Val { func (l *baseList) Equal(other ref.Val) ref.Val { otherList, ok := other.(traits.Lister) if !ok { - return ValOrErr(other, "no such overload") + return MaybeNoSuchOverloadErr(other) } if l.Size() != otherList.Size() { return False @@ -211,25 +245,22 @@ func (l *baseList) Get(index ref.Val) ref.Val { if !ok { return ValOrErr(index, "unsupported index type '%s' in list", index.Type()) } - if i < 0 || i >= l.Size().(Int) { + iv := int(i) + if iv < 0 || iv >= l.size { return NewErr("index '%d' out of range in list size '%d'", i, l.Size()) } - elem := l.refValue.Index(int(i)).Interface() + elem := l.get(iv) return l.NativeToValue(elem) } // Iterator implements the traits.Iterable interface method. func (l *baseList) Iterator() traits.Iterator { - return &listIterator{ - baseIterator: &baseIterator{}, - listValue: l, - cursor: 0, - len: l.Size().(Int)} + return newListIterator(l) } // Size implements the traits.Sizer interface method. func (l *baseList) Size() ref.Val { - return Int(l.refValue.Len()) + return Int(l.size) } // Type implements the ref.Val interface method. @@ -255,7 +286,7 @@ type concatList struct { func (l *concatList) Add(other ref.Val) ref.Val { otherList, ok := other.(traits.Lister) if !ok { - return ValOrErr(other, "no such overload") + return MaybeNoSuchOverloadErr(other) } if l.Size() == IntZero { return other @@ -293,10 +324,7 @@ func (l *concatList) Contains(elem ref.Val) ref.Val { // ConvertToNative implements the ref.Val interface method. func (l *concatList) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { - combined := &baseList{ - TypeAdapter: l.TypeAdapter, - value: l.Value(), - refValue: reflect.ValueOf(l.Value())} + combined := NewDynamicList(l.TypeAdapter, l.Value().([]interface{})) return combined.ConvertToNative(typeDesc) } @@ -315,7 +343,7 @@ func (l *concatList) ConvertToType(typeVal ref.Type) ref.Val { func (l *concatList) Equal(other ref.Val) ref.Val { otherList, ok := other.(traits.Lister) if !ok { - return ValOrErr(other, "no such overload") + return MaybeNoSuchOverloadErr(other) } if l.Size() != otherList.Size() { return False @@ -335,7 +363,7 @@ func (l *concatList) Equal(other ref.Val) ref.Val { func (l *concatList) Get(index ref.Val) ref.Val { i, ok := index.(Int) if !ok { - return ValOrErr(index, "no such overload") + return MaybeNoSuchOverloadErr(index) } if i < l.prevList.Size().(Int) { return l.prevList.Get(i) @@ -346,11 +374,7 @@ func (l *concatList) Get(index ref.Val) ref.Val { // Iterator implements the traits.Iterable interface method. func (l *concatList) Iterator() traits.Iterator { - return &listIterator{ - baseIterator: &baseIterator{}, - listValue: l, - cursor: 0, - len: l.Size().(Int)} + return newListIterator(l) } // Size implements the traits.Sizer interface method. @@ -366,7 +390,7 @@ func (l *concatList) Type() ref.Type { // Value implements the ref.Val interface method. func (l *concatList) Value() interface{} { if l.value == nil { - merged := make([]interface{}, l.Size().(Int), l.Size().(Int)) + merged := make([]interface{}, l.Size().(Int)) prevLen := l.prevList.Size().(Int) for i := Int(0); i < prevLen; i++ { merged[i] = l.prevList.Get(i).Value() @@ -380,131 +404,11 @@ func (l *concatList) Value() interface{} { return l.value } -// stringList is a specialization of the traits.Lister interface which is -// present to demonstrate the ability to specialize Lister implementations. -type stringList struct { - *baseList - elems []string -} - -// Add implments the traits.Adder interface method. -func (l *stringList) Add(other ref.Val) ref.Val { - if other.Type() != ListType { - return ValOrErr(other, "no such overload") - } - if l.Size() == IntZero { - return other - } - if other.(traits.Sizer).Size() == IntZero { - return l - } - switch other.(type) { - case *stringList: - concatElems := append(l.elems, other.(*stringList).elems...) - return NewStringList(l.TypeAdapter, concatElems) - } - return &concatList{ - TypeAdapter: l.TypeAdapter, - prevList: l.baseList, - nextList: other.(traits.Lister)} -} - -// ConvertToNative implements the ref.Val interface method. -func (l *stringList) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { - switch typeDesc.Kind() { - case reflect.Array, reflect.Slice: - if typeDesc.Elem().Kind() == reflect.String { - return l.elems, nil - } - if typeDesc.Elem().Kind() == reflect.Interface { - iface := make([]interface{}, len(l.elems), len(l.elems)) - for i, str := range l.elems { - iface[i] = str - } - return iface, nil - } - case reflect.Ptr: - switch typeDesc { - case anyValueType: - json, err := l.ConvertToNative(jsonListValueType) - if err != nil { - return nil, err - } - return ptypes.MarshalAny(json.(proto.Message)) - case jsonValueType, jsonListValueType: - elemCount := len(l.elems) - listVals := make([]*structpb.Value, elemCount, elemCount) - for i := 0; i < elemCount; i++ { - listVals[i] = &structpb.Value{ - Kind: &structpb.Value_StringValue{StringValue: l.elems[i]}} - } - jsonList := &structpb.ListValue{Values: listVals} - if typeDesc == jsonListValueType { - return jsonList, nil - } - return &structpb.Value{ - Kind: &structpb.Value_ListValue{ - ListValue: jsonList}}, nil - } - } - // If the list is already assignable to the desired type return it. - if reflect.TypeOf(l).AssignableTo(typeDesc) { - return l, nil - } - return nil, fmt.Errorf("no conversion found from list type to native type."+ - " list elem: string, native type: %v", typeDesc) -} - -// Get implements the traits.Indexer interface method. -func (l *stringList) Get(index ref.Val) ref.Val { - i, ok := index.(Int) - if !ok { - return ValOrErr(index, "no such overload") - } - if i < 0 || i >= l.Size().(Int) { - return NewErr("index '%d' out of range in list size '%d'", i, l.Size()) - } - return String(l.elems[i]) -} - -// Size implements the traits.Sizer interface method. -func (l *stringList) Size() ref.Val { - return Int(len(l.elems)) -} - -// valueList is a specialization of traits.Lister for ref.Val. -type valueList struct { - *baseList - elems []ref.Val -} - -// Add implements the traits.Adder interface method. -func (l *valueList) Add(other ref.Val) ref.Val { - otherList, ok := other.(traits.Lister) - if !ok { - return ValOrErr(other, "no such overload") - } - return &concatList{ - TypeAdapter: l.TypeAdapter, - prevList: l, - nextList: otherList} -} - -// Get implements the traits.Indexer interface method. -func (l *valueList) Get(index ref.Val) ref.Val { - i, ok := index.(Int) - if !ok { - return ValOrErr(index, "no such overload") - } - if i < 0 || i >= l.Size().(Int) { - return NewErr("index '%d' out of range in list size '%d'", i, l.Size()) +func newListIterator(listValue traits.Lister) traits.Iterator { + return &listIterator{ + listValue: listValue, + len: listValue.Size().(Int), } - return l.elems[i] -} - -// Size implements the traits.Sizer interface method. -func (l *valueList) Size() ref.Val { - return Int(len(l.elems)) } type listIterator struct { diff --git a/vendor/github.com/google/cel-go/common/types/map.go b/vendor/github.com/google/cel-go/common/types/map.go index d785f2704..4c91f0da3 100644 --- a/vendor/github.com/google/cel-go/common/types/map.go +++ b/vendor/github.com/google/cel-go/common/types/map.go @@ -15,47 +15,81 @@ package types import ( - "errors" "fmt" "reflect" - "strings" - - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" + "github.com/google/cel-go/common/types/pb" "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/common/types/traits" - structpb "github.com/golang/protobuf/ptypes/struct" + "github.com/stoewer/go-strcase" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + + anypb "google.golang.org/protobuf/types/known/anypb" + structpb "google.golang.org/protobuf/types/known/structpb" ) -// baseMap is a reflection based map implementation designed to handle a variety of map-like types. -type baseMap struct { - ref.TypeAdapter - value interface{} - refValue reflect.Value +// NewDynamicMap returns a traits.Mapper value with dynamic key, value pairs. +func NewDynamicMap(adapter ref.TypeAdapter, value interface{}) traits.Mapper { + refValue := reflect.ValueOf(value) + return &baseMap{ + TypeAdapter: adapter, + mapAccessor: newReflectMapAccessor(adapter, refValue), + value: value, + size: refValue.Len(), + } } -// stringMap is a specialization to improve the performance of simple key, value pair lookups by -// string as this is the most common usage of maps. -type stringMap struct { - *baseMap - mapStrStr map[string]string +// NewJSONStruct creates a traits.Mapper implementation backed by a JSON struct that has been +// encoded in protocol buffer form. +// +// The `adapter` argument provides type adaptation capabilities from proto to CEL. +func NewJSONStruct(adapter ref.TypeAdapter, value *structpb.Struct) traits.Mapper { + fields := value.GetFields() + return &baseMap{ + TypeAdapter: adapter, + mapAccessor: newJSONStructAccessor(adapter, fields), + value: value, + size: len(fields), + } } -// NewDynamicMap returns a traits.Mapper value with dynamic key, value pairs. -func NewDynamicMap(adapter ref.TypeAdapter, value interface{}) traits.Mapper { +// NewRefValMap returns a specialized traits.Mapper with CEL valued keys and values. +func NewRefValMap(adapter ref.TypeAdapter, value map[ref.Val]ref.Val) traits.Mapper { + return &baseMap{ + TypeAdapter: adapter, + mapAccessor: newRefValMapAccessor(value), + value: value, + size: len(value), + } +} + +// NewStringInterfaceMap returns a specialized traits.Mapper with string keys and interface values. +func NewStringInterfaceMap(adapter ref.TypeAdapter, value map[string]interface{}) traits.Mapper { return &baseMap{ TypeAdapter: adapter, + mapAccessor: newStringIfaceMapAccessor(adapter, value), value: value, - refValue: reflect.ValueOf(value)} + size: len(value), + } } // NewStringStringMap returns a specialized traits.Mapper with string keys and values. func NewStringStringMap(adapter ref.TypeAdapter, value map[string]string) traits.Mapper { - return &stringMap{ - baseMap: &baseMap{TypeAdapter: adapter, value: value}, - mapStrStr: value, + return &baseMap{ + TypeAdapter: adapter, + mapAccessor: newStringMapAccessor(value), + value: value, + size: len(value), + } +} + +// NewProtoMap returns a specialized traits.Mapper for handling protobuf map values. +func NewProtoMap(adapter ref.TypeAdapter, value *pb.Map) traits.Mapper { + return &protoMap{ + TypeAdapter: adapter, + value: value, } } @@ -68,18 +102,40 @@ var ( traits.SizerType) ) -// Contains implements the traits.Container interface method. -func (m *baseMap) Contains(index ref.Val) ref.Val { - val, found := m.Find(index) - // When the index is not found and val is non-nil, this is an error or unknown value. - if !found && val != nil && IsUnknownOrError(val) { - return val - } - return Bool(found) +// mapAccessor is a private interface for finding values within a map and iterating over the keys. +// This interface implements portions of the API surface area required by the traits.Mapper +// interface. +type mapAccessor interface { + // Find returns a value, if one exists, for the inpput key. + // + // If the key is not found the function returns (nil, false). + // If the input key is not valid for the map, or is Err or Unknown the function returns + // (Unknown|Err, false). + Find(ref.Val) (ref.Val, bool) + + // Iterator returns an Iterator over the map key set. + Iterator() traits.Iterator +} + +// baseMap is a reflection based map implementation designed to handle a variety of map-like types. +// +// Since CEL is side-effect free, the base map represents an immutable object. +type baseMap struct { + // TypeAdapter used to convert keys and values accessed within the map. + ref.TypeAdapter + + // mapAccessor interface implementation used to find and iterate over map keys. + mapAccessor + + // value is the native Go value upon which the map type operators. + value interface{} + + // size is the number of entries in the map. + size int } // Contains implements the traits.Container interface method. -func (m *stringMap) Contains(index ref.Val) ref.Val { +func (m *baseMap) Contains(index ref.Val) ref.Val { val, found := m.Find(index) // When the index is not found and val is non-nil, this is an error or unknown value. if !found && val != nil && IsUnknownOrError(val) { @@ -90,27 +146,32 @@ func (m *stringMap) Contains(index ref.Val) ref.Val { // ConvertToNative implements the ref.Val interface method. func (m *baseMap) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + // If the map is already assignable to the desired type return it, e.g. interfaces and + // maps with the same key value types. + if reflect.TypeOf(m.value).AssignableTo(typeDesc) { + return m.value, nil + } + if reflect.TypeOf(m).AssignableTo(typeDesc) { + return m, nil + } switch typeDesc { case anyValueType: json, err := m.ConvertToNative(jsonStructType) if err != nil { return nil, err } - return ptypes.MarshalAny(json.(proto.Message)) + return anypb.New(json.(proto.Message)) case jsonValueType, jsonStructType: jsonEntries, err := m.ConvertToNative(reflect.TypeOf(map[string]*structpb.Value{})) if err != nil { return nil, err } - jsonMap := &structpb.Struct{ - Fields: jsonEntries.(map[string]*structpb.Value)} + jsonMap := &structpb.Struct{Fields: jsonEntries.(map[string]*structpb.Value)} if typeDesc == jsonStructType { return jsonMap, nil } - return &structpb.Value{ - Kind: &structpb.Value_StructValue{ - StructValue: jsonMap}}, nil + return structpb.NewStructValue(jsonMap), nil } // Unwrap pointers, but track their use. @@ -123,32 +184,12 @@ func (m *baseMap) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { } isPtr = true } - - // If the map is already assignable to the desired type return it, e.g. interfaces and - // maps with the same key value types. - if reflect.TypeOf(m).AssignableTo(typeDesc) { - return m, nil - } - - // Establish some basic facts about the map key and value types. - thisType := m.refValue.Type() - thisKey := thisType.Key() - thisKeyKind := thisKey.Kind() - thisElem := thisType.Elem() - thisElemKind := thisElem.Kind() - switch typeDesc.Kind() { // Map conversion. case reflect.Map: otherKey := typeDesc.Key() - otherKeyKind := otherKey.Kind() otherElem := typeDesc.Elem() - otherElemKind := otherElem.Kind() - if otherKeyKind == thisKeyKind && otherElemKind == thisElemKind { - return m.value, nil - } - elemCount := m.Size().(Int) - nativeMap := reflect.MakeMapWithSize(typeDesc, int(elemCount)) + nativeMap := reflect.MakeMapWithSize(typeDesc, m.size) it := m.Iterator() for it.HasNext() == True { key := it.Next() @@ -160,15 +201,10 @@ func (m *baseMap) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { if err != nil { return nil, err } - nativeMap.SetMapIndex( - reflect.ValueOf(refKeyValue), - reflect.ValueOf(refElemValue)) + nativeMap.SetMapIndex(reflect.ValueOf(refKeyValue), reflect.ValueOf(refElemValue)) } return nativeMap.Interface(), nil case reflect.Struct: - if thisKeyKind != reflect.String && thisKeyKind != reflect.Interface { - break - } nativeStructPtr := reflect.New(typeDesc) nativeStruct := nativeStructPtr.Elem() it := m.Iterator() @@ -177,20 +213,15 @@ func (m *baseMap) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { // Ensure the field name being referenced is exported. // Only exported (public) field names can be set by reflection, where the name // must be at least one character in length and start with an upper-case letter. - fieldName := string(key.ConvertToType(StringType).(String)) - switch len(fieldName) { - case 0: - return nil, errors.New("type conversion error, unsupported empty field") - case 1: - fieldName = strings.ToUpper(fieldName) - default: - fieldName = strings.ToUpper(fieldName[0:1]) + fieldName[1:] + fieldName := key.ConvertToType(StringType) + if IsError(fieldName) { + return nil, fieldName.(*Err) } - fieldRef := nativeStruct.FieldByName(fieldName) + name := string(fieldName.(String)) + name = strcase.UpperCamelCase(name) + fieldRef := nativeStruct.FieldByName(name) if !fieldRef.IsValid() { - return nil, fmt.Errorf( - "type conversion error, no such field '%s' in type '%v'", - fieldName, typeDesc) + return nil, fmt.Errorf("type conversion error, no such field '%s' in type '%v'", name, typeDesc) } fieldValue, err := m.Get(key).ConvertToNative(fieldRef.Type()) if err != nil { @@ -206,14 +237,6 @@ func (m *baseMap) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { return nil, fmt.Errorf("type conversion error from map to '%v'", typeDesc) } -// ConvertToNative implements the ref.Val interface method. -func (m *stringMap) ConvertToNative(refType reflect.Type) (interface{}, error) { - if !m.baseMap.refValue.IsValid() { - m.baseMap.refValue = reflect.ValueOf(m.value) - } - return m.baseMap.ConvertToNative(refType) -} - // ConvertToType implements the ref.Val interface method. func (m *baseMap) ConvertToType(typeVal ref.Type) ref.Val { switch typeVal { @@ -225,22 +248,12 @@ func (m *baseMap) ConvertToType(typeVal ref.Type) ref.Val { return NewErr("type conversion error from '%s' to '%s'", MapType, typeVal) } -// ConvertToType implements the ref.Val interface method. -func (m *stringMap) ConvertToType(typeVal ref.Type) ref.Val { - switch typeVal { - case MapType: - return m - default: - return m.baseMap.ConvertToType(typeVal) - } -} - // Equal implements the ref.Val interface method. func (m *baseMap) Equal(other ref.Val) ref.Val { - if MapType != other.Type() { - return ValOrErr(other, "no such overload") + otherMap, ok := other.(traits.Mapper) + if !ok { + return MaybeNoSuchOverloadErr(other) } - otherMap := other.(traits.Mapper) if m.Size() != otherMap.Size() { return False } @@ -253,7 +266,7 @@ func (m *baseMap) Equal(other ref.Val) ref.Val { if otherVal == nil { return False } - return ValOrErr(otherVal, "no such overload") + return MaybeNoSuchOverloadErr(otherVal) } valEq := thisVal.Equal(otherVal) if valEq != True { @@ -263,59 +276,409 @@ func (m *baseMap) Equal(other ref.Val) ref.Val { return True } -// Equal implements the ref.Val interface method. -func (m *stringMap) Equal(other ref.Val) ref.Val { - if !m.baseMap.refValue.IsValid() { - m.baseMap.refValue = reflect.ValueOf(m.value) +// Get implements the traits.Indexer interface method. +func (m *baseMap) Get(key ref.Val) ref.Val { + v, found := m.Find(key) + if !found { + return ValOrErr(v, "no such key: %v", key) + } + return v +} + +// Size implements the traits.Sizer interface method. +func (m *baseMap) Size() ref.Val { + return Int(m.size) +} + +// Type implements the ref.Val interface method. +func (m *baseMap) Type() ref.Type { + return MapType +} + +// Value implements the ref.Val interface method. +func (m *baseMap) Value() interface{} { + return m.value +} + +func newJSONStructAccessor(adapter ref.TypeAdapter, st map[string]*structpb.Value) mapAccessor { + return &jsonStructAccessor{ + TypeAdapter: adapter, + st: st, } - return m.baseMap.Equal(other) } -// Find implements the traits.Mapper interface method. -func (m *baseMap) Find(key ref.Val) (ref.Val, bool) { - // TODO: There are multiple reasons why a Get could fail. Typically, this is because the key - // does not exist in the map; however, it's possible that the value cannot be converted to - // the desired type. Refine this strategy to disambiguate these cases. +type jsonStructAccessor struct { + ref.TypeAdapter + st map[string]*structpb.Value +} + +// Find searches the json struct field map for the input key value and returns (value, true) if +// found. +// +// If the key is not found the function returns (nil, false). +// If the input key is not a String, or is an Err or Unknown, the function returns +// (Unknown|Err, false). +func (a *jsonStructAccessor) Find(key ref.Val) (ref.Val, bool) { + strKey, ok := key.(String) + if !ok { + return MaybeNoSuchOverloadErr(key), false + } + keyVal, found := a.st[string(strKey)] + if !found { + return nil, false + } + return a.NativeToValue(keyVal), true +} + +// Iterator creates a new traits.Iterator from the set of JSON struct field names. +func (a *jsonStructAccessor) Iterator() traits.Iterator { + // Copy the keys to make their order stable. + mapKeys := make([]string, len(a.st)) + i := 0 + for k := range a.st { + mapKeys[i] = k + i++ + } + return &stringKeyIterator{ + mapKeys: mapKeys, + len: len(mapKeys), + } +} + +func newReflectMapAccessor(adapter ref.TypeAdapter, value reflect.Value) mapAccessor { + keyType := value.Type().Key() + return &reflectMapAccessor{ + TypeAdapter: adapter, + refValue: value, + keyType: keyType, + } +} + +type reflectMapAccessor struct { + ref.TypeAdapter + refValue reflect.Value + keyType reflect.Type +} + +// Find converts the input key to a native Golang type and then uses reflection to find the key, +// returning (value, true) if present. +// +// If the key is not found the function returns (nil, false). +// If the input key is not a String, or is an Err or Unknown, the function returns +// (Unknown|Err, false). +func (a *reflectMapAccessor) Find(key ref.Val) (ref.Val, bool) { if IsUnknownOrError(key) { - return key, false + return MaybeNoSuchOverloadErr(key), false } - thisKeyType := m.refValue.Type().Key() - nativeKey, err := key.ConvertToNative(thisKeyType) + k, err := key.ConvertToNative(a.keyType) if err != nil { return &Err{err}, false } - nativeKeyVal := reflect.ValueOf(nativeKey) - value := m.refValue.MapIndex(nativeKeyVal) - if !value.IsValid() { + var refKey reflect.Value + switch k := k.(type) { + case reflect.Value: + refKey = k + default: + refKey = reflect.ValueOf(k) + } + val := a.refValue.MapIndex(refKey) + if !val.IsValid() { return nil, false } - return m.NativeToValue(value.Interface()), true + return a.NativeToValue(val.Interface()), true +} + +// Iterator creates a Golang reflection based traits.Iterator. +func (a *reflectMapAccessor) Iterator() traits.Iterator { + return &mapIterator{ + TypeAdapter: a.TypeAdapter, + mapKeys: a.refValue.MapKeys(), + len: a.refValue.Len(), + } +} + +func newRefValMapAccessor(mapVal map[ref.Val]ref.Val) mapAccessor { + return &refValMapAccessor{mapVal: mapVal} +} + +type refValMapAccessor struct { + mapVal map[ref.Val]ref.Val +} + +// Find uses native map accesses to find the key, returning (value, true) if present. +// +// If the key is not found the function returns (nil, false). +// If the input key is an Err or Unknown, the function returns (Unknown|Err, false). +func (a *refValMapAccessor) Find(key ref.Val) (ref.Val, bool) { + if IsUnknownOrError(key) { + return key, false + } + keyVal, found := a.mapVal[key] + return keyVal, found +} + +// Iterator produces a new traits.Iterator which iterates over the map keys via Golang reflection. +func (a *refValMapAccessor) Iterator() traits.Iterator { + return &mapIterator{ + TypeAdapter: DefaultTypeAdapter, + mapKeys: reflect.ValueOf(a.mapVal).MapKeys(), + len: len(a.mapVal), + } +} + +func newStringMapAccessor(strMap map[string]string) mapAccessor { + return &stringMapAccessor{mapVal: strMap} } -// Find implements the traits.Mapper interface method. -func (m *stringMap) Find(key ref.Val) (ref.Val, bool) { +type stringMapAccessor struct { + mapVal map[string]string +} + +// Find uses native map accesses to find the key, returning (value, true) if present. +// +// If the key is not found the function returns (nil, false). +// If the input key is not a String, or is an Err or Unknown, the function returns +// (Unknown|Err, false). +func (a *stringMapAccessor) Find(key ref.Val) (ref.Val, bool) { strKey, ok := key.(String) if !ok { - return ValOrErr(key, "no such overload"), false + return MaybeNoSuchOverloadErr(key), false } - val, found := m.mapStrStr[string(strKey)] + keyVal, found := a.mapVal[string(strKey)] if !found { return nil, false } - return String(val), true + return String(keyVal), true } -// Get implements the traits.Indexer interface method. -func (m *baseMap) Get(key ref.Val) ref.Val { - v, found := m.Find(key) +// Iterator creates a new traits.Iterator from the string key set of the map. +func (a *stringMapAccessor) Iterator() traits.Iterator { + // Copy the keys to make their order stable. + mapKeys := make([]string, len(a.mapVal)) + i := 0 + for k := range a.mapVal { + mapKeys[i] = k + i++ + } + return &stringKeyIterator{ + mapKeys: mapKeys, + len: len(mapKeys), + } +} + +func newStringIfaceMapAccessor(adapter ref.TypeAdapter, mapVal map[string]interface{}) mapAccessor { + return &stringIfaceMapAccessor{ + TypeAdapter: adapter, + mapVal: mapVal, + } +} + +type stringIfaceMapAccessor struct { + ref.TypeAdapter + mapVal map[string]interface{} +} + +// Find uses native map accesses to find the key, returning (value, true) if present. +// +// If the key is not found the function returns (nil, false). +// If the input key is not a String, or is an Err or Unknown, the function returns +// (Unknown|Err, false). +func (a *stringIfaceMapAccessor) Find(key ref.Val) (ref.Val, bool) { + strKey, ok := key.(String) + if !ok { + return MaybeNoSuchOverloadErr(key), false + } + keyVal, found := a.mapVal[string(strKey)] if !found { - return ValOrErr(v, "no such key: %v", key) + return nil, false + } + return a.NativeToValue(keyVal), true +} + +// Iterator creates a new traits.Iterator from the string key set of the map. +func (a *stringIfaceMapAccessor) Iterator() traits.Iterator { + // Copy the keys to make their order stable. + mapKeys := make([]string, len(a.mapVal)) + i := 0 + for k := range a.mapVal { + mapKeys[i] = k + i++ + } + return &stringKeyIterator{ + mapKeys: mapKeys, + len: len(mapKeys), + } +} + +// protoMap is a specialized, separate implementation of the traits.Mapper interfaces tailored to +// accessing protoreflect.Map values. +type protoMap struct { + ref.TypeAdapter + value *pb.Map +} + +// Contains returns whether the map contains the given key. +func (m *protoMap) Contains(key ref.Val) ref.Val { + val, found := m.Find(key) + // When the index is not found and val is non-nil, this is an error or unknown value. + if !found && val != nil && IsUnknownOrError(val) { + return val + } + return Bool(found) +} + +// ConvertToNative implements the ref.Val interface method. +// +// Note, assignment to Golang struct types is not yet supported. +func (m *protoMap) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + // If the map is already assignable to the desired type return it, e.g. interfaces and + // maps with the same key value types. + switch typeDesc { + case anyValueType: + json, err := m.ConvertToNative(jsonStructType) + if err != nil { + return nil, err + } + return anypb.New(json.(proto.Message)) + case jsonValueType, jsonStructType: + jsonEntries, err := + m.ConvertToNative(reflect.TypeOf(map[string]*structpb.Value{})) + if err != nil { + return nil, err + } + jsonMap := &structpb.Struct{ + Fields: jsonEntries.(map[string]*structpb.Value)} + if typeDesc == jsonStructType { + return jsonMap, nil + } + return structpb.NewStructValue(jsonMap), nil + } + switch typeDesc.Kind() { + case reflect.Struct, reflect.Ptr: + if reflect.TypeOf(m.value).AssignableTo(typeDesc) { + return m.value, nil + } + if reflect.TypeOf(m).AssignableTo(typeDesc) { + return m, nil + } + } + if typeDesc.Kind() != reflect.Map { + return nil, fmt.Errorf("unsupported type conversion: %v to map", typeDesc) + } + + keyType := m.value.KeyType.ReflectType() + valType := m.value.ValueType.ReflectType() + otherKeyType := typeDesc.Key() + otherValType := typeDesc.Elem() + mapVal := reflect.MakeMapWithSize(typeDesc, m.value.Len()) + var err error + m.value.Range(func(key protoreflect.MapKey, val protoreflect.Value) bool { + ntvKey := key.Interface() + ntvVal := val.Interface() + switch ntvVal.(type) { + case protoreflect.Message: + ntvVal = ntvVal.(protoreflect.Message).Interface() + } + if keyType == otherKeyType && valType == otherValType { + mapVal.SetMapIndex(reflect.ValueOf(ntvKey), reflect.ValueOf(ntvVal)) + return true + } + celKey := m.NativeToValue(ntvKey) + celVal := m.NativeToValue(ntvVal) + ntvKey, err = celKey.ConvertToNative(otherKeyType) + if err != nil { + // early terminate the range loop. + return false + } + ntvVal, err = celVal.ConvertToNative(otherValType) + if err != nil { + // early terminate the range loop. + return false + } + mapVal.SetMapIndex(reflect.ValueOf(ntvKey), reflect.ValueOf(ntvVal)) + return true + }) + if err != nil { + return nil, err + } + return mapVal.Interface(), nil +} + +// ConvertToType implements the ref.Val interface method. +func (m *protoMap) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case MapType: + return m + case TypeType: + return MapType + } + return NewErr("type conversion error from '%s' to '%s'", MapType, typeVal) +} + +// Equal implements the ref.Val interface method. +func (m *protoMap) Equal(other ref.Val) ref.Val { + if MapType != other.Type() { + return MaybeNoSuchOverloadErr(other) + } + otherMap := other.(traits.Mapper) + if m.value.Map.Len() != int(otherMap.Size().(Int)) { + return False + } + var retVal ref.Val = True + m.value.Range(func(key protoreflect.MapKey, val protoreflect.Value) bool { + keyVal := m.NativeToValue(key.Interface()) + valVal := m.NativeToValue(val) + otherVal, found := otherMap.Find(keyVal) + if !found { + if otherVal == nil { + retVal = False + return false + } + retVal = MaybeNoSuchOverloadErr(otherVal) + return false + } + valEq := valVal.Equal(otherVal) + if valEq != True { + retVal = valEq + return false + } + return true + }) + return retVal +} + +// Find returns whether the protoreflect.Map contains the input key. +// +// If the key is not found the function returns (nil, false). +// If the input key is not a supported proto map key type, or is an Err or Unknown, +// the function returns +// (Unknown|Err, false). +func (m *protoMap) Find(key ref.Val) (ref.Val, bool) { + if IsUnknownOrError(key) { + return key, false + } + // Convert the input key to the expected protobuf key type. + ntvKey, err := key.ConvertToNative(m.value.KeyType.ReflectType()) + if err != nil { + return &Err{err}, false + } + // Use protoreflection to get the key value. + val := m.value.Get(protoreflect.ValueOf(ntvKey).MapKey()) + if !val.IsValid() { + return nil, false + } + // Perform nominal type unwrapping from the input value. + switch v := val.Interface().(type) { + case protoreflect.List, protoreflect.Map: + // Maps do not support list or map values + return NewErr("unsupported map element type: (%T)%v", v, v), false + default: + return m.NativeToValue(v), true } - return v } // Get implements the traits.Indexer interface method. -func (m *stringMap) Get(key ref.Val) ref.Val { +func (m *protoMap) Get(key ref.Val) ref.Val { v, found := m.Find(key) if !found { return ValOrErr(v, "no such key: %v", key) @@ -324,52 +687,41 @@ func (m *stringMap) Get(key ref.Val) ref.Val { } // Iterator implements the traits.Iterable interface method. -func (m *baseMap) Iterator() traits.Iterator { - mapKeys := m.refValue.MapKeys() - return &mapIterator{ - baseIterator: &baseIterator{}, - TypeAdapter: m.TypeAdapter, - mapValue: m, - mapKeys: mapKeys, - cursor: 0, - len: int(m.Size().(Int))} -} - -// Iterator implements the traits.Iterable interface method. -func (m *stringMap) Iterator() traits.Iterator { - if !m.baseMap.refValue.IsValid() { - m.baseMap.refValue = reflect.ValueOf(m.value) +func (m *protoMap) Iterator() traits.Iterator { + // Copy the keys to make their order stable. + mapKeys := make([]protoreflect.MapKey, 0, m.value.Len()) + m.value.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool { + mapKeys = append(mapKeys, k) + return true + }) + return &protoMapIterator{ + TypeAdapter: m.TypeAdapter, + mapKeys: mapKeys, + len: m.value.Len(), } - return m.baseMap.Iterator() } -// Size implements the traits.Sizer interface method. -func (m *baseMap) Size() ref.Val { - return Int(m.refValue.Len()) -} - -// Size implements the traits.Sizer interface method. -func (m *stringMap) Size() ref.Val { - return Int(len(m.mapStrStr)) +// Size returns the number of entries in the protoreflect.Map. +func (m *protoMap) Size() ref.Val { + return Int(m.value.Len()) } // Type implements the ref.Val interface method. -func (m *baseMap) Type() ref.Type { +func (m *protoMap) Type() ref.Type { return MapType } // Value implements the ref.Val interface method. -func (m *baseMap) Value() interface{} { +func (m *protoMap) Value() interface{} { return m.value } type mapIterator struct { *baseIterator ref.TypeAdapter - mapValue traits.Mapper - mapKeys []reflect.Value - cursor int - len int + mapKeys []reflect.Value + cursor int + len int } // HasNext implements the traits.Iterator interface method. @@ -387,3 +739,49 @@ func (it *mapIterator) Next() ref.Val { } return nil } + +type protoMapIterator struct { + *baseIterator + ref.TypeAdapter + mapKeys []protoreflect.MapKey + cursor int + len int +} + +// HasNext implements the traits.Iterator interface method. +func (it *protoMapIterator) HasNext() ref.Val { + return Bool(it.cursor < it.len) +} + +// Next implements the traits.Iterator interface method. +func (it *protoMapIterator) Next() ref.Val { + if it.HasNext() == True { + index := it.cursor + it.cursor++ + refKey := it.mapKeys[index] + return it.NativeToValue(refKey.Interface()) + } + return nil +} + +type stringKeyIterator struct { + *baseIterator + mapKeys []string + cursor int + len int +} + +// HasNext implements the traits.Iterator interface method. +func (it *stringKeyIterator) HasNext() ref.Val { + return Bool(it.cursor < it.len) +} + +// Next implements the traits.Iterator interface method. +func (it *stringKeyIterator) Next() ref.Val { + if it.HasNext() == True { + index := it.cursor + it.cursor++ + return String(it.mapKeys[index]) + } + return nil +} diff --git a/vendor/github.com/google/cel-go/common/types/null.go b/vendor/github.com/google/cel-go/common/types/null.go index 6d9ac0e44..3dc688856 100644 --- a/vendor/github.com/google/cel-go/common/types/null.go +++ b/vendor/github.com/google/cel-go/common/types/null.go @@ -18,12 +18,12 @@ import ( "fmt" "reflect" - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" + "google.golang.org/protobuf/proto" "github.com/google/cel-go/common/types/ref" - structpb "github.com/golang/protobuf/ptypes/struct" + anypb "google.golang.org/protobuf/types/known/anypb" + structpb "google.golang.org/protobuf/types/known/structpb" ) // Null type implementation. @@ -42,9 +42,7 @@ var ( func (n Null) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { switch typeDesc.Kind() { case reflect.Int32: - if typeDesc == jsonNullType { - return structpb.NullValue_NULL_VALUE, nil - } + return reflect.ValueOf(n).Convert(typeDesc).Interface(), nil case reflect.Ptr: switch typeDesc { case anyValueType: @@ -54,15 +52,15 @@ func (n Null) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { if err != nil { return nil, err } - return ptypes.MarshalAny(pb.(proto.Message)) + return anypb.New(pb.(proto.Message)) case jsonValueType: - return &structpb.Value{ - Kind: &structpb.Value_NullValue{ - NullValue: structpb.NullValue_NULL_VALUE, - }, - }, nil + return structpb.NewNullValue(), nil } case reflect.Interface: + nv := n.Value() + if reflect.TypeOf(nv).Implements(typeDesc) { + return nv, nil + } if reflect.TypeOf(n).Implements(typeDesc) { return n, nil } diff --git a/vendor/github.com/google/cel-go/common/types/object.go b/vendor/github.com/google/cel-go/common/types/object.go index 7a140a020..e77b078fa 100644 --- a/vendor/github.com/google/cel-go/common/types/object.go +++ b/vendor/github.com/google/cel-go/common/types/object.go @@ -18,23 +18,21 @@ import ( "fmt" "reflect" - "github.com/golang/protobuf/jsonpb" - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" - "github.com/google/cel-go/common/types/pb" "github.com/google/cel-go/common/types/ref" - structpb "github.com/golang/protobuf/ptypes/struct" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" + + anypb "google.golang.org/protobuf/types/known/anypb" + structpb "google.golang.org/protobuf/types/known/structpb" ) type protoObj struct { ref.TypeAdapter value proto.Message - refValue reflect.Value typeDesc *pb.TypeDescription typeValue *TypeValue - isAny bool } // NewObject returns an object based on a proto.Message value which handles @@ -51,38 +49,52 @@ func NewObject(adapter ref.TypeAdapter, return &protoObj{ TypeAdapter: adapter, value: value, - refValue: reflect.ValueOf(value), typeDesc: typeDesc, typeValue: typeValue} } func (o *protoObj) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { - pb := o.Value().(proto.Message) + pb := o.value + if reflect.TypeOf(pb).AssignableTo(typeDesc) { + return pb, nil + } + if reflect.TypeOf(o).AssignableTo(typeDesc) { + return o, nil + } switch typeDesc { case anyValueType: - if o.isAny { + _, isAny := pb.(*anypb.Any) + if isAny { return pb, nil } - return ptypes.MarshalAny(pb) + return anypb.New(pb) case jsonValueType: // Marshal the proto to JSON first, and then rehydrate as protobuf.Value as there is no // support for direct conversion from proto.Message to protobuf.Value. - jsonTxt, err := (&jsonpb.Marshaler{}).MarshalToString(pb) + bytes, err := protojson.Marshal(pb) if err != nil { return nil, err } json := &structpb.Value{} - err = jsonpb.UnmarshalString(jsonTxt, json) + err = protojson.Unmarshal(bytes, json) if err != nil { return nil, err } return json, nil + default: + if typeDesc == o.typeDesc.ReflectType() { + return o.value, nil + } + if typeDesc.Kind() == reflect.Ptr { + val := reflect.New(typeDesc.Elem()).Interface() + dstPB, ok := val.(proto.Message) + if ok { + proto.Merge(dstPB, pb) + return dstPB, nil + } + } } - if o.refValue.Type().AssignableTo(typeDesc) { - return pb, nil - } - return nil, fmt.Errorf("type conversion error from '%v' to '%v'", - o.refValue.Type(), typeDesc) + return nil, fmt.Errorf("type conversion error from '%T' to '%v'", o.value, typeDesc) } func (o *protoObj) ConvertToType(typeVal ref.Type) ref.Val { @@ -94,13 +106,12 @@ func (o *protoObj) ConvertToType(typeVal ref.Type) ref.Val { case TypeType: return o.typeValue } - return NewErr("type conversion error from '%s' to '%s'", - o.typeDesc.Name(), typeVal) + return NewErr("type conversion error from '%s' to '%s'", o.typeDesc.Name(), typeVal) } func (o *protoObj) Equal(other ref.Val) ref.Val { if o.typeDesc.Name() != other.Type().TypeName() { - return ValOrErr(other, "no such overload") + return MaybeNoSuchOverloadErr(other) } return Bool(proto.Equal(o.value, other.Value().(proto.Message))) } @@ -109,14 +120,14 @@ func (o *protoObj) Equal(other ref.Val) ref.Val { func (o *protoObj) IsSet(field ref.Val) ref.Val { protoFieldName, ok := field.(String) if !ok { - return ValOrErr(field, "no such overload") + return MaybeNoSuchOverloadErr(field) } protoFieldStr := string(protoFieldName) fd, found := o.typeDesc.FieldByName(protoFieldStr) if !found { return NewErr("no such field '%s'", field) } - if fd.IsSet(o.refValue) { + if fd.IsSet(o.value) { return True } return False @@ -125,14 +136,14 @@ func (o *protoObj) IsSet(field ref.Val) ref.Val { func (o *protoObj) Get(index ref.Val) ref.Val { protoFieldName, ok := index.(String) if !ok { - return ValOrErr(index, "no such overload") + return MaybeNoSuchOverloadErr(index) } protoFieldStr := string(protoFieldName) fd, found := o.typeDesc.FieldByName(protoFieldStr) if !found { return NewErr("no such field '%s'", index) } - fv, err := fd.GetFrom(o.refValue) + fv, err := fd.GetFrom(o.value) if err != nil { return NewErr(err.Error()) } diff --git a/vendor/github.com/google/cel-go/common/types/pb/BUILD.bazel b/vendor/github.com/google/cel-go/common/types/pb/BUILD.bazel index f4d40044b..50d8f4d28 100644 --- a/vendor/github.com/google/cel-go/common/types/pb/BUILD.bazel +++ b/vendor/github.com/google/cel-go/common/types/pb/BUILD.bazel @@ -16,16 +16,17 @@ go_library( ], importpath = "github.com/google/cel-go/common/types/pb", deps = [ - "@com_github_golang_protobuf//descriptor:go_default_library", - "@com_github_golang_protobuf//proto:go_default_library", - "@io_bazel_rules_go//proto/wkt:any_go_proto", - "@io_bazel_rules_go//proto/wkt:descriptor_go_proto", - "@io_bazel_rules_go//proto/wkt:duration_go_proto", - "@io_bazel_rules_go//proto/wkt:empty_go_proto", - "@io_bazel_rules_go//proto/wkt:struct_go_proto", - "@io_bazel_rules_go//proto/wkt:timestamp_go_proto", - "@io_bazel_rules_go//proto/wkt:wrappers_go_proto", "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_protobuf//proto:go_default_library", + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//reflect/protoregistry:go_default_library", + "@org_golang_google_protobuf//types/dynamicpb:go_default_library", + "@org_golang_google_protobuf//types/known/anypb:go_default_library", + "@org_golang_google_protobuf//types/known/durationpb:go_default_library", + "@org_golang_google_protobuf//types/known/emptypb:go_default_library", + "@org_golang_google_protobuf//types/known/structpb:go_default_library", + "@org_golang_google_protobuf//types/known/timestamppb:go_default_library", + "@org_golang_google_protobuf//types/known/wrapperspb:go_default_library", ], ) @@ -33,12 +34,17 @@ go_test( name = "go_default_test", srcs = [ "file_test.go", + "pb_test.go", "type_test.go", ], size = "small", embed = [":go_default_library"], deps = [ + "//checker/decls:go_default_library", "//test/proto2pb:test_all_types_go_proto", "//test/proto3pb:test_all_types_go_proto", + "@org_golang_google_protobuf//reflect/protodesc:go_default_library", + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//types/descriptorpb:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/common/types/pb/checked.go b/vendor/github.com/google/cel-go/common/types/pb/checked.go index 375372f1f..312a6a072 100644 --- a/vendor/github.com/google/cel-go/common/types/pb/checked.go +++ b/vendor/github.com/google/cel-go/common/types/pb/checked.go @@ -15,30 +15,31 @@ package pb import ( - descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" - emptypb "github.com/golang/protobuf/ptypes/empty" - structpb "github.com/golang/protobuf/ptypes/struct" + "google.golang.org/protobuf/reflect/protoreflect" + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + emptypb "google.golang.org/protobuf/types/known/emptypb" + structpb "google.golang.org/protobuf/types/known/structpb" ) var ( // CheckedPrimitives map from proto field descriptor type to expr.Type. - CheckedPrimitives = map[descpb.FieldDescriptorProto_Type]*exprpb.Type{ - descpb.FieldDescriptorProto_TYPE_BOOL: checkedBool, - descpb.FieldDescriptorProto_TYPE_BYTES: checkedBytes, - descpb.FieldDescriptorProto_TYPE_DOUBLE: checkedDouble, - descpb.FieldDescriptorProto_TYPE_FLOAT: checkedDouble, - descpb.FieldDescriptorProto_TYPE_INT32: checkedInt, - descpb.FieldDescriptorProto_TYPE_INT64: checkedInt, - descpb.FieldDescriptorProto_TYPE_SINT32: checkedInt, - descpb.FieldDescriptorProto_TYPE_SINT64: checkedInt, - descpb.FieldDescriptorProto_TYPE_UINT32: checkedUint, - descpb.FieldDescriptorProto_TYPE_UINT64: checkedUint, - descpb.FieldDescriptorProto_TYPE_FIXED32: checkedUint, - descpb.FieldDescriptorProto_TYPE_FIXED64: checkedUint, - descpb.FieldDescriptorProto_TYPE_SFIXED32: checkedInt, - descpb.FieldDescriptorProto_TYPE_SFIXED64: checkedInt, - descpb.FieldDescriptorProto_TYPE_STRING: checkedString} + CheckedPrimitives = map[protoreflect.Kind]*exprpb.Type{ + protoreflect.BoolKind: checkedBool, + protoreflect.BytesKind: checkedBytes, + protoreflect.DoubleKind: checkedDouble, + protoreflect.FloatKind: checkedDouble, + protoreflect.Int32Kind: checkedInt, + protoreflect.Int64Kind: checkedInt, + protoreflect.Sint32Kind: checkedInt, + protoreflect.Sint64Kind: checkedInt, + protoreflect.Uint32Kind: checkedUint, + protoreflect.Uint64Kind: checkedUint, + protoreflect.Fixed32Kind: checkedUint, + protoreflect.Fixed64Kind: checkedUint, + protoreflect.Sfixed32Kind: checkedInt, + protoreflect.Sfixed64Kind: checkedInt, + protoreflect.StringKind: checkedString} // CheckedWellKnowns map from qualified proto type name to expr.Type for // well-known proto types. diff --git a/vendor/github.com/google/cel-go/common/types/pb/enum.go b/vendor/github.com/google/cel-go/common/types/pb/enum.go index be0703957..4a26b5c7c 100644 --- a/vendor/github.com/google/cel-go/common/types/pb/enum.go +++ b/vendor/github.com/google/cel-go/common/types/pb/enum.go @@ -15,13 +15,12 @@ package pb import ( - descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" + "google.golang.org/protobuf/reflect/protoreflect" ) // NewEnumValueDescription produces an enum value description with the fully qualified enum value // name and the enum value descriptor. -func NewEnumValueDescription(name string, - desc *descpb.EnumValueDescriptorProto) *EnumValueDescription { +func NewEnumValueDescription(name string, desc protoreflect.EnumValueDescriptor) *EnumValueDescription { return &EnumValueDescription{ enumValueName: name, desc: desc, @@ -31,7 +30,7 @@ func NewEnumValueDescription(name string, // EnumValueDescription maps a fully-qualified enum value name to its numeric value. type EnumValueDescription struct { enumValueName string - desc *descpb.EnumValueDescriptorProto + desc protoreflect.EnumValueDescriptor } // Name returns the fully-qualified identifier name for the enum value. @@ -41,5 +40,5 @@ func (ed *EnumValueDescription) Name() string { // Value returns the (numeric) value of the enum. func (ed *EnumValueDescription) Value() int32 { - return ed.desc.GetNumber() + return int32(ed.desc.Number()) } diff --git a/vendor/github.com/google/cel-go/common/types/pb/file.go b/vendor/github.com/google/cel-go/common/types/pb/file.go index 030cbc0ca..0bcade75f 100644 --- a/vendor/github.com/google/cel-go/common/types/pb/file.go +++ b/vendor/github.com/google/cel-go/common/types/pb/file.go @@ -17,13 +17,12 @@ package pb import ( "fmt" - descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" + "google.golang.org/protobuf/reflect/protoreflect" ) // NewFileDescription returns a FileDescription instance with a complete listing of all the message // types and enum values declared within any scope in the file. -func NewFileDescription(fileDesc *descpb.FileDescriptorProto, pbdb *Db) *FileDescription { - isProto3 := fileDesc.GetSyntax() == "proto3" +func NewFileDescription(fileDesc protoreflect.FileDescriptor, pbdb *Db) *FileDescription { metadata := collectFileMetadata(fileDesc) enums := make(map[string]*EnumValueDescription) for name, enumVal := range metadata.enumValues { @@ -31,7 +30,7 @@ func NewFileDescription(fileDesc *descpb.FileDescriptorProto, pbdb *Db) *FileDes } types := make(map[string]*TypeDescription) for name, msgType := range metadata.msgTypes { - types[name] = NewTypeDescription(name, msgType, isProto3, pbdb.DescribeType) + types[name] = NewTypeDescription(name, msgType) } return &FileDescription{ types: types, @@ -47,11 +46,9 @@ type FileDescription struct { // GetEnumDescription returns an EnumDescription for a qualified enum value // name declared within the .proto file. -func (fd *FileDescription) GetEnumDescription(enumName string) (*EnumValueDescription, error) { - if ed, found := fd.enums[sanitizeProtoName(enumName)]; found { - return ed, nil - } - return nil, fmt.Errorf("no such enum value '%s'", enumName) +func (fd *FileDescription) GetEnumDescription(enumName string) (*EnumValueDescription, bool) { + ed, found := fd.enums[sanitizeProtoName(enumName)] + return ed, found } // GetEnumNames returns the string names of all enum values in the file. @@ -65,13 +62,11 @@ func (fd *FileDescription) GetEnumNames() []string { return enumNames } -// GetTypeDescription returns a TypeDescription for a qualified type name +// GetTypeDescription returns a TypeDescription for a qualified protobuf message type name // declared within the .proto file. -func (fd *FileDescription) GetTypeDescription(typeName string) (*TypeDescription, error) { - if td, found := fd.types[sanitizeProtoName(typeName)]; found { - return td, nil - } - return nil, fmt.Errorf("no such type '%s'", typeName) +func (fd *FileDescription) GetTypeDescription(typeName string) (*TypeDescription, bool) { + td, found := fd.types[sanitizeProtoName(typeName)] + return td, found } // GetTypeNames returns the list of all type names contained within the file. @@ -96,56 +91,51 @@ func sanitizeProtoName(name string) string { // fileMetadata is a flattened view of message types and enum values within a file descriptor. type fileMetadata struct { // msgTypes maps from fully-qualified message name to descriptor. - msgTypes map[string]*descpb.DescriptorProto + msgTypes map[string]protoreflect.MessageDescriptor // enumValues maps from fully-qualified enum value to enum value descriptor. - enumValues map[string]*descpb.EnumValueDescriptorProto + enumValues map[string]protoreflect.EnumValueDescriptor + // TODO: support enum type definitions for use in future type-check enhancements. } // collectFileMetadata traverses the proto file object graph to collect message types and enum // values and index them by their fully qualified names. -func collectFileMetadata(fileDesc *descpb.FileDescriptorProto) *fileMetadata { - pkg := fileDesc.GetPackage() - msgTypes := make(map[string]*descpb.DescriptorProto) - collectMsgTypes(pkg, fileDesc.GetMessageType(), msgTypes) - enumValues := make(map[string]*descpb.EnumValueDescriptorProto) - collectEnumValues(pkg, fileDesc.GetEnumType(), enumValues) - for container, msgType := range msgTypes { - nestedEnums := msgType.GetEnumType() - if len(nestedEnums) == 0 { - continue - } - collectEnumValues(container, nestedEnums, enumValues) - } +func collectFileMetadata(fileDesc protoreflect.FileDescriptor) *fileMetadata { + msgTypes := make(map[string]protoreflect.MessageDescriptor) + enumValues := make(map[string]protoreflect.EnumValueDescriptor) + collectMsgTypes(fileDesc.Messages(), msgTypes, enumValues) + collectEnumValues(fileDesc.Enums(), enumValues) return &fileMetadata{ msgTypes: msgTypes, enumValues: enumValues, } } -// collectMsgTypes recursively collects messages and nested messages into a map of fully -// qualified message names to message descriptors. -func collectMsgTypes(container string, - msgTypes []*descpb.DescriptorProto, - msgTypeMap map[string]*descpb.DescriptorProto) { - for _, msgType := range msgTypes { - msgName := fmt.Sprintf("%s.%s", container, msgType.GetName()) - msgTypeMap[msgName] = msgType - nestedTypes := msgType.GetNestedType() - if len(nestedTypes) == 0 { - continue +// collectMsgTypes recursively collects messages, nested messages, and nested enums into a map of +// fully qualified protobuf names to descriptors. +func collectMsgTypes(msgTypes protoreflect.MessageDescriptors, msgTypeMap map[string]protoreflect.MessageDescriptor, enumValueMap map[string]protoreflect.EnumValueDescriptor) { + for i := 0; i < msgTypes.Len(); i++ { + msgType := msgTypes.Get(i) + msgTypeMap[string(msgType.FullName())] = msgType + nestedMsgTypes := msgType.Messages() + if nestedMsgTypes.Len() != 0 { + collectMsgTypes(nestedMsgTypes, msgTypeMap, enumValueMap) + } + nestedEnumTypes := msgType.Enums() + if nestedEnumTypes.Len() != 0 { + collectEnumValues(nestedEnumTypes, enumValueMap) } - collectMsgTypes(msgName, nestedTypes, msgTypeMap) } } // collectEnumValues accumulates the enum values within an enum declaration. -func collectEnumValues(container string, - enumTypes []*descpb.EnumDescriptorProto, - enumValueMap map[string]*descpb.EnumValueDescriptorProto) { - for _, enumType := range enumTypes { - for _, enumValue := range enumType.GetValue() { - name := fmt.Sprintf("%s.%s.%s", container, enumType.GetName(), enumValue.GetName()) - enumValueMap[name] = enumValue +func collectEnumValues(enumTypes protoreflect.EnumDescriptors, enumValueMap map[string]protoreflect.EnumValueDescriptor) { + for i := 0; i < enumTypes.Len(); i++ { + enumType := enumTypes.Get(i) + enumTypeValues := enumType.Values() + for j := 0; j < enumTypeValues.Len(); j++ { + enumValue := enumTypeValues.Get(j) + enumValueName := fmt.Sprintf("%s.%s", string(enumType.FullName()), string(enumValue.Name())) + enumValueMap[enumValueName] = enumValue } } } diff --git a/vendor/github.com/google/cel-go/common/types/pb/pb.go b/vendor/github.com/google/cel-go/common/types/pb/pb.go index 656d76773..d02fbe0c2 100644 --- a/vendor/github.com/google/cel-go/common/types/pb/pb.go +++ b/vendor/github.com/google/cel-go/common/types/pb/pb.go @@ -17,31 +17,34 @@ package pb import ( - "bytes" - "compress/gzip" - "fmt" - "io/ioutil" - - "github.com/golang/protobuf/descriptor" - "github.com/golang/protobuf/proto" - - descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" - anypb "github.com/golang/protobuf/ptypes/any" - durpb "github.com/golang/protobuf/ptypes/duration" - structpb "github.com/golang/protobuf/ptypes/struct" - tspb "github.com/golang/protobuf/ptypes/timestamp" - wrapperspb "github.com/golang/protobuf/ptypes/wrappers" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + + anypb "google.golang.org/protobuf/types/known/anypb" + durpb "google.golang.org/protobuf/types/known/durationpb" + emptypb "google.golang.org/protobuf/types/known/emptypb" + structpb "google.golang.org/protobuf/types/known/structpb" + tspb "google.golang.org/protobuf/types/known/timestamppb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" ) // Db maps from file / message / enum name to file description. +// +// Each Db is isolated from each other, and while information about protobuf descriptors may be +// fetched from the global protobuf registry, no descriptors are added to this registry, else +// the isolation guarantees of the Db object would be violated. type Db struct { revFileDescriptorMap map[string]*FileDescription + // files contains the deduped set of FileDescriptions whose types are contained in the pb.Db. + files []*FileDescription } var ( // DefaultDb used at evaluation time or unless overridden at check time. DefaultDb = &Db{ revFileDescriptorMap: make(map[string]*FileDescription), + files: []*FileDescription{}, } ) @@ -49,6 +52,7 @@ var ( func NewDb() *Db { pbdb := &Db{ revFileDescriptorMap: make(map[string]*FileDescription), + files: []*FileDescription{}, } // The FileDescription objects in the default db contain lazily initialized TypeDescription // values which may point to the state contained in the DefaultDb irrespective of this shallow @@ -58,6 +62,7 @@ func NewDb() *Db { for k, v := range DefaultDb.revFileDescriptorMap { pbdb.revFileDescriptorMap[k] = v } + pbdb.files = append(pbdb.files, DefaultDb.files...) return pbdb } @@ -67,16 +72,44 @@ func (pbdb *Db) Copy() *Db { for k, v := range pbdb.revFileDescriptorMap { copy.revFileDescriptorMap[k] = v } + for _, f := range pbdb.files { + hasFile := false + for _, f2 := range copy.files { + if f2 == f { + hasFile = true + } + } + if !hasFile { + copy.files = append(copy.files, f) + } + } return copy } -// RegisterDescriptor produces a `FileDescription` from a `FileDescriptorProto` and registers the +// FileDescriptions returns the set of file descriptions associated with this db. +func (pbdb *Db) FileDescriptions() []*FileDescription { + return pbdb.files +} + +// RegisterDescriptor produces a `FileDescription` from a `FileDescriptor` and registers the // message and enum types into the `pb.Db`. -func (pbdb *Db) RegisterDescriptor(fileDesc *descpb.FileDescriptorProto) (*FileDescription, error) { - fd, found := pbdb.revFileDescriptorMap[fileDesc.GetName()] +func (pbdb *Db) RegisterDescriptor(fileDesc protoreflect.FileDescriptor) (*FileDescription, error) { + fd, found := pbdb.revFileDescriptorMap[fileDesc.Path()] if found { return fd, nil } + // Make sure to search the global registry to see if a protoreflect.FileDescriptor for + // the file specified has been linked into the binary. If so, use the copy of the descriptor + // from the global cache. + // + // Note: Proto reflection relies on descriptor values being object equal rather than object + // equivalence. This choice means that a FieldDescriptor generated from a FileDescriptorProto + // will be incompatible with the FieldDescriptor in the global registry and any message created + // from that global registry. + globalFD, err := protoregistry.GlobalFiles.FindFileByPath(fileDesc.Path()) + if err == nil { + fileDesc = globalFD + } fd = NewFileDescription(fileDesc, pbdb) for _, enumValName := range fd.GetEnumNames() { pbdb.revFileDescriptorMap[enumValName] = fd @@ -84,105 +117,67 @@ func (pbdb *Db) RegisterDescriptor(fileDesc *descpb.FileDescriptorProto) (*FileD for _, msgTypeName := range fd.GetTypeNames() { pbdb.revFileDescriptorMap[msgTypeName] = fd } - pbdb.revFileDescriptorMap[fileDesc.GetName()] = fd + pbdb.revFileDescriptorMap[fileDesc.Path()] = fd // Return the specific file descriptor registered. + pbdb.files = append(pbdb.files, fd) return fd, nil } // RegisterMessage produces a `FileDescription` from a `message` and registers the message and all // other definitions within the message file into the `pb.Db`. func (pbdb *Db) RegisterMessage(message proto.Message) (*FileDescription, error) { - typeName := sanitizeProtoName(proto.MessageName(message)) + msgDesc := message.ProtoReflect().Descriptor() + msgName := msgDesc.FullName() + typeName := sanitizeProtoName(string(msgName)) if fd, found := pbdb.revFileDescriptorMap[typeName]; found { return fd, nil } - fileDesc, _ := descriptor.ForMessage(message.(descriptor.Message)) - return pbdb.RegisterDescriptor(fileDesc) -} - -// DescribeFile gets the `FileDescription` for the `message` type if it exists in the `pb.Db`. -func (pbdb *Db) DescribeFile(message proto.Message) (*FileDescription, error) { - typeName := sanitizeProtoName(proto.MessageName(message)) - if fd, found := pbdb.revFileDescriptorMap[typeName]; found { - return fd, nil - } - return nil, fmt.Errorf("unrecognized proto type name '%s'", typeName) + return pbdb.RegisterDescriptor(msgDesc.ParentFile()) } // DescribeEnum takes a qualified enum name and returns an `EnumDescription` if it exists in the // `pb.Db`. -func (pbdb *Db) DescribeEnum(enumName string) (*EnumValueDescription, error) { +func (pbdb *Db) DescribeEnum(enumName string) (*EnumValueDescription, bool) { enumName = sanitizeProtoName(enumName) if fd, found := pbdb.revFileDescriptorMap[enumName]; found { return fd.GetEnumDescription(enumName) } - return nil, fmt.Errorf("unrecognized enum '%s'", enumName) + return nil, false } // DescribeType returns a `TypeDescription` for the `typeName` if it exists in the `pb.Db`. -func (pbdb *Db) DescribeType(typeName string) (*TypeDescription, error) { +func (pbdb *Db) DescribeType(typeName string) (*TypeDescription, bool) { typeName = sanitizeProtoName(typeName) if fd, found := pbdb.revFileDescriptorMap[typeName]; found { return fd.GetTypeDescription(typeName) } - return nil, fmt.Errorf("unrecognized type '%s'", typeName) + return nil, false } // CollectFileDescriptorSet builds a file descriptor set associated with the file where the input // message is declared. -func CollectFileDescriptorSet(message proto.Message) (*descpb.FileDescriptorSet, error) { - fdMap := map[string]*descpb.FileDescriptorProto{} - fd, _ := descriptor.ForMessage(message.(descriptor.Message)) - fdMap[fd.GetName()] = fd +func CollectFileDescriptorSet(message proto.Message) map[string]protoreflect.FileDescriptor { + fdMap := map[string]protoreflect.FileDescriptor{} + parentFile := message.ProtoReflect().Descriptor().ParentFile() + fdMap[parentFile.Path()] = parentFile // Initialize list of dependencies - fileDeps := fd.GetDependency() - deps := make([]string, len(fileDeps)) - copy(deps, fileDeps) + deps := make([]protoreflect.FileImport, parentFile.Imports().Len()) + for i := 0; i < parentFile.Imports().Len(); i++ { + deps[i] = parentFile.Imports().Get(i) + } // Expand list for new dependencies for i := 0; i < len(deps); i++ { dep := deps[i] - if _, found := fdMap[dep]; found { + if _, found := fdMap[dep.Path()]; found { continue } - depDesc, err := readFileDescriptor(dep) - if err != nil { - return nil, err + fdMap[dep.Path()] = dep.FileDescriptor + for j := 0; j < dep.FileDescriptor.Imports().Len(); j++ { + deps = append(deps, dep.FileDescriptor.Imports().Get(j)) } - fdMap[dep] = depDesc - deps = append(deps, depDesc.GetDependency()...) - } - - fds := make([]*descpb.FileDescriptorProto, len(fdMap), len(fdMap)) - i := 0 - for _, fd = range fdMap { - fds[i] = fd - i++ - } - return &descpb.FileDescriptorSet{ - File: fds, - }, nil -} - -// readFileDescriptor will read the gzipped file descriptor for a given proto file and return the -// hydrated FileDescriptorProto. -// -// If the file name is not found or there is an error during deserialization an error is returned. -func readFileDescriptor(protoFileName string) (*descpb.FileDescriptorProto, error) { - gzipped := proto.FileDescriptor(protoFileName) - r, err := gzip.NewReader(bytes.NewReader(gzipped)) - if err != nil { - return nil, fmt.Errorf("bad gzipped descriptor: %v", err) } - unzipped, err := ioutil.ReadAll(r) - if err != nil { - return nil, fmt.Errorf("bad gzipped descriptor: %v", err) - } - fd := &descpb.FileDescriptorProto{} - if err := proto.Unmarshal(unzipped, fd); err != nil { - return nil, fmt.Errorf("bad gzipped descriptor: %v", err) - } - return fd, nil + return fdMap } func init() { @@ -194,6 +189,7 @@ func init() { // where the message is declared. DefaultDb.RegisterMessage(&anypb.Any{}) DefaultDb.RegisterMessage(&durpb.Duration{}) + DefaultDb.RegisterMessage(&emptypb.Empty{}) DefaultDb.RegisterMessage(&tspb.Timestamp{}) DefaultDb.RegisterMessage(&structpb.Value{}) DefaultDb.RegisterMessage(&wrapperspb.BoolValue{}) diff --git a/vendor/github.com/google/cel-go/common/types/pb/type.go b/vendor/github.com/google/cel-go/common/types/pb/type.go index cdf6b864b..c5060a468 100644 --- a/vendor/github.com/google/cel-go/common/types/pb/type.go +++ b/vendor/github.com/google/cel-go/common/types/pb/type.go @@ -17,280 +17,166 @@ package pb import ( "fmt" "reflect" - "strings" - "sync" - "github.com/golang/protobuf/proto" - descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" - structpb "github.com/golang/protobuf/ptypes/struct" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + dynamicpb "google.golang.org/protobuf/types/dynamicpb" + anypb "google.golang.org/protobuf/types/known/anypb" + dpb "google.golang.org/protobuf/types/known/durationpb" + structpb "google.golang.org/protobuf/types/known/structpb" + tpb "google.golang.org/protobuf/types/known/timestamppb" + "google.golang.org/protobuf/types/known/wrapperspb" ) +// description is a private interface used to make it convenient to perform type unwrapping at +// the TypeDescription or FieldDescription level. +type description interface { + // Zero returns an empty immutable protobuf message when the description is a protobuf message + // type. + Zero() proto.Message +} + // NewTypeDescription produces a TypeDescription value for the fully-qualified proto type name // with a given descriptor. -// -// The type description creation method also expects the type to be marked clearly as a proto2 or -// proto3 type, and accepts a typeResolver reference for resolving field TypeDescription during -// lazily initialization of the type which is done atomically. -func NewTypeDescription(typeName string, desc *descpb.DescriptorProto, - isProto3 bool, resolveType typeResolver) *TypeDescription { +func NewTypeDescription(typeName string, desc protoreflect.MessageDescriptor) *TypeDescription { + msgType := dynamicpb.NewMessageType(desc) + msgZero := dynamicpb.NewMessage(desc) + fieldMap := map[string]*FieldDescription{} + fields := desc.Fields() + for i := 0; i < fields.Len(); i++ { + f := fields.Get(i) + fieldMap[string(f.Name())] = NewFieldDescription(f) + } return &TypeDescription{ typeName: typeName, - isProto3: isProto3, desc: desc, - resolveType: resolveType, + msgType: msgType, + fieldMap: fieldMap, + reflectType: reflectTypeOf(msgZero), + zeroMsg: zeroValueOf(msgZero), } } // TypeDescription is a collection of type metadata relevant to expression // checking and evaluation. type TypeDescription struct { - typeName string - isProto3 bool - desc *descpb.DescriptorProto - - // resolveType is used to lookup field types during type initialization. - // The resolver may point to shared state; however, this state is guaranteed to be computed at - // most one time. - resolveType typeResolver - init sync.Once - metadata *typeMetadata + typeName string + desc protoreflect.MessageDescriptor + msgType protoreflect.MessageType + fieldMap map[string]*FieldDescription + reflectType reflect.Type + zeroMsg proto.Message } -// typeResolver accepts a type name and returns a TypeDescription. -// The typeResolver is used to resolve field types during lazily initialization of the type -// description metadata. -type typeResolver func(typeName string) (*TypeDescription, error) - -type typeMetadata struct { - fields map[string]*FieldDescription // fields by name (proto) - fieldIndices map[int][]*FieldDescription // fields by Go struct idx - fieldProperties *proto.StructProperties - reflectedType *reflect.Type - reflectedVal *reflect.Value - emptyVal interface{} +// FieldMap returns a string field name to FieldDescription map. +func (td *TypeDescription) FieldMap() map[string]*FieldDescription { + return td.fieldMap } -// FieldCount returns the number of fields declared within the type. -func (td *TypeDescription) FieldCount() int { - // The number of keys in the field indices map corresponds to the number - // of fields on the proto message. - return len(td.getMetadata().fieldIndices) +// FieldByName returns (FieldDescription, true) if the field name is declared within the type. +func (td *TypeDescription) FieldByName(name string) (*FieldDescription, bool) { + fd, found := td.fieldMap[name] + if !found { + return nil, false + } + return fd, true } -// FieldByName returns the FieldDescription associated with a field name. -func (td *TypeDescription) FieldByName(name string) (*FieldDescription, bool) { - fd, found := td.getMetadata().fields[name] - return fd, found +// MaybeUnwrap accepts a proto message as input and unwraps it to a primitive CEL type if possible. +// +// This method returns the unwrapped value and 'true', else the original value and 'false'. +func (td *TypeDescription) MaybeUnwrap(msg proto.Message) (interface{}, bool) { + return unwrap(td, msg) } -// Name of the type. +// Name returns the fully-qualified name of the type. func (td *TypeDescription) Name() string { - return td.typeName + return string(td.desc.FullName()) } -// ReflectType returns the reflected struct type of the generated proto struct. -func (td *TypeDescription) ReflectType() reflect.Type { - if td.getMetadata().reflectedType == nil { - return nil - } - return *td.getMetadata().reflectedType +// New returns a mutable proto message +func (td *TypeDescription) New() protoreflect.Message { + return td.msgType.New() } -// DefaultValue returns an empty instance of the proto message associated with the type, -// or nil for wrapper types. -func (td *TypeDescription) DefaultValue() proto.Message { - val := td.getMetadata().emptyVal - if val == nil { - return nil - } - return val.(proto.Message) +// ReflectType returns the Golang reflect.Type for this type. +func (td *TypeDescription) ReflectType() reflect.Type { + return td.reflectType } -// getMetadata computes the type field metadata used for determining field types and default -// values. The call to makeMetadata within this method is guaranteed to be invoked exactly -// once. -func (td *TypeDescription) getMetadata() *typeMetadata { - td.init.Do(func() { - td.metadata = td.makeMetadata() - }) - return td.metadata +// Zero returns the zero proto.Message value for this type. +func (td *TypeDescription) Zero() proto.Message { + return td.zeroMsg } -func (td *TypeDescription) makeMetadata() *typeMetadata { - refType := proto.MessageType(td.typeName) - meta := &typeMetadata{ - fields: make(map[string]*FieldDescription), - fieldIndices: make(map[int][]*FieldDescription), - } - if refType != nil { - // Set the reflected type if non-nil. - meta.reflectedType = &refType - - // Unwrap the pointer reference for the sake of later checks. - elemType := refType - if elemType.Kind() == reflect.Ptr { - elemType = elemType.Elem() - } - if elemType.Kind() == reflect.Struct { - meta.fieldProperties = proto.GetProperties(elemType) - } - refVal := reflect.New(elemType) - meta.reflectedVal = &refVal - if refVal.CanInterface() { - meta.emptyVal = refVal.Interface() - } else { - meta.emptyVal = reflect.Zero(elemType).Interface() - } - } - - fieldIndexMap := make(map[string]int) - fieldDescMap := make(map[string]*descpb.FieldDescriptorProto) - for i, f := range td.desc.Field { - fieldDescMap[f.GetName()] = f - fieldIndexMap[f.GetName()] = i - } - if meta.fieldProperties != nil { - // This is a proper message type. - for i, prop := range meta.fieldProperties.Prop { - if strings.HasPrefix(prop.OrigName, "XXX_") { - // Book-keeping fields generated by protoc start with XXX_ - continue +// NewFieldDescription creates a new field description from a protoreflect.FieldDescriptor. +func NewFieldDescription(fieldDesc protoreflect.FieldDescriptor) *FieldDescription { + var reflectType reflect.Type + var zeroMsg proto.Message + switch fieldDesc.Kind() { + case protoreflect.EnumKind: + reflectType = reflectTypeOf(protoreflect.EnumNumber(0)) + case protoreflect.MessageKind: + zeroMsg = dynamicpb.NewMessage(fieldDesc.Message()) + reflectType = reflectTypeOf(zeroMsg) + default: + reflectType = reflectTypeOf(fieldDesc.Default().Interface()) + if fieldDesc.IsList() { + parentMsg := dynamicpb.NewMessage(fieldDesc.ContainingMessage()) + listField := parentMsg.NewField(fieldDesc).List() + elem := listField.NewElement().Interface() + switch elemType := elem.(type) { + case protoreflect.Message: + elem = elemType.Interface() } - desc := fieldDescMap[prop.OrigName] - fd := td.newFieldDesc(*meta.reflectedType, desc, prop, i) - meta.fields[prop.OrigName] = fd - meta.fieldIndices[i] = append(meta.fieldIndices[i], fd) - } - for _, oneofProp := range meta.fieldProperties.OneofTypes { - desc := fieldDescMap[oneofProp.Prop.OrigName] - fd := td.newOneofFieldDesc(*meta.reflectedType, desc, oneofProp, oneofProp.Field) - meta.fields[oneofProp.Prop.OrigName] = fd - meta.fieldIndices[oneofProp.Field] = append(meta.fieldIndices[oneofProp.Field], fd) + reflectType = reflectTypeOf(elem) } - } else { - for fieldName, desc := range fieldDescMap { - fd := td.newMapFieldDesc(desc) - meta.fields[fieldName] = fd - index := fieldIndexMap[fieldName] - meta.fieldIndices[index] = append(meta.fieldIndices[index], fd) - } - } - return meta -} - -// Create a new field description for the proto field descriptor associated with the given type. -// The field properties should never not be found when performing reflection on the type unless -// there are fundamental changes to the backing proto library behavior. -func (td *TypeDescription) newFieldDesc( - tdType reflect.Type, - desc *descpb.FieldDescriptorProto, - prop *proto.Properties, - index int) *FieldDescription { - getterName := fmt.Sprintf("Get%s", prop.Name) - getter, _ := tdType.MethodByName(getterName) - var field *reflect.StructField - if tdType.Kind() == reflect.Ptr { - tdType = tdType.Elem() } - f, found := tdType.FieldByName(prop.Name) - if found { - field = &f - } - fieldDesc := &FieldDescription{ - desc: desc, - index: index, - getter: getter.Func, - field: field, - prop: prop, - isProto3: td.isProto3, - isWrapper: isWrapperType(desc), + // Ensure the list type is appropriately reflected as a Go-native list. + if fieldDesc.IsList() { + reflectType = reflect.SliceOf(reflectType) } - if desc.GetType() == descpb.FieldDescriptorProto_TYPE_MESSAGE { - typeName := sanitizeProtoName(desc.GetTypeName()) - fieldType, _ := td.resolveType(typeName) - fieldDesc.td = fieldType - return fieldDesc + var keyType, valType *FieldDescription + if fieldDesc.IsMap() { + keyType = NewFieldDescription(fieldDesc.MapKey()) + valType = NewFieldDescription(fieldDesc.MapValue()) } - return fieldDesc -} - -func (td *TypeDescription) newOneofFieldDesc( - tdType reflect.Type, - desc *descpb.FieldDescriptorProto, - oneofProp *proto.OneofProperties, - index int) *FieldDescription { - fieldDesc := td.newFieldDesc(tdType, desc, oneofProp.Prop, index) - fieldDesc.oneofProp = oneofProp - return fieldDesc -} - -func (td *TypeDescription) newMapFieldDesc(desc *descpb.FieldDescriptorProto) *FieldDescription { return &FieldDescription{ - desc: desc, - index: int(desc.GetNumber()), - isProto3: td.isProto3, + desc: fieldDesc, + KeyType: keyType, + ValueType: valType, + reflectType: reflectType, + zeroMsg: zeroValueOf(zeroMsg), } } -func isWrapperType(desc *descpb.FieldDescriptorProto) bool { - if desc.GetType() != descpb.FieldDescriptorProto_TYPE_MESSAGE { - return false - } - switch sanitizeProtoName(desc.GetTypeName()) { - case "google.protobuf.BoolValue", - "google.protobuf.BytesValue", - "google.protobuf.DoubleValue", - "google.protobuf.FloatValue", - "google.protobuf.Int32Value", - "google.protobuf.Int64Value", - "google.protobuf.StringValue", - "google.protobuf.UInt32Value", - "google.protobuf.UInt64Value": - return true - } - return false -} - // FieldDescription holds metadata related to fields declared within a type. type FieldDescription struct { - // getter is the reflected accessor method that obtains the field value. - getter reflect.Value - // field is the field location in a refValue - // The field will be not found for oneofs, but this is accounted for - // by checking the 'desc' value which provides this information. - field *reflect.StructField - // isProto3 indicates whether the field is defined in a proto3 syntax. - isProto3 bool - // isWrapper indicates whether the field is a wrapper type. - isWrapper bool - - // td is the type description for message typed fields. - td *TypeDescription - - // proto descriptor data. - desc *descpb.FieldDescriptorProto - index int - prop *proto.Properties - oneofProp *proto.OneofProperties + // KeyType holds the key FieldDescription for map fields. + KeyType *FieldDescription + // ValueType holds the value FieldDescription for map fields. + ValueType *FieldDescription + + desc protoreflect.FieldDescriptor + reflectType reflect.Type + zeroMsg proto.Message } // CheckedType returns the type-definition used at type-check time. func (fd *FieldDescription) CheckedType() *exprpb.Type { - if fd.IsMap() { - // Get the FieldDescriptors for the type arranged by their index within the - // generated Go struct. - fieldIndices := fd.getFieldIndicies() - // Map keys and values are represented as repeated entries in a list. - key := fieldIndices[0][0] - val := fieldIndices[1][0] + if fd.desc.IsMap() { return &exprpb.Type{ TypeKind: &exprpb.Type_MapType_{ MapType: &exprpb.Type_MapType{ - KeyType: key.typeDefToType(), - ValueType: val.typeDefToType()}}} + KeyType: fd.KeyType.typeDefToType(), + ValueType: fd.ValueType.typeDefToType(), + }, + }, + } } - if fd.IsRepeated() { + if fd.desc.IsList() { return &exprpb.Type{ TypeKind: &exprpb.Type_ListType_{ ListType: &exprpb.Type_ListType{ @@ -299,203 +185,156 @@ func (fd *FieldDescription) CheckedType() *exprpb.Type { return fd.typeDefToType() } +// Descriptor returns the protoreflect.FieldDescriptor for this type. +func (fd *FieldDescription) Descriptor() protoreflect.FieldDescriptor { + return fd.desc +} + // IsSet returns whether the field is set on the target value, per the proto presence conventions // of proto2 or proto3 accordingly. // -// The input target may either be a reflect.Value or Go struct type. +// This function implements the FieldType.IsSet function contract which can be used to operate on +// more than just protobuf field accesses; however, the target here must be a protobuf.Message. func (fd *FieldDescription) IsSet(target interface{}) bool { - t, ok := target.(reflect.Value) - if !ok { - t = reflect.ValueOf(target) - } - // For the case where the field is not a oneof, test whether the field is set on the target - // value assuming it is a struct. A field that is not set will be one of the following values: - // - nil for message and primitive typed fields in proto2 - // - nil for message typed fields in proto3 - // - empty for primitive typed fields in proto3 - if fd.field != nil && !fd.IsOneof() { - t = reflect.Indirect(t) - return isFieldSet(t.FieldByIndex(fd.field.Index)) - } - // Oneof fields must consider two pieces of information: - // - whether the oneof is set to any value at all - // - whether the field in the oneof is the same as the field under test. - // - // In go protobuf libraries, oneofs result in the creation of special oneof type messages - // which contain a reference to the actual field type. The creation of these special message - // types makes it possible to test for presence of primitive field values in proto3. - // - // The logic below performs a get on the oneof to obtain the field reference and then checks - // the type of the field reference against the known oneof type determined FieldDescription - // initialization. - if fd.IsOneof() { - t = reflect.Indirect(t) - oneof := t.Field(fd.Index()) - if !isFieldSet(oneof) { - return false + switch v := target.(type) { + case proto.Message: + pbRef := v.ProtoReflect() + pbDesc := pbRef.Descriptor() + if pbDesc == fd.desc.ContainingMessage() { + // When the target protobuf shares the same message descriptor instance as the field + // descriptor, use the cached field descriptor value. + return pbRef.Has(fd.desc) } - oneofVal := oneof.Interface() - oneofType := reflect.TypeOf(oneofVal) - return oneofType == fd.OneofType() + // Otherwise, fallback to a dynamic lookup of the field descriptor from the target + // instance as an attempt to use the cached field descriptor will result in a panic. + return pbRef.Has(pbDesc.Fields().ByName(protoreflect.Name(fd.Name()))) + default: + return false } - - // When the field is nil or when the field is a oneof, call the accessor - // associated with this field name to determine whether the field value is - // the default. - fieldVal := fd.getter.Call([]reflect.Value{t})[0] - return isFieldSet(fieldVal) } // GetFrom returns the accessor method associated with the field on the proto generated struct. // // If the field is not set, the proto default value is returned instead. // -// The input target may either be a reflect.Value or Go struct type. +// This function implements the FieldType.GetFrom function contract which can be used to operate +// on more than just protobuf field accesses; however, the target here must be a protobuf.Message. func (fd *FieldDescription) GetFrom(target interface{}) (interface{}, error) { - t, ok := target.(reflect.Value) + v, ok := target.(proto.Message) if !ok { - t = reflect.ValueOf(target) + return nil, fmt.Errorf("unsupported field selection target: (%T)%v", target, target) } - var fieldVal reflect.Value - // For proto3, prefer direct field access as the primitive types are simple values. - // For proto2, prefer the getter method to ensure that the primitive types are dereferenced - // to a value. - // If the getter method does not exist (as may be the case for gogo protogen sources), then - // prefer the direct field access. - if !fd.getter.IsValid() || (fd.isProto3 && fd.field != nil && !fd.IsOneof()) { - // The target object should always be a struct. - t = reflect.Indirect(t) - if t.Kind() != reflect.Struct { - return nil, fmt.Errorf("unsupported field selection target: %T", target) - } - fieldVal = t.FieldByIndex(fd.field.Index) + pbRef := v.ProtoReflect() + pbDesc := pbRef.Descriptor() + var fieldVal interface{} + if pbDesc == fd.desc.ContainingMessage() { + // When the target protobuf shares the same message descriptor instance as the field + // descriptor, use the cached field descriptor value. + fieldVal = pbRef.Get(fd.desc).Interface() } else { - // The accessor method must be used for proto2 in order to properly handle - // default values. - // Additionally, proto3 oneofs require the use of the accessor to get the proper value. - fieldVal = fd.getter.Call([]reflect.Value{t})[0] - } - // If the field is a non-repeated message, and it's not set, return its default value. - // Note, repeated fields should have default values of empty list or empty map, so the checks - // for whether to return a default proto message don't really apply. - if fd.IsMessage() && !fd.IsRepeated() && !isFieldSet(fieldVal) { - // Well known wrapper types default to null if not set. - if fd.IsWrapper() { - return structpb.NullValue_NULL_VALUE, nil - } - // Otherwise, return an empty message. - return fd.Type().DefaultValue(), nil + // Otherwise, fallback to a dynamic lookup of the field descriptor from the target + // instance as an attempt to use the cached field descriptor will result in a panic. + fieldVal = pbRef.Get(pbDesc.Fields().ByName(protoreflect.Name(fd.Name()))).Interface() } - // Otherwise, return the field value or the zero value for its type. - if fieldVal.CanInterface() { - return fieldVal.Interface(), nil + switch fv := fieldVal.(type) { + // Fast-path return for primitive types. + case bool, []byte, float32, float64, int32, int64, string, uint32, uint64, protoreflect.List: + return fv, nil + case protoreflect.EnumNumber: + return int64(fv), nil + case protoreflect.Map: + // Return a wrapper around the protobuf-reflected Map types which carries additional + // information about the key and value definitions of the map. + return &Map{Map: fv, KeyType: fd.KeyType, ValueType: fd.ValueType}, nil + case protoreflect.Message: + // Make sure to unwrap well-known protobuf types before returning. + unwrapped, _ := fd.MaybeUnwrapDynamic(fv) + return unwrapped, nil + default: + return fv, nil } - return reflect.Zero(fieldVal.Type()).Interface(), nil -} - -// Index returns the field index within a reflected value. -func (fd *FieldDescription) Index() int { - return fd.index } // IsEnum returns true if the field type refers to an enum value. func (fd *FieldDescription) IsEnum() bool { - return fd.desc.GetType() == descpb.FieldDescriptorProto_TYPE_ENUM + return fd.desc.Kind() == protoreflect.EnumKind } // IsMap returns true if the field is of map type. func (fd *FieldDescription) IsMap() bool { - if !fd.IsRepeated() || !fd.IsMessage() { - return false - } - if fd.td == nil { - return false - } - return fd.td.desc.GetOptions().GetMapEntry() + return fd.desc.IsMap() } // IsMessage returns true if the field is of message type. func (fd *FieldDescription) IsMessage() bool { - return fd.desc.GetType() == descpb.FieldDescriptorProto_TYPE_MESSAGE + return fd.desc.Kind() == protoreflect.MessageKind } // IsOneof returns true if the field is declared within a oneof block. func (fd *FieldDescription) IsOneof() bool { - if fd.desc != nil { - return fd.desc.OneofIndex != nil - } - return fd.oneofProp != nil + return fd.desc.ContainingOneof() != nil } -// IsRepeated returns true if the field is a repeated value. +// IsList returns true if the field is a repeated value. // // This method will also return true for map values, so check whether the // field is also a map. -func (fd *FieldDescription) IsRepeated() bool { - return *fd.desc.Label == descpb.FieldDescriptorProto_LABEL_REPEATED +func (fd *FieldDescription) IsList() bool { + return fd.desc.IsList() } -// IsWrapper returns true if the field type is a primitive wrapper type. -func (fd *FieldDescription) IsWrapper() bool { - return fd.isWrapper -} - -// OneofType returns the reflect.Type value of a oneof field. +// MaybeUnwrapDynamic takes the reflected protoreflect.Message and determines whether the +// value can be unwrapped to a more primitive CEL type. // -// Oneof field values are wrapped in a struct which contains one field whose -// value is a proto.Message. -func (fd *FieldDescription) OneofType() reflect.Type { - return fd.oneofProp.Type -} - -// OrigName returns the snake_case name of the field as it was declared within -// the proto. This is the same name format that is expected within expressions. -func (fd *FieldDescription) OrigName() string { - if fd.desc != nil && fd.desc.Name != nil { - return *fd.desc.Name - } - return fd.prop.OrigName +// This function returns the unwrapped value and 'true' on success, or the original value +// and 'false' otherwise. +func (fd *FieldDescription) MaybeUnwrapDynamic(msg protoreflect.Message) (interface{}, bool) { + return unwrapDynamic(fd, msg) } // Name returns the CamelCase name of the field within the proto-based struct. func (fd *FieldDescription) Name() string { - return fd.prop.Name + return string(fd.desc.Name()) } -// String returns a struct-like field definition string. -func (fd *FieldDescription) String() string { - return fmt.Sprintf("%s %s `oneof=%t`", - fd.TypeName(), fd.OrigName(), fd.IsOneof()) +// ReflectType returns the Golang reflect.Type for this field. +func (fd *FieldDescription) ReflectType() reflect.Type { + return fd.reflectType } -// Type returns the TypeDescription for the field. -func (fd *FieldDescription) Type() *TypeDescription { - return fd.td -} - -// TypeName returns the type name of the field. -func (fd *FieldDescription) TypeName() string { - return sanitizeProtoName(fd.desc.GetTypeName()) +// String returns the fully qualified name of the field within its type as well as whether the +// field occurs within a oneof. +func (fd *FieldDescription) String() string { + return fmt.Sprintf("%v.%s `oneof=%t`", fd.desc.ContainingMessage().FullName(), fd.Name(), fd.IsOneof()) } -func (fd *FieldDescription) getFieldIndicies() map[int][]*FieldDescription { - return fd.td.getMetadata().fieldIndices +// Zero returns the zero value for the protobuf message represented by this field. +// +// If the field is not a proto.Message type, the zero value is nil. +func (fd *FieldDescription) Zero() proto.Message { + return fd.zeroMsg } func (fd *FieldDescription) typeDefToType() *exprpb.Type { - if fd.IsMessage() { - if wk, found := CheckedWellKnowns[fd.TypeName()]; found { + if fd.desc.Kind() == protoreflect.MessageKind { + msgType := string(fd.desc.Message().FullName()) + if wk, found := CheckedWellKnowns[msgType]; found { return wk } - return checkedMessageType(fd.TypeName()) + return checkedMessageType(msgType) } - if fd.IsEnum() { + if fd.desc.Kind() == protoreflect.EnumKind { return checkedInt } - if p, found := CheckedPrimitives[fd.desc.GetType()]; found { - return p - } - return CheckedPrimitives[fd.desc.GetType()] + return CheckedPrimitives[fd.desc.Kind()] +} + +// Map wraps the protoreflect.Map object with a key and value FieldDescription for use in +// retrieving individual elements within CEL value data types. +type Map struct { + protoreflect.Map + KeyType *FieldDescription + ValueType *FieldDescription } func checkedMessageType(name string) *exprpb.Type { @@ -518,24 +357,176 @@ func checkedWrap(t *exprpb.Type) *exprpb.Type { TypeKind: &exprpb.Type_Wrapper{Wrapper: t.GetPrimitive()}} } -func isFieldSet(refVal reflect.Value) bool { - switch refVal.Kind() { - case reflect.Ptr: - // proto2 represents all non-repeated fields as pointers. - // proto3 represents message fields as pointers. - // if the value is non-nil, it is set. - return !refVal.IsNil() - case reflect.Array, reflect.Slice, reflect.Map: - // proto2 and proto3 repeated and map types are considered set if not empty. - return refVal.Len() > 0 - default: - // proto3 represents simple types by their zero value when they are not set. - // return whether the value is something other than the zero value. - zeroVal := reflect.Zero(refVal.Type()).Interface() - if refVal.CanInterface() { - val := refVal.Interface() - return !reflect.DeepEqual(val, zeroVal) +// unwrap unwraps the provided proto.Message value, potentially based on the description if the +// input message is a *dynamicpb.Message which obscures the typing information from Go. +// +// Returns the unwrapped value and 'true' if unwrapped, otherwise the input value and 'false'. +func unwrap(desc description, msg proto.Message) (interface{}, bool) { + switch v := msg.(type) { + case *anypb.Any: + dynMsg, err := v.UnmarshalNew() + if err != nil { + return v, false } - return false + return unwrapDynamic(desc, dynMsg.ProtoReflect()) + case *dynamicpb.Message: + return unwrapDynamic(desc, v) + case *dpb.Duration: + return v.AsDuration(), true + case *tpb.Timestamp: + return v.AsTime(), true + case *structpb.Value: + switch v.GetKind().(type) { + case *structpb.Value_BoolValue: + return v.GetBoolValue(), true + case *structpb.Value_ListValue: + return v.GetListValue(), true + case *structpb.Value_NullValue: + return structpb.NullValue_NULL_VALUE, true + case *structpb.Value_NumberValue: + return v.GetNumberValue(), true + case *structpb.Value_StringValue: + return v.GetStringValue(), true + case *structpb.Value_StructValue: + return v.GetStructValue(), true + default: + return structpb.NullValue_NULL_VALUE, true + } + case *wrapperspb.BoolValue: + return v.GetValue(), true + case *wrapperspb.BytesValue: + return v.GetValue(), true + case *wrapperspb.DoubleValue: + return v.GetValue(), true + case *wrapperspb.FloatValue: + return float64(v.GetValue()), true + case *wrapperspb.Int32Value: + return int64(v.GetValue()), true + case *wrapperspb.Int64Value: + return v.GetValue(), true + case *wrapperspb.StringValue: + return v.GetValue(), true + case *wrapperspb.UInt32Value: + return uint64(v.GetValue()), true + case *wrapperspb.UInt64Value: + return v.GetValue(), true } + return msg, false } + +// unwrapDynamic unwraps a reflected protobuf Message value. +// +// Returns the unwrapped value and 'true' if unwrapped, otherwise the input value and 'false'. +func unwrapDynamic(desc description, refMsg protoreflect.Message) (interface{}, bool) { + msg := refMsg.Interface() + if !refMsg.IsValid() { + msg = desc.Zero() + } + // In order to ensure that these wrapped types match the expectations of the CEL type system + // the dynamicpb.Message must be merged with an protobuf instance of the well-known type value. + typeName := string(refMsg.Descriptor().FullName()) + switch typeName { + case "google.protobuf.Any": + // Note, Any values require further unwrapping; however, this unwrapping may or may not + // be to a well-known type. If the unwrapped value is a well-known type it will be further + // unwrapped before being returned to the caller. Otherwise, the dynamic protobuf object + // represented by the Any will be returned. + unwrappedAny := &anypb.Any{} + proto.Merge(unwrappedAny, msg) + dynMsg, err := unwrappedAny.UnmarshalNew() + if err != nil { + // Allow the error to move further up the stack as it should result in an type + // conversion error if the caller does not recover it somehow. + return unwrappedAny, true + } + // Attempt to unwrap the dynamic type, otherwise return the dynamic message. + if unwrapped, nested := unwrapDynamic(desc, dynMsg.ProtoReflect()); nested { + return unwrapped, true + } + return dynMsg, true + case "google.protobuf.BoolValue", + "google.protobuf.BytesValue", + "google.protobuf.DoubleValue", + "google.protobuf.FloatValue", + "google.protobuf.Int32Value", + "google.protobuf.Int64Value", + "google.protobuf.StringValue", + "google.protobuf.UInt32Value", + "google.protobuf.UInt64Value": + // The msg value is ignored when dealing with wrapper types as they have a null or value + // behavior, rather than the standard zero value behavior of other proto message types. + if !refMsg.IsValid() { + return structpb.NullValue_NULL_VALUE, true + } + valueField := refMsg.Descriptor().Fields().ByName("value") + return refMsg.Get(valueField).Interface(), true + case "google.protobuf.Duration": + unwrapped := &dpb.Duration{} + proto.Merge(unwrapped, msg) + return unwrapped.AsDuration(), true + case "google.protobuf.ListValue": + unwrapped := &structpb.ListValue{} + proto.Merge(unwrapped, msg) + return unwrapped, true + case "google.protobuf.NullValue": + return structpb.NullValue_NULL_VALUE, true + case "google.protobuf.Struct": + unwrapped := &structpb.Struct{} + proto.Merge(unwrapped, msg) + return unwrapped, true + case "google.protobuf.Timestamp": + unwrapped := &tpb.Timestamp{} + proto.Merge(unwrapped, msg) + return unwrapped.AsTime(), true + case "google.protobuf.Value": + unwrapped := &structpb.Value{} + proto.Merge(unwrapped, msg) + return unwrap(desc, unwrapped) + } + return msg, false +} + +// reflectTypeOf intercepts the reflect.Type call to ensure that dynamicpb.Message types preserve +// well-known protobuf reflected types expected by the CEL type system. +func reflectTypeOf(val interface{}) reflect.Type { + switch v := val.(type) { + case proto.Message: + return reflect.TypeOf(zeroValueOf(v)) + default: + return reflect.TypeOf(v) + } +} + +// zeroValueOf will return the strongest possible proto.Message representing the default protobuf +// message value of the input msg type. +func zeroValueOf(msg proto.Message) proto.Message { + if msg == nil { + return nil + } + typeName := string(msg.ProtoReflect().Descriptor().FullName()) + zeroVal, found := zeroValueMap[typeName] + if found { + return zeroVal + } + return msg +} + +var ( + zeroValueMap = map[string]proto.Message{ + "google.protobuf.Any": &anypb.Any{}, + "google.protobuf.Duration": &dpb.Duration{}, + "google.protobuf.ListValue": &structpb.ListValue{}, + "google.protobuf.Struct": &structpb.Struct{}, + "google.protobuf.Timestamp": &tpb.Timestamp{}, + "google.protobuf.Value": &structpb.Value{}, + "google.protobuf.BoolValue": wrapperspb.Bool(false), + "google.protobuf.BytesValue": wrapperspb.Bytes([]byte{}), + "google.protobuf.DoubleValue": wrapperspb.Double(0.0), + "google.protobuf.FloatValue": wrapperspb.Float(0.0), + "google.protobuf.Int32Value": wrapperspb.Int32(0), + "google.protobuf.Int64Value": wrapperspb.Int64(0), + "google.protobuf.StringValue": wrapperspb.String(""), + "google.protobuf.UInt32Value": wrapperspb.UInt32(0), + "google.protobuf.UInt64Value": wrapperspb.UInt64(0), + } +) diff --git a/vendor/github.com/google/cel-go/common/types/provider.go b/vendor/github.com/google/cel-go/common/types/provider.go index 2b14e108d..62be9f00c 100644 --- a/vendor/github.com/google/cel-go/common/types/provider.go +++ b/vendor/github.com/google/cel-go/common/types/provider.go @@ -15,22 +15,22 @@ package types import ( + "fmt" "reflect" - - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" + "time" "github.com/google/cel-go/common/types/pb" "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" - descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" - anypb "github.com/golang/protobuf/ptypes/any" - dpb "github.com/golang/protobuf/ptypes/duration" - structpb "github.com/golang/protobuf/ptypes/struct" - tpb "github.com/golang/protobuf/ptypes/timestamp" - wrapperspb "github.com/golang/protobuf/ptypes/wrappers" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + anypb "google.golang.org/protobuf/types/known/anypb" + dpb "google.golang.org/protobuf/types/known/durationpb" + structpb "google.golang.org/protobuf/types/known/structpb" + tpb "google.golang.org/protobuf/types/known/timestamppb" ) type protoTypeRegistry struct { @@ -41,12 +41,12 @@ type protoTypeRegistry struct { // NewRegistry accepts a list of proto message instances and returns a type // provider which can create new instances of the provided message or any // message that proto depends upon in its FileDescriptor. -func NewRegistry(types ...proto.Message) ref.TypeRegistry { +func NewRegistry(types ...proto.Message) (ref.TypeRegistry, error) { p := &protoTypeRegistry{ revTypeMap: make(map[string]ref.Type), pbdb: pb.NewDb(), } - p.RegisterType( + err := p.RegisterType( BoolType, BytesType, DoubleType, @@ -59,14 +59,23 @@ func NewRegistry(types ...proto.Message) ref.TypeRegistry { TimestampType, TypeType, UintType) - + if err != nil { + return nil, err + } + // This block ensures that the well-known protobuf types are registered by default. + for _, fd := range p.pbdb.FileDescriptions() { + err = p.registerAllTypes(fd) + if err != nil { + return nil, err + } + } for _, msgType := range types { - err := p.RegisterMessage(msgType) + err = p.RegisterMessage(msgType) if err != nil { - panic(err) + return nil, err } } - return p + return p, nil } // NewEmptyRegistry returns a registry which is completely unconfigured. @@ -91,8 +100,8 @@ func (p *protoTypeRegistry) Copy() ref.TypeRegistry { } func (p *protoTypeRegistry) EnumValue(enumName string) ref.Val { - enumVal, err := p.pbdb.DescribeEnum(enumName) - if err != nil { + enumVal, found := p.pbdb.DescribeEnum(enumName) + if !found { return NewErr("unknown enum name '%s'", enumName) } return Int(enumVal.Value()) @@ -100,8 +109,8 @@ func (p *protoTypeRegistry) EnumValue(enumName string) ref.Val { func (p *protoTypeRegistry) FindFieldType(messageType string, fieldName string) (*ref.FieldType, bool) { - msgType, err := p.pbdb.DescribeType(messageType) - if err != nil { + msgType, found := p.pbdb.DescribeType(messageType) + if !found { return nil, false } field, found := msgType.FieldByName(fieldName) @@ -119,14 +128,14 @@ func (p *protoTypeRegistry) FindIdent(identName string) (ref.Val, bool) { if t, found := p.revTypeMap[identName]; found { return t.(ref.Val), true } - if enumVal, err := p.pbdb.DescribeEnum(identName); err == nil { + if enumVal, found := p.pbdb.DescribeEnum(identName); found { return Int(enumVal.Value()), true } return nil, false } func (p *protoTypeRegistry) FindType(typeName string) (*exprpb.Type, bool) { - if _, err := p.pbdb.DescribeType(typeName); err != nil { + if _, found := p.pbdb.DescribeType(typeName); !found { return nil, false } if typeName != "" && typeName[0] == '.' { @@ -140,45 +149,26 @@ func (p *protoTypeRegistry) FindType(typeName string) (*exprpb.Type, bool) { } func (p *protoTypeRegistry) NewValue(typeName string, fields map[string]ref.Val) ref.Val { - td, err := p.pbdb.DescribeType(typeName) - if err != nil { + td, found := p.pbdb.DescribeType(typeName) + if !found { return NewErr("unknown type '%s'", typeName) } - refType := td.ReflectType() - // create the new type instance. - value := reflect.New(refType.Elem()) - pbValue := value.Elem() - - // for all of the field names referenced, set the provided value. + msg := td.New() + fieldMap := td.FieldMap() for name, value := range fields { - fd, found := td.FieldByName(name) + field, found := fieldMap[name] if !found { - return NewErr("no such field '%s'", name) + return NewErr("no such field: %s", name) } - refField := pbValue.Field(fd.Index()) - if !refField.IsValid() { - return NewErr("no such field '%s'", name) - } - - dstType := refField.Type() - // Oneof fields are defined with wrapper structs that have a single proto.Message - // field value. The oneof wrapper is not a proto.Message instance. - if fd.IsOneof() { - oneofVal := reflect.New(fd.OneofType().Elem()) - refField.Set(oneofVal) - refField = oneofVal.Elem().Field(0) - dstType = refField.Type() - } - fieldValue, err := value.ConvertToNative(dstType) + err := msgSetField(msg, field, value) if err != nil { return &Err{err} } - refField.Set(reflect.ValueOf(fieldValue)) } - return p.NativeToValue(value.Interface()) + return p.NativeToValue(msg.Interface()) } -func (p *protoTypeRegistry) RegisterDescriptor(fileDesc *descpb.FileDescriptorProto) error { +func (p *protoTypeRegistry) RegisterDescriptor(fileDesc protoreflect.FileDescriptor) error { fd, err := p.pbdb.RegisterDescriptor(fileDesc) if err != nil { return err @@ -202,94 +192,50 @@ func (p *protoTypeRegistry) RegisterType(types ...ref.Type) error { return nil } -func (p *protoTypeRegistry) registerAllTypes(fd *pb.FileDescription) error { - for _, typeName := range fd.GetTypeNames() { - err := p.RegisterType(NewObjectTypeValue(typeName)) - if err != nil { - return err - } - } - return nil -} - // NativeToValue converts various "native" types to ref.Val with this specific implementation // providing support for custom proto-based types. // // This method should be the inverse of ref.Val.ConvertToNative. func (p *protoTypeRegistry) NativeToValue(value interface{}) ref.Val { + if val, found := nativeToValue(p, value); found { + return val + } switch v := value.(type) { - case ref.Val: - return v - // Adapt common types and aggregate specializations using the DefaultTypeAdapter. - case bool, *bool, - float32, *float32, float64, *float64, - int, *int, int32, *int32, int64, *int64, - string, *string, - uint, *uint, uint32, *uint32, uint64, *uint64, - []byte, - []string, - map[string]string: - return DefaultTypeAdapter.NativeToValue(value) - // Adapt well-known proto-types using the DefaultTypeAdapter. - case *dpb.Duration, - *tpb.Timestamp, - *structpb.ListValue, - structpb.NullValue, - *structpb.Struct, - *structpb.Value, - *wrapperspb.BoolValue, - *wrapperspb.BytesValue, - *wrapperspb.DoubleValue, - *wrapperspb.FloatValue, - *wrapperspb.Int32Value, - *wrapperspb.Int64Value, - *wrapperspb.StringValue, - *wrapperspb.UInt32Value, - *wrapperspb.UInt64Value: - return DefaultTypeAdapter.NativeToValue(value) - // Override the Any type by ensuring that custom proto-types are considered on recursive calls. - case *anypb.Any: - if v == nil { - return NewErr("unsupported type conversion: '%T'", value) - } - unpackedAny := ptypes.DynamicAny{} - if ptypes.UnmarshalAny(v, &unpackedAny) != nil { - return NewErr("unknown type: '%s'", v.GetTypeUrl()) - } - return p.NativeToValue(unpackedAny.Message) - // Convert custom proto types to CEL values based on type's presence within the pb.Db. case proto.Message: - typeName := proto.MessageName(v) - td, err := p.pbdb.DescribeType(typeName) - if err != nil { + typeName := string(v.ProtoReflect().Descriptor().FullName()) + td, found := p.pbdb.DescribeType(typeName) + if !found { return NewErr("unknown type: '%s'", typeName) } + unwrapped, isUnwrapped := td.MaybeUnwrap(v) + if isUnwrapped { + return p.NativeToValue(unwrapped) + } typeVal, found := p.FindIdent(typeName) if !found { return NewErr("unknown type: '%s'", typeName) } return NewObject(p, td, typeVal.(*TypeValue), v) - // Override default handling for list and maps to ensure that blends of Go + proto types - // are appropriately adapted on recursive calls or subsequent inspection of the aggregate - // value. - default: - refValue := reflect.ValueOf(value) - if refValue.Kind() == reflect.Ptr { - if refValue.IsNil() { - return NewErr("unsupported type conversion: '%T'", value) - } - refValue = refValue.Elem() - } - refKind := refValue.Kind() - switch refKind { - case reflect.Array, reflect.Slice: - return NewDynamicList(p, value) - case reflect.Map: - return NewDynamicMap(p, value) + case *pb.Map: + return NewProtoMap(p, v) + case protoreflect.List: + return NewProtoList(p, v) + case protoreflect.Message: + return p.NativeToValue(v.Interface()) + case protoreflect.Value: + return p.NativeToValue(v.Interface()) + } + return UnsupportedRefValConversionErr(value) +} + +func (p *protoTypeRegistry) registerAllTypes(fd *pb.FileDescription) error { + for _, typeName := range fd.GetTypeNames() { + err := p.RegisterType(NewObjectTypeValue(typeName)) + if err != nil { + return err } } - // By default return the default type adapter's conversion to CEL. - return DefaultTypeAdapter.NativeToValue(value) + return nil } // defaultTypeAdapter converts go native types to CEL values. @@ -302,237 +248,287 @@ var ( // NativeToValue implements the ref.TypeAdapter interface. func (a *defaultTypeAdapter) NativeToValue(value interface{}) ref.Val { - switch value.(type) { + if val, found := nativeToValue(a, value); found { + return val + } + return UnsupportedRefValConversionErr(value) +} + +// nativeToValue returns the converted (ref.Val, true) of a conversion is found, +// otherwise (nil, false) +func nativeToValue(a ref.TypeAdapter, value interface{}) (ref.Val, bool) { + switch v := value.(type) { case nil: - return NullValue + return NullValue, true case *Bool: - if ptr := value.(*Bool); ptr != nil { - return ptr + if v != nil { + return *v, true } case *Bytes: - if ptr := value.(*Bytes); ptr != nil { - return ptr + if v != nil { + return *v, true } case *Double: - if ptr := value.(*Double); ptr != nil { - return ptr + if v != nil { + return *v, true } case *Int: - if ptr := value.(*Int); ptr != nil { - return ptr + if v != nil { + return *v, true } case *String: - if ptr := value.(*String); ptr != nil { - return ptr + if v != nil { + return *v, true } case *Uint: - if ptr := value.(*Uint); ptr != nil { - return ptr + if v != nil { + return *v, true } - case ref.Val: - return value.(ref.Val) case bool: - return Bool(value.(bool)) + return Bool(v), true case int: - return Int(value.(int)) + return Int(v), true case int32: - return Int(value.(int32)) + return Int(v), true case int64: - return Int(value.(int64)) + return Int(v), true case uint: - return Uint(value.(uint)) + return Uint(v), true case uint32: - return Uint(value.(uint32)) + return Uint(v), true case uint64: - return Uint(value.(uint64)) + return Uint(v), true case float32: - return Double(value.(float32)) + return Double(v), true case float64: - return Double(value.(float64)) + return Double(v), true case string: - return String(value.(string)) + return String(v), true + case *dpb.Duration: + return Duration{Duration: v.AsDuration()}, true + case time.Duration: + return Duration{Duration: v}, true + case *tpb.Timestamp: + return Timestamp{Time: v.AsTime()}, true + case time.Time: + return Timestamp{Time: v}, true case *bool: - if ptr := value.(*bool); ptr != nil { - return Bool(*ptr) + if v != nil { + return Bool(*v), true } case *float32: - if ptr := value.(*float32); ptr != nil { - return Double(*ptr) + if v != nil { + return Double(*v), true } case *float64: - if ptr := value.(*float64); ptr != nil { - return Double(*ptr) + if v != nil { + return Double(*v), true } case *int: - if ptr := value.(*int); ptr != nil { - return Int(*ptr) + if v != nil { + return Int(*v), true } case *int32: - if ptr := value.(*int32); ptr != nil { - return Int(*ptr) + if v != nil { + return Int(*v), true } case *int64: - if ptr := value.(*int64); ptr != nil { - return Int(*ptr) + if v != nil { + return Int(*v), true } case *string: - if ptr := value.(*string); ptr != nil { - return String(*ptr) + if v != nil { + return String(*v), true } case *uint: - if ptr := value.(*uint); ptr != nil { - return Uint(*ptr) + if v != nil { + return Uint(*v), true } case *uint32: - if ptr := value.(*uint32); ptr != nil { - return Uint(*ptr) + if v != nil { + return Uint(*v), true } case *uint64: - if ptr := value.(*uint64); ptr != nil { - return Uint(*ptr) + if v != nil { + return Uint(*v), true } case []byte: - return Bytes(value.([]byte)) + return Bytes(v), true + // specializations for common lists types. case []string: - return NewStringList(a, value.([]string)) + return NewStringList(a, v), true + case []ref.Val: + return NewRefValList(a, v), true + // specializations for common map types. case map[string]string: - return NewStringStringMap(a, value.(map[string]string)) - case *dpb.Duration: - if ptr := value.(*dpb.Duration); ptr != nil { - return Duration{ptr} + return NewStringStringMap(a, v), true + case map[string]interface{}: + return NewStringInterfaceMap(a, v), true + case map[ref.Val]ref.Val: + return NewRefValMap(a, v), true + // additional specializations may be added upon request / need. + case *anypb.Any: + if v == nil { + return UnsupportedRefValConversionErr(v), true } - case *structpb.ListValue: - if ptr := value.(*structpb.ListValue); ptr != nil { - return NewJSONList(a, ptr) + unpackedAny, err := v.UnmarshalNew() + if err != nil { + return NewErr("anypb.UnmarshalNew() failed for type %q: %v", v.GetTypeUrl(), err), true } - case structpb.NullValue, *structpb.NullValue: - return NullValue + return a.NativeToValue(unpackedAny), true + case *structpb.NullValue, structpb.NullValue: + return NullValue, true + case *structpb.ListValue: + return NewJSONList(a, v), true case *structpb.Struct: - if ptr := value.(*structpb.Struct); ptr != nil { - return NewJSONStruct(a, ptr) - } - case *structpb.Value: - v := value.(*structpb.Value) + return NewJSONStruct(a, v), true + case ref.Val: + return v, true + case protoreflect.EnumNumber: + return Int(v), true + case proto.Message: if v == nil { - return NullValue - } - switch v.Kind.(type) { - case *structpb.Value_BoolValue: - return a.NativeToValue(v.GetBoolValue()) - case *structpb.Value_ListValue: - return a.NativeToValue(v.GetListValue()) - case *structpb.Value_NullValue: - return NullValue - case *structpb.Value_NumberValue: - return a.NativeToValue(v.GetNumberValue()) - case *structpb.Value_StringValue: - return a.NativeToValue(v.GetStringValue()) - case *structpb.Value_StructValue: - return a.NativeToValue(v.GetStructValue()) + return UnsupportedRefValConversionErr(v), true } - case *tpb.Timestamp: - if ptr := value.(*tpb.Timestamp); ptr != nil { - return Timestamp{ptr} + typeName := string(v.ProtoReflect().Descriptor().FullName()) + td, found := pb.DefaultDb.DescribeType(typeName) + if !found { + return nil, false } - case *anypb.Any: - val := value.(*anypb.Any) - if val == nil { - return NewErr("unsupported type conversion") - } - unpackedAny := ptypes.DynamicAny{} - if ptypes.UnmarshalAny(val, &unpackedAny) != nil { - return NewErr("unknown type: %s", val.GetTypeUrl()) - } - return a.NativeToValue(unpackedAny.Message) - case *wrapperspb.BoolValue: - val := value.(*wrapperspb.BoolValue) - if val == nil { - return NewErr("unsupported type conversion") - } - return Bool(val.GetValue()) - case *wrapperspb.BytesValue: - val := value.(*wrapperspb.BytesValue) - if val == nil { - return NewErr("unsupported type conversion") - } - return Bytes(val.GetValue()) - case *wrapperspb.DoubleValue: - val := value.(*wrapperspb.DoubleValue) - if val == nil { - return NewErr("unsupported type conversion") - } - return Double(val.GetValue()) - case *wrapperspb.FloatValue: - val := value.(*wrapperspb.FloatValue) - if val == nil { - return NewErr("unsupported type conversion") - } - return Double(val.GetValue()) - case *wrapperspb.Int32Value: - val := value.(*wrapperspb.Int32Value) - if val == nil { - return NewErr("unsupported type conversion") - } - return Int(val.GetValue()) - case *wrapperspb.Int64Value: - val := value.(*wrapperspb.Int64Value) - if val == nil { - return NewErr("unsupported type conversion") - } - return Int(val.GetValue()) - case *wrapperspb.StringValue: - val := value.(*wrapperspb.StringValue) - if val == nil { - return NewErr("unsupported type conversion") - } - return String(val.GetValue()) - case *wrapperspb.UInt32Value: - val := value.(*wrapperspb.UInt32Value) - if val == nil { - return NewErr("unsupported type conversion") - } - return Uint(val.GetValue()) - case *wrapperspb.UInt64Value: - val := value.(*wrapperspb.UInt64Value) - if val == nil { - return NewErr("unsupported type conversion") - } - return Uint(val.GetValue()) + val, unwrapped := td.MaybeUnwrap(v) + if !unwrapped { + return nil, false + } + return a.NativeToValue(val), true + // Note: dynamicpb.Message implements the proto.Message _and_ protoreflect.Message interfaces + // which means that this case must appear after handling a proto.Message type. + case protoreflect.Message: + return a.NativeToValue(v.Interface()), true default: - refValue := reflect.ValueOf(value) + refValue := reflect.ValueOf(v) if refValue.Kind() == reflect.Ptr { if refValue.IsNil() { - return NewErr("unsupported type conversion: '%T'", value) + return UnsupportedRefValConversionErr(v), true } refValue = refValue.Elem() } refKind := refValue.Kind() switch refKind { case reflect.Array, reflect.Slice: - return NewDynamicList(a, value) + return NewDynamicList(a, v), true case reflect.Map: - return NewDynamicMap(a, value) + return NewDynamicMap(a, v), true // type aliases of primitive types cannot be asserted as that type, but rather need // to be downcast to int32 before being converted to a CEL representation. case reflect.Int32: intType := reflect.TypeOf(int32(0)) - return Int(refValue.Convert(intType).Interface().(int32)) + return Int(refValue.Convert(intType).Interface().(int32)), true case reflect.Int64: intType := reflect.TypeOf(int64(0)) - return Int(refValue.Convert(intType).Interface().(int64)) + return Int(refValue.Convert(intType).Interface().(int64)), true case reflect.Uint32: uintType := reflect.TypeOf(uint32(0)) - return Uint(refValue.Convert(uintType).Interface().(uint32)) + return Uint(refValue.Convert(uintType).Interface().(uint32)), true case reflect.Uint64: uintType := reflect.TypeOf(uint64(0)) - return Uint(refValue.Convert(uintType).Interface().(uint64)) + return Uint(refValue.Convert(uintType).Interface().(uint64)), true case reflect.Float32: doubleType := reflect.TypeOf(float32(0)) - return Double(refValue.Convert(doubleType).Interface().(float32)) + return Double(refValue.Convert(doubleType).Interface().(float32)), true case reflect.Float64: doubleType := reflect.TypeOf(float64(0)) - return Double(refValue.Convert(doubleType).Interface().(float64)) + return Double(refValue.Convert(doubleType).Interface().(float64)), true + } + } + return nil, false +} + +func msgSetField(target protoreflect.Message, field *pb.FieldDescription, val ref.Val) error { + if field.IsList() { + lv := target.NewField(field.Descriptor()) + list, ok := val.(traits.Lister) + if !ok { + return unsupportedTypeConversionError(field, val) + } + err := msgSetListField(lv.List(), field, list) + if err != nil { + return err } + target.Set(field.Descriptor(), lv) + return nil } - return NewErr("unsupported type conversion: '%T'", value) + if field.IsMap() { + mv := target.NewField(field.Descriptor()) + mp, ok := val.(traits.Mapper) + if !ok { + return unsupportedTypeConversionError(field, val) + } + err := msgSetMapField(mv.Map(), field, mp) + if err != nil { + return err + } + target.Set(field.Descriptor(), mv) + return nil + } + v, err := val.ConvertToNative(field.ReflectType()) + if err != nil { + return fieldTypeConversionError(field, err) + } + switch v.(type) { + case proto.Message: + v = v.(proto.Message).ProtoReflect() + } + target.Set(field.Descriptor(), protoreflect.ValueOf(v)) + return nil +} + +func msgSetListField(target protoreflect.List, listField *pb.FieldDescription, listVal traits.Lister) error { + elemReflectType := listField.ReflectType().Elem() + for i := Int(0); i < listVal.Size().(Int); i++ { + elem := listVal.Get(i) + elemVal, err := elem.ConvertToNative(elemReflectType) + if err != nil { + return fieldTypeConversionError(listField, err) + } + switch ev := elemVal.(type) { + case proto.Message: + elemVal = ev.ProtoReflect() + } + target.Append(protoreflect.ValueOf(elemVal)) + } + return nil +} + +func msgSetMapField(target protoreflect.Map, mapField *pb.FieldDescription, mapVal traits.Mapper) error { + targetKeyType := mapField.KeyType.ReflectType() + targetValType := mapField.ValueType.ReflectType() + it := mapVal.Iterator() + for it.HasNext() == True { + key := it.Next() + val := mapVal.Get(key) + k, err := key.ConvertToNative(targetKeyType) + if err != nil { + return fieldTypeConversionError(mapField, err) + } + v, err := val.ConvertToNative(targetValType) + if err != nil { + return fieldTypeConversionError(mapField, err) + } + switch v.(type) { + case proto.Message: + v = v.(proto.Message).ProtoReflect() + } + target.Set(protoreflect.ValueOf(k).MapKey(), protoreflect.ValueOf(v)) + } + return nil +} + +func unsupportedTypeConversionError(field *pb.FieldDescription, val ref.Val) error { + msgName := field.Descriptor().ContainingMessage().FullName() + return fmt.Errorf("unsupported field type for %v.%v: %v", msgName, field.Name(), val.Type()) +} + +func fieldTypeConversionError(field *pb.FieldDescription, err error) error { + msgName := field.Descriptor().ContainingMessage().FullName() + return fmt.Errorf("field type conversion error for %v.%v value type: %v", msgName, field.Name(), err) } diff --git a/vendor/github.com/google/cel-go/common/types/ref/BUILD.bazel b/vendor/github.com/google/cel-go/common/types/ref/BUILD.bazel index 3d2a78304..9389256ad 100644 --- a/vendor/github.com/google/cel-go/common/types/ref/BUILD.bazel +++ b/vendor/github.com/google/cel-go/common/types/ref/BUILD.bazel @@ -13,8 +13,8 @@ go_library( ], importpath = "github.com/google/cel-go/common/types/ref", deps = [ - "@com_github_golang_protobuf//proto:go_default_library", - "@io_bazel_rules_go//proto/wkt:descriptor_go_proto", + "@org_golang_google_protobuf//proto:go_default_library", + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/common/types/ref/provider.go b/vendor/github.com/google/cel-go/common/types/ref/provider.go index 541dbdbfe..91a711fa7 100644 --- a/vendor/github.com/google/cel-go/common/types/ref/provider.go +++ b/vendor/github.com/google/cel-go/common/types/ref/provider.go @@ -15,9 +15,9 @@ package ref import ( - "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" - descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) @@ -67,7 +67,7 @@ type TypeRegistry interface { TypeProvider // RegisterDescriptor registers the contents of a protocol buffer `FileDescriptor`. - RegisterDescriptor(fileDesc *descpb.FileDescriptorProto) error + RegisterDescriptor(fileDesc protoreflect.FileDescriptor) error // RegisterMessage registers a protocol buffer message and its dependencies. RegisterMessage(message proto.Message) error diff --git a/vendor/github.com/google/cel-go/common/types/string.go b/vendor/github.com/google/cel-go/common/types/string.go index 4838eef65..792c1781f 100644 --- a/vendor/github.com/google/cel-go/common/types/string.go +++ b/vendor/github.com/google/cel-go/common/types/string.go @@ -22,14 +22,13 @@ import ( "strings" "time" - "github.com/golang/protobuf/ptypes" - "github.com/google/cel-go/common/overloads" "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/common/types/traits" - structpb "github.com/golang/protobuf/ptypes/struct" - wrapperspb "github.com/golang/protobuf/ptypes/wrappers" + anypb "google.golang.org/protobuf/types/known/anypb" + structpb "google.golang.org/protobuf/types/known/structpb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" ) // String type implementation which supports addition, comparison, matching, @@ -76,26 +75,31 @@ func (s String) Compare(other ref.Val) ref.Val { func (s String) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { switch typeDesc.Kind() { case reflect.String: + if reflect.TypeOf(s).AssignableTo(typeDesc) { + return s, nil + } return s.Value(), nil case reflect.Ptr: switch typeDesc { case anyValueType: // Primitives must be wrapped before being set on an Any field. - return ptypes.MarshalAny(&wrapperspb.StringValue{Value: string(s)}) + return anypb.New(wrapperspb.String(string(s))) case jsonValueType: // Convert to a protobuf representation of a JSON String. - return &structpb.Value{ - Kind: &structpb.Value_StringValue{StringValue: string(s)}, - }, nil + return structpb.NewStringValue(string(s)), nil case stringWrapperType: - // Convert to a protobuf.StringValue. - return &wrapperspb.StringValue{Value: string(s)}, nil + // Convert to a wrapperspb.StringValue. + return wrapperspb.String(string(s)), nil } if typeDesc.Elem().Kind() == reflect.String { p := s.Value().(string) return &p, nil } case reflect.Interface: + sv := s.Value() + if reflect.TypeOf(sv).Implements(typeDesc) { + return sv, nil + } if reflect.TypeOf(s).Implements(typeDesc) { return s, nil } @@ -127,13 +131,11 @@ func (s String) ConvertToType(typeVal ref.Type) ref.Val { return Bytes(s) case DurationType: if d, err := time.ParseDuration(s.Value().(string)); err == nil { - return Duration{ptypes.DurationProto(d)} + return Duration{Duration: d} } case TimestampType: if t, err := time.Parse(time.RFC3339, s.Value().(string)); err == nil { - if ts, err := ptypes.TimestampProto(t); err == nil { - return Timestamp{ts} - } + return Timestamp{Time: t} } case StringType: return s diff --git a/vendor/github.com/google/cel-go/common/types/timestamp.go b/vendor/github.com/google/cel-go/common/types/timestamp.go index b9fe33c77..a2e6e1ab7 100644 --- a/vendor/github.com/google/cel-go/common/types/timestamp.go +++ b/vendor/github.com/google/cel-go/common/types/timestamp.go @@ -21,22 +21,20 @@ import ( "strings" "time" - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" - "github.com/google/cel-go/common/overloads" "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/common/types/traits" - structpb "github.com/golang/protobuf/ptypes/struct" - tpb "github.com/golang/protobuf/ptypes/timestamp" + anypb "google.golang.org/protobuf/types/known/anypb" + structpb "google.golang.org/protobuf/types/known/structpb" + tpb "google.golang.org/protobuf/types/known/timestamppb" ) // Timestamp type implementation which supports add, compare, and subtract // operations. Timestamps are also capable of participating in dynamic // function dispatch to instance methods. type Timestamp struct { - *tpb.Timestamp + time.Time } var ( @@ -62,14 +60,8 @@ func (t Timestamp) Compare(other ref.Val) ref.Val { if TimestampType != other.Type() { return ValOrErr(other, "no such overload") } - ts1, err := ptypes.Timestamp(t.Timestamp) - if err != nil { - return &Err{err} - } - ts2, err := ptypes.Timestamp(other.(Timestamp).Timestamp) - if err != nil { - return &Err{err} - } + ts1 := t.Time + ts2 := other.(Timestamp).Time ts := ts1.Sub(ts2) if ts < 0 { return IntNegOne @@ -82,10 +74,17 @@ func (t Timestamp) Compare(other ref.Val) ref.Val { // ConvertToNative implements ref.Val.ConvertToNative. func (t Timestamp) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + // If the timestamp is already assignable to the desired type return it. + if reflect.TypeOf(t.Time).AssignableTo(typeDesc) { + return t.Time, nil + } + if reflect.TypeOf(t).AssignableTo(typeDesc) { + return t, nil + } switch typeDesc { case anyValueType: - // Pack the underlying protobuf.Timestamp to an Any value. - return ptypes.MarshalAny(t.Timestamp) + // Pack the underlying time as a tpb.Timestamp into an Any value. + return anypb.New(tpb.New(t.Time)) case jsonValueType: // CEL follows the proto3 to JSON conversion which formats as an RFC 3339 encoded JSON // string. @@ -93,31 +92,22 @@ func (t Timestamp) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { if IsError(v) { return nil, v.(*Err) } - return &structpb.Value{ - Kind: &structpb.Value_StringValue{StringValue: string(v.(String))}, - }, nil + return structpb.NewStringValue(string(v.(String))), nil case timestampValueType: - // Unwrap the underlying protobuf.Timestamp. - return t.Value(), nil + // Unwrap the underlying tpb.Timestamp. + return tpb.New(t.Time), nil } - // If the timestamp is already assignable to the desired type return it. - if reflect.TypeOf(t).AssignableTo(typeDesc) { - return t, nil - } - return nil, fmt.Errorf("type conversion error from "+ - "'google.protobuf.Timestamp' to '%v'", typeDesc) + return nil, fmt.Errorf("type conversion error from 'Timestamp' to '%v'", typeDesc) } // ConvertToType implements ref.Val.ConvertToType. func (t Timestamp) ConvertToType(typeVal ref.Type) ref.Val { switch typeVal { case StringType: - return String(ptypes.TimestampString(t.Timestamp)) + return String(t.Format(time.RFC3339)) case IntType: - if ts, err := ptypes.Timestamp(t.Timestamp); err == nil { - // Return the Unix time in seconds since 1970 - return Int(ts.Unix()) - } + // Return the Unix time in seconds since 1970 + return Int(t.Unix()) case TimestampType: return t case TypeType: @@ -129,26 +119,21 @@ func (t Timestamp) ConvertToType(typeVal ref.Type) ref.Val { // Equal implements ref.Val.Equal. func (t Timestamp) Equal(other ref.Val) ref.Val { if TimestampType != other.Type() { - return ValOrErr(other, "no such overload") + return MaybeNoSuchOverloadErr(other) } - return Bool(proto.Equal(t.Timestamp, other.Value().(proto.Message))) + return Bool(t.Time.Equal(other.(Timestamp).Time)) } // Receive implements traits.Reciever.Receive. func (t Timestamp) Receive(function string, overload string, args []ref.Val) ref.Val { - ts := t.Timestamp - tstamp, err := ptypes.Timestamp(ts) - if err != nil { - return &Err{err} - } switch len(args) { case 0: if f, found := timestampZeroArgOverloads[function]; found { - return f(tstamp) + return f(t.Time) } case 1: if f, found := timestampOneArgOverloads[function]; found { - return f(tstamp, args[0]) + return f(t.Time, args[0]) } } return NewErr("no such overload") @@ -158,29 +143,11 @@ func (t Timestamp) Receive(function string, overload string, args []ref.Val) ref func (t Timestamp) Subtract(subtrahend ref.Val) ref.Val { switch subtrahend.Type() { case DurationType: - ts, err := ptypes.Timestamp(t.Timestamp) - if err != nil { - return &Err{err} - } - dur, err := ptypes.Duration(subtrahend.(Duration).Duration) - if err != nil { - return &Err{err} - } - tstamp, err := ptypes.TimestampProto(ts.Add(-dur)) - if err != nil { - return &Err{err} - } - return Timestamp{tstamp} + dur := subtrahend.(Duration) + return Timestamp{Time: t.Time.Add(-dur.Duration)} case TimestampType: - ts1, err := ptypes.Timestamp(t.Timestamp) - if err != nil { - return &Err{err} - } - ts2, err := ptypes.Timestamp(subtrahend.(Timestamp).Timestamp) - if err != nil { - return &Err{err} - } - return Duration{ptypes.DurationProto(ts1.Sub(ts2))} + t2 := subtrahend.(Timestamp).Time + return Duration{Duration: t.Time.Sub(t2)} } return ValOrErr(subtrahend, "no such overload") } @@ -192,7 +159,7 @@ func (t Timestamp) Type() ref.Type { // Value implements ref.Val.Value. func (t Timestamp) Value() interface{} { - return t.Timestamp + return t.Time } var ( @@ -306,7 +273,6 @@ func timeZone(tz ref.Val, visitor timestampVisitor) timestampVisitor { // If the input is not the name of a timezone (for example, 'US/Central'), it should be a numerical offset from UTC // in the format ^(+|-)(0[0-9]|1[0-4]):[0-5][0-9]$. The numerical input is parsed in terms of hours and minutes. - hr, err := strconv.Atoi(string(val[0:ind])) if err != nil { return &Err{err} diff --git a/vendor/github.com/google/cel-go/common/types/traits/mapper.go b/vendor/github.com/google/cel-go/common/types/traits/mapper.go index 5edd8f61b..2f7c919a8 100644 --- a/vendor/github.com/google/cel-go/common/types/traits/mapper.go +++ b/vendor/github.com/google/cel-go/common/types/traits/mapper.go @@ -24,10 +24,10 @@ type Mapper interface { Iterable Sizer - // Find a value by key if it exists. + // Find returns a value, if one exists, for the input key. // - // When the value exists, the result will be non-nil, true. When the value does not exist, - // the result will be nil, false. When an error occurs, the value will be non-nil and the - // found result false. + // If the key is not found the function returns (nil, false). + // If the input key is not valid for the map, or is Err or Unknown the function returns + // (Unknown|Err, false). Find(key ref.Val) (ref.Val, bool) } diff --git a/vendor/github.com/google/cel-go/common/types/uint.go b/vendor/github.com/google/cel-go/common/types/uint.go index b50533233..a313d9171 100644 --- a/vendor/github.com/google/cel-go/common/types/uint.go +++ b/vendor/github.com/google/cel-go/common/types/uint.go @@ -20,13 +20,12 @@ import ( "reflect" "strconv" - "github.com/golang/protobuf/ptypes" - "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/common/types/traits" - structpb "github.com/golang/protobuf/ptypes/struct" - wrapperspb "github.com/golang/protobuf/ptypes/wrappers" + anypb "google.golang.org/protobuf/types/known/anypb" + structpb "google.golang.org/protobuf/types/known/structpb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" ) // Uint type implementation which supports comparison and math operators. @@ -58,6 +57,9 @@ func (i Uint) Add(other ref.Val) ref.Val { if !ok { return ValOrErr(other, "no such overload") } + if otherUint > 0 && i > math.MaxUint64-otherUint { + return NewErr("unsigned integer overflow") + } return i + otherUint } @@ -85,29 +87,21 @@ func (i Uint) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { switch typeDesc { case anyValueType: // Primitives must be wrapped before being set on an Any field. - return ptypes.MarshalAny(&wrapperspb.UInt64Value{Value: uint64(i)}) + return anypb.New(wrapperspb.UInt64(uint64(i))) case jsonValueType: // JSON can accurately represent 32-bit uints as floating point values. if i.isJSONSafe() { - return &structpb.Value{ - Kind: &structpb.Value_NumberValue{ - NumberValue: float64(i), - }, - }, nil + return structpb.NewNumberValue(float64(i)), nil } // Proto3 to JSON conversion requires string-formatted uint64 values // since the conversion to floating point would result in truncation. - return &structpb.Value{ - Kind: &structpb.Value_StringValue{ - StringValue: strconv.FormatUint(uint64(i), 10), - }, - }, nil + return structpb.NewStringValue(strconv.FormatUint(uint64(i), 10)), nil case uint32WrapperType: - // Convert the value to a protobuf.UInt32Value (with truncation). - return &wrapperspb.UInt32Value{Value: uint32(i)}, nil + // Convert the value to a wrapperspb.UInt32Value (with truncation). + return wrapperspb.UInt32(uint32(i)), nil case uint64WrapperType: - // Convert the value to a protobuf.UInt64Value. - return &wrapperspb.UInt64Value{Value: uint64(i)}, nil + // Convert the value to a wrapperspb.UInt64Value. + return wrapperspb.UInt64(uint64(i)), nil } switch typeDesc.Elem().Kind() { case reflect.Uint32: @@ -122,6 +116,10 @@ func (i Uint) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { return p.Interface(), nil } case reflect.Interface: + iv := i.Value() + if reflect.TypeOf(iv).Implements(typeDesc) { + return iv, nil + } if reflect.TypeOf(i).Implements(typeDesc) { return i, nil } @@ -188,6 +186,9 @@ func (i Uint) Multiply(other ref.Val) ref.Val { if !ok { return ValOrErr(other, "no such overload") } + if otherUint != 0 && i > math.MaxUint64/otherUint { + return NewErr("unsigned integer overflow") + } return i * otherUint } @@ -197,6 +198,9 @@ func (i Uint) Subtract(subtrahend ref.Val) ref.Val { if !ok { return ValOrErr(subtrahend, "no such overload") } + if subtraUint > i { + return NewErr("unsigned integer overflow") + } return i - subtraUint } diff --git a/vendor/github.com/google/cel-go/ext/guards.go b/vendor/github.com/google/cel-go/ext/guards.go index e833a0a5a..809c0e1b0 100644 --- a/vendor/github.com/google/cel-go/ext/guards.go +++ b/vendor/github.com/google/cel-go/ext/guards.go @@ -22,20 +22,6 @@ import ( // function invocation guards for common call signatures within extension functions. -func callInBytesOutBytes(fn func([]byte) ([]byte, error)) functions.UnaryOp { - return func(val ref.Val) ref.Val { - vVal, ok := val.(types.Bytes) - if !ok { - return types.MaybeNoSuchOverloadErr(val) - } - byt, err := fn([]byte(vVal)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.Bytes(byt) - } -} - func callInBytesOutString(fn func([]byte) (string, error)) functions.UnaryOp { return func(val ref.Val) ref.Val { vVal, ok := val.(types.Bytes) diff --git a/vendor/github.com/google/cel-go/interpreter/BUILD.bazel b/vendor/github.com/google/cel-go/interpreter/BUILD.bazel index 6569b823d..35854f112 100644 --- a/vendor/github.com/google/cel-go/interpreter/BUILD.bazel +++ b/vendor/github.com/google/cel-go/interpreter/BUILD.bazel @@ -30,11 +30,11 @@ go_library( "//common/types/ref:go_default_library", "//common/types/traits:go_default_library", "//interpreter/functions:go_default_library", - "@com_github_golang_protobuf//proto:go_default_library", - "@io_bazel_rules_go//proto/wkt:duration_go_proto", - "@io_bazel_rules_go//proto/wkt:struct_go_proto", - "@io_bazel_rules_go//proto/wkt:timestamp_go_proto", - "@io_bazel_rules_go//proto/wkt:wrappers_go_proto", + "@org_golang_google_protobuf//proto:go_default_library", + "@org_golang_google_protobuf//types/known/durationpb:go_default_library", + "@org_golang_google_protobuf//types/known/structpb:go_default_library", + "@org_golang_google_protobuf//types/known/timestamppb:go_default_library", + "@org_golang_google_protobuf//types/known/wrapperspb:go_default_library", "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", ] ) @@ -63,11 +63,8 @@ go_test( "//test:go_default_library", "//test/proto2pb:go_default_library", "//test/proto3pb:go_default_library", - "@com_github_golang_protobuf//proto:go_default_library", - "@com_github_golang_protobuf//ptypes:go_default_library", - "@io_bazel_rules_go//proto/wkt:duration_go_proto", - "@io_bazel_rules_go//proto/wkt:struct_go_proto", - "@io_bazel_rules_go//proto/wkt:timestamp_go_proto", + "@org_golang_google_protobuf//proto:go_default_library", + "@org_golang_google_protobuf//types/known/anypb:go_default_library", "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/interpreter/activation.go b/vendor/github.com/google/cel-go/interpreter/activation.go index 7eb22f745..4f1315199 100644 --- a/vendor/github.com/google/cel-go/interpreter/activation.go +++ b/vendor/github.com/google/cel-go/interpreter/activation.go @@ -77,7 +77,6 @@ func NewActivation(bindings interface{}) (Activation, error) { // Named bindings may lazily supply values by providing a function which accepts no arguments and // produces an interface value. type mapActivation struct { - adapter ref.TypeAdapter bindings map[string]interface{} } @@ -165,14 +164,6 @@ func (a *partActivation) UnknownAttributePatterns() []*AttributePattern { return a.unknowns } -// newVarActivation returns a new varActivation instance. -func newVarActivation(parent Activation, name string) *varActivation { - return &varActivation{ - parent: parent, - name: name, - } -} - // varActivation represents a single mutable variable binding. // // This activation type should only be used within folds as the fold loop controls the object diff --git a/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go b/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go index aca488c62..3633255d2 100644 --- a/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go +++ b/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go @@ -255,7 +255,7 @@ func (fac *partialAttributeFactory) matchesUnknownPatterns( // Resolve the attribute qualifiers into a static set. This prevents more dynamic // Attribute resolutions than necessary when there are multiple unknown patterns // that traverse the same Attribute-based qualifier field. - newQuals := make([]Qualifier, len(qualifiers), len(qualifiers)) + newQuals := make([]Qualifier, len(qualifiers)) for i, qual := range qualifiers { attr, isAttr := qual.(Attribute) if isAttr { diff --git a/vendor/github.com/google/cel-go/interpreter/attributes.go b/vendor/github.com/google/cel-go/interpreter/attributes.go index db11c761f..e101c669b 100644 --- a/vendor/github.com/google/cel-go/interpreter/attributes.go +++ b/vendor/github.com/google/cel-go/interpreter/attributes.go @@ -382,7 +382,7 @@ func (a *conditionalAttribute) Qualify(vars Activation, obj interface{}) (interf func (a *conditionalAttribute) Resolve(vars Activation) (interface{}, error) { val := a.expr.Eval(vars) if types.IsError(val) { - return nil, val.Value().(error) + return nil, val.(*types.Err) } if val == types.True { return a.truthy.Resolve(vars) @@ -393,7 +393,7 @@ func (a *conditionalAttribute) Resolve(vars Activation) (interface{}, error) { if types.IsUnknown(val) { return val, nil } - return nil, types.ValOrErr(val, "no such overload").Value().(error) + return nil, types.MaybeNoSuchOverloadErr(val).(*types.Err) } // String is an implementation of the Stringer interface method. @@ -476,14 +476,15 @@ func (a *maybeAttribute) AddQualifier(qual Qualifier) (Attribute, error) { for _, attr := range a.attrs { if isStr && len(attr.Qualifiers()) == 0 { candidateVars := attr.CandidateVariableNames() - augmentedNames = make([]string, - len(candidateVars), - len(candidateVars)) + augmentedNames = make([]string, len(candidateVars)) for i, name := range candidateVars { augmentedNames[i] = fmt.Sprintf("%s.%s", name, str) } } - attr.AddQualifier(qual) + _, err := attr.AddQualifier(qual) + if err != nil { + return nil, err + } } // Next, ensure the most specific variable / type reference is searched first. a.attrs = append([]NamespacedAttribute{ @@ -584,7 +585,7 @@ func (a *relativeAttribute) Resolve(vars Activation) (interface{}, error) { // First, evaluate the operand. v := a.operand.Eval(vars) if types.IsError(v) { - return nil, v.Value().(error) + return nil, v.(*types.Err) } if types.IsUnknown(v) { return v, nil @@ -1006,7 +1007,7 @@ func refResolve(adapter ref.TypeAdapter, idx ref.Val, obj interface{}) (ref.Val, return nil, fmt.Errorf("no such key: %v", idx) } if types.IsError(elem) { - return nil, elem.Value().(error) + return nil, elem.(*types.Err) } return elem, nil } @@ -1014,7 +1015,7 @@ func refResolve(adapter ref.TypeAdapter, idx ref.Val, obj interface{}) (ref.Val, if isIndexer { elem := indexer.Get(idx) if types.IsError(elem) { - return nil, elem.Value().(error) + return nil, elem.(*types.Err) } return elem, nil } @@ -1025,7 +1026,7 @@ func refResolve(adapter ref.TypeAdapter, idx ref.Val, obj interface{}) (ref.Val, // future, then it would be reasonable to return error values as ref.Val types rather than // simple go error types. if types.IsError(celVal) { - return nil, celVal.Value().(error) + return nil, celVal.(*types.Err) } return nil, errors.New("no such overload") } diff --git a/vendor/github.com/google/cel-go/interpreter/decorators.go b/vendor/github.com/google/cel-go/interpreter/decorators.go index 6d294cfa5..23a7f695b 100644 --- a/vendor/github.com/google/cel-go/interpreter/decorators.go +++ b/vendor/github.com/google/cel-go/interpreter/decorators.go @@ -113,11 +113,6 @@ func decOptimize() InterpretableDecorator { if overloads.IsTypeConversionFunction(inst.Function()) { return maybeOptimizeConstUnary(i, inst) } - case *evalUnary: - return maybeOptimizeConstUnary(i, inst) - case *evalBinary: - if inst.overload == overloads.InList { - } } return i, nil } diff --git a/vendor/github.com/google/cel-go/interpreter/dispatcher.go b/vendor/github.com/google/cel-go/interpreter/dispatcher.go index 2c6516f24..febf9d8a8 100644 --- a/vendor/github.com/google/cel-go/interpreter/dispatcher.go +++ b/vendor/github.com/google/cel-go/interpreter/dispatcher.go @@ -82,7 +82,7 @@ func (d *defaultDispatcher) FindOverload(overload string) (*functions.Overload, // OverloadIds implements the Dispatcher interface method. func (d *defaultDispatcher) OverloadIds() []string { i := 0 - overloads := make([]string, len(d.overloads), len(d.overloads)) + overloads := make([]string, len(d.overloads)) for name := range d.overloads { overloads[i] = name i++ diff --git a/vendor/github.com/google/cel-go/interpreter/interpretable.go b/vendor/github.com/google/cel-go/interpreter/interpretable.go index 396da55a8..28af6d44b 100644 --- a/vendor/github.com/google/cel-go/interpreter/interpretable.go +++ b/vendor/github.com/google/cel-go/interpreter/interpretable.go @@ -533,7 +533,7 @@ func (fn *evalVarArgs) ID() int64 { // Eval implements the Interpretable interface method. func (fn *evalVarArgs) Eval(ctx Activation) ref.Val { - argVals := make([]ref.Val, len(fn.args), len(fn.args)) + argVals := make([]ref.Val, len(fn.args)) // Early return if any argument to the function is unknown or error. for i, arg := range fn.args { argVals[i] = arg.Eval(ctx) @@ -591,7 +591,7 @@ func (l *evalList) ID() int64 { // Eval implements the Interpretable interface method. func (l *evalList) Eval(ctx Activation) ref.Val { - elemVals := make([]ref.Val, len(l.elems), len(l.elems)) + elemVals := make([]ref.Val, len(l.elems)) // If any argument is unknown or error early terminate. for i, elem := range l.elems { elemVal := elem.Eval(ctx) @@ -600,7 +600,7 @@ func (l *evalList) Eval(ctx Activation) ref.Val { } elemVals[i] = elemVal } - return types.NewDynamicList(l.adapter, elemVals) + return l.adapter.NativeToValue(elemVals) } // Cost implements the Coster interface method. @@ -635,7 +635,7 @@ func (m *evalMap) Eval(ctx Activation) ref.Val { } entries[keyVal] = valVal } - return types.NewDynamicMap(m.adapter, entries) + return m.adapter.NativeToValue(entries) } // Cost implements the Coster interface method. diff --git a/vendor/github.com/google/cel-go/interpreter/planner.go b/vendor/github.com/google/cel-go/interpreter/planner.go index 5755343f7..acfe31e6f 100644 --- a/vendor/github.com/google/cel-go/interpreter/planner.go +++ b/vendor/github.com/google/cel-go/interpreter/planner.go @@ -256,7 +256,7 @@ func (p *planner) planCall(expr *exprpb.Expr) (Interpretable, error) { offset++ } - args := make([]Interpretable, argCount, argCount) + args := make([]Interpretable, argCount) if target != nil { arg, err := p.Plan(target) if err != nil { @@ -513,7 +513,7 @@ func (p *planner) planCallIndex(expr *exprpb.Expr, // planCreateList generates a list construction Interpretable. func (p *planner) planCreateList(expr *exprpb.Expr) (Interpretable, error) { list := expr.GetListExpr() - elems := make([]Interpretable, len(list.GetElements()), len(list.GetElements())) + elems := make([]Interpretable, len(list.GetElements())) for i, elem := range list.GetElements() { elemVal, err := p.Plan(elem) if err != nil { @@ -639,7 +639,7 @@ func (p *planner) constValue(c *exprpb.Constant) (ref.Val, error) { case *exprpb.Constant_DoubleValue: return types.Double(c.GetDoubleValue()), nil case *exprpb.Constant_DurationValue: - return types.Duration{Duration: c.GetDurationValue()}, nil + return types.Duration{Duration: c.GetDurationValue().AsDuration()}, nil case *exprpb.Constant_Int64Value: return types.Int(c.GetInt64Value()), nil case *exprpb.Constant_NullValue: @@ -647,7 +647,7 @@ func (p *planner) constValue(c *exprpb.Constant) (ref.Val, error) { case *exprpb.Constant_StringValue: return types.String(c.GetStringValue()), nil case *exprpb.Constant_TimestampValue: - return types.Timestamp{Timestamp: c.GetTimestampValue()}, nil + return types.Timestamp{Time: c.GetTimestampValue().AsTime()}, nil case *exprpb.Constant_Uint64Value: return types.Uint(c.GetUint64Value()), nil } diff --git a/vendor/github.com/google/cel-go/interpreter/prune.go b/vendor/github.com/google/cel-go/interpreter/prune.go index 18257650e..7bcbb6c9e 100644 --- a/vendor/github.com/google/cel-go/interpreter/prune.go +++ b/vendor/github.com/google/cel-go/interpreter/prune.go @@ -20,9 +20,8 @@ import ( "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/common/types/traits" - structpb "github.com/golang/protobuf/ptypes/struct" + structpb "google.golang.org/protobuf/types/known/structpb" - expr "google.golang.org/genproto/googleapis/api/expr/v1alpha1" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) @@ -122,7 +121,7 @@ func (p *astPruner) maybeCreateLiteral(id int64, val ref.Val) (*exprpb.Expr, boo return &exprpb.Expr{ Id: id, ExprKind: &exprpb.Expr_ListExpr{ - ListExpr: &expr.Expr_CreateList{ + ListExpr: &exprpb.Expr_CreateList{ Elements: elemExprs, }, }, @@ -381,14 +380,13 @@ func (p *astPruner) existsWithKnownValue(id int64) bool { } func (p *astPruner) nextID() int64 { - for true { + for { _, found := p.state.Value(p.nextExprID) - if found { - break + if !found { + next := p.nextExprID + p.nextExprID++ + return next } p.nextExprID++ } - next := p.nextExprID - p.nextExprID++ - return next } diff --git a/vendor/github.com/google/cel-go/parser/BUILD.bazel b/vendor/github.com/google/cel-go/parser/BUILD.bazel index b2ba32cac..96b44da96 100644 --- a/vendor/github.com/google/cel-go/parser/BUILD.bazel +++ b/vendor/github.com/google/cel-go/parser/BUILD.bazel @@ -20,9 +20,9 @@ go_library( "//common/operators:go_default_library", "//parser/gen:go_default_library", "@com_github_antlr//runtime/Go/antlr:go_default_library", - "@com_github_golang_protobuf//proto:go_default_library", + "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", - "@io_bazel_rules_go//proto/wkt:struct_go_proto", + "@org_golang_google_protobuf//types/known/structpb:go_default_library", ], visibility = ["//visibility:public"], ) @@ -43,7 +43,7 @@ go_test( "//common/debug:go_default_library", "//parser/gen:go_default_library", "//test:go_default_library", - "@com_github_golang_protobuf//proto:go_default_library", + "@org_golang_google_protobuf//proto:go_default_library", "@com_github_antlr//runtime/Go/antlr:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/parser/gen/CEL.g4 b/vendor/github.com/google/cel-go/parser/gen/CEL.g4 index 7a6bcd60d..792812028 100644 --- a/vendor/github.com/google/cel-go/parser/gen/CEL.g4 +++ b/vendor/github.com/google/cel-go/parser/gen/CEL.g4 @@ -54,14 +54,14 @@ member : primary # PrimaryExpr | member op='.' id=IDENTIFIER (open='(' args=exprList? ')')? # SelectOrCall | member op='[' index=expr ']' # Index - | member op='{' entries=fieldInitializerList? '}' # CreateMessage + | member op='{' entries=fieldInitializerList? ','? '}' # CreateMessage ; primary : leadingDot='.'? id=IDENTIFIER (op='(' args=exprList? ')')? # IdentOrGlobalCall | '(' e=expr ')' # Nested | op='[' elems=exprList? ','? ']' # CreateList - | op='{' entries=mapInitializerList? '}' # CreateStruct + | op='{' entries=mapInitializerList? ','? '}' # CreateStruct | literal # ConstantLiteral ; diff --git a/vendor/github.com/google/cel-go/parser/gen/CEL.tokens b/vendor/github.com/google/cel-go/parser/gen/CEL.tokens index ce78395aa..c99e4c021 100644 --- a/vendor/github.com/google/cel-go/parser/gen/CEL.tokens +++ b/vendor/github.com/google/cel-go/parser/gen/CEL.tokens @@ -1,6 +1,6 @@ -T__0=1 -EQUALS=2 -NOT_EQUALS=3 +EQUALS=1 +NOT_EQUALS=2 +IN=3 LESS=4 LESS_EQUALS=5 GREATER_EQUALS=6 @@ -34,9 +34,9 @@ NUM_UINT=33 STRING=34 BYTES=35 IDENTIFIER=36 -'in'=1 -'=='=2 -'!='=3 +'=='=1 +'!='=2 +'in'=3 '<'=4 '<='=5 '>='=6 diff --git a/vendor/github.com/google/cel-go/parser/gen/CELLexer.tokens b/vendor/github.com/google/cel-go/parser/gen/CELLexer.tokens index ce78395aa..c99e4c021 100644 --- a/vendor/github.com/google/cel-go/parser/gen/CELLexer.tokens +++ b/vendor/github.com/google/cel-go/parser/gen/CELLexer.tokens @@ -1,6 +1,6 @@ -T__0=1 -EQUALS=2 -NOT_EQUALS=3 +EQUALS=1 +NOT_EQUALS=2 +IN=3 LESS=4 LESS_EQUALS=5 GREATER_EQUALS=6 @@ -34,9 +34,9 @@ NUM_UINT=33 STRING=34 BYTES=35 IDENTIFIER=36 -'in'=1 -'=='=2 -'!='=3 +'=='=1 +'!='=2 +'in'=3 '<'=4 '<='=5 '>='=6 diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go b/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go index 9f27b266f..94f6c5881 100644 --- a/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go +++ b/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go @@ -1,4 +1,4 @@ -// Generated from /Users/tswadell/lace/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.7. +// Generated from /Users/tswadell/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.7. package gen // CEL import "github.com/antlr/antlr4/runtime/Go/antlr" diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go b/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go index e4f32e619..bb46a64d5 100644 --- a/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go +++ b/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go @@ -1,4 +1,4 @@ -// Generated from /Users/tswadell/lace/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.7. +// Generated from /Users/tswadell/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.7. package gen // CEL import "github.com/antlr/antlr4/runtime/Go/antlr" diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go b/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go index e474a5b91..b76f78a65 100644 --- a/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go +++ b/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go @@ -1,4 +1,4 @@ -// Generated from /Users/tswadell/lace/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.7. +// Generated from /Users/tswadell/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.7. package gen @@ -94,9 +94,9 @@ var serializedLexerAtn = []uint16{ 3, 2, 2, 2, 73, 195, 3, 2, 2, 2, 75, 198, 3, 2, 2, 2, 77, 203, 3, 2, 2, 2, 79, 226, 3, 2, 2, 2, 81, 229, 3, 2, 2, 2, 83, 235, 3, 2, 2, 2, 85, 276, 3, 2, 2, 2, 87, 291, 3, 2, 2, 2, 89, 310, 3, 2, 2, 2, 91, 408, 3, 2, 2, - 2, 93, 410, 3, 2, 2, 2, 95, 415, 3, 2, 2, 2, 97, 98, 7, 107, 2, 2, 98, - 99, 7, 112, 2, 2, 99, 4, 3, 2, 2, 2, 100, 101, 7, 63, 2, 2, 101, 102, 7, - 63, 2, 2, 102, 6, 3, 2, 2, 2, 103, 104, 7, 35, 2, 2, 104, 105, 7, 63, 2, + 2, 93, 410, 3, 2, 2, 2, 95, 415, 3, 2, 2, 2, 97, 98, 7, 63, 2, 2, 98, 99, + 7, 63, 2, 2, 99, 4, 3, 2, 2, 2, 100, 101, 7, 35, 2, 2, 101, 102, 7, 63, + 2, 2, 102, 6, 3, 2, 2, 2, 103, 104, 7, 107, 2, 2, 104, 105, 7, 112, 2, 2, 105, 8, 3, 2, 2, 2, 106, 107, 7, 62, 2, 2, 107, 10, 3, 2, 2, 2, 108, 109, 7, 62, 2, 2, 109, 110, 7, 63, 2, 2, 110, 12, 3, 2, 2, 2, 111, 112, 7, 64, 2, 2, 112, 113, 7, 63, 2, 2, 113, 14, 3, 2, 2, 2, 114, 115, 7, 64, @@ -224,13 +224,13 @@ var lexerModeNames = []string{ } var lexerLiteralNames = []string{ - "", "'in'", "'=='", "'!='", "'<'", "'<='", "'>='", "'>'", "'&&'", "'||'", + "", "'=='", "'!='", "'in'", "'<'", "'<='", "'>='", "'>'", "'&&'", "'||'", "'['", "']'", "'{'", "'}'", "'('", "')'", "'.'", "','", "'-'", "'!'", "'?'", "':'", "'+'", "'*'", "'/'", "'%'", "'true'", "'false'", "'null'", } var lexerSymbolicNames = []string{ - "", "", "EQUALS", "NOT_EQUALS", "LESS", "LESS_EQUALS", "GREATER_EQUALS", + "", "EQUALS", "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", "GREATER_EQUALS", "GREATER", "LOGICAL_AND", "LOGICAL_OR", "LBRACKET", "RPRACKET", "LBRACE", "RBRACE", "LPAREN", "RPAREN", "DOT", "COMMA", "MINUS", "EXCLAM", "QUESTIONMARK", "COLON", "PLUS", "STAR", "SLASH", "PERCENT", "TRUE", "FALSE", "NULL", "WHITESPACE", @@ -238,7 +238,7 @@ var lexerSymbolicNames = []string{ } var lexerRuleNames = []string{ - "T__0", "EQUALS", "NOT_EQUALS", "LESS", "LESS_EQUALS", "GREATER_EQUALS", + "EQUALS", "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", "GREATER_EQUALS", "GREATER", "LOGICAL_AND", "LOGICAL_OR", "LBRACKET", "RPRACKET", "LBRACE", "RBRACE", "LPAREN", "RPAREN", "DOT", "COMMA", "MINUS", "EXCLAM", "QUESTIONMARK", "COLON", "PLUS", "STAR", "SLASH", "PERCENT", "TRUE", "FALSE", "NULL", "BACKSLASH", @@ -280,9 +280,9 @@ func NewCELLexer(input antlr.CharStream) *CELLexer { // CELLexer tokens. const ( - CELLexerT__0 = 1 - CELLexerEQUALS = 2 - CELLexerNOT_EQUALS = 3 + CELLexerEQUALS = 1 + CELLexerNOT_EQUALS = 2 + CELLexerIN = 3 CELLexerLESS = 4 CELLexerLESS_EQUALS = 5 CELLexerGREATER_EQUALS = 6 diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_listener.go b/vendor/github.com/google/cel-go/parser/gen/cel_listener.go index 7eaba7264..9abfc1121 100644 --- a/vendor/github.com/google/cel-go/parser/gen/cel_listener.go +++ b/vendor/github.com/google/cel-go/parser/gen/cel_listener.go @@ -1,4 +1,4 @@ -// Generated from /Users/tswadell/lace/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.7. +// Generated from /Users/tswadell/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.7. package gen // CEL import "github.com/antlr/antlr4/runtime/Go/antlr" diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_parser.go b/vendor/github.com/google/cel-go/parser/gen/cel_parser.go index a7d65397a..d99ed1c6a 100644 --- a/vendor/github.com/google/cel-go/parser/gen/cel_parser.go +++ b/vendor/github.com/google/cel-go/parser/gen/cel_parser.go @@ -1,4 +1,4 @@ -// Generated from /Users/tswadell/lace/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.7. +// Generated from /Users/tswadell/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.7. package gen // CEL import ( @@ -15,7 +15,7 @@ var _ = reflect.Copy var _ = strconv.Itoa var parserATN = []uint16{ - 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 38, 205, + 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 38, 211, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -27,96 +27,99 @@ var parserATN = []uint16{ 3, 8, 3, 8, 6, 8, 89, 10, 8, 13, 8, 14, 8, 90, 3, 8, 5, 8, 94, 10, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 104, 10, 9, 3, 9, 5, 9, 107, 10, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 117, - 10, 9, 3, 9, 7, 9, 120, 10, 9, 12, 9, 14, 9, 123, 11, 9, 3, 10, 5, 10, - 126, 10, 10, 3, 10, 3, 10, 3, 10, 5, 10, 131, 10, 10, 3, 10, 5, 10, 134, - 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 5, 10, 142, 10, 10, 3, - 10, 5, 10, 145, 10, 10, 3, 10, 3, 10, 3, 10, 5, 10, 150, 10, 10, 3, 10, - 3, 10, 5, 10, 154, 10, 10, 3, 11, 3, 11, 3, 11, 7, 11, 159, 10, 11, 12, - 11, 14, 11, 162, 11, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, - 7, 12, 171, 10, 12, 12, 12, 14, 12, 174, 11, 12, 3, 13, 3, 13, 3, 13, 3, - 13, 3, 13, 3, 13, 3, 13, 3, 13, 7, 13, 184, 10, 13, 12, 13, 14, 13, 187, - 11, 13, 3, 14, 5, 14, 190, 10, 14, 3, 14, 3, 14, 3, 14, 5, 14, 195, 10, - 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 5, 14, 203, 10, 14, 3, 14, - 2, 5, 10, 12, 16, 15, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 2, - 5, 3, 2, 3, 9, 3, 2, 25, 27, 4, 2, 20, 20, 24, 24, 2, 229, 2, 28, 3, 2, - 2, 2, 4, 31, 3, 2, 2, 2, 6, 39, 3, 2, 2, 2, 8, 47, 3, 2, 2, 2, 10, 55, - 3, 2, 2, 2, 12, 66, 3, 2, 2, 2, 14, 93, 3, 2, 2, 2, 16, 95, 3, 2, 2, 2, - 18, 153, 3, 2, 2, 2, 20, 155, 3, 2, 2, 2, 22, 163, 3, 2, 2, 2, 24, 175, - 3, 2, 2, 2, 26, 202, 3, 2, 2, 2, 28, 29, 5, 4, 3, 2, 29, 30, 7, 2, 2, 3, - 30, 3, 3, 2, 2, 2, 31, 37, 5, 6, 4, 2, 32, 33, 7, 22, 2, 2, 33, 34, 5, - 6, 4, 2, 34, 35, 7, 23, 2, 2, 35, 36, 5, 4, 3, 2, 36, 38, 3, 2, 2, 2, 37, - 32, 3, 2, 2, 2, 37, 38, 3, 2, 2, 2, 38, 5, 3, 2, 2, 2, 39, 44, 5, 8, 5, - 2, 40, 41, 7, 11, 2, 2, 41, 43, 5, 8, 5, 2, 42, 40, 3, 2, 2, 2, 43, 46, - 3, 2, 2, 2, 44, 42, 3, 2, 2, 2, 44, 45, 3, 2, 2, 2, 45, 7, 3, 2, 2, 2, - 46, 44, 3, 2, 2, 2, 47, 52, 5, 10, 6, 2, 48, 49, 7, 10, 2, 2, 49, 51, 5, - 10, 6, 2, 50, 48, 3, 2, 2, 2, 51, 54, 3, 2, 2, 2, 52, 50, 3, 2, 2, 2, 52, - 53, 3, 2, 2, 2, 53, 9, 3, 2, 2, 2, 54, 52, 3, 2, 2, 2, 55, 56, 8, 6, 1, - 2, 56, 57, 5, 12, 7, 2, 57, 63, 3, 2, 2, 2, 58, 59, 12, 3, 2, 2, 59, 60, - 9, 2, 2, 2, 60, 62, 5, 10, 6, 4, 61, 58, 3, 2, 2, 2, 62, 65, 3, 2, 2, 2, - 63, 61, 3, 2, 2, 2, 63, 64, 3, 2, 2, 2, 64, 11, 3, 2, 2, 2, 65, 63, 3, - 2, 2, 2, 66, 67, 8, 7, 1, 2, 67, 68, 5, 14, 8, 2, 68, 77, 3, 2, 2, 2, 69, - 70, 12, 4, 2, 2, 70, 71, 9, 3, 2, 2, 71, 76, 5, 12, 7, 5, 72, 73, 12, 3, - 2, 2, 73, 74, 9, 4, 2, 2, 74, 76, 5, 12, 7, 4, 75, 69, 3, 2, 2, 2, 75, - 72, 3, 2, 2, 2, 76, 79, 3, 2, 2, 2, 77, 75, 3, 2, 2, 2, 77, 78, 3, 2, 2, - 2, 78, 13, 3, 2, 2, 2, 79, 77, 3, 2, 2, 2, 80, 94, 5, 16, 9, 2, 81, 83, - 7, 21, 2, 2, 82, 81, 3, 2, 2, 2, 83, 84, 3, 2, 2, 2, 84, 82, 3, 2, 2, 2, - 84, 85, 3, 2, 2, 2, 85, 86, 3, 2, 2, 2, 86, 94, 5, 16, 9, 2, 87, 89, 7, - 20, 2, 2, 88, 87, 3, 2, 2, 2, 89, 90, 3, 2, 2, 2, 90, 88, 3, 2, 2, 2, 90, - 91, 3, 2, 2, 2, 91, 92, 3, 2, 2, 2, 92, 94, 5, 16, 9, 2, 93, 80, 3, 2, - 2, 2, 93, 82, 3, 2, 2, 2, 93, 88, 3, 2, 2, 2, 94, 15, 3, 2, 2, 2, 95, 96, - 8, 9, 1, 2, 96, 97, 5, 18, 10, 2, 97, 121, 3, 2, 2, 2, 98, 99, 12, 5, 2, - 2, 99, 100, 7, 18, 2, 2, 100, 106, 7, 38, 2, 2, 101, 103, 7, 16, 2, 2, - 102, 104, 5, 20, 11, 2, 103, 102, 3, 2, 2, 2, 103, 104, 3, 2, 2, 2, 104, - 105, 3, 2, 2, 2, 105, 107, 7, 17, 2, 2, 106, 101, 3, 2, 2, 2, 106, 107, - 3, 2, 2, 2, 107, 120, 3, 2, 2, 2, 108, 109, 12, 4, 2, 2, 109, 110, 7, 12, - 2, 2, 110, 111, 5, 4, 3, 2, 111, 112, 7, 13, 2, 2, 112, 120, 3, 2, 2, 2, - 113, 114, 12, 3, 2, 2, 114, 116, 7, 14, 2, 2, 115, 117, 5, 22, 12, 2, 116, - 115, 3, 2, 2, 2, 116, 117, 3, 2, 2, 2, 117, 118, 3, 2, 2, 2, 118, 120, - 7, 15, 2, 2, 119, 98, 3, 2, 2, 2, 119, 108, 3, 2, 2, 2, 119, 113, 3, 2, - 2, 2, 120, 123, 3, 2, 2, 2, 121, 119, 3, 2, 2, 2, 121, 122, 3, 2, 2, 2, - 122, 17, 3, 2, 2, 2, 123, 121, 3, 2, 2, 2, 124, 126, 7, 18, 2, 2, 125, - 124, 3, 2, 2, 2, 125, 126, 3, 2, 2, 2, 126, 127, 3, 2, 2, 2, 127, 133, - 7, 38, 2, 2, 128, 130, 7, 16, 2, 2, 129, 131, 5, 20, 11, 2, 130, 129, 3, - 2, 2, 2, 130, 131, 3, 2, 2, 2, 131, 132, 3, 2, 2, 2, 132, 134, 7, 17, 2, - 2, 133, 128, 3, 2, 2, 2, 133, 134, 3, 2, 2, 2, 134, 154, 3, 2, 2, 2, 135, - 136, 7, 16, 2, 2, 136, 137, 5, 4, 3, 2, 137, 138, 7, 17, 2, 2, 138, 154, - 3, 2, 2, 2, 139, 141, 7, 12, 2, 2, 140, 142, 5, 20, 11, 2, 141, 140, 3, - 2, 2, 2, 141, 142, 3, 2, 2, 2, 142, 144, 3, 2, 2, 2, 143, 145, 7, 19, 2, - 2, 144, 143, 3, 2, 2, 2, 144, 145, 3, 2, 2, 2, 145, 146, 3, 2, 2, 2, 146, - 154, 7, 13, 2, 2, 147, 149, 7, 14, 2, 2, 148, 150, 5, 24, 13, 2, 149, 148, - 3, 2, 2, 2, 149, 150, 3, 2, 2, 2, 150, 151, 3, 2, 2, 2, 151, 154, 7, 15, - 2, 2, 152, 154, 5, 26, 14, 2, 153, 125, 3, 2, 2, 2, 153, 135, 3, 2, 2, - 2, 153, 139, 3, 2, 2, 2, 153, 147, 3, 2, 2, 2, 153, 152, 3, 2, 2, 2, 154, - 19, 3, 2, 2, 2, 155, 160, 5, 4, 3, 2, 156, 157, 7, 19, 2, 2, 157, 159, - 5, 4, 3, 2, 158, 156, 3, 2, 2, 2, 159, 162, 3, 2, 2, 2, 160, 158, 3, 2, - 2, 2, 160, 161, 3, 2, 2, 2, 161, 21, 3, 2, 2, 2, 162, 160, 3, 2, 2, 2, - 163, 164, 7, 38, 2, 2, 164, 165, 7, 23, 2, 2, 165, 172, 5, 4, 3, 2, 166, - 167, 7, 19, 2, 2, 167, 168, 7, 38, 2, 2, 168, 169, 7, 23, 2, 2, 169, 171, - 5, 4, 3, 2, 170, 166, 3, 2, 2, 2, 171, 174, 3, 2, 2, 2, 172, 170, 3, 2, - 2, 2, 172, 173, 3, 2, 2, 2, 173, 23, 3, 2, 2, 2, 174, 172, 3, 2, 2, 2, - 175, 176, 5, 4, 3, 2, 176, 177, 7, 23, 2, 2, 177, 185, 5, 4, 3, 2, 178, - 179, 7, 19, 2, 2, 179, 180, 5, 4, 3, 2, 180, 181, 7, 23, 2, 2, 181, 182, - 5, 4, 3, 2, 182, 184, 3, 2, 2, 2, 183, 178, 3, 2, 2, 2, 184, 187, 3, 2, - 2, 2, 185, 183, 3, 2, 2, 2, 185, 186, 3, 2, 2, 2, 186, 25, 3, 2, 2, 2, - 187, 185, 3, 2, 2, 2, 188, 190, 7, 20, 2, 2, 189, 188, 3, 2, 2, 2, 189, - 190, 3, 2, 2, 2, 190, 191, 3, 2, 2, 2, 191, 203, 7, 34, 2, 2, 192, 203, - 7, 35, 2, 2, 193, 195, 7, 20, 2, 2, 194, 193, 3, 2, 2, 2, 194, 195, 3, - 2, 2, 2, 195, 196, 3, 2, 2, 2, 196, 203, 7, 33, 2, 2, 197, 203, 7, 36, - 2, 2, 198, 203, 7, 37, 2, 2, 199, 203, 7, 28, 2, 2, 200, 203, 7, 29, 2, - 2, 201, 203, 7, 30, 2, 2, 202, 189, 3, 2, 2, 2, 202, 192, 3, 2, 2, 2, 202, - 194, 3, 2, 2, 2, 202, 197, 3, 2, 2, 2, 202, 198, 3, 2, 2, 2, 202, 199, - 3, 2, 2, 2, 202, 200, 3, 2, 2, 2, 202, 201, 3, 2, 2, 2, 203, 27, 3, 2, - 2, 2, 29, 37, 44, 52, 63, 75, 77, 84, 90, 93, 103, 106, 116, 119, 121, - 125, 130, 133, 141, 144, 149, 153, 160, 172, 185, 189, 194, 202, + 10, 9, 3, 9, 5, 9, 120, 10, 9, 3, 9, 7, 9, 123, 10, 9, 12, 9, 14, 9, 126, + 11, 9, 3, 10, 5, 10, 129, 10, 10, 3, 10, 3, 10, 3, 10, 5, 10, 134, 10, + 10, 3, 10, 5, 10, 137, 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, + 5, 10, 145, 10, 10, 3, 10, 5, 10, 148, 10, 10, 3, 10, 3, 10, 3, 10, 5, + 10, 153, 10, 10, 3, 10, 5, 10, 156, 10, 10, 3, 10, 3, 10, 5, 10, 160, 10, + 10, 3, 11, 3, 11, 3, 11, 7, 11, 165, 10, 11, 12, 11, 14, 11, 168, 11, 11, + 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 7, 12, 177, 10, 12, 12, + 12, 14, 12, 180, 11, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, + 3, 13, 7, 13, 190, 10, 13, 12, 13, 14, 13, 193, 11, 13, 3, 14, 5, 14, 196, + 10, 14, 3, 14, 3, 14, 3, 14, 5, 14, 201, 10, 14, 3, 14, 3, 14, 3, 14, 3, + 14, 3, 14, 3, 14, 5, 14, 209, 10, 14, 3, 14, 2, 5, 10, 12, 16, 15, 2, 4, + 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 2, 5, 3, 2, 3, 9, 3, 2, 25, 27, + 4, 2, 20, 20, 24, 24, 2, 237, 2, 28, 3, 2, 2, 2, 4, 31, 3, 2, 2, 2, 6, + 39, 3, 2, 2, 2, 8, 47, 3, 2, 2, 2, 10, 55, 3, 2, 2, 2, 12, 66, 3, 2, 2, + 2, 14, 93, 3, 2, 2, 2, 16, 95, 3, 2, 2, 2, 18, 159, 3, 2, 2, 2, 20, 161, + 3, 2, 2, 2, 22, 169, 3, 2, 2, 2, 24, 181, 3, 2, 2, 2, 26, 208, 3, 2, 2, + 2, 28, 29, 5, 4, 3, 2, 29, 30, 7, 2, 2, 3, 30, 3, 3, 2, 2, 2, 31, 37, 5, + 6, 4, 2, 32, 33, 7, 22, 2, 2, 33, 34, 5, 6, 4, 2, 34, 35, 7, 23, 2, 2, + 35, 36, 5, 4, 3, 2, 36, 38, 3, 2, 2, 2, 37, 32, 3, 2, 2, 2, 37, 38, 3, + 2, 2, 2, 38, 5, 3, 2, 2, 2, 39, 44, 5, 8, 5, 2, 40, 41, 7, 11, 2, 2, 41, + 43, 5, 8, 5, 2, 42, 40, 3, 2, 2, 2, 43, 46, 3, 2, 2, 2, 44, 42, 3, 2, 2, + 2, 44, 45, 3, 2, 2, 2, 45, 7, 3, 2, 2, 2, 46, 44, 3, 2, 2, 2, 47, 52, 5, + 10, 6, 2, 48, 49, 7, 10, 2, 2, 49, 51, 5, 10, 6, 2, 50, 48, 3, 2, 2, 2, + 51, 54, 3, 2, 2, 2, 52, 50, 3, 2, 2, 2, 52, 53, 3, 2, 2, 2, 53, 9, 3, 2, + 2, 2, 54, 52, 3, 2, 2, 2, 55, 56, 8, 6, 1, 2, 56, 57, 5, 12, 7, 2, 57, + 63, 3, 2, 2, 2, 58, 59, 12, 3, 2, 2, 59, 60, 9, 2, 2, 2, 60, 62, 5, 10, + 6, 4, 61, 58, 3, 2, 2, 2, 62, 65, 3, 2, 2, 2, 63, 61, 3, 2, 2, 2, 63, 64, + 3, 2, 2, 2, 64, 11, 3, 2, 2, 2, 65, 63, 3, 2, 2, 2, 66, 67, 8, 7, 1, 2, + 67, 68, 5, 14, 8, 2, 68, 77, 3, 2, 2, 2, 69, 70, 12, 4, 2, 2, 70, 71, 9, + 3, 2, 2, 71, 76, 5, 12, 7, 5, 72, 73, 12, 3, 2, 2, 73, 74, 9, 4, 2, 2, + 74, 76, 5, 12, 7, 4, 75, 69, 3, 2, 2, 2, 75, 72, 3, 2, 2, 2, 76, 79, 3, + 2, 2, 2, 77, 75, 3, 2, 2, 2, 77, 78, 3, 2, 2, 2, 78, 13, 3, 2, 2, 2, 79, + 77, 3, 2, 2, 2, 80, 94, 5, 16, 9, 2, 81, 83, 7, 21, 2, 2, 82, 81, 3, 2, + 2, 2, 83, 84, 3, 2, 2, 2, 84, 82, 3, 2, 2, 2, 84, 85, 3, 2, 2, 2, 85, 86, + 3, 2, 2, 2, 86, 94, 5, 16, 9, 2, 87, 89, 7, 20, 2, 2, 88, 87, 3, 2, 2, + 2, 89, 90, 3, 2, 2, 2, 90, 88, 3, 2, 2, 2, 90, 91, 3, 2, 2, 2, 91, 92, + 3, 2, 2, 2, 92, 94, 5, 16, 9, 2, 93, 80, 3, 2, 2, 2, 93, 82, 3, 2, 2, 2, + 93, 88, 3, 2, 2, 2, 94, 15, 3, 2, 2, 2, 95, 96, 8, 9, 1, 2, 96, 97, 5, + 18, 10, 2, 97, 124, 3, 2, 2, 2, 98, 99, 12, 5, 2, 2, 99, 100, 7, 18, 2, + 2, 100, 106, 7, 38, 2, 2, 101, 103, 7, 16, 2, 2, 102, 104, 5, 20, 11, 2, + 103, 102, 3, 2, 2, 2, 103, 104, 3, 2, 2, 2, 104, 105, 3, 2, 2, 2, 105, + 107, 7, 17, 2, 2, 106, 101, 3, 2, 2, 2, 106, 107, 3, 2, 2, 2, 107, 123, + 3, 2, 2, 2, 108, 109, 12, 4, 2, 2, 109, 110, 7, 12, 2, 2, 110, 111, 5, + 4, 3, 2, 111, 112, 7, 13, 2, 2, 112, 123, 3, 2, 2, 2, 113, 114, 12, 3, + 2, 2, 114, 116, 7, 14, 2, 2, 115, 117, 5, 22, 12, 2, 116, 115, 3, 2, 2, + 2, 116, 117, 3, 2, 2, 2, 117, 119, 3, 2, 2, 2, 118, 120, 7, 19, 2, 2, 119, + 118, 3, 2, 2, 2, 119, 120, 3, 2, 2, 2, 120, 121, 3, 2, 2, 2, 121, 123, + 7, 15, 2, 2, 122, 98, 3, 2, 2, 2, 122, 108, 3, 2, 2, 2, 122, 113, 3, 2, + 2, 2, 123, 126, 3, 2, 2, 2, 124, 122, 3, 2, 2, 2, 124, 125, 3, 2, 2, 2, + 125, 17, 3, 2, 2, 2, 126, 124, 3, 2, 2, 2, 127, 129, 7, 18, 2, 2, 128, + 127, 3, 2, 2, 2, 128, 129, 3, 2, 2, 2, 129, 130, 3, 2, 2, 2, 130, 136, + 7, 38, 2, 2, 131, 133, 7, 16, 2, 2, 132, 134, 5, 20, 11, 2, 133, 132, 3, + 2, 2, 2, 133, 134, 3, 2, 2, 2, 134, 135, 3, 2, 2, 2, 135, 137, 7, 17, 2, + 2, 136, 131, 3, 2, 2, 2, 136, 137, 3, 2, 2, 2, 137, 160, 3, 2, 2, 2, 138, + 139, 7, 16, 2, 2, 139, 140, 5, 4, 3, 2, 140, 141, 7, 17, 2, 2, 141, 160, + 3, 2, 2, 2, 142, 144, 7, 12, 2, 2, 143, 145, 5, 20, 11, 2, 144, 143, 3, + 2, 2, 2, 144, 145, 3, 2, 2, 2, 145, 147, 3, 2, 2, 2, 146, 148, 7, 19, 2, + 2, 147, 146, 3, 2, 2, 2, 147, 148, 3, 2, 2, 2, 148, 149, 3, 2, 2, 2, 149, + 160, 7, 13, 2, 2, 150, 152, 7, 14, 2, 2, 151, 153, 5, 24, 13, 2, 152, 151, + 3, 2, 2, 2, 152, 153, 3, 2, 2, 2, 153, 155, 3, 2, 2, 2, 154, 156, 7, 19, + 2, 2, 155, 154, 3, 2, 2, 2, 155, 156, 3, 2, 2, 2, 156, 157, 3, 2, 2, 2, + 157, 160, 7, 15, 2, 2, 158, 160, 5, 26, 14, 2, 159, 128, 3, 2, 2, 2, 159, + 138, 3, 2, 2, 2, 159, 142, 3, 2, 2, 2, 159, 150, 3, 2, 2, 2, 159, 158, + 3, 2, 2, 2, 160, 19, 3, 2, 2, 2, 161, 166, 5, 4, 3, 2, 162, 163, 7, 19, + 2, 2, 163, 165, 5, 4, 3, 2, 164, 162, 3, 2, 2, 2, 165, 168, 3, 2, 2, 2, + 166, 164, 3, 2, 2, 2, 166, 167, 3, 2, 2, 2, 167, 21, 3, 2, 2, 2, 168, 166, + 3, 2, 2, 2, 169, 170, 7, 38, 2, 2, 170, 171, 7, 23, 2, 2, 171, 178, 5, + 4, 3, 2, 172, 173, 7, 19, 2, 2, 173, 174, 7, 38, 2, 2, 174, 175, 7, 23, + 2, 2, 175, 177, 5, 4, 3, 2, 176, 172, 3, 2, 2, 2, 177, 180, 3, 2, 2, 2, + 178, 176, 3, 2, 2, 2, 178, 179, 3, 2, 2, 2, 179, 23, 3, 2, 2, 2, 180, 178, + 3, 2, 2, 2, 181, 182, 5, 4, 3, 2, 182, 183, 7, 23, 2, 2, 183, 191, 5, 4, + 3, 2, 184, 185, 7, 19, 2, 2, 185, 186, 5, 4, 3, 2, 186, 187, 7, 23, 2, + 2, 187, 188, 5, 4, 3, 2, 188, 190, 3, 2, 2, 2, 189, 184, 3, 2, 2, 2, 190, + 193, 3, 2, 2, 2, 191, 189, 3, 2, 2, 2, 191, 192, 3, 2, 2, 2, 192, 25, 3, + 2, 2, 2, 193, 191, 3, 2, 2, 2, 194, 196, 7, 20, 2, 2, 195, 194, 3, 2, 2, + 2, 195, 196, 3, 2, 2, 2, 196, 197, 3, 2, 2, 2, 197, 209, 7, 34, 2, 2, 198, + 209, 7, 35, 2, 2, 199, 201, 7, 20, 2, 2, 200, 199, 3, 2, 2, 2, 200, 201, + 3, 2, 2, 2, 201, 202, 3, 2, 2, 2, 202, 209, 7, 33, 2, 2, 203, 209, 7, 36, + 2, 2, 204, 209, 7, 37, 2, 2, 205, 209, 7, 28, 2, 2, 206, 209, 7, 29, 2, + 2, 207, 209, 7, 30, 2, 2, 208, 195, 3, 2, 2, 2, 208, 198, 3, 2, 2, 2, 208, + 200, 3, 2, 2, 2, 208, 203, 3, 2, 2, 2, 208, 204, 3, 2, 2, 2, 208, 205, + 3, 2, 2, 2, 208, 206, 3, 2, 2, 2, 208, 207, 3, 2, 2, 2, 209, 27, 3, 2, + 2, 2, 31, 37, 44, 52, 63, 75, 77, 84, 90, 93, 103, 106, 116, 119, 122, + 124, 128, 133, 136, 144, 147, 152, 155, 159, 166, 178, 191, 195, 200, 208, } var literalNames = []string{ - "", "'in'", "'=='", "'!='", "'<'", "'<='", "'>='", "'>'", "'&&'", "'||'", + "", "'=='", "'!='", "'in'", "'<'", "'<='", "'>='", "'>'", "'&&'", "'||'", "'['", "']'", "'{'", "'}'", "'('", "')'", "'.'", "','", "'-'", "'!'", "'?'", "':'", "'+'", "'*'", "'/'", "'%'", "'true'", "'false'", "'null'", } var symbolicNames = []string{ - "", "", "EQUALS", "NOT_EQUALS", "LESS", "LESS_EQUALS", "GREATER_EQUALS", + "", "EQUALS", "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", "GREATER_EQUALS", "GREATER", "LOGICAL_AND", "LOGICAL_OR", "LBRACKET", "RPRACKET", "LBRACE", "RBRACE", "LPAREN", "RPAREN", "DOT", "COMMA", "MINUS", "EXCLAM", "QUESTIONMARK", "COLON", "PLUS", "STAR", "SLASH", "PERCENT", "TRUE", "FALSE", "NULL", "WHITESPACE", @@ -141,6 +144,7 @@ func NewCELParser(input antlr.TokenStream) *CELParser { for index, ds := range deserializedATN.DecisionToState { decisionToDFA[index] = antlr.NewDFA(ds, index) } + this.BaseParser = antlr.NewBaseParser(input) this.Interpreter = antlr.NewParserATNSimulator(this, deserializedATN, decisionToDFA, antlr.NewPredictionContextCache()) @@ -155,9 +159,9 @@ func NewCELParser(input antlr.TokenStream) *CELParser { // CELParser tokens. const ( CELParserEOF = antlr.TokenEOF - CELParserT__0 = 1 - CELParserEQUALS = 2 - CELParserNOT_EQUALS = 3 + CELParserEQUALS = 1 + CELParserNOT_EQUALS = 2 + CELParserIN = 3 CELParserLESS = 4 CELParserLESS_EQUALS = 5 CELParserGREATER_EQUALS = 6 @@ -1135,7 +1139,7 @@ func (p *CELParser) relation(_p int) (localctx IRelationContext) { _la = p.GetTokenStream().LA(1) - if !(((_la)&-(0x1f+1)) == 0 && ((1<