diff --git a/go.mod b/go.mod
index f14d52a6f7..974561d7cf 100644
--- a/go.mod
+++ b/go.mod
@@ -7,79 +7,78 @@ require (
github.com/ghodss/yaml v1.0.0
github.com/go-bindata/go-bindata v3.1.2+incompatible
github.com/google/go-cmp v0.5.9
- github.com/openshift/api v0.0.0-20230613151523-ba04973d3ed1
+ github.com/openshift/api v0.0.0-20231010075512-1ccc6058c62d
github.com/openshift/build-machinery-go v0.0.0-20220913142420-e25cf57ea46d
- github.com/openshift/client-go v0.0.0-20230503144108-75015d2347cb
- github.com/openshift/library-go v0.0.0-20230724150037-c515269de16e
- github.com/spf13/cobra v1.6.1
- github.com/stretchr/testify v1.8.1
- go.etcd.io/etcd/client/v3 v3.5.7
- golang.org/x/net v0.8.0
+ github.com/openshift/client-go v0.0.0-20230926161409-848405da69e1
+ github.com/openshift/library-go v0.0.0-20231017173800-126f85ed0cc7
+ github.com/spf13/cobra v1.7.0
+ github.com/stretchr/testify v1.8.2
+ go.etcd.io/etcd/client/v3 v3.5.9
+ golang.org/x/net v0.17.0
gopkg.in/square/go-jose.v2 v2.6.0
gopkg.in/yaml.v2 v2.4.0
- k8s.io/api v0.27.4
- k8s.io/apimachinery v0.27.4
- k8s.io/client-go v0.27.4
- k8s.io/component-base v0.27.4
- k8s.io/klog/v2 v2.90.1
- k8s.io/kube-aggregator v0.27.4
+ k8s.io/api v0.28.2
+ k8s.io/apimachinery v0.28.2
+ k8s.io/client-go v0.28.2
+ k8s.io/component-base v0.28.2
+ k8s.io/klog/v2 v2.100.1
+ k8s.io/kube-aggregator v0.28.2
k8s.io/pod-security-admission v0.27.4
- k8s.io/utils v0.0.0-20230406110748-d93618cff8a2
+ k8s.io/utils v0.0.0-20230726121419-3b25d923346b
sigs.k8s.io/kube-storage-version-migrator v0.0.6-0.20230721195810-5c8923c5ff96
)
require (
github.com/NYTimes/gziphandler v1.1.1 // indirect
github.com/RangelReale/osincli v0.0.0-20160924135400-fababb0555f2 // indirect
- github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
+ github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
- github.com/cenkalti/backoff/v4 v4.1.3 // indirect
- github.com/cespare/xxhash/v2 v2.1.2 // indirect
- github.com/coreos/go-semver v0.3.0 // indirect
- github.com/coreos/go-systemd/v22 v22.4.0 // indirect
+ github.com/cenkalti/backoff/v4 v4.2.1 // indirect
+ github.com/cespare/xxhash/v2 v2.2.0 // indirect
+ github.com/coreos/go-semver v0.3.1 // indirect
+ github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
- github.com/go-logr/logr v1.2.3 // indirect
+ github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
- github.com/go-openapi/jsonreference v0.20.1 // indirect
+ github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
- github.com/google/cel-go v0.12.6 // indirect
- github.com/google/gnostic v0.5.7-v3refs // indirect
+ github.com/google/cel-go v0.16.1 // indirect
+ github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
github.com/imdario/mergo v0.3.7 // indirect
- github.com/inconshreveable/mousetrap v1.0.1 // indirect
+ github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
- github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect
- github.com/mitchellh/mapstructure v1.4.1 // indirect
+ github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/profile v1.3.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
- github.com/prometheus/client_golang v1.14.0 // indirect
- github.com/prometheus/client_model v0.3.0 // indirect
- github.com/prometheus/common v0.37.0 // indirect
- github.com/prometheus/procfs v0.8.0 // indirect
+ github.com/prometheus/client_golang v1.16.0 // indirect
+ github.com/prometheus/client_model v0.4.0 // indirect
+ github.com/prometheus/common v0.44.0 // indirect
+ github.com/prometheus/procfs v0.10.1 // indirect
github.com/robfig/cron v1.2.0 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
- go.etcd.io/etcd/api/v3 v3.5.7 // indirect
- go.etcd.io/etcd/client/pkg/v3 v3.5.7 // indirect
+ go.etcd.io/etcd/api/v3 v3.5.9 // indirect
+ go.etcd.io/etcd/client/pkg/v3 v3.5.9 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.1 // indirect
go.opentelemetry.io/otel v1.10.0 // indirect
@@ -90,27 +89,30 @@ require (
go.opentelemetry.io/otel/sdk v1.10.0 // indirect
go.opentelemetry.io/otel/trace v1.10.0 // indirect
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
- go.uber.org/atomic v1.7.0 // indirect
- go.uber.org/multierr v1.6.0 // indirect
+ go.uber.org/atomic v1.10.0 // indirect
+ go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.19.0 // indirect
- golang.org/x/crypto v0.1.0 // indirect
- golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
- golang.org/x/sync v0.1.0 // indirect
- golang.org/x/sys v0.6.0 // indirect
- golang.org/x/term v0.6.0 // indirect
- golang.org/x/text v0.8.0 // indirect
- golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
+ golang.org/x/crypto v0.14.0 // indirect
+ golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
+ golang.org/x/oauth2 v0.8.0 // indirect
+ golang.org/x/sync v0.2.0 // indirect
+ golang.org/x/sys v0.13.0 // indirect
+ golang.org/x/term v0.13.0 // indirect
+ golang.org/x/text v0.13.0 // indirect
+ golang.org/x/time v0.3.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
- google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect
- google.golang.org/grpc v1.51.0 // indirect
- google.golang.org/protobuf v1.28.1 // indirect
+ google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54 // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
+ google.golang.org/grpc v1.54.0 // indirect
+ google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
- gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
+ gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
- k8s.io/apiextensions-apiserver v0.27.4 // indirect
- k8s.io/apiserver v0.27.4 // indirect
- k8s.io/kms v0.27.4 // indirect
- k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect
+ k8s.io/apiextensions-apiserver v0.28.2 // indirect
+ k8s.io/apiserver v0.28.2 // indirect
+ k8s.io/kms v0.28.2 // indirect
+ k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
diff --git a/go.sum b/go.sum
index 3d0cdff300..2e8de9378d 100644
--- a/go.sum
+++ b/go.sum
@@ -13,13 +13,15 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
-cloud.google.com/go v0.97.0 h1:3DXvAyifywvq64LfkKaMOmkWPS1CikIQdMe2lY9vxU8=
+cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
+cloud.google.com/go/compute v1.19.0 h1:+9zda3WGgW1ZSTlVppLCYFIr48Pa35q1uG2N1itbCEQ=
+cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
@@ -32,7 +34,6 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
-github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
@@ -40,31 +41,24 @@ github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMo
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/RangelReale/osincli v0.0.0-20160924135400-fababb0555f2 h1:x8Brv0YNEe6jY3V/hQglIG2nd8g5E2Zj5ubGKkPQctQ=
github.com/RangelReale/osincli v0.0.0-20160924135400-fababb0555f2/go.mod h1:XyjUkMA8GN+tOOPXvnbi3XuRxWFvTJntqvTFnjmhzbk=
-github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
-github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
-github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
-github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves=
-github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=
+github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18=
+github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
-github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
-github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
-github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
-github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
+github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
+github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
-github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
+github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@@ -75,19 +69,17 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
-github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
-github.com/coreos/go-systemd/v22 v22.4.0 h1:y9YHcjnjynCd/DVbg5j9L/33jQM3MxJlbj/zWskzfGU=
-github.com/coreos/go-systemd/v22 v22.4.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
+github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
+github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
+github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
+github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
-github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
+github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE=
github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@@ -96,7 +88,6 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
-github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
@@ -111,34 +102,24 @@ github.com/go-bindata/go-bindata v3.1.2+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
-github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
-github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
-github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
-github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
-github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
-github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
+github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
-github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8=
-github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
+github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
+github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
-github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
-github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
+github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
@@ -175,10 +156,10 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
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/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
-github.com/google/cel-go v0.12.6 h1:kjeKudqV0OygrAqA9fX6J55S8gj+Jre2tckIm5RoG4M=
-github.com/google/cel-go v0.12.6/go.mod h1:Jk7ljRzLBhkmiAwBoUxB1sZSCVBAzkqPF25olK/iRDw=
-github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
-github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ=
+github.com/google/cel-go v0.16.1 h1:3hZfSNiAU3KOiNtxuFXVp5WFy4hf/Ly3Sa4/7F8SXNo=
+github.com/google/cel-go v0.16.1/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY=
+github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
+github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
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=
@@ -186,7 +167,6 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
@@ -223,63 +203,45 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI=
github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
-github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
-github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
-github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
-github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
-github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
-github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
-github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
-github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM=
-github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
-github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
-github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
+github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
-github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU=
-github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
-github.com/openshift/api v0.0.0-20230613151523-ba04973d3ed1 h1:sgr89m3ejIIKhSbTtHq7HEZ80et4IAXDrJlk+u+rYX8=
-github.com/openshift/api v0.0.0-20230613151523-ba04973d3ed1/go.mod h1:4VWG+W22wrB4HfBL88P40DxLEpSOaiBVxUnfalfJo9k=
+github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE=
+github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
+github.com/openshift/api v0.0.0-20231010075512-1ccc6058c62d h1:KZRCA2bExuO7wU5MSvDu2Cs9qe9nFUTh3ITReJp7iaQ=
+github.com/openshift/api v0.0.0-20231010075512-1ccc6058c62d/go.mod h1:qNtV0315F+f8ld52TLtPvrfivZpdimOzTi3kn9IVbtU=
github.com/openshift/build-machinery-go v0.0.0-20220913142420-e25cf57ea46d h1:RR4ah7FfaPR1WePizm0jlrsbmPu91xQZnAsVVreQV1k=
github.com/openshift/build-machinery-go v0.0.0-20220913142420-e25cf57ea46d/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE=
-github.com/openshift/client-go v0.0.0-20230503144108-75015d2347cb h1:Nij5OnaECrkmcRQMAE9LMbQXPo95aqFnf+12B7SyFVI=
-github.com/openshift/client-go v0.0.0-20230503144108-75015d2347cb/go.mod h1:Rhb3moCqeiTuGHAbXBOlwPubUMlOZEkrEWTRjIF3jzs=
-github.com/openshift/library-go v0.0.0-20230724150037-c515269de16e h1:E8KSHPb3c68Bjf7I7+A6B5M3j7q3qB1r4or94P8Hqd8=
-github.com/openshift/library-go v0.0.0-20230724150037-c515269de16e/go.mod h1:jPcIZk2ReAozFTDX2s9peO5at1Hs1BS6JvoASSk6NqQ=
-github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/openshift/client-go v0.0.0-20230926161409-848405da69e1 h1:W1N/3nVciqmjPjn2xldHjb0AwwCQzlGxLvX5BCgE8H4=
+github.com/openshift/client-go v0.0.0-20230926161409-848405da69e1/go.mod h1:ihUJrhBcYAGYQrJu/gP2OMgfVds5f5z5kbeLNBqjHLo=
+github.com/openshift/library-go v0.0.0-20231017173800-126f85ed0cc7 h1:pJLcCSJzdiWCaJ4bAepgnvwMdP33LumbVJyWSW7+3ng=
+github.com/openshift/library-go v0.0.0-20231017173800-126f85ed0cc7/go.mod h1:jgxNp8aApJnZtECid9SUSr5Bu6DLo8Hfdv1DgFZaYA8=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -287,81 +249,60 @@ github.com/pkg/profile v1.3.0 h1:OQIvuDgm00gWVWGTf4m4mCt6W1/0YqU7Ntg0mySWgaI=
github.com/pkg/profile v1.3.0/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
-github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
-github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
-github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
-github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
-github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
-github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
+github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
-github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
-github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
-github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
-github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
-github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
-github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
-github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
-github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
-github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
-github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
-github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
-github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
-github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
+github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
+github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
+github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
+github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
+github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
+github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
+github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
-github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
-github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
-github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
-github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
+github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
+github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
-github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
+github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
-go.etcd.io/etcd/api/v3 v3.5.7 h1:sbcmosSVesNrWOJ58ZQFitHMdncusIifYcrBfwrlJSY=
-go.etcd.io/etcd/api/v3 v3.5.7/go.mod h1:9qew1gCdDDLu+VwmeG+iFpL+QlpHTo7iubavdVDgCAA=
-go.etcd.io/etcd/client/pkg/v3 v3.5.7 h1:y3kf5Gbp4e4q7egZdn5T7W9TSHUvkClN6u+Rq9mEOmg=
-go.etcd.io/etcd/client/pkg/v3 v3.5.7/go.mod h1:o0Abi1MK86iad3YrWhgUsbGx1pmTS+hrORWc2CamuhY=
-go.etcd.io/etcd/client/v2 v2.305.7 h1:AELPkjNR3/igjbO7CjyF1fPuVPjrblliiKj+Y6xSGOU=
-go.etcd.io/etcd/client/v3 v3.5.7 h1:u/OhpiuCgYY8awOHlhIhmGIGpxfBU/GZBUP3m/3/Iz4=
-go.etcd.io/etcd/client/v3 v3.5.7/go.mod h1:sOWmj9DZUMyAngS7QQwCyAXXAL6WhgTOPLNS/NabQgw=
-go.etcd.io/etcd/pkg/v3 v3.5.7 h1:obOzeVwerFwZ9trMWapU/VjDcYUJb5OfgC1zqEGWO/0=
-go.etcd.io/etcd/raft/v3 v3.5.7 h1:aN79qxLmV3SvIq84aNTliYGmjwsW6NqJSnqmI1HLJKc=
-go.etcd.io/etcd/server/v3 v3.5.7 h1:BTBD8IJUV7YFgsczZMHhMTS67XuA4KpRquL0MFOJGRk=
+go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
+go.etcd.io/etcd/api/v3 v3.5.9 h1:4wSsluwyTbGGmyjJktOf3wFQoTBIURXHnq9n/G/JQHs=
+go.etcd.io/etcd/api/v3 v3.5.9/go.mod h1:uyAal843mC8uUVSLWz6eHa/d971iDGnCRpmKd2Z+X8k=
+go.etcd.io/etcd/client/pkg/v3 v3.5.9 h1:oidDC4+YEuSIQbsR94rY9gur91UPL6DnxDCIYd2IGsE=
+go.etcd.io/etcd/client/pkg/v3 v3.5.9/go.mod h1:y+CzeSmkMpWN2Jyu1npecjB9BBnABxGM4pN8cGuJeL4=
+go.etcd.io/etcd/client/v2 v2.305.9 h1:YZ2OLi0OvR0H75AcgSUajjd5uqKDKocQUqROTG11jIo=
+go.etcd.io/etcd/client/v3 v3.5.9 h1:r5xghnU7CwbUxD/fbUtRyJGaYNfDun8sp/gTr1hew6E=
+go.etcd.io/etcd/client/v3 v3.5.9/go.mod h1:i/Eo5LrZ5IKqpbtpPDuaUnDOUv471oDg8cjQaUr2MbA=
+go.etcd.io/etcd/pkg/v3 v3.5.9 h1:6R2jg/aWd/zB9+9JxmijDKStGJAPFsX3e6BeJkMi6eQ=
+go.etcd.io/etcd/raft/v3 v3.5.9 h1:ZZ1GIHoUlHsn0QVqiRysAm3/81Xx7+i2d7nSdWxlOiI=
+go.etcd.io/etcd/server/v3 v3.5.9 h1:vomEmmxeztLtS5OEH7d0hBAg4cjVIu9wXuNzUZx2ZA0=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@@ -388,22 +329,23 @@ go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/A
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw=
go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
-go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
+go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
-go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
+go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
+go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE=
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
-golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
+golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
+golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -414,6 +356,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
+golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
+golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -436,7 +380,6 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -444,7 +387,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
-golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -464,21 +406,16 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
-golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
-golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
+golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
+golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
-golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=
-golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
+golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
+golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -488,16 +425,12 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
-golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
+golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -506,7 +439,6 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -519,43 +451,31 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
-golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
-golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
+golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
+golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
-golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44=
-golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
+golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -599,7 +519,7 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
+golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -658,10 +578,13 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/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-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 h1:hrbNEivu7Zn1pxvHk6MBrq9iE22woVILTHqexqBxe6I=
-google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
+google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54 h1:9NWlQfY2ePejTmfwUH1OWwmznFa+0kKcHGPDvcPza9M=
+google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk=
+google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 h1:m8v1xLLLzMe1m5P+gCTF8nJB9epwZQUBERm20Oy1poQ=
+google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@@ -678,9 +601,8 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
-google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
-google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U=
-google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=
+google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag=
+google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -694,33 +616,25 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
-google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
+google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
-gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
-gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
-gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
@@ -731,30 +645,30 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-k8s.io/api v0.27.4 h1:0pCo/AN9hONazBKlNUdhQymmnfLRbSZjd5H5H3f0bSs=
-k8s.io/api v0.27.4/go.mod h1:O3smaaX15NfxjzILfiln1D8Z3+gEYpjEpiNA/1EVK1Y=
-k8s.io/apiextensions-apiserver v0.27.4 h1:ie1yZG4nY/wvFMIR2hXBeSVq+HfNzib60FjnBYtPGSs=
-k8s.io/apiextensions-apiserver v0.27.4/go.mod h1:KHZaDr5H9IbGEnSskEUp/DsdXe1hMQ7uzpQcYUFt2bM=
-k8s.io/apimachinery v0.27.4 h1:CdxflD4AF61yewuid0fLl6bM4a3q04jWel0IlP+aYjs=
-k8s.io/apimachinery v0.27.4/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E=
-k8s.io/apiserver v0.27.4 h1:ncZ0MBR9yQ/Gf34rtu1EK+HqT8In1YpfAUINu/Akvho=
-k8s.io/apiserver v0.27.4/go.mod h1:GDEFRfFZ4/l+pAvwYRnoSfz0K4j3TWiN4WsG2KnRteE=
-k8s.io/client-go v0.27.4 h1:vj2YTtSJ6J4KxaC88P4pMPEQECWMY8gqPqsTgUKzvjk=
-k8s.io/client-go v0.27.4/go.mod h1:ragcly7lUlN0SRPk5/ZkGnDjPknzb37TICq07WhI6Xc=
-k8s.io/component-base v0.27.4 h1:Wqc0jMKEDGjKXdae8hBXeskRP//vu1m6ypC+gwErj4c=
-k8s.io/component-base v0.27.4/go.mod h1:hoiEETnLc0ioLv6WPeDt8vD34DDeB35MfQnxCARq3kY=
-k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
-k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
-k8s.io/kms v0.27.4 h1:FeT17HfqxZMP7dTq3Gpa9dG05iP3J3wgGtqGh1SUoN0=
-k8s.io/kms v0.27.4/go.mod h1:0BY6tkfa+zOP85u8yE7iNNf1Yx7rEZnRQSWLEbsSk+w=
-k8s.io/kube-aggregator v0.27.4 h1:WdK9iiBr32G8bWfpUEFVQl70RZO2dU19ZAktUXL5JFc=
-k8s.io/kube-aggregator v0.27.4/go.mod h1:+eG83gkAyh0uilQEAOgheeQW4hr+PkyV+5O1nLGsjlM=
-k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg=
-k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg=
+k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw=
+k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg=
+k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU=
+k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg=
+k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ=
+k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU=
+k8s.io/apiserver v0.28.2 h1:rBeYkLvF94Nku9XfXyUIirsVzCzJBs6jMn3NWeHieyI=
+k8s.io/apiserver v0.28.2/go.mod h1:f7D5e8wH8MWcKD7azq6Csw9UN+CjdtXIVQUyUhrtb+E=
+k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY=
+k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY=
+k8s.io/component-base v0.28.2 h1:Yc1yU+6AQSlpJZyvehm/NkJBII72rzlEsd6MkBQ+G0E=
+k8s.io/component-base v0.28.2/go.mod h1:4IuQPQviQCg3du4si8GpMrhAIegxpsgPngPRR/zWpzc=
+k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
+k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
+k8s.io/kms v0.28.2 h1:KhG63LHopCdzs1oKA1j+NWleuIXudgOyCqJo4yi3GaM=
+k8s.io/kms v0.28.2/go.mod h1:iAjgIqBrV2+8kmsjbbgUkAyKSuYq5g1dW9knpt6OhaE=
+k8s.io/kube-aggregator v0.28.2 h1:tCjAfB1p/v18yD2NpegNQRuahzyA/szFfcRARnpjDeo=
+k8s.io/kube-aggregator v0.28.2/go.mod h1:g4hZVjC4KhJtZHV2pyiRBiU6AdBA/sAjh9Y9GJC/SbU=
+k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ=
+k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM=
k8s.io/pod-security-admission v0.27.4 h1:AA32ID+ECNJoUU8yuzLt4WzKPDZg7zMmP2cZ9rVsFyE=
k8s.io/pod-security-admission v0.27.4/go.mod h1:GOcnrXk8TT5cPhtCxdlkOAvBnX3QmZiMHqPw9PbZhPs=
-k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk=
-k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
+k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/LICENSE b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/LICENSE
similarity index 100%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/LICENSE
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/LICENSE
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/antlrdoc.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/antlrdoc.go
new file mode 100644
index 0000000000..ab51212676
--- /dev/null
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/antlrdoc.go
@@ -0,0 +1,68 @@
+/*
+Package antlr implements the Go version of the ANTLR 4 runtime.
+
+# The ANTLR Tool
+
+ANTLR (ANother Tool for Language Recognition) is a powerful parser generator for reading, processing, executing,
+or translating structured text or binary files. It's widely used to build languages, tools, and frameworks.
+From a grammar, ANTLR generates a parser that can build parse trees and also generates a listener interface
+(or visitor) that makes it easy to respond to the recognition of phrases of interest.
+
+# Code Generation
+
+ANTLR supports the generation of code in a number of [target languages], and the generated code is supported by a
+runtime library, written specifically to support the generated code in the target language. This library is the
+runtime for the Go target.
+
+To generate code for the go target, it is generally recommended to place the source grammar files in a package of
+their own, and use the `.sh` script method of generating code, using the go generate directive. In that same directory
+it is usual, though not required, to place the antlr tool that should be used to generate the code. That does mean
+that the antlr tool JAR file will be checked in to your source code control though, so you are free to use any other
+way of specifying the version of the ANTLR tool to use, such as aliasing in `.zshrc` or equivalent, or a profile in
+your IDE, or configuration in your CI system.
+
+Here is a general template for an ANTLR based recognizer in Go:
+
+ .
+ ├── myproject
+ ├── parser
+ │ ├── mygrammar.g4
+ │ ├── antlr-4.12.0-complete.jar
+ │ ├── error_listeners.go
+ │ ├── generate.go
+ │ ├── generate.sh
+ ├── go.mod
+ ├── go.sum
+ ├── main.go
+ └── main_test.go
+
+Make sure that the package statement in your grammar file(s) reflects the go package they exist in.
+The generate.go file then looks like this:
+
+ package parser
+
+ //go:generate ./generate.sh
+
+And the generate.sh file will look similar to this:
+
+ #!/bin/sh
+
+ alias antlr4='java -Xmx500M -cp "./antlr4-4.12.0-complete.jar:$CLASSPATH" org.antlr.v4.Tool'
+ antlr4 -Dlanguage=Go -no-visitor -package parser *.g4
+
+depending on whether you want visitors or listeners or any other ANTLR options.
+
+From the command line at the root of your package “myproject” you can then simply issue the command:
+
+ go generate ./...
+
+# Copyright Notice
+
+Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
+
+Use of this file is governed by the BSD 3-clause license, which can be found in the [LICENSE.txt] file in the project root.
+
+[target languages]: https://github.com/antlr/antlr4/tree/master/runtime
+[LICENSE.txt]: https://github.com/antlr/antlr4/blob/master/LICENSE.txt
+*/
+package antlr
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn.go
similarity index 72%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn.go
index a4e2079e65..98010d2e6e 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -6,11 +6,24 @@ package antlr
import "sync"
+// ATNInvalidAltNumber is used to represent an ALT number that has yet to be calculated or
+// which is invalid for a particular struct such as [*antlr.BaseRuleContext]
var ATNInvalidAltNumber int
+// ATN represents an “[Augmented Transition Network]”, though general in ANTLR the term
+// “Augmented Recursive Transition Network” though there are some descriptions of “[Recursive Transition Network]”
+// in existence.
+//
+// ATNs represent the main networks in the system and are serialized by the code generator and support [ALL(*)].
+//
+// [Augmented Transition Network]: https://en.wikipedia.org/wiki/Augmented_transition_network
+// [ALL(*)]: https://www.antlr.org/papers/allstar-techreport.pdf
+// [Recursive Transition Network]: https://en.wikipedia.org/wiki/Recursive_transition_network
type ATN struct {
// DecisionToState is the decision points for all rules, subrules, optional
- // blocks, ()+, ()*, etc. Used to build DFA predictors for them.
+ // blocks, ()+, ()*, etc. Each subrule/rule is a decision point, and we must track them so we
+ // can go back later and build DFA predictors for them. This includes
+ // all the rules, subrules, optional blocks, ()+, ()* etc...
DecisionToState []DecisionState
// grammarType is the ATN type and is used for deserializing ATNs from strings.
@@ -45,6 +58,8 @@ type ATN struct {
edgeMu sync.RWMutex
}
+// NewATN returns a new ATN struct representing the given grammarType and is used
+// for runtime deserialization of ATNs from the code generated by the ANTLR tool
func NewATN(grammarType int, maxTokenType int) *ATN {
return &ATN{
grammarType: grammarType,
@@ -53,7 +68,7 @@ func NewATN(grammarType int, maxTokenType int) *ATN {
}
}
-// NextTokensInContext computes the set of valid tokens that can occur starting
+// NextTokensInContext computes and returns the set of valid tokens that can occur starting
// in state s. If ctx is nil, the set of tokens will not include what can follow
// the rule surrounding s. In other words, the set will be restricted to tokens
// reachable staying within the rule of s.
@@ -61,8 +76,8 @@ func (a *ATN) NextTokensInContext(s ATNState, ctx RuleContext) *IntervalSet {
return NewLL1Analyzer(a).Look(s, nil, ctx)
}
-// NextTokensNoContext computes the set of valid tokens that can occur starting
-// in s and staying in same rule. Token.EPSILON is in set if we reach end of
+// NextTokensNoContext computes and returns the set of valid tokens that can occur starting
+// in state s and staying in same rule. [antlr.Token.EPSILON] is in set if we reach end of
// rule.
func (a *ATN) NextTokensNoContext(s ATNState) *IntervalSet {
a.mu.Lock()
@@ -76,6 +91,8 @@ func (a *ATN) NextTokensNoContext(s ATNState) *IntervalSet {
return iset
}
+// NextTokens computes and returns the set of valid tokens starting in state s, by
+// calling either [NextTokensNoContext] (ctx == nil) or [NextTokensInContext] (ctx != nil).
func (a *ATN) NextTokens(s ATNState, ctx RuleContext) *IntervalSet {
if ctx == nil {
return a.NextTokensNoContext(s)
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_config.go
similarity index 84%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_config.go
index 97ba417f74..7619fa172e 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_config.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -8,19 +8,14 @@ import (
"fmt"
)
-type comparable interface {
- equals(other interface{}) bool
-}
-
// ATNConfig is a tuple: (ATN state, predicted alt, syntactic, semantic
// context). The syntactic context is a graph-structured stack node whose
// path(s) to the root is the rule invocation(s) chain used to arrive at the
// state. The semantic context is the tree of semantic predicates encountered
// before reaching an ATN state.
type ATNConfig interface {
- comparable
-
- hash() int
+ Equals(o Collectable[ATNConfig]) bool
+ Hash() int
GetState() ATNState
GetAlt() int
@@ -47,7 +42,7 @@ type BaseATNConfig struct {
reachesIntoOuterContext int
}
-func NewBaseATNConfig7(old *BaseATNConfig) *BaseATNConfig { // TODO: Dup
+func NewBaseATNConfig7(old *BaseATNConfig) ATNConfig { // TODO: Dup
return &BaseATNConfig{
state: old.state,
alt: old.alt,
@@ -135,11 +130,16 @@ func (b *BaseATNConfig) SetReachesIntoOuterContext(v int) {
b.reachesIntoOuterContext = v
}
+// Equals is the default comparison function for an ATNConfig when no specialist implementation is required
+// for a collection.
+//
// An ATN configuration is equal to another if both have the same state, they
// predict the same alternative, and syntactic/semantic contexts are the same.
-func (b *BaseATNConfig) equals(o interface{}) bool {
+func (b *BaseATNConfig) Equals(o Collectable[ATNConfig]) bool {
if b == o {
return true
+ } else if o == nil {
+ return false
}
var other, ok = o.(*BaseATNConfig)
@@ -153,30 +153,32 @@ func (b *BaseATNConfig) equals(o interface{}) bool {
if b.context == nil {
equal = other.context == nil
} else {
- equal = b.context.equals(other.context)
+ equal = b.context.Equals(other.context)
}
var (
nums = b.state.GetStateNumber() == other.state.GetStateNumber()
alts = b.alt == other.alt
- cons = b.semanticContext.equals(other.semanticContext)
+ cons = b.semanticContext.Equals(other.semanticContext)
sups = b.precedenceFilterSuppressed == other.precedenceFilterSuppressed
)
return nums && alts && cons && sups && equal
}
-func (b *BaseATNConfig) hash() int {
+// Hash is the default hash function for BaseATNConfig, when no specialist hash function
+// is required for a collection
+func (b *BaseATNConfig) Hash() int {
var c int
if b.context != nil {
- c = b.context.hash()
+ c = b.context.Hash()
}
h := murmurInit(7)
h = murmurUpdate(h, b.state.GetStateNumber())
h = murmurUpdate(h, b.alt)
h = murmurUpdate(h, c)
- h = murmurUpdate(h, b.semanticContext.hash())
+ h = murmurUpdate(h, b.semanticContext.Hash())
return murmurFinish(h, 4)
}
@@ -243,7 +245,9 @@ func NewLexerATNConfig1(state ATNState, alt int, context PredictionContext) *Lex
return &LexerATNConfig{BaseATNConfig: NewBaseATNConfig5(state, alt, context, SemanticContextNone)}
}
-func (l *LexerATNConfig) hash() int {
+// Hash is the default hash function for LexerATNConfig objects, it can be used directly or via
+// the default comparator [ObjEqComparator].
+func (l *LexerATNConfig) Hash() int {
var f int
if l.passedThroughNonGreedyDecision {
f = 1
@@ -253,15 +257,20 @@ func (l *LexerATNConfig) hash() int {
h := murmurInit(7)
h = murmurUpdate(h, l.state.GetStateNumber())
h = murmurUpdate(h, l.alt)
- h = murmurUpdate(h, l.context.hash())
- h = murmurUpdate(h, l.semanticContext.hash())
+ h = murmurUpdate(h, l.context.Hash())
+ h = murmurUpdate(h, l.semanticContext.Hash())
h = murmurUpdate(h, f)
- h = murmurUpdate(h, l.lexerActionExecutor.hash())
+ h = murmurUpdate(h, l.lexerActionExecutor.Hash())
h = murmurFinish(h, 6)
return h
}
-func (l *LexerATNConfig) equals(other interface{}) bool {
+// Equals is the default comparison function for LexerATNConfig objects, it can be used directly or via
+// the default comparator [ObjEqComparator].
+func (l *LexerATNConfig) Equals(other Collectable[ATNConfig]) bool {
+ if l == other {
+ return true
+ }
var othert, ok = other.(*LexerATNConfig)
if l == other {
@@ -275,7 +284,7 @@ func (l *LexerATNConfig) equals(other interface{}) bool {
var b bool
if l.lexerActionExecutor != nil {
- b = !l.lexerActionExecutor.equals(othert.lexerActionExecutor)
+ b = !l.lexerActionExecutor.Equals(othert.lexerActionExecutor)
} else {
b = othert.lexerActionExecutor != nil
}
@@ -284,10 +293,9 @@ func (l *LexerATNConfig) equals(other interface{}) bool {
return false
}
- return l.BaseATNConfig.equals(othert.BaseATNConfig)
+ return l.BaseATNConfig.Equals(othert.BaseATNConfig)
}
-
func checkNonGreedyDecision(source *LexerATNConfig, target ATNState) bool {
var ds, ok = target.(DecisionState)
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config_set.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_config_set.go
similarity index 81%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config_set.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_config_set.go
index 49ad4a7197..43e9b33f3b 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config_set.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_config_set.go
@@ -1,24 +1,25 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
package antlr
-import "fmt"
+import (
+ "fmt"
+)
type ATNConfigSet interface {
- hash() int
+ Hash() int
+ Equals(o Collectable[ATNConfig]) bool
Add(ATNConfig, *DoubleDict) bool
AddAll([]ATNConfig) bool
- GetStates() Set
+ GetStates() *JStore[ATNState, Comparator[ATNState]]
GetPredicates() []SemanticContext
GetItems() []ATNConfig
OptimizeConfigs(interpreter *BaseATNSimulator)
- Equals(other interface{}) bool
-
Length() int
IsEmpty() bool
Contains(ATNConfig) bool
@@ -57,7 +58,7 @@ type BaseATNConfigSet struct {
// effectively doubles the number of objects associated with ATNConfigs. All
// keys are hashed by (s, i, _, pi), not including the context. Wiped out when
// read-only because a set becomes a DFA state.
- configLookup Set
+ configLookup *JStore[ATNConfig, Comparator[ATNConfig]]
// configs is the added elements.
configs []ATNConfig
@@ -83,7 +84,7 @@ type BaseATNConfigSet struct {
// readOnly is whether it is read-only. Do not
// allow any code to manipulate the set if true because DFA states will point at
- // sets and those must not change. It not protect other fields; conflictingAlts
+ // sets and those must not change. It not, protect other fields; conflictingAlts
// in particular, which is assigned after readOnly.
readOnly bool
@@ -104,7 +105,7 @@ func (b *BaseATNConfigSet) Alts() *BitSet {
func NewBaseATNConfigSet(fullCtx bool) *BaseATNConfigSet {
return &BaseATNConfigSet{
cachedHash: -1,
- configLookup: newArray2DHashSetWithCap(hashATNConfig, equalATNConfigs, 16, 2),
+ configLookup: NewJStore[ATNConfig, Comparator[ATNConfig]](aConfCompInst),
fullCtx: fullCtx,
}
}
@@ -126,9 +127,11 @@ func (b *BaseATNConfigSet) Add(config ATNConfig, mergeCache *DoubleDict) bool {
b.dipsIntoOuterContext = true
}
- existing := b.configLookup.Add(config).(ATNConfig)
+ existing, present := b.configLookup.Put(config)
- if existing == config {
+ // The config was not already in the set
+ //
+ if !present {
b.cachedHash = -1
b.configs = append(b.configs, config) // Track order here
return true
@@ -154,11 +157,14 @@ func (b *BaseATNConfigSet) Add(config ATNConfig, mergeCache *DoubleDict) bool {
return true
}
-func (b *BaseATNConfigSet) GetStates() Set {
- states := newArray2DHashSet(nil, nil)
+func (b *BaseATNConfigSet) GetStates() *JStore[ATNState, Comparator[ATNState]] {
+
+ // states uses the standard comparator provided by the ATNState instance
+ //
+ states := NewJStore[ATNState, Comparator[ATNState]](aStateEqInst)
for i := 0; i < len(b.configs); i++ {
- states.Add(b.configs[i].GetState())
+ states.Put(b.configs[i].GetState())
}
return states
@@ -214,7 +220,34 @@ func (b *BaseATNConfigSet) AddAll(coll []ATNConfig) bool {
return false
}
-func (b *BaseATNConfigSet) Equals(other interface{}) bool {
+// Compare is a hack function just to verify that adding DFAstares to the known
+// set works, so long as comparison of ATNConfigSet s works. For that to work, we
+// need to make sure that the set of ATNConfigs in two sets are equivalent. We can't
+// know the order, so we do this inefficient hack. If this proves the point, then
+// we can change the config set to a better structure.
+func (b *BaseATNConfigSet) Compare(bs *BaseATNConfigSet) bool {
+ if len(b.configs) != len(bs.configs) {
+ return false
+ }
+
+ for _, c := range b.configs {
+ found := false
+ for _, c2 := range bs.configs {
+ if c.Equals(c2) {
+ found = true
+ break
+ }
+ }
+
+ if !found {
+ return false
+ }
+
+ }
+ return true
+}
+
+func (b *BaseATNConfigSet) Equals(other Collectable[ATNConfig]) bool {
if b == other {
return true
} else if _, ok := other.(*BaseATNConfigSet); !ok {
@@ -224,15 +257,15 @@ func (b *BaseATNConfigSet) Equals(other interface{}) bool {
other2 := other.(*BaseATNConfigSet)
return b.configs != nil &&
- // TODO: b.configs.equals(other2.configs) && // TODO: Is b necessary?
b.fullCtx == other2.fullCtx &&
b.uniqueAlt == other2.uniqueAlt &&
b.conflictingAlts == other2.conflictingAlts &&
b.hasSemanticContext == other2.hasSemanticContext &&
- b.dipsIntoOuterContext == other2.dipsIntoOuterContext
+ b.dipsIntoOuterContext == other2.dipsIntoOuterContext &&
+ b.Compare(other2)
}
-func (b *BaseATNConfigSet) hash() int {
+func (b *BaseATNConfigSet) Hash() int {
if b.readOnly {
if b.cachedHash == -1 {
b.cachedHash = b.hashCodeConfigs()
@@ -247,7 +280,7 @@ func (b *BaseATNConfigSet) hash() int {
func (b *BaseATNConfigSet) hashCodeConfigs() int {
h := 1
for _, config := range b.configs {
- h = 31*h + config.hash()
+ h = 31*h + config.Hash()
}
return h
}
@@ -283,7 +316,7 @@ func (b *BaseATNConfigSet) Clear() {
b.configs = make([]ATNConfig, 0)
b.cachedHash = -1
- b.configLookup = newArray2DHashSet(nil, equalATNConfigs)
+ b.configLookup = NewJStore[ATNConfig, Comparator[ATNConfig]](atnConfCompInst)
}
func (b *BaseATNConfigSet) FullContext() bool {
@@ -365,7 +398,8 @@ type OrderedATNConfigSet struct {
func NewOrderedATNConfigSet() *OrderedATNConfigSet {
b := NewBaseATNConfigSet(false)
- b.configLookup = newArray2DHashSet(nil, nil)
+ // This set uses the standard Hash() and Equals() from ATNConfig
+ b.configLookup = NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst)
return &OrderedATNConfigSet{BaseATNConfigSet: b}
}
@@ -375,7 +409,7 @@ func hashATNConfig(i interface{}) int {
hash := 7
hash = 31*hash + o.GetState().GetStateNumber()
hash = 31*hash + o.GetAlt()
- hash = 31*hash + o.GetSemanticContext().hash()
+ hash = 31*hash + o.GetSemanticContext().Hash()
return hash
}
@@ -403,5 +437,5 @@ func equalATNConfigs(a, b interface{}) bool {
return false
}
- return ai.GetSemanticContext().equals(bi.GetSemanticContext())
+ return ai.GetSemanticContext().Equals(bi.GetSemanticContext())
}
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserialization_options.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_deserialization_options.go
similarity index 96%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserialization_options.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_deserialization_options.go
index cb8eafb0b2..3c975ec7bf 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserialization_options.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_deserialization_options.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserializer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_deserializer.go
similarity index 99%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserializer.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_deserializer.go
index aea9bbfa93..3888856b4b 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserializer.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_deserializer.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_simulator.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_simulator.go
similarity index 94%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_simulator.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_simulator.go
index d5454d6d5d..41529115fa 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_simulator.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_simulator.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_state.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_state.go
similarity index 97%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_state.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_state.go
index 3835bb2e93..1f2a56bc31 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_state.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_state.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -49,7 +49,8 @@ type ATNState interface {
AddTransition(Transition, int)
String() string
- hash() int
+ Hash() int
+ Equals(Collectable[ATNState]) bool
}
type BaseATNState struct {
@@ -123,7 +124,7 @@ func (as *BaseATNState) SetNextTokenWithinRule(v *IntervalSet) {
as.NextTokenWithinRule = v
}
-func (as *BaseATNState) hash() int {
+func (as *BaseATNState) Hash() int {
return as.stateNumber
}
@@ -131,7 +132,7 @@ func (as *BaseATNState) String() string {
return strconv.Itoa(as.stateNumber)
}
-func (as *BaseATNState) equals(other interface{}) bool {
+func (as *BaseATNState) Equals(other Collectable[ATNState]) bool {
if ot, ok := other.(ATNState); ok {
return as.stateNumber == ot.GetStateNumber()
}
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_type.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_type.go
similarity index 79%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_type.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_type.go
index a7b48976b3..3a515a145f 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_type.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/atn_type.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/char_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/char_stream.go
similarity index 82%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/char_stream.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/char_stream.go
index 70c1207f7f..c33f0adb5e 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/char_stream.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/char_stream.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_factory.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/common_token_factory.go
similarity index 96%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_factory.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/common_token_factory.go
index 330ff8f31f..1bb0314ea0 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_factory.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/common_token_factory.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/common_token_stream.go
similarity index 98%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_stream.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/common_token_stream.go
index c90e9b8904..c6c9485a20 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/common_token_stream.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/common_token_stream.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -331,10 +331,12 @@ func (c *CommonTokenStream) GetTextFromRuleContext(interval RuleContext) string
func (c *CommonTokenStream) GetTextFromInterval(interval *Interval) string {
c.lazyInit()
- c.Fill()
if interval == nil {
+ c.Fill()
interval = NewInterval(0, len(c.tokens)-1)
+ } else {
+ c.Sync(interval.Stop)
}
start := interval.Start
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/comparators.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/comparators.go
new file mode 100644
index 0000000000..9ea3200536
--- /dev/null
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/comparators.go
@@ -0,0 +1,147 @@
+package antlr
+
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
+// Use of this file is governed by the BSD 3-clause license that
+// can be found in the LICENSE.txt file in the project root.
+
+// This file contains all the implementations of custom comparators used for generic collections when the
+// Hash() and Equals() funcs supplied by the struct objects themselves need to be overridden. Normally, we would
+// put the comparators in the source file for the struct themselves, but given the organization of this code is
+// sorta kinda based upon the Java code, I found it confusing trying to find out which comparator was where and used by
+// which instantiation of a collection. For instance, an Array2DHashSet in the Java source, when used with ATNConfig
+// collections requires three different comparators depending on what the collection is being used for. Collecting - pun intended -
+// all the comparators here, makes it much easier to see which implementation of hash and equals is used by which collection.
+// It also makes it easy to verify that the Hash() and Equals() functions marry up with the Java implementations.
+
+// ObjEqComparator is the equivalent of the Java ObjectEqualityComparator, which is the default instance of
+// Equality comparator. We do not have inheritance in Go, only interfaces, so we use generics to enforce some
+// type safety and avoid having to implement this for every type that we want to perform comparison on.
+//
+// This comparator works by using the standard Hash() and Equals() methods of the type T that is being compared. Which
+// allows us to use it in any collection instance that does nto require a special hash or equals implementation.
+type ObjEqComparator[T Collectable[T]] struct{}
+
+var (
+ aStateEqInst = &ObjEqComparator[ATNState]{}
+ aConfEqInst = &ObjEqComparator[ATNConfig]{}
+ aConfCompInst = &ATNConfigComparator[ATNConfig]{}
+ atnConfCompInst = &BaseATNConfigComparator[ATNConfig]{}
+ dfaStateEqInst = &ObjEqComparator[*DFAState]{}
+ semctxEqInst = &ObjEqComparator[SemanticContext]{}
+ atnAltCfgEqInst = &ATNAltConfigComparator[ATNConfig]{}
+)
+
+// Equals2 delegates to the Equals() method of type T
+func (c *ObjEqComparator[T]) Equals2(o1, o2 T) bool {
+ return o1.Equals(o2)
+}
+
+// Hash1 delegates to the Hash() method of type T
+func (c *ObjEqComparator[T]) Hash1(o T) int {
+
+ return o.Hash()
+}
+
+type SemCComparator[T Collectable[T]] struct{}
+
+// ATNConfigComparator is used as the compartor for the configLookup field of an ATNConfigSet
+// and has a custom Equals() and Hash() implementation, because equality is not based on the
+// standard Hash() and Equals() methods of the ATNConfig type.
+type ATNConfigComparator[T Collectable[T]] struct {
+}
+
+// Equals2 is a custom comparator for ATNConfigs specifically for configLookup
+func (c *ATNConfigComparator[T]) Equals2(o1, o2 ATNConfig) bool {
+
+ // Same pointer, must be equal, even if both nil
+ //
+ if o1 == o2 {
+ return true
+
+ }
+
+ // If either are nil, but not both, then the result is false
+ //
+ if o1 == nil || o2 == nil {
+ return false
+ }
+
+ return o1.GetState().GetStateNumber() == o2.GetState().GetStateNumber() &&
+ o1.GetAlt() == o2.GetAlt() &&
+ o1.GetSemanticContext().Equals(o2.GetSemanticContext())
+}
+
+// Hash1 is custom hash implementation for ATNConfigs specifically for configLookup
+func (c *ATNConfigComparator[T]) Hash1(o ATNConfig) int {
+ hash := 7
+ hash = 31*hash + o.GetState().GetStateNumber()
+ hash = 31*hash + o.GetAlt()
+ hash = 31*hash + o.GetSemanticContext().Hash()
+ return hash
+}
+
+// ATNAltConfigComparator is used as the comparator for mapping configs to Alt Bitsets
+type ATNAltConfigComparator[T Collectable[T]] struct {
+}
+
+// Equals2 is a custom comparator for ATNConfigs specifically for configLookup
+func (c *ATNAltConfigComparator[T]) Equals2(o1, o2 ATNConfig) bool {
+
+ // Same pointer, must be equal, even if both nil
+ //
+ if o1 == o2 {
+ return true
+
+ }
+
+ // If either are nil, but not both, then the result is false
+ //
+ if o1 == nil || o2 == nil {
+ return false
+ }
+
+ return o1.GetState().GetStateNumber() == o2.GetState().GetStateNumber() &&
+ o1.GetContext().Equals(o2.GetContext())
+}
+
+// Hash1 is custom hash implementation for ATNConfigs specifically for configLookup
+func (c *ATNAltConfigComparator[T]) Hash1(o ATNConfig) int {
+ h := murmurInit(7)
+ h = murmurUpdate(h, o.GetState().GetStateNumber())
+ h = murmurUpdate(h, o.GetContext().Hash())
+ return murmurFinish(h, 2)
+}
+
+// BaseATNConfigComparator is used as the comparator for the configLookup field of a BaseATNConfigSet
+// and has a custom Equals() and Hash() implementation, because equality is not based on the
+// standard Hash() and Equals() methods of the ATNConfig type.
+type BaseATNConfigComparator[T Collectable[T]] struct {
+}
+
+// Equals2 is a custom comparator for ATNConfigs specifically for baseATNConfigSet
+func (c *BaseATNConfigComparator[T]) Equals2(o1, o2 ATNConfig) bool {
+
+ // Same pointer, must be equal, even if both nil
+ //
+ if o1 == o2 {
+ return true
+
+ }
+
+ // If either are nil, but not both, then the result is false
+ //
+ if o1 == nil || o2 == nil {
+ return false
+ }
+
+ return o1.GetState().GetStateNumber() == o2.GetState().GetStateNumber() &&
+ o1.GetAlt() == o2.GetAlt() &&
+ o1.GetSemanticContext().Equals(o2.GetSemanticContext())
+}
+
+// Hash1 is custom hash implementation for ATNConfigs specifically for configLookup, but in fact just
+// delegates to the standard Hash() method of the ATNConfig type.
+func (c *BaseATNConfigComparator[T]) Hash1(o ATNConfig) int {
+
+ return o.Hash()
+}
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa.go
similarity index 80%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa.go
index d55a2a87d5..bfd43e1f73 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa.go
@@ -1,13 +1,9 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
package antlr
-import (
- "sort"
-)
-
type DFA struct {
// atnStartState is the ATN state in which this was created
atnStartState DecisionState
@@ -15,8 +11,15 @@ type DFA struct {
decision int
// states is all the DFA states. Use Map to get the old state back; Set can only
- // indicate whether it is there.
- states map[int]*DFAState
+ // indicate whether it is there. Go maps implement key hash collisions and so on and are very
+ // good, but the DFAState is an object and can't be used directly as the key as it can in say JAva
+ // amd C#, whereby if the hashcode is the same for two objects, then Equals() is called against them
+ // to see if they really are the same object.
+ //
+ //
+ states *JStore[*DFAState, *ObjEqComparator[*DFAState]]
+
+ numstates int
s0 *DFAState
@@ -29,7 +32,7 @@ func NewDFA(atnStartState DecisionState, decision int) *DFA {
dfa := &DFA{
atnStartState: atnStartState,
decision: decision,
- states: make(map[int]*DFAState),
+ states: NewJStore[*DFAState, *ObjEqComparator[*DFAState]](dfaStateEqInst),
}
if s, ok := atnStartState.(*StarLoopEntryState); ok && s.precedenceRuleDecision {
dfa.precedenceDfa = true
@@ -92,7 +95,8 @@ func (d *DFA) getPrecedenceDfa() bool {
// true or nil otherwise, and d.precedenceDfa is updated.
func (d *DFA) setPrecedenceDfa(precedenceDfa bool) {
if d.getPrecedenceDfa() != precedenceDfa {
- d.setStates(make(map[int]*DFAState))
+ d.states = NewJStore[*DFAState, *ObjEqComparator[*DFAState]](dfaStateEqInst)
+ d.numstates = 0
if precedenceDfa {
precedenceState := NewDFAState(-1, NewBaseATNConfigSet(false))
@@ -117,38 +121,12 @@ func (d *DFA) setS0(s *DFAState) {
d.s0 = s
}
-func (d *DFA) getState(hash int) (*DFAState, bool) {
- s, ok := d.states[hash]
- return s, ok
-}
-
-func (d *DFA) setStates(states map[int]*DFAState) {
- d.states = states
-}
-
-func (d *DFA) setState(hash int, state *DFAState) {
- d.states[hash] = state
-}
-
-func (d *DFA) numStates() int {
- return len(d.states)
-}
-
-type dfaStateList []*DFAState
-
-func (d dfaStateList) Len() int { return len(d) }
-func (d dfaStateList) Less(i, j int) bool { return d[i].stateNumber < d[j].stateNumber }
-func (d dfaStateList) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
-
// sortedStates returns the states in d sorted by their state number.
func (d *DFA) sortedStates() []*DFAState {
- vs := make([]*DFAState, 0, len(d.states))
-
- for _, v := range d.states {
- vs = append(vs, v)
- }
- sort.Sort(dfaStateList(vs))
+ vs := d.states.SortedSlice(func(i, j *DFAState) bool {
+ return i.stateNumber < j.stateNumber
+ })
return vs
}
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_serializer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa_serializer.go
similarity index 97%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_serializer.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa_serializer.go
index bf2ccc06cd..84d0a31e53 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_serializer.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa_serializer.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_state.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa_state.go
similarity index 90%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_state.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa_state.go
index 970ed19865..c90dec55c8 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_state.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/dfa_state.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -90,16 +90,16 @@ func NewDFAState(stateNumber int, configs ATNConfigSet) *DFAState {
}
// GetAltSet gets the set of all alts mentioned by all ATN configurations in d.
-func (d *DFAState) GetAltSet() Set {
- alts := newArray2DHashSet(nil, nil)
+func (d *DFAState) GetAltSet() []int {
+ var alts []int
if d.configs != nil {
for _, c := range d.configs.GetItems() {
- alts.Add(c.GetAlt())
+ alts = append(alts, c.GetAlt())
}
}
- if alts.Len() == 0 {
+ if len(alts) == 0 {
return nil
}
@@ -130,27 +130,6 @@ func (d *DFAState) setPrediction(v int) {
d.prediction = v
}
-// equals returns whether d equals other. Two DFAStates are equal if their ATN
-// configuration sets are the same. This method is used to see if a state
-// already exists.
-//
-// Because the number of alternatives and number of ATN configurations are
-// finite, there is a finite number of DFA states that can be processed. This is
-// necessary to show that the algorithm terminates.
-//
-// Cannot test the DFA state numbers here because in
-// ParserATNSimulator.addDFAState we need to know if any other state exists that
-// has d exact set of ATN configurations. The stateNumber is irrelevant.
-func (d *DFAState) equals(other interface{}) bool {
- if d == other {
- return true
- } else if _, ok := other.(*DFAState); !ok {
- return false
- }
-
- return d.configs.Equals(other.(*DFAState).configs)
-}
-
func (d *DFAState) String() string {
var s string
if d.isAcceptState {
@@ -164,8 +143,27 @@ func (d *DFAState) String() string {
return fmt.Sprintf("%d:%s%s", d.stateNumber, fmt.Sprint(d.configs), s)
}
-func (d *DFAState) hash() int {
+func (d *DFAState) Hash() int {
h := murmurInit(7)
- h = murmurUpdate(h, d.configs.hash())
+ h = murmurUpdate(h, d.configs.Hash())
return murmurFinish(h, 1)
}
+
+// Equals returns whether d equals other. Two DFAStates are equal if their ATN
+// configuration sets are the same. This method is used to see if a state
+// already exists.
+//
+// Because the number of alternatives and number of ATN configurations are
+// finite, there is a finite number of DFA states that can be processed. This is
+// necessary to show that the algorithm terminates.
+//
+// Cannot test the DFA state numbers here because in
+// ParserATNSimulator.addDFAState we need to know if any other state exists that
+// has d exact set of ATN configurations. The stateNumber is irrelevant.
+func (d *DFAState) Equals(o Collectable[*DFAState]) bool {
+ if d == o {
+ return true
+ }
+
+ return d.configs.Equals(o.(*DFAState).configs)
+}
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/diagnostic_error_listener.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/diagnostic_error_listener.go
similarity index 98%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/diagnostic_error_listener.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/diagnostic_error_listener.go
index 1fec43d9dc..c55bcc19b2 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/diagnostic_error_listener.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/diagnostic_error_listener.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -87,7 +87,6 @@ func (d *DiagnosticErrorListener) getDecisionDescription(recognizer Parser, dfa
return strconv.Itoa(decision) + " (" + ruleName + ")"
}
-//
// Computes the set of conflicting or ambiguous alternatives from a
// configuration set, if that information was not already provided by the
// parser.
@@ -97,7 +96,6 @@ func (d *DiagnosticErrorListener) getDecisionDescription(recognizer Parser, dfa
// @param configs The conflicting or ambiguous configuration set.
// @return Returns {@code ReportedAlts} if it is not {@code nil}, otherwise
// returns the set of alternatives represented in {@code configs}.
-//
func (d *DiagnosticErrorListener) getConflictingAlts(ReportedAlts *BitSet, set ATNConfigSet) *BitSet {
if ReportedAlts != nil {
return ReportedAlts
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_listener.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/error_listener.go
similarity index 98%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_listener.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/error_listener.go
index 028e1a9d7f..f679f0dcd5 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_listener.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/error_listener.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -48,12 +48,9 @@ func NewConsoleErrorListener() *ConsoleErrorListener {
return new(ConsoleErrorListener)
}
-//
// Provides a default instance of {@link ConsoleErrorListener}.
-//
var ConsoleErrorListenerINSTANCE = NewConsoleErrorListener()
-//
// {@inheritDoc}
//
//
@@ -64,7 +61,6 @@ var ConsoleErrorListenerINSTANCE = NewConsoleErrorListener()
//
// line line:charPositionInLine msg
//
-//
func (c *ConsoleErrorListener) SyntaxError(recognizer Recognizer, offendingSymbol interface{}, line, column int, msg string, e RecognitionException) {
fmt.Fprintln(os.Stderr, "line "+strconv.Itoa(line)+":"+strconv.Itoa(column)+" "+msg)
}
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_strategy.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/error_strategy.go
similarity index 99%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_strategy.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/error_strategy.go
index c4080dbfd1..5c0a637ba4 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_strategy.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/error_strategy.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -23,7 +23,6 @@ type ErrorStrategy interface {
// This is the default implementation of {@link ANTLRErrorStrategy} used for
// error Reporting and recovery in ANTLR parsers.
-//
type DefaultErrorStrategy struct {
errorRecoveryMode bool
lastErrorIndex int
@@ -61,12 +60,10 @@ func (d *DefaultErrorStrategy) reset(recognizer Parser) {
d.endErrorCondition(recognizer)
}
-//
// This method is called to enter error recovery mode when a recognition
// exception is Reported.
//
// @param recognizer the parser instance
-//
func (d *DefaultErrorStrategy) beginErrorCondition(recognizer Parser) {
d.errorRecoveryMode = true
}
@@ -75,28 +72,23 @@ func (d *DefaultErrorStrategy) InErrorRecoveryMode(recognizer Parser) bool {
return d.errorRecoveryMode
}
-//
// This method is called to leave error recovery mode after recovering from
// a recognition exception.
//
// @param recognizer
-//
func (d *DefaultErrorStrategy) endErrorCondition(recognizer Parser) {
d.errorRecoveryMode = false
d.lastErrorStates = nil
d.lastErrorIndex = -1
}
-//
// {@inheritDoc}
//
// The default implementation simply calls {@link //endErrorCondition}.
-//
func (d *DefaultErrorStrategy) ReportMatch(recognizer Parser) {
d.endErrorCondition(recognizer)
}
-//
// {@inheritDoc}
//
// The default implementation returns immediately if the handler is already
@@ -114,7 +106,6 @@ func (d *DefaultErrorStrategy) ReportMatch(recognizer Parser) {
//
All other types: calls {@link Parser//NotifyErrorListeners} to Report
// the exception
//
-//
func (d *DefaultErrorStrategy) ReportError(recognizer Parser, e RecognitionException) {
// if we've already Reported an error and have not Matched a token
// yet successfully, don't Report any errors.
@@ -142,7 +133,6 @@ func (d *DefaultErrorStrategy) ReportError(recognizer Parser, e RecognitionExcep
// The default implementation reSynchronizes the parser by consuming tokens
// until we find one in the reSynchronization set--loosely the set of tokens
// that can follow the current rule.
-//
func (d *DefaultErrorStrategy) Recover(recognizer Parser, e RecognitionException) {
if d.lastErrorIndex == recognizer.GetInputStream().Index() &&
@@ -206,7 +196,6 @@ func (d *DefaultErrorStrategy) Recover(recognizer Parser, e RecognitionException
// compare token set at the start of the loop and at each iteration. If for
// some reason speed is suffering for you, you can turn off d
// functionality by simply overriding d method as a blank { }.
-//
func (d *DefaultErrorStrategy) Sync(recognizer Parser) {
// If already recovering, don't try to Sync
if d.InErrorRecoveryMode(recognizer) {
@@ -247,7 +236,6 @@ func (d *DefaultErrorStrategy) Sync(recognizer Parser) {
//
// @param recognizer the parser instance
// @param e the recognition exception
-//
func (d *DefaultErrorStrategy) ReportNoViableAlternative(recognizer Parser, e *NoViableAltException) {
tokens := recognizer.GetTokenStream()
var input string
@@ -264,7 +252,6 @@ func (d *DefaultErrorStrategy) ReportNoViableAlternative(recognizer Parser, e *N
recognizer.NotifyErrorListeners(msg, e.offendingToken, e)
}
-//
// This is called by {@link //ReportError} when the exception is an
// {@link InputMisMatchException}.
//
@@ -272,14 +259,12 @@ func (d *DefaultErrorStrategy) ReportNoViableAlternative(recognizer Parser, e *N
//
// @param recognizer the parser instance
// @param e the recognition exception
-//
func (this *DefaultErrorStrategy) ReportInputMisMatch(recognizer Parser, e *InputMisMatchException) {
msg := "mismatched input " + this.GetTokenErrorDisplay(e.offendingToken) +
" expecting " + e.getExpectedTokens().StringVerbose(recognizer.GetLiteralNames(), recognizer.GetSymbolicNames(), false)
recognizer.NotifyErrorListeners(msg, e.offendingToken, e)
}
-//
// This is called by {@link //ReportError} when the exception is a
// {@link FailedPredicateException}.
//
@@ -287,7 +272,6 @@ func (this *DefaultErrorStrategy) ReportInputMisMatch(recognizer Parser, e *Inpu
//
// @param recognizer the parser instance
// @param e the recognition exception
-//
func (d *DefaultErrorStrategy) ReportFailedPredicate(recognizer Parser, e *FailedPredicateException) {
ruleName := recognizer.GetRuleNames()[recognizer.GetParserRuleContext().GetRuleIndex()]
msg := "rule " + ruleName + " " + e.message
@@ -310,7 +294,6 @@ func (d *DefaultErrorStrategy) ReportFailedPredicate(recognizer Parser, e *Faile
// {@link Parser//NotifyErrorListeners}.
//
// @param recognizer the parser instance
-//
func (d *DefaultErrorStrategy) ReportUnwantedToken(recognizer Parser) {
if d.InErrorRecoveryMode(recognizer) {
return
@@ -339,7 +322,6 @@ func (d *DefaultErrorStrategy) ReportUnwantedToken(recognizer Parser) {
// {@link Parser//NotifyErrorListeners}.
//
// @param recognizer the parser instance
-//
func (d *DefaultErrorStrategy) ReportMissingToken(recognizer Parser) {
if d.InErrorRecoveryMode(recognizer) {
return
@@ -392,15 +374,14 @@ func (d *DefaultErrorStrategy) ReportMissingToken(recognizer Parser) {
// derivation:
//
//
-// => ID '=' '(' INT ')' ('+' atom)* ''
+// => ID '=' '(' INT ')' ('+' atom)* ”
// ^
//
//
-// The attempt to Match {@code ')'} will fail when it sees {@code ''} and
-// call {@link //recoverInline}. To recover, it sees that {@code LA(1)==''}
+// The attempt to Match {@code ')'} will fail when it sees {@code ”} and
+// call {@link //recoverInline}. To recover, it sees that {@code LA(1)==”}
// is in the set of tokens that can follow the {@code ')'} token reference
// in rule {@code atom}. It can assume that you forgot the {@code ')'}.
-//
func (d *DefaultErrorStrategy) RecoverInline(recognizer Parser) Token {
// SINGLE TOKEN DELETION
MatchedSymbol := d.SingleTokenDeletion(recognizer)
@@ -418,7 +399,6 @@ func (d *DefaultErrorStrategy) RecoverInline(recognizer Parser) Token {
panic(NewInputMisMatchException(recognizer))
}
-//
// This method implements the single-token insertion inline error recovery
// strategy. It is called by {@link //recoverInline} if the single-token
// deletion strategy fails to recover from the mismatched input. If this
@@ -434,7 +414,6 @@ func (d *DefaultErrorStrategy) RecoverInline(recognizer Parser) Token {
// @param recognizer the parser instance
// @return {@code true} if single-token insertion is a viable recovery
// strategy for the current mismatched input, otherwise {@code false}
-//
func (d *DefaultErrorStrategy) SingleTokenInsertion(recognizer Parser) bool {
currentSymbolType := recognizer.GetTokenStream().LA(1)
// if current token is consistent with what could come after current
@@ -469,7 +448,6 @@ func (d *DefaultErrorStrategy) SingleTokenInsertion(recognizer Parser) bool {
// @return the successfully Matched {@link Token} instance if single-token
// deletion successfully recovers from the mismatched input, otherwise
// {@code nil}
-//
func (d *DefaultErrorStrategy) SingleTokenDeletion(recognizer Parser) Token {
NextTokenType := recognizer.GetTokenStream().LA(2)
expecting := d.GetExpectedTokens(recognizer)
@@ -507,7 +485,6 @@ func (d *DefaultErrorStrategy) SingleTokenDeletion(recognizer Parser) Token {
// a CommonToken of the appropriate type. The text will be the token.
// If you change what tokens must be created by the lexer,
// override d method to create the appropriate tokens.
-//
func (d *DefaultErrorStrategy) GetMissingSymbol(recognizer Parser) Token {
currentSymbol := recognizer.GetCurrentToken()
expecting := d.GetExpectedTokens(recognizer)
@@ -546,7 +523,6 @@ func (d *DefaultErrorStrategy) GetExpectedTokens(recognizer Parser) *IntervalSet
// the token). This is better than forcing you to override a method in
// your token objects because you don't have to go modify your lexer
// so that it creates a NewJava type.
-//
func (d *DefaultErrorStrategy) GetTokenErrorDisplay(t Token) string {
if t == nil {
return ""
@@ -578,7 +554,7 @@ func (d *DefaultErrorStrategy) escapeWSAndQuote(s string) string {
// from within the rule i.e., the FIRST computation done by
// ANTLR stops at the end of a rule.
//
-// EXAMPLE
+// # EXAMPLE
//
// When you find a "no viable alt exception", the input is not
// consistent with any of the alternatives for rule r. The best
@@ -597,7 +573,6 @@ func (d *DefaultErrorStrategy) escapeWSAndQuote(s string) string {
// c : ID
// | INT
//
-//
// At each rule invocation, the set of tokens that could follow
// that rule is pushed on a stack. Here are the various
// context-sensitive follow sets:
@@ -660,7 +635,6 @@ func (d *DefaultErrorStrategy) escapeWSAndQuote(s string) string {
//
// Like Grosch I implement context-sensitive FOLLOW sets that are combined
// at run-time upon error to avoid overhead during parsing.
-//
func (d *DefaultErrorStrategy) getErrorRecoverySet(recognizer Parser) *IntervalSet {
atn := recognizer.GetInterpreter().atn
ctx := recognizer.GetParserRuleContext()
@@ -733,7 +707,6 @@ func NewBailErrorStrategy() *BailErrorStrategy {
// in a {@link ParseCancellationException} so it is not caught by the
// rule func catches. Use {@link Exception//getCause()} to get the
// original {@link RecognitionException}.
-//
func (b *BailErrorStrategy) Recover(recognizer Parser, e RecognitionException) {
context := recognizer.GetParserRuleContext()
for context != nil {
@@ -749,7 +722,6 @@ func (b *BailErrorStrategy) Recover(recognizer Parser, e RecognitionException) {
// Make sure we don't attempt to recover inline if the parser
// successfully recovers, it won't panic an exception.
-//
func (b *BailErrorStrategy) RecoverInline(recognizer Parser) Token {
b.Recover(recognizer, NewInputMisMatchException(recognizer))
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/errors.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/errors.go
similarity index 98%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/errors.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/errors.go
index 2ef74926ec..3954c13782 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/errors.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/errors.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -74,7 +74,6 @@ func (b *BaseRecognitionException) GetInputStream() IntStream {
// If the state number is not known, b method returns -1.
-//
// Gets the set of input symbols which could potentially follow the
// previously Matched symbol at the time b exception was panicn.
//
@@ -136,7 +135,6 @@ type NoViableAltException struct {
// to take based upon the remaining input. It tracks the starting token
// of the offending input and also knows where the parser was
// in the various paths when the error. Reported by ReportNoViableAlternative()
-//
func NewNoViableAltException(recognizer Parser, input TokenStream, startToken Token, offendingToken Token, deadEndConfigs ATNConfigSet, ctx ParserRuleContext) *NoViableAltException {
if ctx == nil {
@@ -177,7 +175,6 @@ type InputMisMatchException struct {
// This signifies any kind of mismatched input exceptions such as
// when the current input does not Match the expected token.
-//
func NewInputMisMatchException(recognizer Parser) *InputMisMatchException {
i := new(InputMisMatchException)
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/file_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/file_stream.go
similarity index 92%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/file_stream.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/file_stream.go
index 842170c086..bd6ad5efe3 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/file_stream.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/file_stream.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/input_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/input_stream.go
similarity index 96%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/input_stream.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/input_stream.go
index 5ff270f536..a8b889cedb 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/input_stream.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/input_stream.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/int_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/int_stream.go
similarity index 82%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/int_stream.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/int_stream.go
index 438e0ea6e7..4778878bd0 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/int_stream.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/int_stream.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/interval_set.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/interval_set.go
similarity index 98%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/interval_set.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/interval_set.go
index 1e9393adb6..c1e155e818 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/interval_set.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/interval_set.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -223,6 +223,10 @@ func (i *IntervalSet) StringVerbose(literalNames []string, symbolicNames []strin
return i.toIndexString()
}
+func (i *IntervalSet) GetIntervals() []*Interval {
+ return i.intervals
+}
+
func (i *IntervalSet) toCharString() string {
names := make([]string, len(i.intervals))
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/jcollect.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/jcollect.go
new file mode 100644
index 0000000000..e5a74f0c6c
--- /dev/null
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/jcollect.go
@@ -0,0 +1,198 @@
+package antlr
+
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
+// Use of this file is governed by the BSD 3-clause license that
+// can be found in the LICENSE.txt file in the project root.
+
+import (
+ "sort"
+)
+
+// Collectable is an interface that a struct should implement if it is to be
+// usable as a key in these collections.
+type Collectable[T any] interface {
+ Hash() int
+ Equals(other Collectable[T]) bool
+}
+
+type Comparator[T any] interface {
+ Hash1(o T) int
+ Equals2(T, T) bool
+}
+
+// JStore implements a container that allows the use of a struct to calculate the key
+// for a collection of values akin to map. This is not meant to be a full-blown HashMap but just
+// serve the needs of the ANTLR Go runtime.
+//
+// For ease of porting the logic of the runtime from the master target (Java), this collection
+// operates in a similar way to Java, in that it can use any struct that supplies a Hash() and Equals()
+// function as the key. The values are stored in a standard go map which internally is a form of hashmap
+// itself, the key for the go map is the hash supplied by the key object. The collection is able to deal with
+// hash conflicts by using a simple slice of values associated with the hash code indexed bucket. That isn't
+// particularly efficient, but it is simple, and it works. As this is specifically for the ANTLR runtime, and
+// we understand the requirements, then this is fine - this is not a general purpose collection.
+type JStore[T any, C Comparator[T]] struct {
+ store map[int][]T
+ len int
+ comparator Comparator[T]
+}
+
+func NewJStore[T any, C Comparator[T]](comparator Comparator[T]) *JStore[T, C] {
+
+ if comparator == nil {
+ panic("comparator cannot be nil")
+ }
+
+ s := &JStore[T, C]{
+ store: make(map[int][]T, 1),
+ comparator: comparator,
+ }
+ return s
+}
+
+// Put will store given value in the collection. Note that the key for storage is generated from
+// the value itself - this is specifically because that is what ANTLR needs - this would not be useful
+// as any kind of general collection.
+//
+// If the key has a hash conflict, then the value will be added to the slice of values associated with the
+// hash, unless the value is already in the slice, in which case the existing value is returned. Value equivalence is
+// tested by calling the equals() method on the key.
+//
+// # If the given value is already present in the store, then the existing value is returned as v and exists is set to true
+//
+// If the given value is not present in the store, then the value is added to the store and returned as v and exists is set to false.
+func (s *JStore[T, C]) Put(value T) (v T, exists bool) { //nolint:ireturn
+
+ kh := s.comparator.Hash1(value)
+
+ for _, v1 := range s.store[kh] {
+ if s.comparator.Equals2(value, v1) {
+ return v1, true
+ }
+ }
+ s.store[kh] = append(s.store[kh], value)
+ s.len++
+ return value, false
+}
+
+// Get will return the value associated with the key - the type of the key is the same type as the value
+// which would not generally be useful, but this is a specific thing for ANTLR where the key is
+// generated using the object we are going to store.
+func (s *JStore[T, C]) Get(key T) (T, bool) { //nolint:ireturn
+
+ kh := s.comparator.Hash1(key)
+
+ for _, v := range s.store[kh] {
+ if s.comparator.Equals2(key, v) {
+ return v, true
+ }
+ }
+ return key, false
+}
+
+// Contains returns true if the given key is present in the store
+func (s *JStore[T, C]) Contains(key T) bool { //nolint:ireturn
+
+ _, present := s.Get(key)
+ return present
+}
+
+func (s *JStore[T, C]) SortedSlice(less func(i, j T) bool) []T {
+ vs := make([]T, 0, len(s.store))
+ for _, v := range s.store {
+ vs = append(vs, v...)
+ }
+ sort.Slice(vs, func(i, j int) bool {
+ return less(vs[i], vs[j])
+ })
+
+ return vs
+}
+
+func (s *JStore[T, C]) Each(f func(T) bool) {
+ for _, e := range s.store {
+ for _, v := range e {
+ f(v)
+ }
+ }
+}
+
+func (s *JStore[T, C]) Len() int {
+ return s.len
+}
+
+func (s *JStore[T, C]) Values() []T {
+ vs := make([]T, 0, len(s.store))
+ for _, e := range s.store {
+ for _, v := range e {
+ vs = append(vs, v)
+ }
+ }
+ return vs
+}
+
+type entry[K, V any] struct {
+ key K
+ val V
+}
+
+type JMap[K, V any, C Comparator[K]] struct {
+ store map[int][]*entry[K, V]
+ len int
+ comparator Comparator[K]
+}
+
+func NewJMap[K, V any, C Comparator[K]](comparator Comparator[K]) *JMap[K, V, C] {
+ return &JMap[K, V, C]{
+ store: make(map[int][]*entry[K, V], 1),
+ comparator: comparator,
+ }
+}
+
+func (m *JMap[K, V, C]) Put(key K, val V) {
+ kh := m.comparator.Hash1(key)
+
+ m.store[kh] = append(m.store[kh], &entry[K, V]{key, val})
+ m.len++
+}
+
+func (m *JMap[K, V, C]) Values() []V {
+ vs := make([]V, 0, len(m.store))
+ for _, e := range m.store {
+ for _, v := range e {
+ vs = append(vs, v.val)
+ }
+ }
+ return vs
+}
+
+func (m *JMap[K, V, C]) Get(key K) (V, bool) {
+
+ var none V
+ kh := m.comparator.Hash1(key)
+ for _, e := range m.store[kh] {
+ if m.comparator.Equals2(e.key, key) {
+ return e.val, true
+ }
+ }
+ return none, false
+}
+
+func (m *JMap[K, V, C]) Len() int {
+ return len(m.store)
+}
+
+func (m *JMap[K, V, C]) Delete(key K) {
+ kh := m.comparator.Hash1(key)
+ for i, e := range m.store[kh] {
+ if m.comparator.Equals2(e.key, key) {
+ m.store[kh] = append(m.store[kh][:i], m.store[kh][i+1:]...)
+ m.len--
+ return
+ }
+ }
+}
+
+func (m *JMap[K, V, C]) Clear() {
+ m.store = make(map[int][]*entry[K, V])
+}
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer.go
similarity index 98%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer.go
index b04f04572f..6533f05164 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -232,8 +232,6 @@ func (b *BaseLexer) NextToken() Token {
}
return b.token
}
-
- return nil
}
// Instruct the lexer to Skip creating a token for current lexer rule
@@ -342,7 +340,7 @@ func (b *BaseLexer) GetCharIndex() int {
}
// Return the text Matched so far for the current token or any text override.
-//Set the complete text of l token it wipes any previous changes to the text.
+// Set the complete text of l token it wipes any previous changes to the text.
func (b *BaseLexer) GetText() string {
if b.text != "" {
return b.text
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_action.go
similarity index 91%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_action.go
index 5a325be137..111656c295 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_action.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -21,8 +21,8 @@ type LexerAction interface {
getActionType() int
getIsPositionDependent() bool
execute(lexer Lexer)
- hash() int
- equals(other LexerAction) bool
+ Hash() int
+ Equals(other LexerAction) bool
}
type BaseLexerAction struct {
@@ -51,15 +51,14 @@ func (b *BaseLexerAction) getIsPositionDependent() bool {
return b.isPositionDependent
}
-func (b *BaseLexerAction) hash() int {
+func (b *BaseLexerAction) Hash() int {
return b.actionType
}
-func (b *BaseLexerAction) equals(other LexerAction) bool {
+func (b *BaseLexerAction) Equals(other LexerAction) bool {
return b == other
}
-//
// Implements the {@code Skip} lexer action by calling {@link Lexer//Skip}.
//
// The {@code Skip} command does not have any parameters, so l action is
@@ -85,7 +84,8 @@ func (l *LexerSkipAction) String() string {
return "skip"
}
-// Implements the {@code type} lexer action by calling {@link Lexer//setType}
+// Implements the {@code type} lexer action by calling {@link Lexer//setType}
+//
// with the assigned type.
type LexerTypeAction struct {
*BaseLexerAction
@@ -104,14 +104,14 @@ func (l *LexerTypeAction) execute(lexer Lexer) {
lexer.SetType(l.thetype)
}
-func (l *LexerTypeAction) hash() int {
+func (l *LexerTypeAction) Hash() int {
h := murmurInit(0)
h = murmurUpdate(h, l.actionType)
h = murmurUpdate(h, l.thetype)
return murmurFinish(h, 2)
}
-func (l *LexerTypeAction) equals(other LexerAction) bool {
+func (l *LexerTypeAction) Equals(other LexerAction) bool {
if l == other {
return true
} else if _, ok := other.(*LexerTypeAction); !ok {
@@ -148,14 +148,14 @@ func (l *LexerPushModeAction) execute(lexer Lexer) {
lexer.PushMode(l.mode)
}
-func (l *LexerPushModeAction) hash() int {
+func (l *LexerPushModeAction) Hash() int {
h := murmurInit(0)
h = murmurUpdate(h, l.actionType)
h = murmurUpdate(h, l.mode)
return murmurFinish(h, 2)
}
-func (l *LexerPushModeAction) equals(other LexerAction) bool {
+func (l *LexerPushModeAction) Equals(other LexerAction) bool {
if l == other {
return true
} else if _, ok := other.(*LexerPushModeAction); !ok {
@@ -245,14 +245,14 @@ func (l *LexerModeAction) execute(lexer Lexer) {
lexer.SetMode(l.mode)
}
-func (l *LexerModeAction) hash() int {
+func (l *LexerModeAction) Hash() int {
h := murmurInit(0)
h = murmurUpdate(h, l.actionType)
h = murmurUpdate(h, l.mode)
return murmurFinish(h, 2)
}
-func (l *LexerModeAction) equals(other LexerAction) bool {
+func (l *LexerModeAction) Equals(other LexerAction) bool {
if l == other {
return true
} else if _, ok := other.(*LexerModeAction); !ok {
@@ -303,7 +303,7 @@ func (l *LexerCustomAction) execute(lexer Lexer) {
lexer.Action(nil, l.ruleIndex, l.actionIndex)
}
-func (l *LexerCustomAction) hash() int {
+func (l *LexerCustomAction) Hash() int {
h := murmurInit(0)
h = murmurUpdate(h, l.actionType)
h = murmurUpdate(h, l.ruleIndex)
@@ -311,13 +311,14 @@ func (l *LexerCustomAction) hash() int {
return murmurFinish(h, 3)
}
-func (l *LexerCustomAction) equals(other LexerAction) bool {
+func (l *LexerCustomAction) Equals(other LexerAction) bool {
if l == other {
return true
} else if _, ok := other.(*LexerCustomAction); !ok {
return false
} else {
- return l.ruleIndex == other.(*LexerCustomAction).ruleIndex && l.actionIndex == other.(*LexerCustomAction).actionIndex
+ return l.ruleIndex == other.(*LexerCustomAction).ruleIndex &&
+ l.actionIndex == other.(*LexerCustomAction).actionIndex
}
}
@@ -344,14 +345,14 @@ func (l *LexerChannelAction) execute(lexer Lexer) {
lexer.SetChannel(l.channel)
}
-func (l *LexerChannelAction) hash() int {
+func (l *LexerChannelAction) Hash() int {
h := murmurInit(0)
h = murmurUpdate(h, l.actionType)
h = murmurUpdate(h, l.channel)
return murmurFinish(h, 2)
}
-func (l *LexerChannelAction) equals(other LexerAction) bool {
+func (l *LexerChannelAction) Equals(other LexerAction) bool {
if l == other {
return true
} else if _, ok := other.(*LexerChannelAction); !ok {
@@ -412,10 +413,10 @@ func (l *LexerIndexedCustomAction) execute(lexer Lexer) {
l.lexerAction.execute(lexer)
}
-func (l *LexerIndexedCustomAction) hash() int {
+func (l *LexerIndexedCustomAction) Hash() int {
h := murmurInit(0)
h = murmurUpdate(h, l.offset)
- h = murmurUpdate(h, l.lexerAction.hash())
+ h = murmurUpdate(h, l.lexerAction.Hash())
return murmurFinish(h, 2)
}
@@ -425,6 +426,7 @@ func (l *LexerIndexedCustomAction) equals(other LexerAction) bool {
} else if _, ok := other.(*LexerIndexedCustomAction); !ok {
return false
} else {
- return l.offset == other.(*LexerIndexedCustomAction).offset && l.lexerAction == other.(*LexerIndexedCustomAction).lexerAction
+ return l.offset == other.(*LexerIndexedCustomAction).offset &&
+ l.lexerAction.Equals(other.(*LexerIndexedCustomAction).lexerAction)
}
}
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action_executor.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_action_executor.go
similarity index 88%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action_executor.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_action_executor.go
index 056941dd6e..be1ba7a7e3 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action_executor.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_action_executor.go
@@ -1,9 +1,11 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
package antlr
+import "golang.org/x/exp/slices"
+
// Represents an executor for a sequence of lexer actions which traversed during
// the Matching operation of a lexer rule (token).
//
@@ -12,8 +14,8 @@ package antlr
// not cause bloating of the {@link DFA} created for the lexer.
type LexerActionExecutor struct {
- lexerActions []LexerAction
- cachedHash int
+ lexerActions []LexerAction
+ cachedHash int
}
func NewLexerActionExecutor(lexerActions []LexerAction) *LexerActionExecutor {
@@ -30,7 +32,7 @@ func NewLexerActionExecutor(lexerActions []LexerAction) *LexerActionExecutor {
// of the performance-critical {@link LexerATNConfig//hashCode} operation.
l.cachedHash = murmurInit(57)
for _, a := range lexerActions {
- l.cachedHash = murmurUpdate(l.cachedHash, a.hash())
+ l.cachedHash = murmurUpdate(l.cachedHash, a.Hash())
}
return l
@@ -151,14 +153,17 @@ func (l *LexerActionExecutor) execute(lexer Lexer, input CharStream, startIndex
}
}
-func (l *LexerActionExecutor) hash() int {
+func (l *LexerActionExecutor) Hash() int {
if l == nil {
+ // TODO: Why is this here? l should not be nil
return 61
}
+
+ // TODO: This is created from the action itself when the struct is created - will this be an issue at some point? Java uses the runtime assign hashcode
return l.cachedHash
}
-func (l *LexerActionExecutor) equals(other interface{}) bool {
+func (l *LexerActionExecutor) Equals(other interface{}) bool {
if l == other {
return true
}
@@ -169,5 +174,13 @@ func (l *LexerActionExecutor) equals(other interface{}) bool {
if othert == nil {
return false
}
- return l.cachedHash == othert.cachedHash && &l.lexerActions == &othert.lexerActions
+ if l.cachedHash != othert.cachedHash {
+ return false
+ }
+ if len(l.lexerActions) != len(othert.lexerActions) {
+ return false
+ }
+ return slices.EqualFunc(l.lexerActions, othert.lexerActions, func(i, j LexerAction) bool {
+ return i.Equals(j)
+ })
}
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_atn_simulator.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_atn_simulator.go
similarity index 98%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_atn_simulator.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_atn_simulator.go
index dc05153ea4..c573b75210 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_atn_simulator.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/lexer_atn_simulator.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -591,19 +591,24 @@ func (l *LexerATNSimulator) addDFAState(configs ATNConfigSet, suppressEdge bool)
proposed.lexerActionExecutor = firstConfigWithRuleStopState.(*LexerATNConfig).lexerActionExecutor
proposed.setPrediction(l.atn.ruleToTokenType[firstConfigWithRuleStopState.GetState().GetRuleIndex()])
}
- hash := proposed.hash()
dfa := l.decisionToDFA[l.mode]
l.atn.stateMu.Lock()
defer l.atn.stateMu.Unlock()
- existing, ok := dfa.getState(hash)
- if ok {
+ existing, present := dfa.states.Get(proposed)
+ if present {
+
+ // This state was already present, so just return it.
+ //
proposed = existing
} else {
- proposed.stateNumber = dfa.numStates()
+
+ // We need to add the new state
+ //
+ proposed.stateNumber = dfa.states.Len()
configs.SetReadOnly(true)
proposed.configs = configs
- dfa.setState(hash, proposed)
+ dfa.states.Put(proposed)
}
if !suppressEdge {
dfa.setS0(proposed)
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/ll1_analyzer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/ll1_analyzer.go
similarity index 87%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/ll1_analyzer.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/ll1_analyzer.go
index 6ffb37de69..76689615a6 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/ll1_analyzer.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/ll1_analyzer.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -14,14 +14,15 @@ func NewLL1Analyzer(atn *ATN) *LL1Analyzer {
return la
}
-//* Special value added to the lookahead sets to indicate that we hit
-// a predicate during analysis if {@code seeThruPreds==false}.
-///
+// - Special value added to the lookahead sets to indicate that we hit
+// a predicate during analysis if {@code seeThruPreds==false}.
+//
+// /
const (
LL1AnalyzerHitPred = TokenInvalidType
)
-//*
+// *
// Calculates the SLL(1) expected lookahead set for each outgoing transition
// of an {@link ATNState}. The returned array has one element for each
// outgoing transition in {@code s}. If the closure from transition
@@ -38,7 +39,7 @@ func (la *LL1Analyzer) getDecisionLookahead(s ATNState) []*IntervalSet {
look := make([]*IntervalSet, count)
for alt := 0; alt < count; alt++ {
look[alt] = NewIntervalSet()
- lookBusy := newArray2DHashSet(nil, nil)
+ lookBusy := NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst)
seeThruPreds := false // fail to get lookahead upon pred
la.look1(s.GetTransitions()[alt].getTarget(), nil, BasePredictionContextEMPTY, look[alt], lookBusy, NewBitSet(), seeThruPreds, false)
// Wipe out lookahead for la alternative if we found nothing
@@ -50,7 +51,7 @@ func (la *LL1Analyzer) getDecisionLookahead(s ATNState) []*IntervalSet {
return look
}
-//*
+// *
// Compute set of tokens that can follow {@code s} in the ATN in the
// specified {@code ctx}.
//
@@ -67,7 +68,7 @@ func (la *LL1Analyzer) getDecisionLookahead(s ATNState) []*IntervalSet {
//
// @return The set of tokens that can follow {@code s} in the ATN in the
// specified {@code ctx}.
-///
+// /
func (la *LL1Analyzer) Look(s, stopState ATNState, ctx RuleContext) *IntervalSet {
r := NewIntervalSet()
seeThruPreds := true // ignore preds get all lookahead
@@ -75,7 +76,7 @@ func (la *LL1Analyzer) Look(s, stopState ATNState, ctx RuleContext) *IntervalSet
if ctx != nil {
lookContext = predictionContextFromRuleContext(s.GetATN(), ctx)
}
- la.look1(s, stopState, lookContext, r, newArray2DHashSet(nil, nil), NewBitSet(), seeThruPreds, true)
+ la.look1(s, stopState, lookContext, r, NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst), NewBitSet(), seeThruPreds, true)
return r
}
@@ -109,14 +110,14 @@ func (la *LL1Analyzer) Look(s, stopState ATNState, ctx RuleContext) *IntervalSet
// outermost context is reached. This parameter has no effect if {@code ctx}
// is {@code nil}.
-func (la *LL1Analyzer) look2(s, stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy Set, calledRuleStack *BitSet, seeThruPreds, addEOF bool, i int) {
+func (la *LL1Analyzer) look2(s, stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy *JStore[ATNConfig, Comparator[ATNConfig]], calledRuleStack *BitSet, seeThruPreds, addEOF bool, i int) {
returnState := la.atn.states[ctx.getReturnState(i)]
la.look1(returnState, stopState, ctx.GetParent(i), look, lookBusy, calledRuleStack, seeThruPreds, addEOF)
}
-func (la *LL1Analyzer) look1(s, stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy Set, calledRuleStack *BitSet, seeThruPreds, addEOF bool) {
+func (la *LL1Analyzer) look1(s, stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy *JStore[ATNConfig, Comparator[ATNConfig]], calledRuleStack *BitSet, seeThruPreds, addEOF bool) {
c := NewBaseATNConfig6(s, 0, ctx)
@@ -124,8 +125,11 @@ func (la *LL1Analyzer) look1(s, stopState ATNState, ctx PredictionContext, look
return
}
- lookBusy.Add(c)
+ _, present := lookBusy.Put(c)
+ if present {
+ return
+ }
if s == stopState {
if ctx == nil {
look.addOne(TokenEpsilon)
@@ -198,7 +202,7 @@ func (la *LL1Analyzer) look1(s, stopState ATNState, ctx PredictionContext, look
}
}
-func (la *LL1Analyzer) look3(stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy Set, calledRuleStack *BitSet, seeThruPreds, addEOF bool, t1 *RuleTransition) {
+func (la *LL1Analyzer) look3(stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy *JStore[ATNConfig, Comparator[ATNConfig]], calledRuleStack *BitSet, seeThruPreds, addEOF bool, t1 *RuleTransition) {
newContext := SingletonBasePredictionContextCreate(ctx, t1.followState.GetStateNumber())
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser.go
similarity index 99%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser.go
index 2ab2f56052..d26bf06392 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -91,7 +91,6 @@ func NewBaseParser(input TokenStream) *BaseParser {
// bypass alternatives.
//
// @see ATNDeserializationOptions//isGenerateRuleBypassTransitions()
-//
var bypassAltsAtnCache = make(map[string]int)
// reset the parser's state//
@@ -230,7 +229,6 @@ func (p *BaseParser) GetParseListeners() []ParseTreeListener {
// @param listener the listener to add
//
// @panics nilPointerException if {@code} listener is {@code nil}
-//
func (p *BaseParser) AddParseListener(listener ParseTreeListener) {
if listener == nil {
panic("listener")
@@ -241,13 +239,11 @@ func (p *BaseParser) AddParseListener(listener ParseTreeListener) {
p.parseListeners = append(p.parseListeners, listener)
}
-//
// Remove {@code listener} from the list of parse listeners.
//
// If {@code listener} is {@code nil} or has not been added as a parse
// listener, p.method does nothing.
// @param listener the listener to remove
-//
func (p *BaseParser) RemoveParseListener(listener ParseTreeListener) {
if p.parseListeners != nil {
@@ -289,11 +285,9 @@ func (p *BaseParser) TriggerEnterRuleEvent() {
}
}
-//
// Notify any parse listeners of an exit rule event.
//
// @see //addParseListener
-//
func (p *BaseParser) TriggerExitRuleEvent() {
if p.parseListeners != nil {
// reverse order walk of listeners
@@ -330,7 +324,6 @@ func (p *BaseParser) setTokenFactory(factory TokenFactory) {
//
// @panics UnsupportedOperationException if the current parser does not
// implement the {@link //getSerializedATN()} method.
-//
func (p *BaseParser) GetATNWithBypassAlts() {
// TODO
@@ -402,7 +395,6 @@ func (p *BaseParser) SetTokenStream(input TokenStream) {
// Match needs to return the current input symbol, which gets put
// into the label for the associated token ref e.g., x=ID.
-//
func (p *BaseParser) GetCurrentToken() Token {
return p.input.LT(1)
}
@@ -624,7 +616,6 @@ func (p *BaseParser) IsExpectedToken(symbol int) bool {
// respectively.
//
// @see ATN//getExpectedTokens(int, RuleContext)
-//
func (p *BaseParser) GetExpectedTokens() *IntervalSet {
return p.Interpreter.atn.getExpectedTokens(p.state, p.ctx)
}
@@ -686,7 +677,7 @@ func (p *BaseParser) GetDFAStrings() string {
func (p *BaseParser) DumpDFA() {
seenOne := false
for _, dfa := range p.Interpreter.decisionToDFA {
- if dfa.numStates() > 0 {
+ if dfa.states.Len() > 0 {
if seenOne {
fmt.Println()
}
@@ -703,7 +694,6 @@ func (p *BaseParser) GetSourceName() string {
// During a parse is sometimes useful to listen in on the rule entry and exit
// events as well as token Matches. p.is for quick and dirty debugging.
-//
func (p *BaseParser) SetTrace(trace *TraceListener) {
if trace == nil {
p.RemoveParseListener(p.tracer)
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_atn_simulator.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser_atn_simulator.go
similarity index 94%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_atn_simulator.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser_atn_simulator.go
index 888d512975..8bcc46a0d9 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_atn_simulator.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser_atn_simulator.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -11,11 +11,11 @@ import (
)
var (
- ParserATNSimulatorDebug = false
- ParserATNSimulatorListATNDecisions = false
- ParserATNSimulatorDFADebug = false
- ParserATNSimulatorRetryDebug = false
- TurnOffLRLoopEntryBranchOpt = false
+ ParserATNSimulatorDebug = false
+ ParserATNSimulatorTraceATNSim = false
+ ParserATNSimulatorDFADebug = false
+ ParserATNSimulatorRetryDebug = false
+ TurnOffLRLoopEntryBranchOpt = false
)
type ParserATNSimulator struct {
@@ -70,8 +70,8 @@ func (p *ParserATNSimulator) reset() {
}
func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, outerContext ParserRuleContext) int {
- if ParserATNSimulatorDebug || ParserATNSimulatorListATNDecisions {
- fmt.Println("AdaptivePredict decision " + strconv.Itoa(decision) +
+ if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim {
+ fmt.Println("adaptivePredict decision " + strconv.Itoa(decision) +
" exec LA(1)==" + p.getLookaheadName(input) +
" line " + strconv.Itoa(input.LT(1).GetLine()) + ":" +
strconv.Itoa(input.LT(1).GetColumn()))
@@ -111,15 +111,15 @@ func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, ou
if s0 == nil {
if outerContext == nil {
- outerContext = RuleContextEmpty
+ outerContext = ParserRuleContextEmpty
}
- if ParserATNSimulatorDebug || ParserATNSimulatorListATNDecisions {
+ if ParserATNSimulatorDebug {
fmt.Println("predictATN decision " + strconv.Itoa(dfa.decision) +
" exec LA(1)==" + p.getLookaheadName(input) +
", outerContext=" + outerContext.String(p.parser.GetRuleNames(), nil))
}
fullCtx := false
- s0Closure := p.computeStartState(dfa.atnStartState, RuleContextEmpty, fullCtx)
+ s0Closure := p.computeStartState(dfa.atnStartState, ParserRuleContextEmpty, fullCtx)
p.atn.stateMu.Lock()
if dfa.getPrecedenceDfa() {
@@ -174,17 +174,18 @@ func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, ou
// Reporting insufficient predicates
// cover these cases:
-// dead end
-// single alt
-// single alt + preds
-// conflict
-// conflict + preds
//
+// dead end
+// single alt
+// single alt + preds
+// conflict
+// conflict + preds
func (p *ParserATNSimulator) execATN(dfa *DFA, s0 *DFAState, input TokenStream, startIndex int, outerContext ParserRuleContext) int {
- if ParserATNSimulatorDebug || ParserATNSimulatorListATNDecisions {
+ if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim {
fmt.Println("execATN decision " + strconv.Itoa(dfa.decision) +
- " exec LA(1)==" + p.getLookaheadName(input) +
+ ", DFA state " + s0.String() +
+ ", LA(1)==" + p.getLookaheadName(input) +
" line " + strconv.Itoa(input.LT(1).GetLine()) + ":" + strconv.Itoa(input.LT(1).GetColumn()))
}
@@ -277,8 +278,6 @@ func (p *ParserATNSimulator) execATN(dfa *DFA, s0 *DFAState, input TokenStream,
t = input.LA(1)
}
}
-
- panic("Should not have reached p state")
}
// Get an existing target state for an edge in the DFA. If the target state
@@ -384,7 +383,7 @@ func (p *ParserATNSimulator) predicateDFAState(dfaState *DFAState, decisionState
// comes back with reach.uniqueAlt set to a valid alt
func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 ATNConfigSet, input TokenStream, startIndex int, outerContext ParserRuleContext) int {
- if ParserATNSimulatorDebug || ParserATNSimulatorListATNDecisions {
+ if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim {
fmt.Println("execATNWithFullContext " + s0.String())
}
@@ -492,9 +491,6 @@ func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 AT
}
func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCtx bool) ATNConfigSet {
- if ParserATNSimulatorDebug {
- fmt.Println("in computeReachSet, starting closure: " + closure.String())
- }
if p.mergeCache == nil {
p.mergeCache = NewDoubleDict()
}
@@ -570,7 +566,7 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt
//
if reach == nil {
reach = NewBaseATNConfigSet(fullCtx)
- closureBusy := newArray2DHashSet(nil, nil)
+ closureBusy := NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst)
treatEOFAsEpsilon := t == TokenEOF
amount := len(intermediate.configs)
for k := 0; k < amount; k++ {
@@ -610,6 +606,11 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt
reach.Add(skippedStopStates[l], p.mergeCache)
}
}
+
+ if ParserATNSimulatorTraceATNSim {
+ fmt.Println("computeReachSet " + closure.String() + " -> " + reach.String())
+ }
+
if len(reach.GetItems()) == 0 {
return nil
}
@@ -617,7 +618,6 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt
return reach
}
-//
// Return a configuration set containing only the configurations from
// {@code configs} which are in a {@link RuleStopState}. If all
// configurations in {@code configs} are already in a rule stop state, p
@@ -636,7 +636,6 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt
// @return {@code configs} if all configurations in {@code configs} are in a
// rule stop state, otherwise return a Newconfiguration set containing only
// the configurations from {@code configs} which are in a rule stop state
-//
func (p *ParserATNSimulator) removeAllConfigsNotInRuleStopState(configs ATNConfigSet, lookToEndOfRule bool) ATNConfigSet {
if PredictionModeallConfigsInRuleStopStates(configs) {
return configs
@@ -662,16 +661,20 @@ func (p *ParserATNSimulator) computeStartState(a ATNState, ctx RuleContext, full
// always at least the implicit call to start rule
initialContext := predictionContextFromRuleContext(p.atn, ctx)
configs := NewBaseATNConfigSet(fullCtx)
+ if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim {
+ fmt.Println("computeStartState from ATN state " + a.String() +
+ " initialContext=" + initialContext.String())
+ }
+
for i := 0; i < len(a.GetTransitions()); i++ {
target := a.GetTransitions()[i].getTarget()
c := NewBaseATNConfig6(target, i+1, initialContext)
- closureBusy := newArray2DHashSet(nil, nil)
+ closureBusy := NewJStore[ATNConfig, Comparator[ATNConfig]](atnConfCompInst)
p.closure(c, configs, closureBusy, true, fullCtx, false)
}
return configs
}
-//
// This method transforms the start state computed by
// {@link //computeStartState} to the special start state used by a
// precedence DFA for a particular precedence value. The transformation
@@ -726,7 +729,6 @@ func (p *ParserATNSimulator) computeStartState(a ATNState, ctx RuleContext, full
// @return The transformed configuration set representing the start state
// for a precedence DFA at a particular precedence level (determined by
// calling {@link Parser//getPrecedence}).
-//
func (p *ParserATNSimulator) applyPrecedenceFilter(configs ATNConfigSet) ATNConfigSet {
statesFromAlt1 := make(map[int]PredictionContext)
@@ -760,7 +762,7 @@ func (p *ParserATNSimulator) applyPrecedenceFilter(configs ATNConfigSet) ATNConf
// (basically a graph subtraction algorithm).
if !config.getPrecedenceFilterSuppressed() {
context := statesFromAlt1[config.GetState().GetStateNumber()]
- if context != nil && context.equals(config.GetContext()) {
+ if context != nil && context.Equals(config.GetContext()) {
// eliminated
continue
}
@@ -824,7 +826,6 @@ func (p *ParserATNSimulator) getPredicatePredictions(ambigAlts *BitSet, altToPre
return pairs
}
-//
// This method is used to improve the localization of error messages by
// choosing an alternative rather than panicing a
// {@link NoViableAltException} in particular prediction scenarios where the
@@ -869,7 +870,6 @@ func (p *ParserATNSimulator) getPredicatePredictions(ambigAlts *BitSet, altToPre
// @return The value to return from {@link //AdaptivePredict}, or
// {@link ATN//INVALID_ALT_NUMBER} if a suitable alternative was not
// identified and {@link //AdaptivePredict} should Report an error instead.
-//
func (p *ParserATNSimulator) getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(configs ATNConfigSet, outerContext ParserRuleContext) int {
cfgs := p.splitAccordingToSemanticValidity(configs, outerContext)
semValidConfigs := cfgs[0]
@@ -938,11 +938,11 @@ func (p *ParserATNSimulator) splitAccordingToSemanticValidity(configs ATNConfigS
}
// Look through a list of predicate/alt pairs, returning alts for the
-// pairs that win. A {@code NONE} predicate indicates an alt containing an
-// unpredicated config which behaves as "always true." If !complete
-// then we stop at the first predicate that evaluates to true. This
-// includes pairs with nil predicates.
//
+// pairs that win. A {@code NONE} predicate indicates an alt containing an
+// unpredicated config which behaves as "always true." If !complete
+// then we stop at the first predicate that evaluates to true. This
+// includes pairs with nil predicates.
func (p *ParserATNSimulator) evalSemanticContext(predPredictions []*PredPrediction, outerContext ParserRuleContext, complete bool) *BitSet {
predictions := NewBitSet()
for i := 0; i < len(predPredictions); i++ {
@@ -972,16 +972,16 @@ func (p *ParserATNSimulator) evalSemanticContext(predPredictions []*PredPredicti
return predictions
}
-func (p *ParserATNSimulator) closure(config ATNConfig, configs ATNConfigSet, closureBusy Set, collectPredicates, fullCtx, treatEOFAsEpsilon bool) {
+func (p *ParserATNSimulator) closure(config ATNConfig, configs ATNConfigSet, closureBusy *JStore[ATNConfig, Comparator[ATNConfig]], collectPredicates, fullCtx, treatEOFAsEpsilon bool) {
initialDepth := 0
p.closureCheckingStopState(config, configs, closureBusy, collectPredicates,
fullCtx, initialDepth, treatEOFAsEpsilon)
}
-func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs ATNConfigSet, closureBusy Set, collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) {
- if ParserATNSimulatorDebug {
+func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs ATNConfigSet, closureBusy *JStore[ATNConfig, Comparator[ATNConfig]], collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) {
+ if ParserATNSimulatorTraceATNSim {
fmt.Println("closure(" + config.String() + ")")
- fmt.Println("configs(" + configs.String() + ")")
+ //fmt.Println("configs(" + configs.String() + ")")
if config.GetReachesIntoOuterContext() > 50 {
panic("problem")
}
@@ -1031,7 +1031,7 @@ func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs
}
// Do the actual work of walking epsilon edges//
-func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, closureBusy Set, collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) {
+func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, closureBusy *JStore[ATNConfig, Comparator[ATNConfig]], collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) {
state := config.GetState()
// optimization
if !state.GetEpsilonOnlyTransitions() {
@@ -1066,7 +1066,8 @@ func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet,
c.SetReachesIntoOuterContext(c.GetReachesIntoOuterContext() + 1)
- if closureBusy.Add(c) != c {
+ _, present := closureBusy.Put(c)
+ if present {
// avoid infinite recursion for right-recursive rules
continue
}
@@ -1077,9 +1078,13 @@ func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet,
fmt.Println("dips into outer ctx: " + c.String())
}
} else {
- if !t.getIsEpsilon() && closureBusy.Add(c) != c {
- // avoid infinite recursion for EOF* and EOF+
- continue
+
+ if !t.getIsEpsilon() {
+ _, present := closureBusy.Put(c)
+ if present {
+ // avoid infinite recursion for EOF* and EOF+
+ continue
+ }
}
if _, ok := t.(*RuleTransition); ok {
// latch when newDepth goes negative - once we step out of the entry context we can't return
@@ -1104,7 +1109,16 @@ func (p *ParserATNSimulator) canDropLoopEntryEdgeInLeftRecursiveRule(config ATNC
// left-recursion elimination. For efficiency, also check if
// the context has an empty stack case. If so, it would mean
// global FOLLOW so we can't perform optimization
- if startLoop, ok := _p.(StarLoopEntryState); !ok || !startLoop.precedenceRuleDecision || config.GetContext().isEmpty() || config.GetContext().hasEmptyPath() {
+ if _p.GetStateType() != ATNStateStarLoopEntry {
+ return false
+ }
+ startLoop, ok := _p.(*StarLoopEntryState)
+ if !ok {
+ return false
+ }
+ if !startLoop.precedenceRuleDecision ||
+ config.GetContext().isEmpty() ||
+ config.GetContext().hasEmptyPath() {
return false
}
@@ -1117,8 +1131,8 @@ func (p *ParserATNSimulator) canDropLoopEntryEdgeInLeftRecursiveRule(config ATNC
return false
}
}
-
- decisionStartState := _p.(BlockStartState).GetTransitions()[0].getTarget().(BlockStartState)
+ x := _p.GetTransitions()[0].getTarget()
+ decisionStartState := x.(BlockStartState)
blockEndStateNum := decisionStartState.getEndState().stateNumber
blockEndState := p.atn.states[blockEndStateNum].(*BlockEndState)
@@ -1355,13 +1369,12 @@ func (p *ParserATNSimulator) GetTokenName(t int) string {
return "EOF"
}
- if p.parser != nil && p.parser.GetLiteralNames() != nil {
- if t >= len(p.parser.GetLiteralNames()) {
- fmt.Println(strconv.Itoa(t) + " ttype out of range: " + strings.Join(p.parser.GetLiteralNames(), ","))
- // fmt.Println(p.parser.GetInputStream().(TokenStream).GetAllText()) // p seems incorrect
- } else {
- return p.parser.GetLiteralNames()[t] + "<" + strconv.Itoa(t) + ">"
- }
+ if p.parser != nil && p.parser.GetLiteralNames() != nil && t < len(p.parser.GetLiteralNames()) {
+ return p.parser.GetLiteralNames()[t] + "<" + strconv.Itoa(t) + ">"
+ }
+
+ if p.parser != nil && p.parser.GetLiteralNames() != nil && t < len(p.parser.GetSymbolicNames()) {
+ return p.parser.GetSymbolicNames()[t] + "<" + strconv.Itoa(t) + ">"
}
return strconv.Itoa(t)
@@ -1372,9 +1385,9 @@ func (p *ParserATNSimulator) getLookaheadName(input TokenStream) string {
}
// Used for debugging in AdaptivePredict around execATN but I cut
-// it out for clarity now that alg. works well. We can leave p
-// "dead" code for a bit.
//
+// it out for clarity now that alg. works well. We can leave p
+// "dead" code for a bit.
func (p *ParserATNSimulator) dumpDeadEndConfigs(nvae *NoViableAltException) {
panic("Not implemented")
@@ -1421,7 +1434,6 @@ func (p *ParserATNSimulator) getUniqueAlt(configs ATNConfigSet) int {
return alt
}
-//
// Add an edge to the DFA, if possible. This method calls
// {@link //addDFAState} to ensure the {@code to} state is present in the
// DFA. If {@code from} is {@code nil}, or if {@code t} is outside the
@@ -1440,7 +1452,6 @@ func (p *ParserATNSimulator) getUniqueAlt(configs ATNConfigSet) int {
// @return If {@code to} is {@code nil}, p method returns {@code nil}
// otherwise p method returns the result of calling {@link //addDFAState}
// on {@code to}
-//
func (p *ParserATNSimulator) addDFAEdge(dfa *DFA, from *DFAState, t int, to *DFAState) *DFAState {
if ParserATNSimulatorDebug {
fmt.Println("EDGE " + from.String() + " -> " + to.String() + " upon " + p.GetTokenName(t))
@@ -1472,7 +1483,6 @@ func (p *ParserATNSimulator) addDFAEdge(dfa *DFA, from *DFAState, t int, to *DFA
return to
}
-//
// Add state {@code D} to the DFA if it is not already present, and return
// the actual instance stored in the DFA. If a state equivalent to {@code D}
// is already in the DFA, the existing state is returned. Otherwise p
@@ -1486,25 +1496,30 @@ func (p *ParserATNSimulator) addDFAEdge(dfa *DFA, from *DFAState, t int, to *DFA
// @return The state stored in the DFA. This will be either the existing
// state if {@code D} is already in the DFA, or {@code D} itself if the
// state was not already present.
-//
func (p *ParserATNSimulator) addDFAState(dfa *DFA, d *DFAState) *DFAState {
if d == ATNSimulatorError {
return d
}
- hash := d.hash()
- existing, ok := dfa.getState(hash)
- if ok {
+ existing, present := dfa.states.Get(d)
+ if present {
+ if ParserATNSimulatorTraceATNSim {
+ fmt.Print("addDFAState " + d.String() + " exists")
+ }
return existing
}
- d.stateNumber = dfa.numStates()
+
+ // The state was not present, so update it with configs
+ //
+ d.stateNumber = dfa.states.Len()
if !d.configs.ReadOnly() {
d.configs.OptimizeConfigs(p.BaseATNSimulator)
d.configs.SetReadOnly(true)
}
- dfa.setState(hash, d)
- if ParserATNSimulatorDebug {
- fmt.Println("adding NewDFA state: " + d.String())
+ dfa.states.Put(d)
+ if ParserATNSimulatorTraceATNSim {
+ fmt.Println("addDFAState new " + d.String())
}
+
return d
}
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_rule_context.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser_rule_context.go
similarity index 98%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_rule_context.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser_rule_context.go
index 49cd10c5ff..1c8cee7479 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_rule_context.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/parser_rule_context.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -340,7 +340,7 @@ func (prc *BaseParserRuleContext) String(ruleNames []string, stop RuleContext) s
return s
}
-var RuleContextEmpty = NewBaseParserRuleContext(nil, -1)
+var ParserRuleContextEmpty = NewBaseParserRuleContext(nil, -1)
type InterpreterRuleContext interface {
ParserRuleContext
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_context.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/prediction_context.go
similarity index 81%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_context.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/prediction_context.go
index 9fdfd52b26..ba62af3610 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_context.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/prediction_context.go
@@ -1,10 +1,12 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
package antlr
import (
+ "fmt"
+ "golang.org/x/exp/slices"
"strconv"
)
@@ -26,10 +28,10 @@ var (
)
type PredictionContext interface {
- hash() int
+ Hash() int
+ Equals(interface{}) bool
GetParent(int) PredictionContext
getReturnState(int) int
- equals(PredictionContext) bool
length() int
isEmpty() bool
hasEmptyPath() bool
@@ -53,7 +55,7 @@ func (b *BasePredictionContext) isEmpty() bool {
func calculateHash(parent PredictionContext, returnState int) int {
h := murmurInit(1)
- h = murmurUpdate(h, parent.hash())
+ h = murmurUpdate(h, parent.Hash())
h = murmurUpdate(h, returnState)
return murmurFinish(h, 2)
}
@@ -86,7 +88,6 @@ func NewPredictionContextCache() *PredictionContextCache {
// Add a context to the cache and return it. If the context already exists,
// return that one instead and do not add a Newcontext to the cache.
// Protect shared cache from unsafe thread access.
-//
func (p *PredictionContextCache) add(ctx PredictionContext) PredictionContext {
if ctx == BasePredictionContextEMPTY {
return BasePredictionContextEMPTY
@@ -160,28 +161,28 @@ func (b *BaseSingletonPredictionContext) hasEmptyPath() bool {
return b.returnState == BasePredictionContextEmptyReturnState
}
-func (b *BaseSingletonPredictionContext) equals(other PredictionContext) bool {
+func (b *BaseSingletonPredictionContext) Hash() int {
+ return b.cachedHash
+}
+
+func (b *BaseSingletonPredictionContext) Equals(other interface{}) bool {
if b == other {
return true
- } else if _, ok := other.(*BaseSingletonPredictionContext); !ok {
+ }
+ if _, ok := other.(*BaseSingletonPredictionContext); !ok {
return false
- } else if b.hash() != other.hash() {
- return false // can't be same if hash is different
}
otherP := other.(*BaseSingletonPredictionContext)
- if b.returnState != other.getReturnState(0) {
+ if b.returnState != otherP.getReturnState(0) {
return false
- } else if b.parentCtx == nil {
+ }
+ if b.parentCtx == nil {
return otherP.parentCtx == nil
}
- return b.parentCtx.equals(otherP.parentCtx)
-}
-
-func (b *BaseSingletonPredictionContext) hash() int {
- return b.cachedHash
+ return b.parentCtx.Equals(otherP.parentCtx)
}
func (b *BaseSingletonPredictionContext) String() string {
@@ -215,7 +216,7 @@ func NewEmptyPredictionContext() *EmptyPredictionContext {
p := new(EmptyPredictionContext)
p.BaseSingletonPredictionContext = NewBaseSingletonPredictionContext(nil, BasePredictionContextEmptyReturnState)
-
+ p.cachedHash = calculateEmptyHash()
return p
}
@@ -231,7 +232,11 @@ func (e *EmptyPredictionContext) getReturnState(index int) int {
return e.returnState
}
-func (e *EmptyPredictionContext) equals(other PredictionContext) bool {
+func (e *EmptyPredictionContext) Hash() int {
+ return e.cachedHash
+}
+
+func (e *EmptyPredictionContext) Equals(other interface{}) bool {
return e == other
}
@@ -254,7 +259,7 @@ func NewArrayPredictionContext(parents []PredictionContext, returnStates []int)
hash := murmurInit(1)
for _, parent := range parents {
- hash = murmurUpdate(hash, parent.hash())
+ hash = murmurUpdate(hash, parent.Hash())
}
for _, returnState := range returnStates {
@@ -298,18 +303,31 @@ func (a *ArrayPredictionContext) getReturnState(index int) int {
return a.returnStates[index]
}
-func (a *ArrayPredictionContext) equals(other PredictionContext) bool {
- if _, ok := other.(*ArrayPredictionContext); !ok {
+// Equals is the default comparison function for ArrayPredictionContext when no specialized
+// implementation is needed for a collection
+func (a *ArrayPredictionContext) Equals(o interface{}) bool {
+ if a == o {
+ return true
+ }
+ other, ok := o.(*ArrayPredictionContext)
+ if !ok {
return false
- } else if a.cachedHash != other.hash() {
+ }
+ if a.cachedHash != other.Hash() {
return false // can't be same if hash is different
- } else {
- otherP := other.(*ArrayPredictionContext)
- return &a.returnStates == &otherP.returnStates && &a.parents == &otherP.parents
}
+
+ // Must compare the actual array elements and not just the array address
+ //
+ return slices.Equal(a.returnStates, other.returnStates) &&
+ slices.EqualFunc(a.parents, other.parents, func(x, y PredictionContext) bool {
+ return x.Equals(y)
+ })
}
-func (a *ArrayPredictionContext) hash() int {
+// Hash is the default hash function for ArrayPredictionContext when no specialized
+// implementation is needed for a collection
+func (a *ArrayPredictionContext) Hash() int {
return a.BasePredictionContext.cachedHash
}
@@ -343,11 +361,11 @@ func (a *ArrayPredictionContext) String() string {
// /
func predictionContextFromRuleContext(a *ATN, outerContext RuleContext) PredictionContext {
if outerContext == nil {
- outerContext = RuleContextEmpty
+ outerContext = ParserRuleContextEmpty
}
// if we are in RuleContext of start rule, s, then BasePredictionContext
// is EMPTY. Nobody called us. (if we are empty, return empty)
- if outerContext.GetParent() == nil || outerContext == RuleContextEmpty {
+ if outerContext.GetParent() == nil || outerContext == ParserRuleContextEmpty {
return BasePredictionContextEMPTY
}
// If we have a parent, convert it to a BasePredictionContext graph
@@ -359,11 +377,20 @@ func predictionContextFromRuleContext(a *ATN, outerContext RuleContext) Predicti
}
func merge(a, b PredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) PredictionContext {
- // share same graph if both same
- if a == b {
+
+ // Share same graph if both same
+ //
+ if a == b || a.Equals(b) {
return a
}
+ // In Java, EmptyPredictionContext inherits from SingletonPredictionContext, and so the test
+ // in java for SingletonPredictionContext will succeed and a new ArrayPredictionContext will be created
+ // from it.
+ // In go, EmptyPredictionContext does not equate to SingletonPredictionContext and so that conversion
+ // will fail. We need to test for both Empty and Singleton and create an ArrayPredictionContext from
+ // either of them.
+
ac, ok1 := a.(*BaseSingletonPredictionContext)
bc, ok2 := b.(*BaseSingletonPredictionContext)
@@ -380,17 +407,32 @@ func merge(a, b PredictionContext, rootIsWildcard bool, mergeCache *DoubleDict)
return b
}
}
- // convert singleton so both are arrays to normalize
- if _, ok := a.(*BaseSingletonPredictionContext); ok {
- a = NewArrayPredictionContext([]PredictionContext{a.GetParent(0)}, []int{a.getReturnState(0)})
+
+ // Convert Singleton or Empty so both are arrays to normalize - We should not use the existing parameters
+ // here.
+ //
+ // TODO: I think that maybe the Prediction Context structs should be redone as there is a chance we will see this mess again - maybe redo the logic here
+
+ var arp, arb *ArrayPredictionContext
+ var ok bool
+ if arp, ok = a.(*ArrayPredictionContext); ok {
+ } else if _, ok = a.(*BaseSingletonPredictionContext); ok {
+ arp = NewArrayPredictionContext([]PredictionContext{a.GetParent(0)}, []int{a.getReturnState(0)})
+ } else if _, ok = a.(*EmptyPredictionContext); ok {
+ arp = NewArrayPredictionContext([]PredictionContext{}, []int{})
}
- if _, ok := b.(*BaseSingletonPredictionContext); ok {
- b = NewArrayPredictionContext([]PredictionContext{b.GetParent(0)}, []int{b.getReturnState(0)})
+
+ if arb, ok = b.(*ArrayPredictionContext); ok {
+ } else if _, ok = b.(*BaseSingletonPredictionContext); ok {
+ arb = NewArrayPredictionContext([]PredictionContext{b.GetParent(0)}, []int{b.getReturnState(0)})
+ } else if _, ok = b.(*EmptyPredictionContext); ok {
+ arb = NewArrayPredictionContext([]PredictionContext{}, []int{})
}
- return mergeArrays(a.(*ArrayPredictionContext), b.(*ArrayPredictionContext), rootIsWildcard, mergeCache)
+
+ // Both arp and arb
+ return mergeArrays(arp, arb, rootIsWildcard, mergeCache)
}
-//
// Merge two {@link SingletonBasePredictionContext} instances.
//
// Stack tops equal, parents merge is same return left graph.
@@ -423,11 +465,11 @@ func merge(a, b PredictionContext, rootIsWildcard bool, mergeCache *DoubleDict)
// /
func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) PredictionContext {
if mergeCache != nil {
- previous := mergeCache.Get(a.hash(), b.hash())
+ previous := mergeCache.Get(a.Hash(), b.Hash())
if previous != nil {
return previous.(PredictionContext)
}
- previous = mergeCache.Get(b.hash(), a.hash())
+ previous = mergeCache.Get(b.Hash(), a.Hash())
if previous != nil {
return previous.(PredictionContext)
}
@@ -436,7 +478,7 @@ func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool,
rootMerge := mergeRoot(a, b, rootIsWildcard)
if rootMerge != nil {
if mergeCache != nil {
- mergeCache.set(a.hash(), b.hash(), rootMerge)
+ mergeCache.set(a.Hash(), b.Hash(), rootMerge)
}
return rootMerge
}
@@ -456,7 +498,7 @@ func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool,
// Newjoined parent so create Newsingleton pointing to it, a'
spc := SingletonBasePredictionContextCreate(parent, a.returnState)
if mergeCache != nil {
- mergeCache.set(a.hash(), b.hash(), spc)
+ mergeCache.set(a.Hash(), b.Hash(), spc)
}
return spc
}
@@ -478,7 +520,7 @@ func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool,
parents := []PredictionContext{singleParent, singleParent}
apc := NewArrayPredictionContext(parents, payloads)
if mergeCache != nil {
- mergeCache.set(a.hash(), b.hash(), apc)
+ mergeCache.set(a.Hash(), b.Hash(), apc)
}
return apc
}
@@ -494,12 +536,11 @@ func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool,
}
apc := NewArrayPredictionContext(parents, payloads)
if mergeCache != nil {
- mergeCache.set(a.hash(), b.hash(), apc)
+ mergeCache.set(a.Hash(), b.Hash(), apc)
}
return apc
}
-//
// Handle case where at least one of {@code a} or {@code b} is
// {@link //EMPTY}. In the following diagrams, the symbol {@code $} is used
// to represent {@link //EMPTY}.
@@ -561,7 +602,6 @@ func mergeRoot(a, b SingletonPredictionContext, rootIsWildcard bool) PredictionC
return nil
}
-//
// Merge two {@link ArrayBasePredictionContext} instances.
//
//
Different tops, different parents.
@@ -583,12 +623,18 @@ func mergeRoot(a, b SingletonPredictionContext, rootIsWildcard bool) PredictionC
// /
func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) PredictionContext {
if mergeCache != nil {
- previous := mergeCache.Get(a.hash(), b.hash())
+ previous := mergeCache.Get(a.Hash(), b.Hash())
if previous != nil {
+ if ParserATNSimulatorTraceATNSim {
+ fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> previous")
+ }
return previous.(PredictionContext)
}
- previous = mergeCache.Get(b.hash(), a.hash())
+ previous = mergeCache.Get(b.Hash(), a.Hash())
if previous != nil {
+ if ParserATNSimulatorTraceATNSim {
+ fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> previous")
+ }
return previous.(PredictionContext)
}
}
@@ -608,7 +654,7 @@ func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache *
payload := a.returnStates[i]
// $+$ = $
bothDollars := payload == BasePredictionContextEmptyReturnState && aParent == nil && bParent == nil
- axAX := (aParent != nil && bParent != nil && aParent == bParent) // ax+ax
+ axAX := aParent != nil && bParent != nil && aParent == bParent // ax+ax
// ->
// ax
if bothDollars || axAX {
@@ -651,7 +697,7 @@ func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache *
if k == 1 { // for just one merged element, return singleton top
pc := SingletonBasePredictionContextCreate(mergedParents[0], mergedReturnStates[0])
if mergeCache != nil {
- mergeCache.set(a.hash(), b.hash(), pc)
+ mergeCache.set(a.Hash(), b.Hash(), pc)
}
return pc
}
@@ -663,27 +709,36 @@ func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache *
// if we created same array as a or b, return that instead
// TODO: track whether this is possible above during merge sort for speed
+ // TODO: In go, I do not think we can just do M == xx as M is a brand new allocation. This could be causing allocation problems
if M == a {
if mergeCache != nil {
- mergeCache.set(a.hash(), b.hash(), a)
+ mergeCache.set(a.Hash(), b.Hash(), a)
+ }
+ if ParserATNSimulatorTraceATNSim {
+ fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> a")
}
return a
}
if M == b {
if mergeCache != nil {
- mergeCache.set(a.hash(), b.hash(), b)
+ mergeCache.set(a.Hash(), b.Hash(), b)
+ }
+ if ParserATNSimulatorTraceATNSim {
+ fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> b")
}
return b
}
combineCommonParents(mergedParents)
if mergeCache != nil {
- mergeCache.set(a.hash(), b.hash(), M)
+ mergeCache.set(a.Hash(), b.Hash(), M)
+ }
+ if ParserATNSimulatorTraceATNSim {
+ fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> " + M.String())
}
return M
}
-//
// Make pass over all M {@code parents} merge any {@code equals()}
// ones.
// /
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_mode.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/prediction_mode.go
similarity index 95%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_mode.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/prediction_mode.go
index 15718f912b..7b9b72fab1 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_mode.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/prediction_mode.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -70,7 +70,6 @@ const (
PredictionModeLLExactAmbigDetection = 2
)
-//
// Computes the SLL prediction termination condition.
//
//
@@ -108,9 +107,9 @@ const (
// The single-alt-state thing lets prediction continue upon rules like
// (otherwise, it would admit defeat too soon):
//
-// {@code [12|1|[], 6|2|[], 12|2|[]]. s : (ID | ID ID?) '' }
+// {@code [12|1|[], 6|2|[], 12|2|[]]. s : (ID | ID ID?) ” }
//
-// When the ATN simulation reaches the state before {@code ''}, it has a
+//
When the ATN simulation reaches the state before {@code ”}, it has a
// DFA state that looks like: {@code [12|1|[], 6|2|[], 12|2|[]]}. Naturally
// {@code 12|1|[]} and {@code 12|2|[]} conflict, but we cannot stop
// processing this node because alternative to has another way to continue,
@@ -152,16 +151,15 @@ const (
//
//
Before testing these configurations against others, we have to merge
// {@code x} and {@code x'} (without modifying the existing configurations).
-// For example, we test {@code (x+x')==x''} when looking for conflicts in
+// For example, we test {@code (x+x')==x”} when looking for conflicts in
// the following configurations.
//
-// {@code (s, 1, x, {}), (s, 1, x', {p}), (s, 2, x'', {})}
+// {@code (s, 1, x, {}), (s, 1, x', {p}), (s, 2, x”, {})}
//
// If the configuration set has predicates (as indicated by
// {@link ATNConfigSet//hasSemanticContext}), this algorithm makes a copy of
// the configurations to strip out all of the predicates so that a standard
// {@link ATNConfigSet} will merge everything ignoring predicates.
-//
func PredictionModehasSLLConflictTerminatingPrediction(mode int, configs ATNConfigSet) bool {
// Configs in rule stop states indicate reaching the end of the decision
// rule (local context) or end of start rule (full context). If all
@@ -229,7 +227,6 @@ func PredictionModeallConfigsInRuleStopStates(configs ATNConfigSet) bool {
return true
}
-//
// Full LL prediction termination.
//
// Can we stop looking ahead during ATN simulation or is there some
@@ -334,7 +331,7 @@ func PredictionModeallConfigsInRuleStopStates(configs ATNConfigSet) bool {
//
//
//
{@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 1, y)},
-// {@code (s', 2, y)}, {@code (s'', 1, z)} yields non-conflicting set
+// {@code (s', 2, y)}, {@code (s”, 1, z)} yields non-conflicting set
// {@code {1}} U conflicting sets {@code min({1,2})} U {@code min({1,2})} =
// {@code {1}} => stop and predict 1
//
@@ -369,31 +366,26 @@ func PredictionModeallConfigsInRuleStopStates(configs ATNConfigSet) bool {
// two or one and three so we keep going. We can only stop prediction when
// we need exact ambiguity detection when the sets look like
// {@code A={{1,2}}} or {@code {{1,2},{1,2}}}, etc...
-//
func PredictionModeresolvesToJustOneViableAlt(altsets []*BitSet) int {
return PredictionModegetSingleViableAlt(altsets)
}
-//
// Determines if every alternative subset in {@code altsets} contains more
// than one alternative.
//
// @param altsets a collection of alternative subsets
// @return {@code true} if every {@link BitSet} in {@code altsets} has
// {@link BitSet//cardinality cardinality} > 1, otherwise {@code false}
-//
func PredictionModeallSubsetsConflict(altsets []*BitSet) bool {
return !PredictionModehasNonConflictingAltSet(altsets)
}
-//
// Determines if any single alternative subset in {@code altsets} contains
// exactly one alternative.
//
// @param altsets a collection of alternative subsets
// @return {@code true} if {@code altsets} contains a {@link BitSet} with
// {@link BitSet//cardinality cardinality} 1, otherwise {@code false}
-//
func PredictionModehasNonConflictingAltSet(altsets []*BitSet) bool {
for i := 0; i < len(altsets); i++ {
alts := altsets[i]
@@ -404,14 +396,12 @@ func PredictionModehasNonConflictingAltSet(altsets []*BitSet) bool {
return false
}
-//
// Determines if any single alternative subset in {@code altsets} contains
// more than one alternative.
//
// @param altsets a collection of alternative subsets
// @return {@code true} if {@code altsets} contains a {@link BitSet} with
// {@link BitSet//cardinality cardinality} > 1, otherwise {@code false}
-//
func PredictionModehasConflictingAltSet(altsets []*BitSet) bool {
for i := 0; i < len(altsets); i++ {
alts := altsets[i]
@@ -422,13 +412,11 @@ func PredictionModehasConflictingAltSet(altsets []*BitSet) bool {
return false
}
-//
// Determines if every alternative subset in {@code altsets} is equivalent.
//
// @param altsets a collection of alternative subsets
// @return {@code true} if every member of {@code altsets} is equal to the
// others, otherwise {@code false}
-//
func PredictionModeallSubsetsEqual(altsets []*BitSet) bool {
var first *BitSet
@@ -444,13 +432,11 @@ func PredictionModeallSubsetsEqual(altsets []*BitSet) bool {
return true
}
-//
// Returns the unique alternative predicted by all alternative subsets in
// {@code altsets}. If no such alternative exists, this method returns
// {@link ATN//INVALID_ALT_NUMBER}.
//
// @param altsets a collection of alternative subsets
-//
func PredictionModegetUniqueAlt(altsets []*BitSet) int {
all := PredictionModeGetAlts(altsets)
if all.length() == 1 {
@@ -466,7 +452,6 @@ func PredictionModegetUniqueAlt(altsets []*BitSet) int {
//
// @param altsets a collection of alternative subsets
// @return the set of represented alternatives in {@code altsets}
-//
func PredictionModeGetAlts(altsets []*BitSet) *BitSet {
all := NewBitSet()
for _, alts := range altsets {
@@ -475,44 +460,35 @@ func PredictionModeGetAlts(altsets []*BitSet) *BitSet {
return all
}
-//
-// This func gets the conflicting alt subsets from a configuration set.
+// PredictionModegetConflictingAltSubsets gets the conflicting alt subsets from a configuration set.
// For each configuration {@code c} in {@code configs}:
//
//
// map[c] U= c.{@link ATNConfig//alt alt} // map hash/equals uses s and x, not
// alt and not pred
//
-//
func PredictionModegetConflictingAltSubsets(configs ATNConfigSet) []*BitSet {
- configToAlts := make(map[int]*BitSet)
+ configToAlts := NewJMap[ATNConfig, *BitSet, *ATNAltConfigComparator[ATNConfig]](atnAltCfgEqInst)
for _, c := range configs.GetItems() {
- key := 31 * c.GetState().GetStateNumber() + c.GetContext().hash()
- alts, ok := configToAlts[key]
+ alts, ok := configToAlts.Get(c)
if !ok {
alts = NewBitSet()
- configToAlts[key] = alts
+ configToAlts.Put(c, alts)
}
alts.add(c.GetAlt())
}
- values := make([]*BitSet, 0, 10)
- for _, v := range configToAlts {
- values = append(values, v)
- }
- return values
+ return configToAlts.Values()
}
-//
-// Get a map from state to alt subset from a configuration set. For each
+// PredictionModeGetStateToAltMap gets a map from state to alt subset from a configuration set. For each
// configuration {@code c} in {@code configs}:
//
//
// map[c.{@link ATNConfig//state state}] U= c.{@link ATNConfig//alt alt}
//
-//
func PredictionModeGetStateToAltMap(configs ATNConfigSet) *AltDict {
m := NewAltDict()
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/recognizer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/recognizer.go
similarity index 92%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/recognizer.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/recognizer.go
index 93efcf355d..bfe542d091 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/recognizer.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/recognizer.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -49,7 +49,7 @@ var tokenTypeMapCache = make(map[string]int)
var ruleIndexMapCache = make(map[string]int)
func (b *BaseRecognizer) checkVersion(toolVersion string) {
- runtimeVersion := "4.10.1"
+ runtimeVersion := "4.12.0"
if runtimeVersion != toolVersion {
fmt.Println("ANTLR runtime and generated code versions disagree: " + runtimeVersion + "!=" + toolVersion)
}
@@ -108,7 +108,6 @@ func (b *BaseRecognizer) SetState(v int) {
// Get a map from rule names to rule indexes.
//
// Used for XPath and tree pattern compilation.
-//
func (b *BaseRecognizer) GetRuleIndexMap() map[string]int {
panic("Method not defined!")
@@ -171,18 +170,18 @@ func (b *BaseRecognizer) GetErrorHeader(e RecognitionException) string {
}
// How should a token be displayed in an error message? The default
-// is to display just the text, but during development you might
-// want to have a lot of information spit out. Override in that case
-// to use t.String() (which, for CommonToken, dumps everything about
-// the token). This is better than forcing you to override a method in
-// your token objects because you don't have to go modify your lexer
-// so that it creates a NewJava type.
+//
+// is to display just the text, but during development you might
+// want to have a lot of information spit out. Override in that case
+// to use t.String() (which, for CommonToken, dumps everything about
+// the token). This is better than forcing you to override a method in
+// your token objects because you don't have to go modify your lexer
+// so that it creates a NewJava type.
//
// @deprecated This method is not called by the ANTLR 4 Runtime. Specific
// implementations of {@link ANTLRErrorStrategy} may provide a similar
// feature when necessary. For example, see
// {@link DefaultErrorStrategy//GetTokenErrorDisplay}.
-//
func (b *BaseRecognizer) GetTokenErrorDisplay(t Token) string {
if t == nil {
return ""
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/rule_context.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/rule_context.go
similarity index 97%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/rule_context.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/rule_context.go
index 600cf8c062..210699ba23 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/rule_context.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/rule_context.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/semantic_context.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/semantic_context.go
similarity index 85%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/semantic_context.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/semantic_context.go
index 9ada430779..a702e99def 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/semantic_context.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/semantic_context.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -18,12 +18,12 @@ import (
//
type SemanticContext interface {
- comparable
+ Equals(other Collectable[SemanticContext]) bool
+ Hash() int
evaluate(parser Recognizer, outerContext RuleContext) bool
evalPrecedence(parser Recognizer, outerContext RuleContext) SemanticContext
- hash() int
String() string
}
@@ -78,7 +78,7 @@ func NewPredicate(ruleIndex, predIndex int, isCtxDependent bool) *Predicate {
//The default {@link SemanticContext}, which is semantically equivalent to
//a predicate of the form {@code {true}?}.
-var SemanticContextNone SemanticContext = NewPredicate(-1, -1, false)
+var SemanticContextNone = NewPredicate(-1, -1, false)
func (p *Predicate) evalPrecedence(parser Recognizer, outerContext RuleContext) SemanticContext {
return p
@@ -95,7 +95,7 @@ func (p *Predicate) evaluate(parser Recognizer, outerContext RuleContext) bool {
return parser.Sempred(localctx, p.ruleIndex, p.predIndex)
}
-func (p *Predicate) equals(other interface{}) bool {
+func (p *Predicate) Equals(other Collectable[SemanticContext]) bool {
if p == other {
return true
} else if _, ok := other.(*Predicate); !ok {
@@ -107,7 +107,7 @@ func (p *Predicate) equals(other interface{}) bool {
}
}
-func (p *Predicate) hash() int {
+func (p *Predicate) Hash() int {
h := murmurInit(0)
h = murmurUpdate(h, p.ruleIndex)
h = murmurUpdate(h, p.predIndex)
@@ -151,17 +151,22 @@ func (p *PrecedencePredicate) compareTo(other *PrecedencePredicate) int {
return p.precedence - other.precedence
}
-func (p *PrecedencePredicate) equals(other interface{}) bool {
- if p == other {
- return true
- } else if _, ok := other.(*PrecedencePredicate); !ok {
+func (p *PrecedencePredicate) Equals(other Collectable[SemanticContext]) bool {
+
+ var op *PrecedencePredicate
+ var ok bool
+ if op, ok = other.(*PrecedencePredicate); !ok {
return false
- } else {
- return p.precedence == other.(*PrecedencePredicate).precedence
}
+
+ if p == op {
+ return true
+ }
+
+ return p.precedence == other.(*PrecedencePredicate).precedence
}
-func (p *PrecedencePredicate) hash() int {
+func (p *PrecedencePredicate) Hash() int {
h := uint32(1)
h = 31*h + uint32(p.precedence)
return int(h)
@@ -171,10 +176,10 @@ func (p *PrecedencePredicate) String() string {
return "{" + strconv.Itoa(p.precedence) + ">=prec}?"
}
-func PrecedencePredicatefilterPrecedencePredicates(set Set) []*PrecedencePredicate {
+func PrecedencePredicatefilterPrecedencePredicates(set *JStore[SemanticContext, Comparator[SemanticContext]]) []*PrecedencePredicate {
result := make([]*PrecedencePredicate, 0)
- set.Each(func(v interface{}) bool {
+ set.Each(func(v SemanticContext) bool {
if c2, ok := v.(*PrecedencePredicate); ok {
result = append(result, c2)
}
@@ -193,21 +198,21 @@ type AND struct {
func NewAND(a, b SemanticContext) *AND {
- operands := newArray2DHashSet(nil, nil)
+ operands := NewJStore[SemanticContext, Comparator[SemanticContext]](semctxEqInst)
if aa, ok := a.(*AND); ok {
for _, o := range aa.opnds {
- operands.Add(o)
+ operands.Put(o)
}
} else {
- operands.Add(a)
+ operands.Put(a)
}
if ba, ok := b.(*AND); ok {
for _, o := range ba.opnds {
- operands.Add(o)
+ operands.Put(o)
}
} else {
- operands.Add(b)
+ operands.Put(b)
}
precedencePredicates := PrecedencePredicatefilterPrecedencePredicates(operands)
if len(precedencePredicates) > 0 {
@@ -220,7 +225,7 @@ func NewAND(a, b SemanticContext) *AND {
}
}
- operands.Add(reduced)
+ operands.Put(reduced)
}
vs := operands.Values()
@@ -235,14 +240,15 @@ func NewAND(a, b SemanticContext) *AND {
return and
}
-func (a *AND) equals(other interface{}) bool {
+func (a *AND) Equals(other Collectable[SemanticContext]) bool {
if a == other {
return true
- } else if _, ok := other.(*AND); !ok {
+ }
+ if _, ok := other.(*AND); !ok {
return false
} else {
for i, v := range other.(*AND).opnds {
- if !a.opnds[i].equals(v) {
+ if !a.opnds[i].Equals(v) {
return false
}
}
@@ -250,13 +256,11 @@ func (a *AND) equals(other interface{}) bool {
}
}
-//
// {@inheritDoc}
//
//
// The evaluation of predicates by a context is short-circuiting, but
// unordered.
-//
func (a *AND) evaluate(parser Recognizer, outerContext RuleContext) bool {
for i := 0; i < len(a.opnds); i++ {
if !a.opnds[i].evaluate(parser, outerContext) {
@@ -304,18 +308,18 @@ func (a *AND) evalPrecedence(parser Recognizer, outerContext RuleContext) Semant
return result
}
-func (a *AND) hash() int {
+func (a *AND) Hash() int {
h := murmurInit(37) // Init with a value different from OR
for _, op := range a.opnds {
- h = murmurUpdate(h, op.hash())
+ h = murmurUpdate(h, op.Hash())
}
return murmurFinish(h, len(a.opnds))
}
-func (a *OR) hash() int {
+func (a *OR) Hash() int {
h := murmurInit(41) // Init with a value different from AND
for _, op := range a.opnds {
- h = murmurUpdate(h, op.hash())
+ h = murmurUpdate(h, op.Hash())
}
return murmurFinish(h, len(a.opnds))
}
@@ -345,21 +349,21 @@ type OR struct {
func NewOR(a, b SemanticContext) *OR {
- operands := newArray2DHashSet(nil, nil)
+ operands := NewJStore[SemanticContext, Comparator[SemanticContext]](semctxEqInst)
if aa, ok := a.(*OR); ok {
for _, o := range aa.opnds {
- operands.Add(o)
+ operands.Put(o)
}
} else {
- operands.Add(a)
+ operands.Put(a)
}
if ba, ok := b.(*OR); ok {
for _, o := range ba.opnds {
- operands.Add(o)
+ operands.Put(o)
}
} else {
- operands.Add(b)
+ operands.Put(b)
}
precedencePredicates := PrecedencePredicatefilterPrecedencePredicates(operands)
if len(precedencePredicates) > 0 {
@@ -372,7 +376,7 @@ func NewOR(a, b SemanticContext) *OR {
}
}
- operands.Add(reduced)
+ operands.Put(reduced)
}
vs := operands.Values()
@@ -388,14 +392,14 @@ func NewOR(a, b SemanticContext) *OR {
return o
}
-func (o *OR) equals(other interface{}) bool {
+func (o *OR) Equals(other Collectable[SemanticContext]) bool {
if o == other {
return true
} else if _, ok := other.(*OR); !ok {
return false
} else {
for i, v := range other.(*OR).opnds {
- if !o.opnds[i].equals(v) {
+ if !o.opnds[i].Equals(v) {
return false
}
}
@@ -406,7 +410,6 @@ func (o *OR) equals(other interface{}) bool {
//
// The evaluation of predicates by o context is short-circuiting, but
// unordered.
-//
func (o *OR) evaluate(parser Recognizer, outerContext RuleContext) bool {
for i := 0; i < len(o.opnds); i++ {
if o.opnds[i].evaluate(parser, outerContext) {
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token.go
similarity index 98%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/token.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token.go
index 2d8e99095d..f73b06bc6a 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
@@ -158,7 +158,6 @@ func NewCommonToken(source *TokenSourceCharStreamPair, tokenType, channel, start
// {@link Token//GetInputStream}.
//
// @param oldToken The token to copy.
-//
func (c *CommonToken) clone() *CommonToken {
t := NewCommonToken(c.source, c.tokenType, c.channel, c.start, c.stop)
t.tokenIndex = c.GetTokenIndex()
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_source.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token_source.go
similarity index 85%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_source.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token_source.go
index e023978fef..a3f36eaa67 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_source.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token_source.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_stream.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token_stream.go
similarity index 87%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_stream.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token_stream.go
index df92c81478..1527d43f60 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/token_stream.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/token_stream.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/tokenstream_rewriter.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/tokenstream_rewriter.go
similarity index 58%
rename from vendor/github.com/antlr/antlr4/runtime/Go/antlr/tokenstream_rewriter.go
rename to vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/tokenstream_rewriter.go
index 96a03f02aa..b3e38af344 100644
--- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/tokenstream_rewriter.go
+++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/tokenstream_rewriter.go
@@ -1,15 +1,15 @@
-// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that
// can be found in the LICENSE.txt file in the project root.
+
package antlr
import (
-"bytes"
-"fmt"
+ "bytes"
+ "fmt"
)
-
-//
+//
// Useful for rewriting out a buffered input token stream after doing some
// augmentation or other manipulations on it.
@@ -85,12 +85,10 @@ import (
// If you don't use named rewrite streams, a "default" stream is used as the
// first example shows.
-
-
-const(
+const (
Default_Program_Name = "default"
- Program_Init_Size = 100
- Min_Token_Index = 0
+ Program_Init_Size = 100
+ Min_Token_Index = 0
)
// Define the rewrite operation hierarchy
@@ -98,13 +96,13 @@ const(
type RewriteOperation interface {
// Execute the rewrite operation by possibly adding to the buffer.
// Return the index of the next token to operate on.
- Execute(buffer *bytes.Buffer) int
- String() string
- GetInstructionIndex() int
- GetIndex() int
- GetText() string
- GetOpName() string
- GetTokens() TokenStream
+ Execute(buffer *bytes.Buffer) int
+ String() string
+ GetInstructionIndex() int
+ GetIndex() int
+ GetText() string
+ GetOpName() string
+ GetTokens() TokenStream
SetInstructionIndex(val int)
SetIndex(int)
SetText(string)
@@ -114,63 +112,62 @@ type RewriteOperation interface {
type BaseRewriteOperation struct {
//Current index of rewrites list
- instruction_index int
+ instruction_index int
//Token buffer index
- index int
+ index int
//Substitution text
- text string
+ text string
//Actual operation name
- op_name string
+ op_name string
//Pointer to token steam
- tokens TokenStream
+ tokens TokenStream
}
-func (op *BaseRewriteOperation)GetInstructionIndex() int{
+func (op *BaseRewriteOperation) GetInstructionIndex() int {
return op.instruction_index
}
-func (op *BaseRewriteOperation)GetIndex() int{
+func (op *BaseRewriteOperation) GetIndex() int {
return op.index
}
-func (op *BaseRewriteOperation)GetText() string{
+func (op *BaseRewriteOperation) GetText() string {
return op.text
}
-func (op *BaseRewriteOperation)GetOpName() string{
+func (op *BaseRewriteOperation) GetOpName() string {
return op.op_name
}
-func (op *BaseRewriteOperation)GetTokens() TokenStream{
+func (op *BaseRewriteOperation) GetTokens() TokenStream {
return op.tokens
}
-func (op *BaseRewriteOperation)SetInstructionIndex(val int){
+func (op *BaseRewriteOperation) SetInstructionIndex(val int) {
op.instruction_index = val
}
-func (op *BaseRewriteOperation)SetIndex(val int) {
+func (op *BaseRewriteOperation) SetIndex(val int) {
op.index = val
}
-func (op *BaseRewriteOperation)SetText(val string){
+func (op *BaseRewriteOperation) SetText(val string) {
op.text = val
}
-func (op *BaseRewriteOperation)SetOpName(val string){
+func (op *BaseRewriteOperation) SetOpName(val string) {
op.op_name = val
}
-func (op *BaseRewriteOperation)SetTokens(val TokenStream) {
+func (op *BaseRewriteOperation) SetTokens(val TokenStream) {
op.tokens = val
}
-
-func (op *BaseRewriteOperation) Execute(buffer *bytes.Buffer) int{
+func (op *BaseRewriteOperation) Execute(buffer *bytes.Buffer) int {
return op.index
}
-func (op *BaseRewriteOperation) String() string {
+func (op *BaseRewriteOperation) String() string {
return fmt.Sprintf("<%s@%d:\"%s\">",
op.op_name,
op.tokens.Get(op.GetIndex()),
@@ -179,26 +176,25 @@ func (op *BaseRewriteOperation) String() string {
}
-
type InsertBeforeOp struct {
BaseRewriteOperation
}
-func NewInsertBeforeOp(index int, text string, stream TokenStream) *InsertBeforeOp{
- return &InsertBeforeOp{BaseRewriteOperation:BaseRewriteOperation{
- index:index,
- text:text,
- op_name:"InsertBeforeOp",
- tokens:stream,
+func NewInsertBeforeOp(index int, text string, stream TokenStream) *InsertBeforeOp {
+ return &InsertBeforeOp{BaseRewriteOperation: BaseRewriteOperation{
+ index: index,
+ text: text,
+ op_name: "InsertBeforeOp",
+ tokens: stream,
}}
}
-func (op *InsertBeforeOp) Execute(buffer *bytes.Buffer) int{
+func (op *InsertBeforeOp) Execute(buffer *bytes.Buffer) int {
buffer.WriteString(op.text)
- if op.tokens.Get(op.index).GetTokenType() != TokenEOF{
+ if op.tokens.Get(op.index).GetTokenType() != TokenEOF {
buffer.WriteString(op.tokens.Get(op.index).GetText())
}
- return op.index+1
+ return op.index + 1
}
func (op *InsertBeforeOp) String() string {
@@ -213,20 +209,20 @@ type InsertAfterOp struct {
BaseRewriteOperation
}
-func NewInsertAfterOp(index int, text string, stream TokenStream) *InsertAfterOp{
- return &InsertAfterOp{BaseRewriteOperation:BaseRewriteOperation{
- index:index+1,
- text:text,
- tokens:stream,
+func NewInsertAfterOp(index int, text string, stream TokenStream) *InsertAfterOp {
+ return &InsertAfterOp{BaseRewriteOperation: BaseRewriteOperation{
+ index: index + 1,
+ text: text,
+ tokens: stream,
}}
}
func (op *InsertAfterOp) Execute(buffer *bytes.Buffer) int {
buffer.WriteString(op.text)
- if op.tokens.Get(op.index).GetTokenType() != TokenEOF{
+ if op.tokens.Get(op.index).GetTokenType() != TokenEOF {
buffer.WriteString(op.tokens.Get(op.index).GetText())
}
- return op.index+1
+ return op.index + 1
}
func (op *InsertAfterOp) String() string {
@@ -235,28 +231,28 @@ func (op *InsertAfterOp) String() string {
// I'm going to try replacing range from x..y with (y-x)+1 ReplaceOp
// instructions.
-type ReplaceOp struct{
+type ReplaceOp struct {
BaseRewriteOperation
LastIndex int
}
-func NewReplaceOp(from, to int, text string, stream TokenStream)*ReplaceOp {
+func NewReplaceOp(from, to int, text string, stream TokenStream) *ReplaceOp {
return &ReplaceOp{
- BaseRewriteOperation:BaseRewriteOperation{
- index:from,
- text:text,
- op_name:"ReplaceOp",
- tokens:stream,
+ BaseRewriteOperation: BaseRewriteOperation{
+ index: from,
+ text: text,
+ op_name: "ReplaceOp",
+ tokens: stream,
},
- LastIndex:to,
+ LastIndex: to,
}
}
-func (op *ReplaceOp)Execute(buffer *bytes.Buffer) int{
- if op.text != ""{
+func (op *ReplaceOp) Execute(buffer *bytes.Buffer) int {
+ if op.text != "" {
buffer.WriteString(op.text)
}
- return op.LastIndex +1
+ return op.LastIndex + 1
}
func (op *ReplaceOp) String() string {
@@ -268,54 +264,54 @@ func (op *ReplaceOp) String() string {
op.tokens.Get(op.index), op.tokens.Get(op.LastIndex), op.text)
}
-
type TokenStreamRewriter struct {
//Our source stream
- tokens TokenStream
+ tokens TokenStream
// You may have multiple, named streams of rewrite operations.
// I'm calling these things "programs."
// Maps String (name) → rewrite (List)
- programs map[string][]RewriteOperation
- last_rewrite_token_indexes map[string]int
+ programs map[string][]RewriteOperation
+ last_rewrite_token_indexes map[string]int
}
-func NewTokenStreamRewriter(tokens TokenStream) *TokenStreamRewriter{
+func NewTokenStreamRewriter(tokens TokenStream) *TokenStreamRewriter {
return &TokenStreamRewriter{
- tokens: tokens,
- programs: map[string][]RewriteOperation{
- Default_Program_Name:make([]RewriteOperation,0, Program_Init_Size),
+ tokens: tokens,
+ programs: map[string][]RewriteOperation{
+ Default_Program_Name: make([]RewriteOperation, 0, Program_Init_Size),
},
- last_rewrite_token_indexes: map[string]int{},
+ last_rewrite_token_indexes: map[string]int{},
}
}
-func (tsr *TokenStreamRewriter) GetTokenStream() TokenStream{
+func (tsr *TokenStreamRewriter) GetTokenStream() TokenStream {
return tsr.tokens
}
-// Rollback the instruction stream for a program so that
-// the indicated instruction (via instructionIndex) is no
-// longer in the stream. UNTESTED!
-func (tsr *TokenStreamRewriter) Rollback(program_name string, instruction_index int){
- is, ok := tsr.programs[program_name]
- if ok{
+// Rollback the instruction stream for a program so that
+// the indicated instruction (via instructionIndex) is no
+// longer in the stream. UNTESTED!
+func (tsr *TokenStreamRewriter) Rollback(program_name string, instruction_index int) {
+ is, ok := tsr.programs[program_name]
+ if ok {
tsr.programs[program_name] = is[Min_Token_Index:instruction_index]
}
}
-func (tsr *TokenStreamRewriter) RollbackDefault(instruction_index int){
+func (tsr *TokenStreamRewriter) RollbackDefault(instruction_index int) {
tsr.Rollback(Default_Program_Name, instruction_index)
}
-//Reset the program so that no instructions exist
-func (tsr *TokenStreamRewriter) DeleteProgram(program_name string){
+
+// Reset the program so that no instructions exist
+func (tsr *TokenStreamRewriter) DeleteProgram(program_name string) {
tsr.Rollback(program_name, Min_Token_Index) //TODO: double test on that cause lower bound is not included
}
-func (tsr *TokenStreamRewriter) DeleteProgramDefault(){
+func (tsr *TokenStreamRewriter) DeleteProgramDefault() {
tsr.DeleteProgram(Default_Program_Name)
}
-func (tsr *TokenStreamRewriter) InsertAfter(program_name string, index int, text string){
+func (tsr *TokenStreamRewriter) InsertAfter(program_name string, index int, text string) {
// to insert after, just insert before next index (even if past end)
var op RewriteOperation = NewInsertAfterOp(index, text, tsr.tokens)
rewrites := tsr.GetProgram(program_name)
@@ -323,31 +319,31 @@ func (tsr *TokenStreamRewriter) InsertAfter(program_name string, index int, text
tsr.AddToProgram(program_name, op)
}
-func (tsr *TokenStreamRewriter) InsertAfterDefault(index int, text string){
+func (tsr *TokenStreamRewriter) InsertAfterDefault(index int, text string) {
tsr.InsertAfter(Default_Program_Name, index, text)
}
-func (tsr *TokenStreamRewriter) InsertAfterToken(program_name string, token Token, text string){
+func (tsr *TokenStreamRewriter) InsertAfterToken(program_name string, token Token, text string) {
tsr.InsertAfter(program_name, token.GetTokenIndex(), text)
}
-func (tsr* TokenStreamRewriter) InsertBefore(program_name string, index int, text string){
+func (tsr *TokenStreamRewriter) InsertBefore(program_name string, index int, text string) {
var op RewriteOperation = NewInsertBeforeOp(index, text, tsr.tokens)
rewrites := tsr.GetProgram(program_name)
op.SetInstructionIndex(len(rewrites))
tsr.AddToProgram(program_name, op)
}
-func (tsr *TokenStreamRewriter) InsertBeforeDefault(index int, text string){
+func (tsr *TokenStreamRewriter) InsertBeforeDefault(index int, text string) {
tsr.InsertBefore(Default_Program_Name, index, text)
}
-func (tsr *TokenStreamRewriter) InsertBeforeToken(program_name string,token Token, text string){
+func (tsr *TokenStreamRewriter) InsertBeforeToken(program_name string, token Token, text string) {
tsr.InsertBefore(program_name, token.GetTokenIndex(), text)
}
-func (tsr *TokenStreamRewriter) Replace(program_name string, from, to int, text string){
- if from > to || from < 0 || to < 0 || to >= tsr.tokens.Size(){
+func (tsr *TokenStreamRewriter) Replace(program_name string, from, to int, text string) {
+ if from > to || from < 0 || to < 0 || to >= tsr.tokens.Size() {
panic(fmt.Sprintf("replace: range invalid: %d..%d(size=%d)",
from, to, tsr.tokens.Size()))
}
@@ -357,207 +353,216 @@ func (tsr *TokenStreamRewriter) Replace(program_name string, from, to int, text
tsr.AddToProgram(program_name, op)
}
-func (tsr *TokenStreamRewriter)ReplaceDefault(from, to int, text string) {
+func (tsr *TokenStreamRewriter) ReplaceDefault(from, to int, text string) {
tsr.Replace(Default_Program_Name, from, to, text)
}
-func (tsr *TokenStreamRewriter)ReplaceDefaultPos(index int, text string){
+func (tsr *TokenStreamRewriter) ReplaceDefaultPos(index int, text string) {
tsr.ReplaceDefault(index, index, text)
}
-func (tsr *TokenStreamRewriter)ReplaceToken(program_name string, from, to Token, text string){
+func (tsr *TokenStreamRewriter) ReplaceToken(program_name string, from, to Token, text string) {
tsr.Replace(program_name, from.GetTokenIndex(), to.GetTokenIndex(), text)
}
-func (tsr *TokenStreamRewriter)ReplaceTokenDefault(from, to Token, text string){
+func (tsr *TokenStreamRewriter) ReplaceTokenDefault(from, to Token, text string) {
tsr.ReplaceToken(Default_Program_Name, from, to, text)
}
-func (tsr *TokenStreamRewriter)ReplaceTokenDefaultPos(index Token, text string){
+func (tsr *TokenStreamRewriter) ReplaceTokenDefaultPos(index Token, text string) {
tsr.ReplaceTokenDefault(index, index, text)
}
-func (tsr *TokenStreamRewriter)Delete(program_name string, from, to int){
- tsr.Replace(program_name, from, to, "" )
+func (tsr *TokenStreamRewriter) Delete(program_name string, from, to int) {
+ tsr.Replace(program_name, from, to, "")
}
-func (tsr *TokenStreamRewriter)DeleteDefault(from, to int){
+func (tsr *TokenStreamRewriter) DeleteDefault(from, to int) {
tsr.Delete(Default_Program_Name, from, to)
}
-func (tsr *TokenStreamRewriter)DeleteDefaultPos(index int){
- tsr.DeleteDefault(index,index)
+func (tsr *TokenStreamRewriter) DeleteDefaultPos(index int) {
+ tsr.DeleteDefault(index, index)
}
-func (tsr *TokenStreamRewriter)DeleteToken(program_name string, from, to Token) {
+func (tsr *TokenStreamRewriter) DeleteToken(program_name string, from, to Token) {
tsr.ReplaceToken(program_name, from, to, "")
}
-func (tsr *TokenStreamRewriter)DeleteTokenDefault(from,to Token){
+func (tsr *TokenStreamRewriter) DeleteTokenDefault(from, to Token) {
tsr.DeleteToken(Default_Program_Name, from, to)
}
-func (tsr *TokenStreamRewriter)GetLastRewriteTokenIndex(program_name string)int {
+func (tsr *TokenStreamRewriter) GetLastRewriteTokenIndex(program_name string) int {
i, ok := tsr.last_rewrite_token_indexes[program_name]
- if !ok{
+ if !ok {
return -1
}
return i
}
-func (tsr *TokenStreamRewriter)GetLastRewriteTokenIndexDefault()int{
+func (tsr *TokenStreamRewriter) GetLastRewriteTokenIndexDefault() int {
return tsr.GetLastRewriteTokenIndex(Default_Program_Name)
}
-func (tsr *TokenStreamRewriter)SetLastRewriteTokenIndex(program_name string, i int){
+func (tsr *TokenStreamRewriter) SetLastRewriteTokenIndex(program_name string, i int) {
tsr.last_rewrite_token_indexes[program_name] = i
}
-func (tsr *TokenStreamRewriter)InitializeProgram(name string)[]RewriteOperation{
+func (tsr *TokenStreamRewriter) InitializeProgram(name string) []RewriteOperation {
is := make([]RewriteOperation, 0, Program_Init_Size)
tsr.programs[name] = is
return is
}
-func (tsr *TokenStreamRewriter)AddToProgram(name string, op RewriteOperation){
+func (tsr *TokenStreamRewriter) AddToProgram(name string, op RewriteOperation) {
is := tsr.GetProgram(name)
is = append(is, op)
tsr.programs[name] = is
}
-func (tsr *TokenStreamRewriter)GetProgram(name string) []RewriteOperation {
+func (tsr *TokenStreamRewriter) GetProgram(name string) []RewriteOperation {
is, ok := tsr.programs[name]
- if !ok{
+ if !ok {
is = tsr.InitializeProgram(name)
}
return is
}
-// Return the text from the original tokens altered per the
-// instructions given to this rewriter.
-func (tsr *TokenStreamRewriter)GetTextDefault() string{
+
+// Return the text from the original tokens altered per the
+// instructions given to this rewriter.
+func (tsr *TokenStreamRewriter) GetTextDefault() string {
return tsr.GetText(
Default_Program_Name,
NewInterval(0, tsr.tokens.Size()-1))
}
-// Return the text from the original tokens altered per the
-// instructions given to this rewriter.
-func (tsr *TokenStreamRewriter)GetText(program_name string, interval *Interval) string {
+
+// Return the text from the original tokens altered per the
+// instructions given to this rewriter.
+func (tsr *TokenStreamRewriter) GetText(program_name string, interval *Interval) string {
rewrites := tsr.programs[program_name]
start := interval.Start
- stop := interval.Stop
+ stop := interval.Stop
// ensure start/end are in range
stop = min(stop, tsr.tokens.Size()-1)
- start = max(start,0)
- if rewrites == nil || len(rewrites) == 0{
+ start = max(start, 0)
+ if rewrites == nil || len(rewrites) == 0 {
return tsr.tokens.GetTextFromInterval(interval) // no instructions to execute
}
buf := bytes.Buffer{}
// First, optimize instruction stream
indexToOp := reduceToSingleOperationPerIndex(rewrites)
// Walk buffer, executing instructions and emitting tokens
- for i:=start; i<=stop && i= tsr.tokens.Size()-1 {buf.WriteString(op.GetText())}
+ for _, op := range indexToOp {
+ if op.GetIndex() >= tsr.tokens.Size()-1 {
+ buf.WriteString(op.GetText())
+ }
}
}
return buf.String()
}
-// We need to combine operations and report invalid operations (like
-// overlapping replaces that are not completed nested). Inserts to
-// same index need to be combined etc... Here are the cases:
+// We need to combine operations and report invalid operations (like
+// overlapping replaces that are not completed nested). Inserts to
+// same index need to be combined etc... Here are the cases:
//
-// I.i.u I.j.v leave alone, nonoverlapping
-// I.i.u I.i.v combine: Iivu
+// I.i.u I.j.v leave alone, nonoverlapping
+// I.i.u I.i.v combine: Iivu
//
-// R.i-j.u R.x-y.v | i-j in x-y delete first R
-// R.i-j.u R.i-j.v delete first R
-// R.i-j.u R.x-y.v | x-y in i-j ERROR
-// R.i-j.u R.x-y.v | boundaries overlap ERROR
+// R.i-j.u R.x-y.v | i-j in x-y delete first R
+// R.i-j.u R.i-j.v delete first R
+// R.i-j.u R.x-y.v | x-y in i-j ERROR
+// R.i-j.u R.x-y.v | boundaries overlap ERROR
//
-// Delete special case of replace (text==null):
-// D.i-j.u D.x-y.v | boundaries overlap combine to max(min)..max(right)
+// Delete special case of replace (text==null):
+// D.i-j.u D.x-y.v | boundaries overlap combine to max(min)..max(right)
//
-// I.i.u R.x-y.v | i in (x+1)-y delete I (since insert before
-// we're not deleting i)
-// I.i.u R.x-y.v | i not in (x+1)-y leave alone, nonoverlapping
-// R.x-y.v I.i.u | i in x-y ERROR
-// R.x-y.v I.x.u R.x-y.uv (combine, delete I)
-// R.x-y.v I.i.u | i not in x-y leave alone, nonoverlapping
+// I.i.u R.x-y.v | i in (x+1)-y delete I (since insert before
+// we're not deleting i)
+// I.i.u R.x-y.v | i not in (x+1)-y leave alone, nonoverlapping
+// R.x-y.v I.i.u | i in x-y ERROR
+// R.x-y.v I.x.u R.x-y.uv (combine, delete I)
+// R.x-y.v I.i.u | i not in x-y leave alone, nonoverlapping
//
-// I.i.u = insert u before op @ index i
-// R.x-y.u = replace x-y indexed tokens with u
+// I.i.u = insert u before op @ index i
+// R.x-y.u = replace x-y indexed tokens with u
//
-// First we need to examine replaces. For any replace op:
+// First we need to examine replaces. For any replace op:
//
-// 1. wipe out any insertions before op within that range.
-// 2. Drop any replace op before that is contained completely within
-// that range.
-// 3. Throw exception upon boundary overlap with any previous replace.
+// 1. wipe out any insertions before op within that range.
+// 2. Drop any replace op before that is contained completely within
+// that range.
+// 3. Throw exception upon boundary overlap with any previous replace.
//
-// Then we can deal with inserts:
+// Then we can deal with inserts:
//
-// 1. for any inserts to same index, combine even if not adjacent.
-// 2. for any prior replace with same left boundary, combine this
-// insert with replace and delete this replace.
-// 3. throw exception if index in same range as previous replace
+// 1. for any inserts to same index, combine even if not adjacent.
+// 2. for any prior replace with same left boundary, combine this
+// insert with replace and delete this replace.
+// 3. throw exception if index in same range as previous replace
//
-// Don't actually delete; make op null in list. Easier to walk list.
-// Later we can throw as we add to index → op map.
+// Don't actually delete; make op null in list. Easier to walk list.
+// Later we can throw as we add to index → op map.
//
-// Note that I.2 R.2-2 will wipe out I.2 even though, technically, the
-// inserted stuff would be before the replace range. But, if you
-// add tokens in front of a method body '{' and then delete the method
-// body, I think the stuff before the '{' you added should disappear too.
+// Note that I.2 R.2-2 will wipe out I.2 even though, technically, the
+// inserted stuff would be before the replace range. But, if you
+// add tokens in front of a method body '{' and then delete the method
+// body, I think the stuff before the '{' you added should disappear too.
//
-// Return a map from token index to operation.
-//
-func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]RewriteOperation{
+// Return a map from token index to operation.
+func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]RewriteOperation {
// WALK REPLACES
- for i:=0; i < len(rewrites); i++{
+ for i := 0; i < len(rewrites); i++ {
op := rewrites[i]
- if op == nil{continue}
+ if op == nil {
+ continue
+ }
rop, ok := op.(*ReplaceOp)
- if !ok{continue}
+ if !ok {
+ continue
+ }
// Wipe prior inserts within range
- for j:=0; j rop.index && iop.index <=rop.LastIndex{
+ } else if iop.index > rop.index && iop.index <= rop.LastIndex {
// delete insert as it's a no-op.
rewrites[iop.instruction_index] = nil
}
}
}
// Drop any prior replaces contained within
- for j:=0; j=rop.index && prevop.LastIndex <= rop.LastIndex{
+ for j := 0; j < i && j < len(rewrites); j++ {
+ if prevop, ok := rewrites[j].(*ReplaceOp); ok {
+ if prevop.index >= rop.index && prevop.LastIndex <= rop.LastIndex {
// delete replace as it's a no-op.
rewrites[prevop.instruction_index] = nil
continue
@@ -566,61 +571,67 @@ func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]Rewrit
disjoint := prevop.LastIndex < rop.index || prevop.index > rop.LastIndex
// Delete special case of replace (text==null):
// D.i-j.u D.x-y.v | boundaries overlap combine to max(min)..max(right)
- if prevop.text == "" && rop.text == "" && !disjoint{
+ if prevop.text == "" && rop.text == "" && !disjoint {
rewrites[prevop.instruction_index] = nil
rop.index = min(prevop.index, rop.index)
rop.LastIndex = max(prevop.LastIndex, rop.LastIndex)
println("new rop" + rop.String()) //TODO: remove console write, taken from Java version
- }else if !disjoint{
+ } else if !disjoint {
panic("replace op boundaries of " + rop.String() + " overlap with previous " + prevop.String())
}
}
}
}
// WALK INSERTS
- for i:=0; i < len(rewrites); i++ {
+ for i := 0; i < len(rewrites); i++ {
op := rewrites[i]
- if op == nil{continue}
+ if op == nil {
+ continue
+ }
//hack to replicate inheritance in composition
_, iok := rewrites[i].(*InsertBeforeOp)
_, aok := rewrites[i].(*InsertAfterOp)
- if !iok && !aok{continue}
+ if !iok && !aok {
+ continue
+ }
iop := rewrites[i]
// combine current insert with prior if any at same index
// deviating a bit from TokenStreamRewriter.java - hard to incorporate inheritance logic
- for j:=0; j= rop.index && iop.GetIndex() <= rop.LastIndex{
- panic("insert op "+iop.String()+" within boundaries of previous "+rop.String())
+ if iop.GetIndex() >= rop.index && iop.GetIndex() <= rop.LastIndex {
+ panic("insert op " + iop.String() + " within boundaries of previous " + rop.String())
}
}
}
}
m := map[int]RewriteOperation{}
- for i:=0; i < len(rewrites); i++{
+ for i := 0; i < len(rewrites); i++ {
op := rewrites[i]
- if op == nil {continue}
- if _, ok := m[op.GetIndex()]; ok{
+ if op == nil {
+ continue
+ }
+ if _, ok := m[op.GetIndex()]; ok {
panic("should only be one op per index")
}
m[op.GetIndex()] = op
@@ -628,22 +639,21 @@ func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]Rewrit
return m
}
-
/*
Quick fixing Go lack of overloads
- */
+*/
-func max(a,b int)int{
- if a>b{
+func max(a, b int) int {
+ if a > b {
return a
- }else {
+ } else {
return b
}
}
-func min(a,b int)int{
- if a as.threshold {
as.expand()
}
@@ -98,7 +96,7 @@ func (as *array2DHashSet) expand() {
b := as.getBuckets(o)
bucketLength := newBucketLengths[b]
- var newBucket []interface{}
+ var newBucket []Collectable[any]
if bucketLength == 0 {
// new bucket
newBucket = as.createBucket(as.initialBucketCapacity)
@@ -107,7 +105,7 @@ func (as *array2DHashSet) expand() {
newBucket = newTable[b]
if bucketLength == len(newBucket) {
// expand
- newBucketCopy := make([]interface{}, len(newBucket)<<1)
+ newBucketCopy := make([]Collectable[any], len(newBucket)<<1)
copy(newBucketCopy[:bucketLength], newBucket)
newBucket = newBucketCopy
newTable[b] = newBucket
@@ -124,7 +122,7 @@ func (as *array2DHashSet) Len() int {
return as.n
}
-func (as *array2DHashSet) Get(o interface{}) interface{} {
+func (as *array2DHashSet) Get(o Collectable[any]) interface{} {
if o == nil {
return nil
}
@@ -147,7 +145,7 @@ func (as *array2DHashSet) Get(o interface{}) interface{} {
return nil
}
-func (as *array2DHashSet) innerAdd(o interface{}) interface{} {
+func (as *array2DHashSet) innerAdd(o Collectable[any]) interface{} {
b := as.getBuckets(o)
bucket := as.buckets[b]
@@ -178,7 +176,7 @@ func (as *array2DHashSet) innerAdd(o interface{}) interface{} {
// full bucket, expand and add to end
oldLength := len(bucket)
- bucketCopy := make([]interface{}, oldLength<<1)
+ bucketCopy := make([]Collectable[any], oldLength<<1)
copy(bucketCopy[:oldLength], bucket)
bucket = bucketCopy
as.buckets[b] = bucket
@@ -187,22 +185,22 @@ func (as *array2DHashSet) innerAdd(o interface{}) interface{} {
return o
}
-func (as *array2DHashSet) getBuckets(value interface{}) int {
+func (as *array2DHashSet) getBuckets(value Collectable[any]) int {
hash := as.hashcodeFunction(value)
return hash & (len(as.buckets) - 1)
}
-func (as *array2DHashSet) createBuckets(cap int) [][]interface{} {
- return make([][]interface{}, cap)
+func (as *array2DHashSet) createBuckets(cap int) [][]Collectable[any] {
+ return make([][]Collectable[any], cap)
}
-func (as *array2DHashSet) createBucket(cap int) []interface{} {
- return make([]interface{}, cap)
+func (as *array2DHashSet) createBucket(cap int) []Collectable[any] {
+ return make([]Collectable[any], cap)
}
func newArray2DHashSetWithCap(
hashcodeFunction func(interface{}) int,
- equalsFunction func(interface{}, interface{}) bool,
+ equalsFunction func(Collectable[any], Collectable[any]) bool,
initCap int,
initBucketCap int,
) *array2DHashSet {
@@ -231,7 +229,7 @@ func newArray2DHashSetWithCap(
func newArray2DHashSet(
hashcodeFunction func(interface{}) int,
- equalsFunction func(interface{}, interface{}) bool,
+ equalsFunction func(Collectable[any], Collectable[any]) bool,
) *array2DHashSet {
return newArray2DHashSetWithCap(hashcodeFunction, equalsFunction, _initalCapacity, _initalBucketCapacity)
}
diff --git a/vendor/github.com/cenkalti/backoff/v4/.travis.yml b/vendor/github.com/cenkalti/backoff/v4/.travis.yml
deleted file mode 100644
index c79105c2fb..0000000000
--- a/vendor/github.com/cenkalti/backoff/v4/.travis.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-language: go
-go:
- - 1.13
- - 1.x
- - tip
-before_install:
- - go get github.com/mattn/goveralls
- - go get golang.org/x/tools/cmd/cover
-script:
- - $HOME/gopath/bin/goveralls -service=travis-ci
diff --git a/vendor/github.com/cenkalti/backoff/v4/retry.go b/vendor/github.com/cenkalti/backoff/v4/retry.go
index 1ce2507ebc..b9c0c51cd7 100644
--- a/vendor/github.com/cenkalti/backoff/v4/retry.go
+++ b/vendor/github.com/cenkalti/backoff/v4/retry.go
@@ -5,10 +5,20 @@ import (
"time"
)
+// An OperationWithData is executing by RetryWithData() or RetryNotifyWithData().
+// The operation will be retried using a backoff policy if it returns an error.
+type OperationWithData[T any] func() (T, error)
+
// An Operation is executing by Retry() or RetryNotify().
// The operation will be retried using a backoff policy if it returns an error.
type Operation func() error
+func (o Operation) withEmptyData() OperationWithData[struct{}] {
+ return func() (struct{}, error) {
+ return struct{}{}, o()
+ }
+}
+
// Notify is a notify-on-error function. It receives an operation error and
// backoff delay if the operation failed (with an error).
//
@@ -28,18 +38,41 @@ func Retry(o Operation, b BackOff) error {
return RetryNotify(o, b, nil)
}
+// RetryWithData is like Retry but returns data in the response too.
+func RetryWithData[T any](o OperationWithData[T], b BackOff) (T, error) {
+ return RetryNotifyWithData(o, b, nil)
+}
+
// RetryNotify calls notify function with the error and wait duration
// for each failed attempt before sleep.
func RetryNotify(operation Operation, b BackOff, notify Notify) error {
return RetryNotifyWithTimer(operation, b, notify, nil)
}
+// RetryNotifyWithData is like RetryNotify but returns data in the response too.
+func RetryNotifyWithData[T any](operation OperationWithData[T], b BackOff, notify Notify) (T, error) {
+ return doRetryNotify(operation, b, notify, nil)
+}
+
// RetryNotifyWithTimer calls notify function with the error and wait duration using the given Timer
// for each failed attempt before sleep.
// A default timer that uses system timer is used when nil is passed.
func RetryNotifyWithTimer(operation Operation, b BackOff, notify Notify, t Timer) error {
- var err error
- var next time.Duration
+ _, err := doRetryNotify(operation.withEmptyData(), b, notify, t)
+ return err
+}
+
+// RetryNotifyWithTimerAndData is like RetryNotifyWithTimer but returns data in the response too.
+func RetryNotifyWithTimerAndData[T any](operation OperationWithData[T], b BackOff, notify Notify, t Timer) (T, error) {
+ return doRetryNotify(operation, b, notify, t)
+}
+
+func doRetryNotify[T any](operation OperationWithData[T], b BackOff, notify Notify, t Timer) (T, error) {
+ var (
+ err error
+ next time.Duration
+ res T
+ )
if t == nil {
t = &defaultTimer{}
}
@@ -52,21 +85,22 @@ func RetryNotifyWithTimer(operation Operation, b BackOff, notify Notify, t Timer
b.Reset()
for {
- if err = operation(); err == nil {
- return nil
+ res, err = operation()
+ if err == nil {
+ return res, nil
}
var permanent *PermanentError
if errors.As(err, &permanent) {
- return permanent.Err
+ return res, permanent.Err
}
if next = b.NextBackOff(); next == Stop {
if cerr := ctx.Err(); cerr != nil {
- return cerr
+ return res, cerr
}
- return err
+ return res, err
}
if notify != nil {
@@ -77,7 +111,7 @@ func RetryNotifyWithTimer(operation Operation, b BackOff, notify Notify, t Timer
select {
case <-ctx.Done():
- return ctx.Err()
+ return res, ctx.Err()
case <-t.C():
}
}
diff --git a/vendor/github.com/cespare/xxhash/v2/README.md b/vendor/github.com/cespare/xxhash/v2/README.md
index 792b4a60b3..8bf0e5b781 100644
--- a/vendor/github.com/cespare/xxhash/v2/README.md
+++ b/vendor/github.com/cespare/xxhash/v2/README.md
@@ -3,8 +3,7 @@
[![Go Reference](https://pkg.go.dev/badge/github.com/cespare/xxhash/v2.svg)](https://pkg.go.dev/github.com/cespare/xxhash/v2)
[![Test](https://github.com/cespare/xxhash/actions/workflows/test.yml/badge.svg)](https://github.com/cespare/xxhash/actions/workflows/test.yml)
-xxhash is a Go implementation of the 64-bit
-[xxHash](http://cyan4973.github.io/xxHash/) algorithm, XXH64. This is a
+xxhash is a Go implementation of the 64-bit [xxHash] algorithm, XXH64. This is a
high-quality hashing algorithm that is much faster than anything in the Go
standard library.
@@ -25,8 +24,11 @@ func (*Digest) WriteString(string) (int, error)
func (*Digest) Sum64() uint64
```
-This implementation provides a fast pure-Go implementation and an even faster
-assembly implementation for amd64.
+The package is written with optimized pure Go and also contains even faster
+assembly implementations for amd64 and arm64. If desired, the `purego` build tag
+opts into using the Go code even on those architectures.
+
+[xxHash]: http://cyan4973.github.io/xxHash/
## Compatibility
@@ -45,19 +47,20 @@ I recommend using the latest release of Go.
Here are some quick benchmarks comparing the pure-Go and assembly
implementations of Sum64.
-| input size | purego | asm |
-| --- | --- | --- |
-| 5 B | 979.66 MB/s | 1291.17 MB/s |
-| 100 B | 7475.26 MB/s | 7973.40 MB/s |
-| 4 KB | 17573.46 MB/s | 17602.65 MB/s |
-| 10 MB | 17131.46 MB/s | 17142.16 MB/s |
+| input size | purego | asm |
+| ---------- | --------- | --------- |
+| 4 B | 1.3 GB/s | 1.2 GB/s |
+| 16 B | 2.9 GB/s | 3.5 GB/s |
+| 100 B | 6.9 GB/s | 8.1 GB/s |
+| 4 KB | 11.7 GB/s | 16.7 GB/s |
+| 10 MB | 12.0 GB/s | 17.3 GB/s |
-These numbers were generated on Ubuntu 18.04 with an Intel i7-8700K CPU using
-the following commands under Go 1.11.2:
+These numbers were generated on Ubuntu 20.04 with an Intel Xeon Platinum 8252C
+CPU using the following commands under Go 1.19.2:
```
-$ go test -tags purego -benchtime 10s -bench '/xxhash,direct,bytes'
-$ go test -benchtime 10s -bench '/xxhash,direct,bytes'
+benchstat <(go test -tags purego -benchtime 500ms -count 15 -bench 'Sum64$')
+benchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$')
```
## Projects using this package
diff --git a/vendor/github.com/cespare/xxhash/v2/testall.sh b/vendor/github.com/cespare/xxhash/v2/testall.sh
new file mode 100644
index 0000000000..94b9c44398
--- /dev/null
+++ b/vendor/github.com/cespare/xxhash/v2/testall.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+set -eu -o pipefail
+
+# Small convenience script for running the tests with various combinations of
+# arch/tags. This assumes we're running on amd64 and have qemu available.
+
+go test ./...
+go test -tags purego ./...
+GOARCH=arm64 go test
+GOARCH=arm64 go test -tags purego
diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash.go b/vendor/github.com/cespare/xxhash/v2/xxhash.go
index 15c835d541..a9e0d45c9d 100644
--- a/vendor/github.com/cespare/xxhash/v2/xxhash.go
+++ b/vendor/github.com/cespare/xxhash/v2/xxhash.go
@@ -16,19 +16,11 @@ const (
prime5 uint64 = 2870177450012600261
)
-// NOTE(caleb): I'm using both consts and vars of the primes. Using consts where
-// possible in the Go code is worth a small (but measurable) performance boost
-// by avoiding some MOVQs. Vars are needed for the asm and also are useful for
-// convenience in the Go code in a few places where we need to intentionally
-// avoid constant arithmetic (e.g., v1 := prime1 + prime2 fails because the
-// result overflows a uint64).
-var (
- prime1v = prime1
- prime2v = prime2
- prime3v = prime3
- prime4v = prime4
- prime5v = prime5
-)
+// Store the primes in an array as well.
+//
+// The consts are used when possible in Go code to avoid MOVs but we need a
+// contiguous array of the assembly code.
+var primes = [...]uint64{prime1, prime2, prime3, prime4, prime5}
// Digest implements hash.Hash64.
type Digest struct {
@@ -50,10 +42,10 @@ func New() *Digest {
// Reset clears the Digest's state so that it can be reused.
func (d *Digest) Reset() {
- d.v1 = prime1v + prime2
+ d.v1 = primes[0] + prime2
d.v2 = prime2
d.v3 = 0
- d.v4 = -prime1v
+ d.v4 = -primes[0]
d.total = 0
d.n = 0
}
@@ -69,21 +61,23 @@ func (d *Digest) Write(b []byte) (n int, err error) {
n = len(b)
d.total += uint64(n)
+ memleft := d.mem[d.n&(len(d.mem)-1):]
+
if d.n+n < 32 {
// This new data doesn't even fill the current block.
- copy(d.mem[d.n:], b)
+ copy(memleft, b)
d.n += n
return
}
if d.n > 0 {
// Finish off the partial block.
- copy(d.mem[d.n:], b)
+ c := copy(memleft, b)
d.v1 = round(d.v1, u64(d.mem[0:8]))
d.v2 = round(d.v2, u64(d.mem[8:16]))
d.v3 = round(d.v3, u64(d.mem[16:24]))
d.v4 = round(d.v4, u64(d.mem[24:32]))
- b = b[32-d.n:]
+ b = b[c:]
d.n = 0
}
@@ -133,21 +127,20 @@ func (d *Digest) Sum64() uint64 {
h += d.total
- i, end := 0, d.n
- for ; i+8 <= end; i += 8 {
- k1 := round(0, u64(d.mem[i:i+8]))
+ b := d.mem[:d.n&(len(d.mem)-1)]
+ for ; len(b) >= 8; b = b[8:] {
+ k1 := round(0, u64(b[:8]))
h ^= k1
h = rol27(h)*prime1 + prime4
}
- if i+4 <= end {
- h ^= uint64(u32(d.mem[i:i+4])) * prime1
+ if len(b) >= 4 {
+ h ^= uint64(u32(b[:4])) * prime1
h = rol23(h)*prime2 + prime3
- i += 4
+ b = b[4:]
}
- for i < end {
- h ^= uint64(d.mem[i]) * prime5
+ for ; len(b) > 0; b = b[1:] {
+ h ^= uint64(b[0]) * prime5
h = rol11(h) * prime1
- i++
}
h ^= h >> 33
diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s b/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s
index be8db5bf79..3e8b132579 100644
--- a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s
+++ b/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s
@@ -1,215 +1,209 @@
+//go:build !appengine && gc && !purego
// +build !appengine
// +build gc
// +build !purego
#include "textflag.h"
-// Register allocation:
-// AX h
-// SI pointer to advance through b
-// DX n
-// BX loop end
-// R8 v1, k1
-// R9 v2
-// R10 v3
-// R11 v4
-// R12 tmp
-// R13 prime1v
-// R14 prime2v
-// DI prime4v
-
-// round reads from and advances the buffer pointer in SI.
-// It assumes that R13 has prime1v and R14 has prime2v.
-#define round(r) \
- MOVQ (SI), R12 \
- ADDQ $8, SI \
- IMULQ R14, R12 \
- ADDQ R12, r \
- ROLQ $31, r \
- IMULQ R13, r
-
-// mergeRound applies a merge round on the two registers acc and val.
-// It assumes that R13 has prime1v, R14 has prime2v, and DI has prime4v.
-#define mergeRound(acc, val) \
- IMULQ R14, val \
- ROLQ $31, val \
- IMULQ R13, val \
- XORQ val, acc \
- IMULQ R13, acc \
- ADDQ DI, acc
+// Registers:
+#define h AX
+#define d AX
+#define p SI // pointer to advance through b
+#define n DX
+#define end BX // loop end
+#define v1 R8
+#define v2 R9
+#define v3 R10
+#define v4 R11
+#define x R12
+#define prime1 R13
+#define prime2 R14
+#define prime4 DI
+
+#define round(acc, x) \
+ IMULQ prime2, x \
+ ADDQ x, acc \
+ ROLQ $31, acc \
+ IMULQ prime1, acc
+
+// round0 performs the operation x = round(0, x).
+#define round0(x) \
+ IMULQ prime2, x \
+ ROLQ $31, x \
+ IMULQ prime1, x
+
+// mergeRound applies a merge round on the two registers acc and x.
+// It assumes that prime1, prime2, and prime4 have been loaded.
+#define mergeRound(acc, x) \
+ round0(x) \
+ XORQ x, acc \
+ IMULQ prime1, acc \
+ ADDQ prime4, acc
+
+// blockLoop processes as many 32-byte blocks as possible,
+// updating v1, v2, v3, and v4. It assumes that there is at least one block
+// to process.
+#define blockLoop() \
+loop: \
+ MOVQ +0(p), x \
+ round(v1, x) \
+ MOVQ +8(p), x \
+ round(v2, x) \
+ MOVQ +16(p), x \
+ round(v3, x) \
+ MOVQ +24(p), x \
+ round(v4, x) \
+ ADDQ $32, p \
+ CMPQ p, end \
+ JLE loop
// func Sum64(b []byte) uint64
-TEXT ·Sum64(SB), NOSPLIT, $0-32
+TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32
// Load fixed primes.
- MOVQ ·prime1v(SB), R13
- MOVQ ·prime2v(SB), R14
- MOVQ ·prime4v(SB), DI
+ MOVQ ·primes+0(SB), prime1
+ MOVQ ·primes+8(SB), prime2
+ MOVQ ·primes+24(SB), prime4
// Load slice.
- MOVQ b_base+0(FP), SI
- MOVQ b_len+8(FP), DX
- LEAQ (SI)(DX*1), BX
+ MOVQ b_base+0(FP), p
+ MOVQ b_len+8(FP), n
+ LEAQ (p)(n*1), end
// The first loop limit will be len(b)-32.
- SUBQ $32, BX
+ SUBQ $32, end
// Check whether we have at least one block.
- CMPQ DX, $32
+ CMPQ n, $32
JLT noBlocks
// Set up initial state (v1, v2, v3, v4).
- MOVQ R13, R8
- ADDQ R14, R8
- MOVQ R14, R9
- XORQ R10, R10
- XORQ R11, R11
- SUBQ R13, R11
-
- // Loop until SI > BX.
-blockLoop:
- round(R8)
- round(R9)
- round(R10)
- round(R11)
-
- CMPQ SI, BX
- JLE blockLoop
-
- MOVQ R8, AX
- ROLQ $1, AX
- MOVQ R9, R12
- ROLQ $7, R12
- ADDQ R12, AX
- MOVQ R10, R12
- ROLQ $12, R12
- ADDQ R12, AX
- MOVQ R11, R12
- ROLQ $18, R12
- ADDQ R12, AX
-
- mergeRound(AX, R8)
- mergeRound(AX, R9)
- mergeRound(AX, R10)
- mergeRound(AX, R11)
+ MOVQ prime1, v1
+ ADDQ prime2, v1
+ MOVQ prime2, v2
+ XORQ v3, v3
+ XORQ v4, v4
+ SUBQ prime1, v4
+
+ blockLoop()
+
+ MOVQ v1, h
+ ROLQ $1, h
+ MOVQ v2, x
+ ROLQ $7, x
+ ADDQ x, h
+ MOVQ v3, x
+ ROLQ $12, x
+ ADDQ x, h
+ MOVQ v4, x
+ ROLQ $18, x
+ ADDQ x, h
+
+ mergeRound(h, v1)
+ mergeRound(h, v2)
+ mergeRound(h, v3)
+ mergeRound(h, v4)
JMP afterBlocks
noBlocks:
- MOVQ ·prime5v(SB), AX
+ MOVQ ·primes+32(SB), h
afterBlocks:
- ADDQ DX, AX
-
- // Right now BX has len(b)-32, and we want to loop until SI > len(b)-8.
- ADDQ $24, BX
-
- CMPQ SI, BX
- JG fourByte
-
-wordLoop:
- // Calculate k1.
- MOVQ (SI), R8
- ADDQ $8, SI
- IMULQ R14, R8
- ROLQ $31, R8
- IMULQ R13, R8
-
- XORQ R8, AX
- ROLQ $27, AX
- IMULQ R13, AX
- ADDQ DI, AX
-
- CMPQ SI, BX
- JLE wordLoop
-
-fourByte:
- ADDQ $4, BX
- CMPQ SI, BX
- JG singles
-
- MOVL (SI), R8
- ADDQ $4, SI
- IMULQ R13, R8
- XORQ R8, AX
-
- ROLQ $23, AX
- IMULQ R14, AX
- ADDQ ·prime3v(SB), AX
-
-singles:
- ADDQ $4, BX
- CMPQ SI, BX
+ ADDQ n, h
+
+ ADDQ $24, end
+ CMPQ p, end
+ JG try4
+
+loop8:
+ MOVQ (p), x
+ ADDQ $8, p
+ round0(x)
+ XORQ x, h
+ ROLQ $27, h
+ IMULQ prime1, h
+ ADDQ prime4, h
+
+ CMPQ p, end
+ JLE loop8
+
+try4:
+ ADDQ $4, end
+ CMPQ p, end
+ JG try1
+
+ MOVL (p), x
+ ADDQ $4, p
+ IMULQ prime1, x
+ XORQ x, h
+
+ ROLQ $23, h
+ IMULQ prime2, h
+ ADDQ ·primes+16(SB), h
+
+try1:
+ ADDQ $4, end
+ CMPQ p, end
JGE finalize
-singlesLoop:
- MOVBQZX (SI), R12
- ADDQ $1, SI
- IMULQ ·prime5v(SB), R12
- XORQ R12, AX
+loop1:
+ MOVBQZX (p), x
+ ADDQ $1, p
+ IMULQ ·primes+32(SB), x
+ XORQ x, h
+ ROLQ $11, h
+ IMULQ prime1, h
- ROLQ $11, AX
- IMULQ R13, AX
-
- CMPQ SI, BX
- JL singlesLoop
+ CMPQ p, end
+ JL loop1
finalize:
- MOVQ AX, R12
- SHRQ $33, R12
- XORQ R12, AX
- IMULQ R14, AX
- MOVQ AX, R12
- SHRQ $29, R12
- XORQ R12, AX
- IMULQ ·prime3v(SB), AX
- MOVQ AX, R12
- SHRQ $32, R12
- XORQ R12, AX
-
- MOVQ AX, ret+24(FP)
+ MOVQ h, x
+ SHRQ $33, x
+ XORQ x, h
+ IMULQ prime2, h
+ MOVQ h, x
+ SHRQ $29, x
+ XORQ x, h
+ IMULQ ·primes+16(SB), h
+ MOVQ h, x
+ SHRQ $32, x
+ XORQ x, h
+
+ MOVQ h, ret+24(FP)
RET
-// writeBlocks uses the same registers as above except that it uses AX to store
-// the d pointer.
-
// func writeBlocks(d *Digest, b []byte) int
-TEXT ·writeBlocks(SB), NOSPLIT, $0-40
+TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40
// Load fixed primes needed for round.
- MOVQ ·prime1v(SB), R13
- MOVQ ·prime2v(SB), R14
+ MOVQ ·primes+0(SB), prime1
+ MOVQ ·primes+8(SB), prime2
// Load slice.
- MOVQ b_base+8(FP), SI
- MOVQ b_len+16(FP), DX
- LEAQ (SI)(DX*1), BX
- SUBQ $32, BX
+ MOVQ b_base+8(FP), p
+ MOVQ b_len+16(FP), n
+ LEAQ (p)(n*1), end
+ SUBQ $32, end
// Load vN from d.
- MOVQ d+0(FP), AX
- MOVQ 0(AX), R8 // v1
- MOVQ 8(AX), R9 // v2
- MOVQ 16(AX), R10 // v3
- MOVQ 24(AX), R11 // v4
+ MOVQ s+0(FP), d
+ MOVQ 0(d), v1
+ MOVQ 8(d), v2
+ MOVQ 16(d), v3
+ MOVQ 24(d), v4
// We don't need to check the loop condition here; this function is
// always called with at least one block of data to process.
-blockLoop:
- round(R8)
- round(R9)
- round(R10)
- round(R11)
-
- CMPQ SI, BX
- JLE blockLoop
+ blockLoop()
// Copy vN back to d.
- MOVQ R8, 0(AX)
- MOVQ R9, 8(AX)
- MOVQ R10, 16(AX)
- MOVQ R11, 24(AX)
-
- // The number of bytes written is SI minus the old base pointer.
- SUBQ b_base+8(FP), SI
- MOVQ SI, ret+32(FP)
+ MOVQ v1, 0(d)
+ MOVQ v2, 8(d)
+ MOVQ v3, 16(d)
+ MOVQ v4, 24(d)
+
+ // The number of bytes written is p minus the old base pointer.
+ SUBQ b_base+8(FP), p
+ MOVQ p, ret+32(FP)
RET
diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s b/vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s
new file mode 100644
index 0000000000..7e3145a221
--- /dev/null
+++ b/vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s
@@ -0,0 +1,183 @@
+//go:build !appengine && gc && !purego
+// +build !appengine
+// +build gc
+// +build !purego
+
+#include "textflag.h"
+
+// Registers:
+#define digest R1
+#define h R2 // return value
+#define p R3 // input pointer
+#define n R4 // input length
+#define nblocks R5 // n / 32
+#define prime1 R7
+#define prime2 R8
+#define prime3 R9
+#define prime4 R10
+#define prime5 R11
+#define v1 R12
+#define v2 R13
+#define v3 R14
+#define v4 R15
+#define x1 R20
+#define x2 R21
+#define x3 R22
+#define x4 R23
+
+#define round(acc, x) \
+ MADD prime2, acc, x, acc \
+ ROR $64-31, acc \
+ MUL prime1, acc
+
+// round0 performs the operation x = round(0, x).
+#define round0(x) \
+ MUL prime2, x \
+ ROR $64-31, x \
+ MUL prime1, x
+
+#define mergeRound(acc, x) \
+ round0(x) \
+ EOR x, acc \
+ MADD acc, prime4, prime1, acc
+
+// blockLoop processes as many 32-byte blocks as possible,
+// updating v1, v2, v3, and v4. It assumes that n >= 32.
+#define blockLoop() \
+ LSR $5, n, nblocks \
+ PCALIGN $16 \
+ loop: \
+ LDP.P 16(p), (x1, x2) \
+ LDP.P 16(p), (x3, x4) \
+ round(v1, x1) \
+ round(v2, x2) \
+ round(v3, x3) \
+ round(v4, x4) \
+ SUB $1, nblocks \
+ CBNZ nblocks, loop
+
+// func Sum64(b []byte) uint64
+TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32
+ LDP b_base+0(FP), (p, n)
+
+ LDP ·primes+0(SB), (prime1, prime2)
+ LDP ·primes+16(SB), (prime3, prime4)
+ MOVD ·primes+32(SB), prime5
+
+ CMP $32, n
+ CSEL LT, prime5, ZR, h // if n < 32 { h = prime5 } else { h = 0 }
+ BLT afterLoop
+
+ ADD prime1, prime2, v1
+ MOVD prime2, v2
+ MOVD $0, v3
+ NEG prime1, v4
+
+ blockLoop()
+
+ ROR $64-1, v1, x1
+ ROR $64-7, v2, x2
+ ADD x1, x2
+ ROR $64-12, v3, x3
+ ROR $64-18, v4, x4
+ ADD x3, x4
+ ADD x2, x4, h
+
+ mergeRound(h, v1)
+ mergeRound(h, v2)
+ mergeRound(h, v3)
+ mergeRound(h, v4)
+
+afterLoop:
+ ADD n, h
+
+ TBZ $4, n, try8
+ LDP.P 16(p), (x1, x2)
+
+ round0(x1)
+
+ // NOTE: here and below, sequencing the EOR after the ROR (using a
+ // rotated register) is worth a small but measurable speedup for small
+ // inputs.
+ ROR $64-27, h
+ EOR x1 @> 64-27, h, h
+ MADD h, prime4, prime1, h
+
+ round0(x2)
+ ROR $64-27, h
+ EOR x2 @> 64-27, h, h
+ MADD h, prime4, prime1, h
+
+try8:
+ TBZ $3, n, try4
+ MOVD.P 8(p), x1
+
+ round0(x1)
+ ROR $64-27, h
+ EOR x1 @> 64-27, h, h
+ MADD h, prime4, prime1, h
+
+try4:
+ TBZ $2, n, try2
+ MOVWU.P 4(p), x2
+
+ MUL prime1, x2
+ ROR $64-23, h
+ EOR x2 @> 64-23, h, h
+ MADD h, prime3, prime2, h
+
+try2:
+ TBZ $1, n, try1
+ MOVHU.P 2(p), x3
+ AND $255, x3, x1
+ LSR $8, x3, x2
+
+ MUL prime5, x1
+ ROR $64-11, h
+ EOR x1 @> 64-11, h, h
+ MUL prime1, h
+
+ MUL prime5, x2
+ ROR $64-11, h
+ EOR x2 @> 64-11, h, h
+ MUL prime1, h
+
+try1:
+ TBZ $0, n, finalize
+ MOVBU (p), x4
+
+ MUL prime5, x4
+ ROR $64-11, h
+ EOR x4 @> 64-11, h, h
+ MUL prime1, h
+
+finalize:
+ EOR h >> 33, h
+ MUL prime2, h
+ EOR h >> 29, h
+ MUL prime3, h
+ EOR h >> 32, h
+
+ MOVD h, ret+24(FP)
+ RET
+
+// func writeBlocks(d *Digest, b []byte) int
+TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40
+ LDP ·primes+0(SB), (prime1, prime2)
+
+ // Load state. Assume v[1-4] are stored contiguously.
+ MOVD d+0(FP), digest
+ LDP 0(digest), (v1, v2)
+ LDP 16(digest), (v3, v4)
+
+ LDP b_base+8(FP), (p, n)
+
+ blockLoop()
+
+ // Store updated state.
+ STP (v1, v2), 0(digest)
+ STP (v3, v4), 16(digest)
+
+ BIC $31, n
+ MOVD n, ret+32(FP)
+ RET
diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.go b/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go
similarity index 73%
rename from vendor/github.com/cespare/xxhash/v2/xxhash_amd64.go
rename to vendor/github.com/cespare/xxhash/v2/xxhash_asm.go
index ad14b807f4..9216e0a40c 100644
--- a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.go
+++ b/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go
@@ -1,3 +1,5 @@
+//go:build (amd64 || arm64) && !appengine && gc && !purego
+// +build amd64 arm64
// +build !appengine
// +build gc
// +build !purego
diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_other.go b/vendor/github.com/cespare/xxhash/v2/xxhash_other.go
index 4a5a821603..26df13bba4 100644
--- a/vendor/github.com/cespare/xxhash/v2/xxhash_other.go
+++ b/vendor/github.com/cespare/xxhash/v2/xxhash_other.go
@@ -1,4 +1,5 @@
-// +build !amd64 appengine !gc purego
+//go:build (!amd64 && !arm64) || appengine || !gc || purego
+// +build !amd64,!arm64 appengine !gc purego
package xxhash
@@ -14,10 +15,10 @@ func Sum64(b []byte) uint64 {
var h uint64
if n >= 32 {
- v1 := prime1v + prime2
+ v1 := primes[0] + prime2
v2 := prime2
v3 := uint64(0)
- v4 := -prime1v
+ v4 := -primes[0]
for len(b) >= 32 {
v1 = round(v1, u64(b[0:8:len(b)]))
v2 = round(v2, u64(b[8:16:len(b)]))
@@ -36,19 +37,18 @@ func Sum64(b []byte) uint64 {
h += uint64(n)
- i, end := 0, len(b)
- for ; i+8 <= end; i += 8 {
- k1 := round(0, u64(b[i:i+8:len(b)]))
+ for ; len(b) >= 8; b = b[8:] {
+ k1 := round(0, u64(b[:8]))
h ^= k1
h = rol27(h)*prime1 + prime4
}
- if i+4 <= end {
- h ^= uint64(u32(b[i:i+4:len(b)])) * prime1
+ if len(b) >= 4 {
+ h ^= uint64(u32(b[:4])) * prime1
h = rol23(h)*prime2 + prime3
- i += 4
+ b = b[4:]
}
- for ; i < end; i++ {
- h ^= uint64(b[i]) * prime5
+ for ; len(b) > 0; b = b[1:] {
+ h ^= uint64(b[0]) * prime5
h = rol11(h) * prime1
}
diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go b/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go
index fc9bea7a31..e86f1b5fd8 100644
--- a/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go
+++ b/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go
@@ -1,3 +1,4 @@
+//go:build appengine
// +build appengine
// This file contains the safe implementations of otherwise unsafe-using code.
diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go b/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go
index 376e0ca2e4..1c1638fd88 100644
--- a/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go
+++ b/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go
@@ -1,3 +1,4 @@
+//go:build !appengine
// +build !appengine
// This file encapsulates usage of unsafe.
@@ -11,7 +12,7 @@ import (
// In the future it's possible that compiler optimizations will make these
// XxxString functions unnecessary by realizing that calls such as
-// Sum64([]byte(s)) don't need to copy s. See https://golang.org/issue/2205.
+// Sum64([]byte(s)) don't need to copy s. See https://go.dev/issue/2205.
// If that happens, even if we keep these functions they can be replaced with
// the trivial safe code.
diff --git a/vendor/github.com/coreos/go-semver/semver/semver.go b/vendor/github.com/coreos/go-semver/semver/semver.go
index 76cf4852c7..eb9fb7ff2d 100644
--- a/vendor/github.com/coreos/go-semver/semver/semver.go
+++ b/vendor/github.com/coreos/go-semver/semver/semver.go
@@ -85,7 +85,7 @@ func (v *Version) Set(version string) error {
return fmt.Errorf("failed to validate metadata: %v", err)
}
- parsed := make([]int64, 3, 3)
+ parsed := make([]int64, 3)
for i, v := range dotParts[:3] {
val, err := strconv.ParseInt(v, 10, 64)
diff --git a/vendor/github.com/coreos/go-systemd/v22/journal/journal_unix.go b/vendor/github.com/coreos/go-systemd/v22/journal/journal_unix.go
index 439ad28746..c5b23a8196 100644
--- a/vendor/github.com/coreos/go-systemd/v22/journal/journal_unix.go
+++ b/vendor/github.com/coreos/go-systemd/v22/journal/journal_unix.go
@@ -69,6 +69,58 @@ func Enabled() bool {
return true
}
+// StderrIsJournalStream returns whether the process stderr is connected
+// to the Journal's stream transport.
+//
+// This can be used for automatic protocol upgrading described in [Journal Native Protocol].
+//
+// Returns true if JOURNAL_STREAM environment variable is present,
+// and stderr's device and inode numbers match it.
+//
+// Error is returned if unexpected error occurs: e.g. if JOURNAL_STREAM environment variable
+// is present, but malformed, fstat syscall fails, etc.
+//
+// [Journal Native Protocol]: https://systemd.io/JOURNAL_NATIVE_PROTOCOL/#automatic-protocol-upgrading
+func StderrIsJournalStream() (bool, error) {
+ return fdIsJournalStream(syscall.Stderr)
+}
+
+// StdoutIsJournalStream returns whether the process stdout is connected
+// to the Journal's stream transport.
+//
+// Returns true if JOURNAL_STREAM environment variable is present,
+// and stdout's device and inode numbers match it.
+//
+// Error is returned if unexpected error occurs: e.g. if JOURNAL_STREAM environment variable
+// is present, but malformed, fstat syscall fails, etc.
+//
+// Most users should probably use [StderrIsJournalStream].
+func StdoutIsJournalStream() (bool, error) {
+ return fdIsJournalStream(syscall.Stdout)
+}
+
+func fdIsJournalStream(fd int) (bool, error) {
+ journalStream := os.Getenv("JOURNAL_STREAM")
+ if journalStream == "" {
+ return false, nil
+ }
+
+ var expectedStat syscall.Stat_t
+ _, err := fmt.Sscanf(journalStream, "%d:%d", &expectedStat.Dev, &expectedStat.Ino)
+ if err != nil {
+ return false, fmt.Errorf("failed to parse JOURNAL_STREAM=%q: %v", journalStream, err)
+ }
+
+ var stat syscall.Stat_t
+ err = syscall.Fstat(fd, &stat)
+ if err != nil {
+ return false, err
+ }
+
+ match := stat.Dev == expectedStat.Dev && stat.Ino == expectedStat.Ino
+ return match, nil
+}
+
// Send a message to the local systemd journal. vars is a map of journald
// fields to values. Fields must be composed of uppercase letters, numbers,
// and underscores, but must not start with an underscore. Within these
diff --git a/vendor/github.com/coreos/go-systemd/v22/journal/journal_windows.go b/vendor/github.com/coreos/go-systemd/v22/journal/journal_windows.go
index 677aca68ed..322e41e74c 100644
--- a/vendor/github.com/coreos/go-systemd/v22/journal/journal_windows.go
+++ b/vendor/github.com/coreos/go-systemd/v22/journal/journal_windows.go
@@ -33,3 +33,11 @@ func Enabled() bool {
func Send(message string, priority Priority, vars map[string]string) error {
return errors.New("could not initialize socket to journald")
}
+
+func StderrIsJournalStream() (bool, error) {
+ return false, nil
+}
+
+func StdoutIsJournalStream() (bool, error) {
+ return false, nil
+}
diff --git a/vendor/github.com/go-logr/logr/.golangci.yaml b/vendor/github.com/go-logr/logr/.golangci.yaml
index 94ff801df1..0cffafa7bf 100644
--- a/vendor/github.com/go-logr/logr/.golangci.yaml
+++ b/vendor/github.com/go-logr/logr/.golangci.yaml
@@ -6,7 +6,6 @@ linters:
disable-all: true
enable:
- asciicheck
- - deadcode
- errcheck
- forcetypeassert
- gocritic
@@ -18,10 +17,8 @@ linters:
- misspell
- revive
- staticcheck
- - structcheck
- typecheck
- unused
- - varcheck
issues:
exclude-use-default: false
diff --git a/vendor/github.com/go-logr/logr/discard.go b/vendor/github.com/go-logr/logr/discard.go
index 9d92a38f1d..99fe8be93c 100644
--- a/vendor/github.com/go-logr/logr/discard.go
+++ b/vendor/github.com/go-logr/logr/discard.go
@@ -20,35 +20,5 @@ package logr
// used whenever the caller is not interested in the logs. Logger instances
// produced by this function always compare as equal.
func Discard() Logger {
- return Logger{
- level: 0,
- sink: discardLogSink{},
- }
-}
-
-// discardLogSink is a LogSink that discards all messages.
-type discardLogSink struct{}
-
-// Verify that it actually implements the interface
-var _ LogSink = discardLogSink{}
-
-func (l discardLogSink) Init(RuntimeInfo) {
-}
-
-func (l discardLogSink) Enabled(int) bool {
- return false
-}
-
-func (l discardLogSink) Info(int, string, ...interface{}) {
-}
-
-func (l discardLogSink) Error(error, string, ...interface{}) {
-}
-
-func (l discardLogSink) WithValues(...interface{}) LogSink {
- return l
-}
-
-func (l discardLogSink) WithName(string) LogSink {
- return l
+ return New(nil)
}
diff --git a/vendor/github.com/go-logr/logr/funcr/funcr.go b/vendor/github.com/go-logr/logr/funcr/funcr.go
index 7accdb0c40..e52f0cd01e 100644
--- a/vendor/github.com/go-logr/logr/funcr/funcr.go
+++ b/vendor/github.com/go-logr/logr/funcr/funcr.go
@@ -21,13 +21,13 @@ limitations under the License.
// github.com/go-logr/logr.LogSink with output through an arbitrary
// "write" function. See New and NewJSON for details.
//
-// Custom LogSinks
+// # Custom LogSinks
//
// For users who need more control, a funcr.Formatter can be embedded inside
// your own custom LogSink implementation. This is useful when the LogSink
// needs to implement additional methods, for example.
//
-// Formatting
+// # Formatting
//
// This will respect logr.Marshaler, fmt.Stringer, and error interfaces for
// values which are being logged. When rendering a struct, funcr will use Go's
@@ -37,6 +37,7 @@ package funcr
import (
"bytes"
"encoding"
+ "encoding/json"
"fmt"
"path/filepath"
"reflect"
@@ -217,7 +218,7 @@ func newFormatter(opts Options, outfmt outputFormat) Formatter {
prefix: "",
values: nil,
depth: 0,
- opts: opts,
+ opts: &opts,
}
return f
}
@@ -231,7 +232,7 @@ type Formatter struct {
values []interface{}
valuesStr string
depth int
- opts Options
+ opts *Options
}
// outputFormat indicates which outputFormat to use.
@@ -447,6 +448,7 @@ func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) s
if flags&flagRawStruct == 0 {
buf.WriteByte('{')
}
+ printComma := false // testing i>0 is not enough because of JSON omitted fields
for i := 0; i < t.NumField(); i++ {
fld := t.Field(i)
if fld.PkgPath != "" {
@@ -478,9 +480,10 @@ func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) s
if omitempty && isEmpty(v.Field(i)) {
continue
}
- if i > 0 {
+ if printComma {
buf.WriteByte(',')
}
+ printComma = true // if we got here, we are rendering a field
if fld.Anonymous && fld.Type.Kind() == reflect.Struct && name == "" {
buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), flags|flagRawStruct, depth+1))
continue
@@ -500,6 +503,20 @@ func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) s
}
return buf.String()
case reflect.Slice, reflect.Array:
+ // If this is outputing as JSON make sure this isn't really a json.RawMessage.
+ // If so just emit "as-is" and don't pretty it as that will just print
+ // it as [X,Y,Z,...] which isn't terribly useful vs the string form you really want.
+ if f.outputFormat == outputJSON {
+ if rm, ok := value.(json.RawMessage); ok {
+ // If it's empty make sure we emit an empty value as the array style would below.
+ if len(rm) > 0 {
+ buf.Write(rm)
+ } else {
+ buf.WriteString("null")
+ }
+ return buf.String()
+ }
+ }
buf.WriteByte('[')
for i := 0; i < v.Len(); i++ {
if i > 0 {
diff --git a/vendor/github.com/go-logr/logr/logr.go b/vendor/github.com/go-logr/logr/logr.go
index c3b56b3d2c..e027aea3fd 100644
--- a/vendor/github.com/go-logr/logr/logr.go
+++ b/vendor/github.com/go-logr/logr/logr.go
@@ -21,7 +21,7 @@ limitations under the License.
// to back that API. Packages in the Go ecosystem can depend on this package,
// while callers can implement logging with whatever backend is appropriate.
//
-// Usage
+// # Usage
//
// Logging is done using a Logger instance. Logger is a concrete type with
// methods, which defers the actual logging to a LogSink interface. The main
@@ -30,16 +30,20 @@ limitations under the License.
// "structured logging".
//
// With Go's standard log package, we might write:
-// log.Printf("setting target value %s", targetValue)
+//
+// log.Printf("setting target value %s", targetValue)
//
// With logr's structured logging, we'd write:
-// logger.Info("setting target", "value", targetValue)
+//
+// logger.Info("setting target", "value", targetValue)
//
// Errors are much the same. Instead of:
-// log.Printf("failed to open the pod bay door for user %s: %v", user, err)
+//
+// log.Printf("failed to open the pod bay door for user %s: %v", user, err)
//
// We'd write:
-// logger.Error(err, "failed to open the pod bay door", "user", user)
+//
+// logger.Error(err, "failed to open the pod bay door", "user", user)
//
// Info() and Error() are very similar, but they are separate methods so that
// LogSink implementations can choose to do things like attach additional
@@ -47,7 +51,7 @@ limitations under the License.
// always logged, regardless of the current verbosity. If there is no error
// instance available, passing nil is valid.
//
-// Verbosity
+// # Verbosity
//
// Often we want to log information only when the application in "verbose
// mode". To write log lines that are more verbose, Logger has a V() method.
@@ -58,20 +62,22 @@ limitations under the License.
// Error messages do not have a verbosity level and are always logged.
//
// Where we might have written:
-// if flVerbose >= 2 {
-// log.Printf("an unusual thing happened")
-// }
+//
+// if flVerbose >= 2 {
+// log.Printf("an unusual thing happened")
+// }
//
// We can write:
-// logger.V(2).Info("an unusual thing happened")
//
-// Logger Names
+// logger.V(2).Info("an unusual thing happened")
+//
+// # Logger Names
//
// Logger instances can have name strings so that all messages logged through
// that instance have additional context. For example, you might want to add
// a subsystem name:
//
-// logger.WithName("compactor").Info("started", "time", time.Now())
+// logger.WithName("compactor").Info("started", "time", time.Now())
//
// The WithName() method returns a new Logger, which can be passed to
// constructors or other functions for further use. Repeated use of WithName()
@@ -82,25 +88,27 @@ limitations under the License.
// joining operation (e.g. whitespace, commas, periods, slashes, brackets,
// quotes, etc).
//
-// Saved Values
+// # Saved Values
//
// Logger instances can store any number of key/value pairs, which will be
// logged alongside all messages logged through that instance. For example,
// you might want to create a Logger instance per managed object:
//
// With the standard log package, we might write:
-// log.Printf("decided to set field foo to value %q for object %s/%s",
-// targetValue, object.Namespace, object.Name)
+//
+// log.Printf("decided to set field foo to value %q for object %s/%s",
+// targetValue, object.Namespace, object.Name)
//
// With logr we'd write:
-// // Elsewhere: set up the logger to log the object name.
-// obj.logger = mainLogger.WithValues(
-// "name", obj.name, "namespace", obj.namespace)
//
-// // later on...
-// obj.logger.Info("setting foo", "value", targetValue)
+// // Elsewhere: set up the logger to log the object name.
+// obj.logger = mainLogger.WithValues(
+// "name", obj.name, "namespace", obj.namespace)
+//
+// // later on...
+// obj.logger.Info("setting foo", "value", targetValue)
//
-// Best Practices
+// # Best Practices
//
// Logger has very few hard rules, with the goal that LogSink implementations
// might have a lot of freedom to differentiate. There are, however, some
@@ -124,15 +132,15 @@ limitations under the License.
// around. For cases where passing a logger is optional, a pointer to Logger
// should be used.
//
-// Key Naming Conventions
+// # Key Naming Conventions
//
// Keys are not strictly required to conform to any specification or regex, but
// it is recommended that they:
-// * be human-readable and meaningful (not auto-generated or simple ordinals)
-// * be constant (not dependent on input data)
-// * contain only printable characters
-// * not contain whitespace or punctuation
-// * use lower case for simple keys and lowerCamelCase for more complex ones
+// - be human-readable and meaningful (not auto-generated or simple ordinals)
+// - be constant (not dependent on input data)
+// - contain only printable characters
+// - not contain whitespace or punctuation
+// - use lower case for simple keys and lowerCamelCase for more complex ones
//
// These guidelines help ensure that log data is processed properly regardless
// of the log implementation. For example, log implementations will try to
@@ -141,51 +149,54 @@ limitations under the License.
// While users are generally free to use key names of their choice, it's
// generally best to avoid using the following keys, as they're frequently used
// by implementations:
-// * "caller": the calling information (file/line) of a particular log line
-// * "error": the underlying error value in the `Error` method
-// * "level": the log level
-// * "logger": the name of the associated logger
-// * "msg": the log message
-// * "stacktrace": the stack trace associated with a particular log line or
-// error (often from the `Error` message)
-// * "ts": the timestamp for a log line
+// - "caller": the calling information (file/line) of a particular log line
+// - "error": the underlying error value in the `Error` method
+// - "level": the log level
+// - "logger": the name of the associated logger
+// - "msg": the log message
+// - "stacktrace": the stack trace associated with a particular log line or
+// error (often from the `Error` message)
+// - "ts": the timestamp for a log line
//
// Implementations are encouraged to make use of these keys to represent the
// above concepts, when necessary (for example, in a pure-JSON output form, it
// would be necessary to represent at least message and timestamp as ordinary
// named values).
//
-// Break Glass
+// # Break Glass
//
// Implementations may choose to give callers access to the underlying
// logging implementation. The recommended pattern for this is:
-// // Underlier exposes access to the underlying logging implementation.
-// // Since callers only have a logr.Logger, they have to know which
-// // implementation is in use, so this interface is less of an abstraction
-// // and more of way to test type conversion.
-// type Underlier interface {
-// GetUnderlying()
-// }
+//
+// // Underlier exposes access to the underlying logging implementation.
+// // Since callers only have a logr.Logger, they have to know which
+// // implementation is in use, so this interface is less of an abstraction
+// // and more of way to test type conversion.
+// type Underlier interface {
+// GetUnderlying()
+// }
//
// Logger grants access to the sink to enable type assertions like this:
-// func DoSomethingWithImpl(log logr.Logger) {
-// if underlier, ok := log.GetSink()(impl.Underlier) {
-// implLogger := underlier.GetUnderlying()
-// ...
-// }
-// }
+//
+// func DoSomethingWithImpl(log logr.Logger) {
+// if underlier, ok := log.GetSink().(impl.Underlier); ok {
+// implLogger := underlier.GetUnderlying()
+// ...
+// }
+// }
//
// Custom `With*` functions can be implemented by copying the complete
// Logger struct and replacing the sink in the copy:
-// // WithFooBar changes the foobar parameter in the log sink and returns a
-// // new logger with that modified sink. It does nothing for loggers where
-// // the sink doesn't support that parameter.
-// func WithFoobar(log logr.Logger, foobar int) logr.Logger {
-// if foobarLogSink, ok := log.GetSink()(FoobarSink); ok {
-// log = log.WithSink(foobarLogSink.WithFooBar(foobar))
-// }
-// return log
-// }
+//
+// // WithFooBar changes the foobar parameter in the log sink and returns a
+// // new logger with that modified sink. It does nothing for loggers where
+// // the sink doesn't support that parameter.
+// func WithFoobar(log logr.Logger, foobar int) logr.Logger {
+// if foobarLogSink, ok := log.GetSink().(FoobarSink); ok {
+// log = log.WithSink(foobarLogSink.WithFooBar(foobar))
+// }
+// return log
+// }
//
// Don't use New to construct a new Logger with a LogSink retrieved from an
// existing Logger. Source code attribution might not work correctly and
@@ -201,11 +212,14 @@ import (
)
// New returns a new Logger instance. This is primarily used by libraries
-// implementing LogSink, rather than end users.
+// implementing LogSink, rather than end users. Passing a nil sink will create
+// a Logger which discards all log lines.
func New(sink LogSink) Logger {
logger := Logger{}
logger.setSink(sink)
- sink.Init(runtimeInfo)
+ if sink != nil {
+ sink.Init(runtimeInfo)
+ }
return logger
}
@@ -244,7 +258,7 @@ type Logger struct {
// Enabled tests whether this Logger is enabled. For example, commandline
// flags might be used to set the logging verbosity and disable some info logs.
func (l Logger) Enabled() bool {
- return l.sink.Enabled(l.level)
+ return l.sink != nil && l.sink.Enabled(l.level)
}
// Info logs a non-error message with the given key/value pairs as context.
@@ -254,6 +268,9 @@ func (l Logger) Enabled() bool {
// information. The key/value pairs must alternate string keys and arbitrary
// values.
func (l Logger) Info(msg string, keysAndValues ...interface{}) {
+ if l.sink == nil {
+ return
+ }
if l.Enabled() {
if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
withHelper.GetCallStackHelper()()
@@ -273,6 +290,9 @@ func (l Logger) Info(msg string, keysAndValues ...interface{}) {
// triggered this log line, if present. The err parameter is optional
// and nil may be passed instead of an error instance.
func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) {
+ if l.sink == nil {
+ return
+ }
if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
withHelper.GetCallStackHelper()()
}
@@ -284,6 +304,9 @@ func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) {
// level means a log message is less important. Negative V-levels are treated
// as 0.
func (l Logger) V(level int) Logger {
+ if l.sink == nil {
+ return l
+ }
if level < 0 {
level = 0
}
@@ -294,6 +317,9 @@ func (l Logger) V(level int) Logger {
// WithValues returns a new Logger instance with additional key/value pairs.
// See Info for documentation on how key/value pairs work.
func (l Logger) WithValues(keysAndValues ...interface{}) Logger {
+ if l.sink == nil {
+ return l
+ }
l.setSink(l.sink.WithValues(keysAndValues...))
return l
}
@@ -304,6 +330,9 @@ func (l Logger) WithValues(keysAndValues ...interface{}) Logger {
// contain only letters, digits, and hyphens (see the package documentation for
// more information).
func (l Logger) WithName(name string) Logger {
+ if l.sink == nil {
+ return l
+ }
l.setSink(l.sink.WithName(name))
return l
}
@@ -324,6 +353,9 @@ func (l Logger) WithName(name string) Logger {
// WithCallDepth(1) because it works with implementions that support the
// CallDepthLogSink and/or CallStackHelperLogSink interfaces.
func (l Logger) WithCallDepth(depth int) Logger {
+ if l.sink == nil {
+ return l
+ }
if withCallDepth, ok := l.sink.(CallDepthLogSink); ok {
l.setSink(withCallDepth.WithCallDepth(depth))
}
@@ -345,6 +377,9 @@ func (l Logger) WithCallDepth(depth int) Logger {
// implementation does not support either of these, the original Logger will be
// returned.
func (l Logger) WithCallStackHelper() (func(), Logger) {
+ if l.sink == nil {
+ return func() {}, l
+ }
var helper func()
if withCallDepth, ok := l.sink.(CallDepthLogSink); ok {
l.setSink(withCallDepth.WithCallDepth(1))
@@ -357,6 +392,11 @@ func (l Logger) WithCallStackHelper() (func(), Logger) {
return helper, l
}
+// IsZero returns true if this logger is an uninitialized zero value
+func (l Logger) IsZero() bool {
+ return l.sink == nil
+}
+
// contextKey is how we find Loggers in a context.Context.
type contextKey struct{}
@@ -442,7 +482,7 @@ type LogSink interface {
WithName(name string) LogSink
}
-// CallDepthLogSink represents a Logger that knows how to climb the call stack
+// CallDepthLogSink represents a LogSink that knows how to climb the call stack
// to identify the original call site and can offset the depth by a specified
// number of frames. This is useful for users who have helper functions
// between the "real" call site and the actual calls to Logger methods.
@@ -467,7 +507,7 @@ type CallDepthLogSink interface {
WithCallDepth(depth int) LogSink
}
-// CallStackHelperLogSink represents a Logger that knows how to climb
+// CallStackHelperLogSink represents a LogSink that knows how to climb
// the call stack to identify the original call site and can skip
// intermediate helper functions if they mark themselves as
// helper. Go's testing package uses that approach.
diff --git a/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go b/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go
index fb376fce2d..f0610cf1e5 100644
--- a/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go
+++ b/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go
@@ -26,11 +26,16 @@ var rxDupSlashes = regexp.MustCompile(`/{2,}`)
// - FlagLowercaseHost
// - FlagRemoveDefaultPort
// - FlagRemoveDuplicateSlashes (and this was mixed in with the |)
+//
+// This also normalizes the URL into its urlencoded form by removing RawPath and RawFragment.
func NormalizeURL(u *url.URL) {
lowercaseScheme(u)
lowercaseHost(u)
removeDefaultPort(u)
removeDuplicateSlashes(u)
+
+ u.RawPath = ""
+ u.RawFragment = ""
}
func lowercaseScheme(u *url.URL) {
diff --git a/vendor/github.com/google/cel-go/cel/BUILD.bazel b/vendor/github.com/google/cel-go/cel/BUILD.bazel
index e973abfc54..4331321139 100644
--- a/vendor/github.com/google/cel-go/cel/BUILD.bazel
+++ b/vendor/github.com/google/cel-go/cel/BUILD.bazel
@@ -23,6 +23,7 @@ go_library(
"//checker/decls:go_default_library",
"//common:go_default_library",
"//common/containers:go_default_library",
+ "//common/operators:go_default_library",
"//common/overloads:go_default_library",
"//common/types:go_default_library",
"//common/types/pb:go_default_library",
@@ -31,7 +32,7 @@ go_library(
"//interpreter:go_default_library",
"//interpreter/functions:go_default_library",
"//parser:go_default_library",
- "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
+ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
"@org_golang_google_protobuf//reflect/protodesc:go_default_library",
"@org_golang_google_protobuf//reflect/protoreflect:go_default_library",
@@ -69,7 +70,7 @@ go_test(
"//test/proto2pb:go_default_library",
"//test/proto3pb:go_default_library",
"@io_bazel_rules_go//proto/wkt:descriptor_go_proto",
- "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
+ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
"@org_golang_google_protobuf//types/known/structpb:go_default_library",
],
diff --git a/vendor/github.com/google/cel-go/cel/decls.go b/vendor/github.com/google/cel-go/cel/decls.go
index f2df721d07..c0624d1e59 100644
--- a/vendor/github.com/google/cel-go/cel/decls.go
+++ b/vendor/github.com/google/cel-go/cel/decls.go
@@ -139,7 +139,7 @@ var (
kind: TypeKind,
runtimeType: types.TypeType,
}
- //UintType represents a uint type.
+ // UintType represents a uint type.
UintType = &Type{
kind: UintKind,
runtimeType: types.UintType,
@@ -222,7 +222,8 @@ func (t *Type) equals(other *Type) bool {
// - The from types are the same instance
// - The target type is dynamic
// - The fromType has the same kind and type name as the target type, and all parameters of the target type
-// are IsAssignableType() from the parameters of the fromType.
+//
+// are IsAssignableType() from the parameters of the fromType.
func (t *Type) defaultIsAssignableType(fromType *Type) bool {
if t == fromType || t.isDyn() {
return true
@@ -312,6 +313,11 @@ func NullableType(wrapped *Type) *Type {
}
}
+// OptionalType creates an abstract parameterized type instance corresponding to CEL's notion of optional.
+func OptionalType(param *Type) *Type {
+ return OpaqueType("optional", param)
+}
+
// OpaqueType creates an abstract parameterized type with a given name.
func OpaqueType(name string, params ...*Type) *Type {
return &Type{
@@ -365,7 +371,9 @@ func Variable(name string, t *Type) EnvOption {
//
// - Overloads are searched in the order they are declared
// - Dynamic dispatch for lists and maps is limited by inspection of the list and map contents
-// at runtime. Empty lists and maps will result in a 'default dispatch'
+//
+// at runtime. Empty lists and maps will result in a 'default dispatch'
+//
// - In the event that a default dispatch occurs, the first overload provided is the one invoked
//
// If you intend to use overloads which differentiate based on the key or element type of a list or
@@ -405,7 +413,7 @@ func Function(name string, opts ...FunctionOpt) EnvOption {
// FunctionOpt defines a functional option for configuring a function declaration.
type FunctionOpt func(*functionDecl) (*functionDecl, error)
-// SingletonUnaryBinding creates a singleton function defintion to be used for all function overloads.
+// SingletonUnaryBinding creates a singleton function definition to be used for all function overloads.
//
// Note, this approach works well if operand is expected to have a specific trait which it implements,
// e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings.
@@ -431,7 +439,17 @@ func SingletonUnaryBinding(fn functions.UnaryOp, traits ...int) FunctionOpt {
//
// Note, this approach works well if operand is expected to have a specific trait which it implements,
// e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings.
+//
+// Deprecated: use SingletonBinaryBinding
func SingletonBinaryImpl(fn functions.BinaryOp, traits ...int) FunctionOpt {
+ return SingletonBinaryBinding(fn, traits...)
+}
+
+// SingletonBinaryBinding creates a singleton function definition to be used with all function overloads.
+//
+// Note, this approach works well if operand is expected to have a specific trait which it implements,
+// e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings.
+func SingletonBinaryBinding(fn functions.BinaryOp, traits ...int) FunctionOpt {
trait := 0
for _, t := range traits {
trait = trait | t
@@ -453,7 +471,17 @@ func SingletonBinaryImpl(fn functions.BinaryOp, traits ...int) FunctionOpt {
//
// Note, this approach works well if operand is expected to have a specific trait which it implements,
// e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings.
+//
+// Deprecated: use SingletonFunctionBinding
func SingletonFunctionImpl(fn functions.FunctionOp, traits ...int) FunctionOpt {
+ return SingletonFunctionBinding(fn, traits...)
+}
+
+// SingletonFunctionBinding creates a singleton function definition to be used with all function overloads.
+//
+// Note, this approach works well if operand is expected to have a specific trait which it implements,
+// e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings.
+func SingletonFunctionBinding(fn functions.FunctionOp, traits ...int) FunctionOpt {
trait := 0
for _, t := range traits {
trait = trait | t
@@ -720,9 +748,8 @@ func (f *functionDecl) addOverload(overload *overloadDecl) error {
// Allow redefinition of an overload implementation so long as the signatures match.
f.overloads[index] = overload
return nil
- } else {
- return fmt.Errorf("overload redefinition in function. %s: %s has multiple definitions", f.name, o.id)
}
+ return fmt.Errorf("overload redefinition in function. %s: %s has multiple definitions", f.name, o.id)
}
}
f.overloads = append(f.overloads, overload)
@@ -1177,3 +1204,43 @@ func collectParamNames(paramNames map[string]struct{}, arg *Type) {
collectParamNames(paramNames, param)
}
}
+
+func typeValueToKind(tv *types.TypeValue) (Kind, error) {
+ switch tv {
+ case types.BoolType:
+ return BoolKind, nil
+ case types.DoubleType:
+ return DoubleKind, nil
+ case types.IntType:
+ return IntKind, nil
+ case types.UintType:
+ return UintKind, nil
+ case types.ListType:
+ return ListKind, nil
+ case types.MapType:
+ return MapKind, nil
+ case types.StringType:
+ return StringKind, nil
+ case types.BytesType:
+ return BytesKind, nil
+ case types.DurationType:
+ return DurationKind, nil
+ case types.TimestampType:
+ return TimestampKind, nil
+ case types.NullType:
+ return NullTypeKind, nil
+ case types.TypeType:
+ return TypeKind, nil
+ default:
+ switch tv.TypeName() {
+ case "dyn":
+ return DynKind, nil
+ case "google.protobuf.Any":
+ return AnyKind, nil
+ case "optional":
+ return OpaqueKind, nil
+ default:
+ return 0, fmt.Errorf("no known conversion for type of %s", tv.TypeName())
+ }
+ }
+}
diff --git a/vendor/github.com/google/cel-go/cel/env.go b/vendor/github.com/google/cel-go/cel/env.go
index 4e9ecdd648..d9c2ef63f2 100644
--- a/vendor/github.com/google/cel-go/cel/env.go
+++ b/vendor/github.com/google/cel-go/cel/env.go
@@ -102,15 +102,18 @@ type Env struct {
provider ref.TypeProvider
features map[int]bool
appliedFeatures map[int]bool
+ libraries map[string]bool
// Internal parser representation
- prsr *parser.Parser
+ prsr *parser.Parser
+ prsrOpts []parser.Option
// Internal checker representation
- chk *checker.Env
- chkErr error
- chkOnce sync.Once
- chkOpts []checker.Option
+ chkMutex sync.Mutex
+ chk *checker.Env
+ chkErr error
+ chkOnce sync.Once
+ chkOpts []checker.Option
// Program options tied to the environment
progOpts []ProgramOption
@@ -159,6 +162,7 @@ func NewCustomEnv(opts ...EnvOption) (*Env, error) {
provider: registry,
features: map[int]bool{},
appliedFeatures: map[int]bool{},
+ libraries: map[string]bool{},
progOpts: []ProgramOption{},
}).configure(opts)
}
@@ -175,14 +179,14 @@ func (e *Env) Check(ast *Ast) (*Ast, *Issues) {
pe, _ := AstToParsedExpr(ast)
// Construct the internal checker env, erroring if there is an issue adding the declarations.
- err := e.initChecker()
+ chk, err := e.initChecker()
if err != nil {
errs := common.NewErrors(ast.Source())
- errs.ReportError(common.NoLocation, e.chkErr.Error())
+ errs.ReportError(common.NoLocation, err.Error())
return nil, NewIssues(errs)
}
- res, errs := checker.Check(pe, ast.Source(), e.chk)
+ res, errs := checker.Check(pe, ast.Source(), chk)
if len(errs.GetErrors()) > 0 {
return nil, NewIssues(errs)
}
@@ -236,10 +240,14 @@ func (e *Env) CompileSource(src Source) (*Ast, *Issues) {
// TypeProvider are immutable, or that their underlying implementations are based on the
// ref.TypeRegistry which provides a Copy method which will be invoked by this method.
func (e *Env) Extend(opts ...EnvOption) (*Env, error) {
- if e.chkErr != nil {
- return nil, e.chkErr
+ chk, chkErr := e.getCheckerOrError()
+ if chkErr != nil {
+ return nil, chkErr
}
+ prsrOptsCopy := make([]parser.Option, len(e.prsrOpts))
+ copy(prsrOptsCopy, e.prsrOpts)
+
// The type-checker is configured with Declarations. The declarations may either be provided
// as options which have not yet been validated, or may come from a previous checker instance
// whose types have already been validated.
@@ -248,10 +256,10 @@ func (e *Env) Extend(opts ...EnvOption) (*Env, error) {
// Copy the declarations if needed.
decsCopy := []*exprpb.Decl{}
- if e.chk != nil {
+ if chk != nil {
// If the type-checker has already been instantiated, then the e.declarations have been
- // valdiated within the chk instance.
- chkOptsCopy = append(chkOptsCopy, checker.ValidatedDeclarations(e.chk))
+ // validated within the chk instance.
+ chkOptsCopy = append(chkOptsCopy, checker.ValidatedDeclarations(chk))
} else {
// If the type-checker has not been instantiated, ensure the unvalidated declarations are
// provided to the extended Env instance.
@@ -304,8 +312,11 @@ func (e *Env) Extend(opts ...EnvOption) (*Env, error) {
for k, v := range e.functions {
funcsCopy[k] = v
}
+ libsCopy := make(map[string]bool, len(e.libraries))
+ for k, v := range e.libraries {
+ libsCopy[k] = v
+ }
- // TODO: functions copy needs to happen here.
ext := &Env{
Container: e.Container,
declarations: decsCopy,
@@ -315,8 +326,10 @@ func (e *Env) Extend(opts ...EnvOption) (*Env, error) {
adapter: adapter,
features: featuresCopy,
appliedFeatures: appliedFeaturesCopy,
+ libraries: libsCopy,
provider: provider,
chkOpts: chkOptsCopy,
+ prsrOpts: prsrOptsCopy,
}
return ext.configure(opts)
}
@@ -328,6 +341,12 @@ func (e *Env) HasFeature(flag int) bool {
return has && enabled
}
+// HasLibrary returns whether a specific SingletonLibrary has been configured in the environment.
+func (e *Env) HasLibrary(libName string) bool {
+ configured, exists := e.libraries[libName]
+ return exists && configured
+}
+
// Parse parses the input expression value `txt` to a Ast and/or a set of Issues.
//
// This form of Parse creates a Source value for the input `txt` and forwards to the
@@ -422,8 +441,8 @@ func (e *Env) UnknownVars() interpreter.PartialActivation {
// TODO: Consider adding an option to generate a Program.Residual to avoid round-tripping to an
// Ast format and then Program again.
func (e *Env) ResidualAst(a *Ast, details *EvalDetails) (*Ast, error) {
- pruned := interpreter.PruneAst(a.Expr(), details.State())
- expr, err := AstToString(ParsedExprToAst(&exprpb.ParsedExpr{Expr: pruned}))
+ pruned := interpreter.PruneAst(a.Expr(), a.SourceInfo().GetMacroCalls(), details.State())
+ expr, err := AstToString(ParsedExprToAst(pruned))
if err != nil {
return nil, err
}
@@ -443,12 +462,12 @@ func (e *Env) ResidualAst(a *Ast, details *EvalDetails) (*Ast, error) {
// EstimateCost estimates the cost of a type checked CEL expression using the length estimates of input data and
// extension functions provided by estimator.
-func (e *Env) EstimateCost(ast *Ast, estimator checker.CostEstimator) (checker.CostEstimate, error) {
+func (e *Env) EstimateCost(ast *Ast, estimator checker.CostEstimator, opts ...checker.CostOption) (checker.CostEstimate, error) {
checked, err := AstToCheckedExpr(ast)
if err != nil {
return checker.CostEstimate{}, fmt.Errorf("EsimateCost could not inspect Ast: %v", err)
}
- return checker.Cost(checked, estimator), nil
+ return checker.Cost(checked, estimator, opts...)
}
// configure applies a series of EnvOptions to the current environment.
@@ -464,17 +483,9 @@ func (e *Env) configure(opts []EnvOption) (*Env, error) {
}
// If the default UTC timezone fix has been enabled, make sure the library is configured
- if e.HasFeature(featureDefaultUTCTimeZone) {
- if _, found := e.appliedFeatures[featureDefaultUTCTimeZone]; !found {
- e, err = Lib(timeUTCLibrary{})(e)
- if err != nil {
- return nil, err
- }
- // record that the feature has been applied since it will generate declarations
- // and functions which will be propagated on Extend() calls and which should only
- // be registered once.
- e.appliedFeatures[featureDefaultUTCTimeZone] = true
- }
+ e, err = e.maybeApplyFeature(featureDefaultUTCTimeZone, Lib(timeUTCLibrary{}))
+ if err != nil {
+ return nil, err
}
// Initialize all of the functions configured within the environment.
@@ -486,7 +497,10 @@ func (e *Env) configure(opts []EnvOption) (*Env, error) {
}
// Configure the parser.
- prsrOpts := []parser.Option{parser.Macros(e.macros...)}
+ prsrOpts := []parser.Option{}
+ prsrOpts = append(prsrOpts, e.prsrOpts...)
+ prsrOpts = append(prsrOpts, parser.Macros(e.macros...))
+
if e.HasFeature(featureEnableMacroCallTracking) {
prsrOpts = append(prsrOpts, parser.PopulateMacroCalls(true))
}
@@ -497,7 +511,7 @@ func (e *Env) configure(opts []EnvOption) (*Env, error) {
// Ensure that the checker init happens eagerly rather than lazily.
if e.HasFeature(featureEagerlyValidateDeclarations) {
- err := e.initChecker()
+ _, err := e.initChecker()
if err != nil {
return nil, err
}
@@ -506,7 +520,7 @@ func (e *Env) configure(opts []EnvOption) (*Env, error) {
return e, nil
}
-func (e *Env) initChecker() error {
+func (e *Env) initChecker() (*checker.Env, error) {
e.chkOnce.Do(func() {
chkOpts := []checker.Option{}
chkOpts = append(chkOpts, e.chkOpts...)
@@ -518,32 +532,68 @@ func (e *Env) initChecker() error {
ce, err := checker.NewEnv(e.Container, e.provider, chkOpts...)
if err != nil {
- e.chkErr = err
+ e.setCheckerOrError(nil, err)
return
}
// Add the statically configured declarations.
err = ce.Add(e.declarations...)
if err != nil {
- e.chkErr = err
+ e.setCheckerOrError(nil, err)
return
}
// Add the function declarations which are derived from the FunctionDecl instances.
for _, fn := range e.functions {
fnDecl, err := functionDeclToExprDecl(fn)
if err != nil {
- e.chkErr = err
+ e.setCheckerOrError(nil, err)
return
}
err = ce.Add(fnDecl)
if err != nil {
- e.chkErr = err
+ e.setCheckerOrError(nil, err)
return
}
}
// Add function declarations here separately.
- e.chk = ce
+ e.setCheckerOrError(ce, nil)
})
- return e.chkErr
+ return e.getCheckerOrError()
+}
+
+// setCheckerOrError sets the checker.Env or error state in a concurrency-safe manner
+func (e *Env) setCheckerOrError(chk *checker.Env, chkErr error) {
+ e.chkMutex.Lock()
+ e.chk = chk
+ e.chkErr = chkErr
+ e.chkMutex.Unlock()
+}
+
+// getCheckerOrError gets the checker.Env or error state in a concurrency-safe manner
+func (e *Env) getCheckerOrError() (*checker.Env, error) {
+ e.chkMutex.Lock()
+ defer e.chkMutex.Unlock()
+ return e.chk, e.chkErr
+}
+
+// maybeApplyFeature determines whether the feature-guarded option is enabled, and if so applies
+// the feature if it has not already been enabled.
+func (e *Env) maybeApplyFeature(feature int, option EnvOption) (*Env, error) {
+ if !e.HasFeature(feature) {
+ return e, nil
+ }
+ _, applied := e.appliedFeatures[feature]
+ if applied {
+ return e, nil
+ }
+ e, err := option(e)
+ if err != nil {
+ return nil, err
+ }
+ // record that the feature has been applied since it will generate declarations
+ // and functions which will be propagated on Extend() calls and which should only
+ // be registered once.
+ e.appliedFeatures[feature] = true
+ return e, nil
}
// Issues defines methods for inspecting the error details of parse and check calls.
diff --git a/vendor/github.com/google/cel-go/cel/io.go b/vendor/github.com/google/cel-go/cel/io.go
index e721c97f66..93ded3cf1b 100644
--- a/vendor/github.com/google/cel-go/cel/io.go
+++ b/vendor/github.com/google/cel-go/cel/io.go
@@ -19,14 +19,14 @@ import (
"fmt"
"reflect"
+ "google.golang.org/protobuf/proto"
+
"github.com/google/cel-go/common"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"github.com/google/cel-go/common/types/traits"
"github.com/google/cel-go/parser"
- "google.golang.org/protobuf/proto"
-
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
anypb "google.golang.org/protobuf/types/known/anypb"
)
diff --git a/vendor/github.com/google/cel-go/cel/library.go b/vendor/github.com/google/cel-go/cel/library.go
index 5ca528459a..bcfd44f78a 100644
--- a/vendor/github.com/google/cel-go/cel/library.go
+++ b/vendor/github.com/google/cel-go/cel/library.go
@@ -20,10 +20,27 @@ import (
"time"
"github.com/google/cel-go/checker"
+ "github.com/google/cel-go/common"
+ "github.com/google/cel-go/common/operators"
"github.com/google/cel-go/common/overloads"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
+ "github.com/google/cel-go/common/types/traits"
+ "github.com/google/cel-go/interpreter"
"github.com/google/cel-go/interpreter/functions"
+ "github.com/google/cel-go/parser"
+
+ exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
+)
+
+const (
+ optMapMacro = "optMap"
+ hasValueFunc = "hasValue"
+ optionalNoneFunc = "optional.none"
+ optionalOfFunc = "optional.of"
+ optionalOfNonZeroValueFunc = "optional.ofNonZeroValue"
+ valueFunc = "value"
+ unusedIterVar = "#unused"
)
// Library provides a collection of EnvOption and ProgramOption values used to configure a CEL
@@ -42,10 +59,27 @@ type Library interface {
ProgramOptions() []ProgramOption
}
+// SingletonLibrary refines the Library interface to ensure that libraries in this format are only
+// configured once within the environment.
+type SingletonLibrary interface {
+ Library
+
+ // LibraryName provides a namespaced name which is used to check whether the library has already
+ // been configured in the environment.
+ LibraryName() string
+}
+
// Lib creates an EnvOption out of a Library, allowing libraries to be provided as functional args,
// and to be linked to each other.
func Lib(l Library) EnvOption {
+ singleton, isSingleton := l.(SingletonLibrary)
return func(e *Env) (*Env, error) {
+ if isSingleton {
+ if e.HasLibrary(singleton.LibraryName()) {
+ return e, nil
+ }
+ e.libraries[singleton.LibraryName()] = true
+ }
var err error
for _, opt := range l.CompileOptions() {
e, err = opt(e)
@@ -67,6 +101,11 @@ func StdLib() EnvOption {
// features documented in the specification.
type stdLibrary struct{}
+// LibraryName implements the SingletonLibrary interface method.
+func (stdLibrary) LibraryName() string {
+ return "cel.lib.std"
+}
+
// EnvOptions returns options for the standard CEL function declarations and macros.
func (stdLibrary) CompileOptions() []EnvOption {
return []EnvOption{
@@ -82,6 +121,225 @@ func (stdLibrary) ProgramOptions() []ProgramOption {
}
}
+type optionalLibrary struct{}
+
+// LibraryName implements the SingletonLibrary interface method.
+func (optionalLibrary) LibraryName() string {
+ return "cel.lib.optional"
+}
+
+// CompileOptions implements the Library interface method.
+func (optionalLibrary) CompileOptions() []EnvOption {
+ paramTypeK := TypeParamType("K")
+ paramTypeV := TypeParamType("V")
+ optionalTypeV := OptionalType(paramTypeV)
+ listTypeV := ListType(paramTypeV)
+ mapTypeKV := MapType(paramTypeK, paramTypeV)
+
+ return []EnvOption{
+ // Enable the optional syntax in the parser.
+ enableOptionalSyntax(),
+
+ // Introduce the optional type.
+ Types(types.OptionalType),
+
+ // Configure the optMap macro.
+ Macros(NewReceiverMacro(optMapMacro, 2, optMap)),
+
+ // Global and member functions for working with optional values.
+ Function(optionalOfFunc,
+ Overload("optional_of", []*Type{paramTypeV}, optionalTypeV,
+ UnaryBinding(func(value ref.Val) ref.Val {
+ return types.OptionalOf(value)
+ }))),
+ Function(optionalOfNonZeroValueFunc,
+ Overload("optional_ofNonZeroValue", []*Type{paramTypeV}, optionalTypeV,
+ UnaryBinding(func(value ref.Val) ref.Val {
+ v, isZeroer := value.(traits.Zeroer)
+ if !isZeroer || !v.IsZeroValue() {
+ return types.OptionalOf(value)
+ }
+ return types.OptionalNone
+ }))),
+ Function(optionalNoneFunc,
+ Overload("optional_none", []*Type{}, optionalTypeV,
+ FunctionBinding(func(values ...ref.Val) ref.Val {
+ return types.OptionalNone
+ }))),
+ Function(valueFunc,
+ MemberOverload("optional_value", []*Type{optionalTypeV}, paramTypeV,
+ UnaryBinding(func(value ref.Val) ref.Val {
+ opt := value.(*types.Optional)
+ return opt.GetValue()
+ }))),
+ Function(hasValueFunc,
+ MemberOverload("optional_hasValue", []*Type{optionalTypeV}, BoolType,
+ UnaryBinding(func(value ref.Val) ref.Val {
+ opt := value.(*types.Optional)
+ return types.Bool(opt.HasValue())
+ }))),
+
+ // Implementation of 'or' and 'orValue' are special-cased to support short-circuiting in the
+ // evaluation chain.
+ Function("or",
+ MemberOverload("optional_or_optional", []*Type{optionalTypeV, optionalTypeV}, optionalTypeV)),
+ Function("orValue",
+ MemberOverload("optional_orValue_value", []*Type{optionalTypeV, paramTypeV}, paramTypeV)),
+
+ // OptSelect is handled specially by the type-checker, so the receiver's field type is used to determine the
+ // optput type.
+ Function(operators.OptSelect,
+ Overload("select_optional_field", []*Type{DynType, StringType}, optionalTypeV)),
+
+ // OptIndex is handled mostly like any other indexing operation on a list or map, so the type-checker can use
+ // these signatures to determine type-agreement without any special handling.
+ Function(operators.OptIndex,
+ Overload("list_optindex_optional_int", []*Type{listTypeV, IntType}, optionalTypeV),
+ Overload("optional_list_optindex_optional_int", []*Type{OptionalType(listTypeV), IntType}, optionalTypeV),
+ Overload("map_optindex_optional_value", []*Type{mapTypeKV, paramTypeK}, optionalTypeV),
+ Overload("optional_map_optindex_optional_value", []*Type{OptionalType(mapTypeKV), paramTypeK}, optionalTypeV)),
+
+ // Index overloads to accommodate using an optional value as the operand.
+ Function(operators.Index,
+ Overload("optional_list_index_int", []*Type{OptionalType(listTypeV), IntType}, optionalTypeV),
+ Overload("optional_map_index_optional_value", []*Type{OptionalType(mapTypeKV), paramTypeK}, optionalTypeV)),
+ }
+}
+
+func optMap(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
+ varIdent := args[0]
+ varName := ""
+ switch varIdent.GetExprKind().(type) {
+ case *exprpb.Expr_IdentExpr:
+ varName = varIdent.GetIdentExpr().GetName()
+ default:
+ return nil, &common.Error{
+ Message: "optMap() variable name must be a simple identifier",
+ Location: meh.OffsetLocation(varIdent.GetId()),
+ }
+ }
+ mapExpr := args[1]
+ return meh.GlobalCall(
+ operators.Conditional,
+ meh.ReceiverCall(hasValueFunc, target),
+ meh.GlobalCall(optionalOfFunc,
+ meh.Fold(
+ unusedIterVar,
+ meh.NewList(),
+ varName,
+ meh.ReceiverCall(valueFunc, target),
+ meh.LiteralBool(false),
+ meh.Ident(varName),
+ mapExpr,
+ ),
+ ),
+ meh.GlobalCall(optionalNoneFunc),
+ ), nil
+}
+
+// ProgramOptions implements the Library interface method.
+func (optionalLibrary) ProgramOptions() []ProgramOption {
+ return []ProgramOption{
+ CustomDecorator(decorateOptionalOr),
+ }
+}
+
+func enableOptionalSyntax() EnvOption {
+ return func(e *Env) (*Env, error) {
+ e.prsrOpts = append(e.prsrOpts, parser.EnableOptionalSyntax(true))
+ return e, nil
+ }
+}
+
+func decorateOptionalOr(i interpreter.Interpretable) (interpreter.Interpretable, error) {
+ call, ok := i.(interpreter.InterpretableCall)
+ if !ok {
+ return i, nil
+ }
+ args := call.Args()
+ if len(args) != 2 {
+ return i, nil
+ }
+ switch call.Function() {
+ case "or":
+ if call.OverloadID() != "" && call.OverloadID() != "optional_or_optional" {
+ return i, nil
+ }
+ return &evalOptionalOr{
+ id: call.ID(),
+ lhs: args[0],
+ rhs: args[1],
+ }, nil
+ case "orValue":
+ if call.OverloadID() != "" && call.OverloadID() != "optional_orValue_value" {
+ return i, nil
+ }
+ return &evalOptionalOrValue{
+ id: call.ID(),
+ lhs: args[0],
+ rhs: args[1],
+ }, nil
+ default:
+ return i, nil
+ }
+}
+
+// evalOptionalOr selects between two optional values, either the first if it has a value, or
+// the second optional expression is evaluated and returned.
+type evalOptionalOr struct {
+ id int64
+ lhs interpreter.Interpretable
+ rhs interpreter.Interpretable
+}
+
+// ID implements the Interpretable interface method.
+func (opt *evalOptionalOr) ID() int64 {
+ return opt.id
+}
+
+// Eval evaluates the left-hand side optional to determine whether it contains a value, else
+// proceeds with the right-hand side evaluation.
+func (opt *evalOptionalOr) Eval(ctx interpreter.Activation) ref.Val {
+ // short-circuit lhs.
+ optLHS := opt.lhs.Eval(ctx)
+ optVal, ok := optLHS.(*types.Optional)
+ if !ok {
+ return optLHS
+ }
+ if optVal.HasValue() {
+ return optVal
+ }
+ return opt.rhs.Eval(ctx)
+}
+
+// evalOptionalOrValue selects between an optional or a concrete value. If the optional has a value,
+// its value is returned, otherwise the alternative value expression is evaluated and returned.
+type evalOptionalOrValue struct {
+ id int64
+ lhs interpreter.Interpretable
+ rhs interpreter.Interpretable
+}
+
+// ID implements the Interpretable interface method.
+func (opt *evalOptionalOrValue) ID() int64 {
+ return opt.id
+}
+
+// Eval evaluates the left-hand side optional to determine whether it contains a value, else
+// proceeds with the right-hand side evaluation.
+func (opt *evalOptionalOrValue) Eval(ctx interpreter.Activation) ref.Val {
+ // short-circuit lhs.
+ optLHS := opt.lhs.Eval(ctx)
+ optVal, ok := optLHS.(*types.Optional)
+ if !ok {
+ return optLHS
+ }
+ if optVal.HasValue() {
+ return optVal.GetValue()
+ }
+ return opt.rhs.Eval(ctx)
+}
+
type timeUTCLibrary struct{}
func (timeUTCLibrary) CompileOptions() []EnvOption {
diff --git a/vendor/github.com/google/cel-go/cel/macro.go b/vendor/github.com/google/cel-go/cel/macro.go
index e43cb4eeea..e48c5bf8ee 100644
--- a/vendor/github.com/google/cel-go/cel/macro.go
+++ b/vendor/github.com/google/cel-go/cel/macro.go
@@ -17,6 +17,7 @@ package cel
import (
"github.com/google/cel-go/common"
"github.com/google/cel-go/parser"
+
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
)
@@ -26,8 +27,11 @@ import (
// a Macro should be created per arg-count or as a var arg macro.
type Macro = parser.Macro
-// MacroExpander converts a call and its associated arguments into a new CEL abstract syntax tree, or an error
-// if the input arguments are not suitable for the expansion requirements for the macro in question.
+// MacroExpander converts a call and its associated arguments into a new CEL abstract syntax tree.
+//
+// If the MacroExpander determines within the implementation that an expansion is not needed it may return
+// a nil Expr value to indicate a non-match. However, if an expansion is to be performed, but the arguments
+// are not well-formed, the result of the expansion will be an error.
//
// The MacroExpander accepts as arguments a MacroExprHelper as well as the arguments used in the function call
// and produces as output an Expr ast node.
@@ -81,8 +85,10 @@ func ExistsOneMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*ex
// input to produce an output list.
//
// There are two call patterns supported by map:
-// .map(, )
-// .map(, , )
+//
+// .map(, )
+// .map(, , )
+//
// In the second form only iterVar values which return true when provided to the predicate expression
// are transformed.
func MapMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
diff --git a/vendor/github.com/google/cel-go/cel/options.go b/vendor/github.com/google/cel-go/cel/options.go
index 21c7570106..07f3d6c716 100644
--- a/vendor/github.com/google/cel-go/cel/options.go
+++ b/vendor/github.com/google/cel-go/cel/options.go
@@ -29,6 +29,7 @@ import (
"github.com/google/cel-go/common/types/ref"
"github.com/google/cel-go/interpreter"
"github.com/google/cel-go/interpreter/functions"
+ "github.com/google/cel-go/parser"
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
descpb "google.golang.org/protobuf/types/descriptorpb"
@@ -61,6 +62,10 @@ const (
// on a CEL timestamp operation. This fixes the scenario where the input time
// is not already in UTC.
featureDefaultUTCTimeZone
+
+ // Enable the use of optional types in the syntax, type-system, type-checking,
+ // and runtime.
+ featureOptionalTypes
)
// EnvOption is a functional interface for configuring the environment.
@@ -163,19 +168,19 @@ func Container(name string) EnvOption {
// Abbreviations can be useful when working with variables, functions, and especially types from
// multiple namespaces:
//
-// // CEL object construction
-// qual.pkg.version.ObjTypeName{
-// field: alt.container.ver.FieldTypeName{value: ...}
-// }
+// // CEL object construction
+// qual.pkg.version.ObjTypeName{
+// field: alt.container.ver.FieldTypeName{value: ...}
+// }
//
// Only one the qualified names above may be used as the CEL container, so at least one of these
// references must be a long qualified name within an otherwise short CEL program. Using the
// following abbreviations, the program becomes much simpler:
//
-// // CEL Go option
-// Abbrevs("qual.pkg.version.ObjTypeName", "alt.container.ver.FieldTypeName")
-// // Simplified Object construction
-// ObjTypeName{field: FieldTypeName{value: ...}}
+// // CEL Go option
+// Abbrevs("qual.pkg.version.ObjTypeName", "alt.container.ver.FieldTypeName")
+// // Simplified Object construction
+// ObjTypeName{field: FieldTypeName{value: ...}}
//
// There are a few rules for the qualified names and the simple abbreviations generated from them:
// - Qualified names must be dot-delimited, e.g. `package.subpkg.name`.
@@ -188,9 +193,12 @@ func Container(name string) EnvOption {
// - Expanded abbreviations do not participate in namespace resolution.
// - Abbreviation expansion is done instead of the container search for a matching identifier.
// - Containers follow C++ namespace resolution rules with searches from the most qualified name
-// to the least qualified name.
+//
+// to the least qualified name.
+//
// - Container references within the CEL program may be relative, and are resolved to fully
-// qualified names at either type-check time or program plan time, whichever comes first.
+//
+// qualified names at either type-check time or program plan time, whichever comes first.
//
// If there is ever a case where an identifier could be in both the container and as an
// abbreviation, the abbreviation wins as this will ensure that the meaning of a program is
@@ -216,7 +224,7 @@ func Abbrevs(qualifiedNames ...string) EnvOption {
// environment by default.
//
// Note: This option must be specified after the CustomTypeProvider option when used together.
-func Types(addTypes ...interface{}) EnvOption {
+func Types(addTypes ...any) EnvOption {
return func(e *Env) (*Env, error) {
reg, isReg := e.provider.(ref.TypeRegistry)
if !isReg {
@@ -253,7 +261,7 @@ func Types(addTypes ...interface{}) EnvOption {
//
// 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 {
+func TypeDescs(descs ...any) EnvOption {
return func(e *Env) (*Env, error) {
reg, isReg := e.provider.(ref.TypeRegistry)
if !isReg {
@@ -350,8 +358,8 @@ func Functions(funcs ...*functions.Overload) ProgramOption {
// variables with the same name provided to the Eval() call. If Globals is used in a Library with
// a Lib EnvOption, vars may shadow variables provided by previously added libraries.
//
-// The vars value may either be an `interpreter.Activation` instance or a `map[string]interface{}`.
-func Globals(vars interface{}) ProgramOption {
+// The vars value may either be an `interpreter.Activation` instance or a `map[string]any`.
+func Globals(vars any) ProgramOption {
return func(p *prog) (*prog, error) {
defaultVars, err := interpreter.NewActivation(vars)
if err != nil {
@@ -404,6 +412,9 @@ const (
// OptTrackCost enables the runtime cost calculation while validation and return cost within evalDetails
// cost calculation is available via func ActualCost()
OptTrackCost EvalOption = 1 << iota
+
+ // OptCheckStringFormat enables compile-time checking of string.format calls for syntax/cardinality.
+ OptCheckStringFormat EvalOption = 1 << iota
)
// EvalOptions sets one or more evaluation options which may affect the evaluation or Result.
@@ -534,6 +545,13 @@ func DefaultUTCTimeZone(enabled bool) EnvOption {
return features(featureDefaultUTCTimeZone, enabled)
}
+// OptionalTypes enable support for optional syntax and types in CEL. The optional value type makes
+// it possible to express whether variables have been provided, whether a result has been computed,
+// and in the future whether an object field path, map key value, or list index has a value.
+func OptionalTypes() EnvOption {
+ return Lib(optionalLibrary{})
+}
+
// features sets the given feature flags. See list of Feature constants above.
func features(flag int, enabled bool) EnvOption {
return func(e *Env) (*Env, error) {
@@ -541,3 +559,21 @@ func features(flag int, enabled bool) EnvOption {
return e, nil
}
}
+
+// ParserRecursionLimit adjusts the AST depth the parser will tolerate.
+// Defaults defined in the parser package.
+func ParserRecursionLimit(limit int) EnvOption {
+ return func(e *Env) (*Env, error) {
+ e.prsrOpts = append(e.prsrOpts, parser.MaxRecursionDepth(limit))
+ return e, nil
+ }
+}
+
+// ParserExpressionSizeLimit adjusts the number of code points the expression parser is allowed to parse.
+// Defaults defined in the parser package.
+func ParserExpressionSizeLimit(limit int) EnvOption {
+ return func(e *Env) (*Env, error) {
+ e.prsrOpts = append(e.prsrOpts, parser.ExpressionSizeCodePointLimit(limit))
+ return e, nil
+ }
+}
diff --git a/vendor/github.com/google/cel-go/cel/program.go b/vendor/github.com/google/cel-go/cel/program.go
index 6219a4da58..a630f5bfa1 100644
--- a/vendor/github.com/google/cel-go/cel/program.go
+++ b/vendor/github.com/google/cel-go/cel/program.go
@@ -17,21 +17,20 @@ package cel
import (
"context"
"fmt"
- "math"
"sync"
- exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
-
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"github.com/google/cel-go/interpreter"
+
+ exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
)
// Program is an evaluable view of an Ast.
type Program interface {
// Eval returns the result of an evaluation of the Ast and environment against the input vars.
//
- // The vars value may either be an `interpreter.Activation` or a `map[string]interface{}`.
+ // The vars value may either be an `interpreter.Activation` or a `map[string]any`.
//
// If the `OptTrackState`, `OptTrackCost` or `OptExhaustiveEval` flags are used, the `details` response will
// be non-nil. Given this caveat on `details`, the return state from evaluation will be:
@@ -43,16 +42,16 @@ type Program interface {
// An unsuccessful evaluation is typically the result of a series of incompatible `EnvOption`
// or `ProgramOption` values used in the creation of the evaluation environment or executable
// program.
- Eval(interface{}) (ref.Val, *EvalDetails, error)
+ Eval(any) (ref.Val, *EvalDetails, error)
// ContextEval evaluates the program with a set of input variables and a context object in order
// to support cancellation and timeouts. This method must be used in conjunction with the
// InterruptCheckFrequency() option for cancellation interrupts to be impact evaluation.
//
- // The vars value may either be an `interpreter.Activation` or `map[string]interface{}`.
+ // The vars value may either be an `interpreter.Activation` or `map[string]any`.
//
// The output contract for `ContextEval` is otherwise identical to the `Eval` method.
- ContextEval(context.Context, interface{}) (ref.Val, *EvalDetails, error)
+ ContextEval(context.Context, any) (ref.Val, *EvalDetails, error)
}
// NoVars returns an empty Activation.
@@ -65,7 +64,7 @@ func NoVars() interpreter.Activation {
//
// The `vars` value may either be an interpreter.Activation or any valid input to the
// interpreter.NewActivation call.
-func PartialVars(vars interface{},
+func PartialVars(vars any,
unknowns ...*interpreter.AttributePattern) (interpreter.PartialActivation, error) {
return interpreter.NewPartialActivation(vars, unknowns...)
}
@@ -207,6 +206,37 @@ func newProgram(e *Env, ast *Ast, opts []ProgramOption) (Program, error) {
if len(p.regexOptimizations) > 0 {
decorators = append(decorators, interpreter.CompileRegexConstants(p.regexOptimizations...))
}
+ // Enable compile-time checking of syntax/cardinality for string.format calls.
+ if p.evalOpts&OptCheckStringFormat == OptCheckStringFormat {
+ var isValidType func(id int64, validTypes ...*types.TypeValue) (bool, error)
+ if ast.IsChecked() {
+ isValidType = func(id int64, validTypes ...*types.TypeValue) (bool, error) {
+ t, err := ExprTypeToType(ast.typeMap[id])
+ if err != nil {
+ return false, err
+ }
+ if t.kind == DynKind {
+ return true, nil
+ }
+ for _, vt := range validTypes {
+ k, err := typeValueToKind(vt)
+ if err != nil {
+ return false, err
+ }
+ if k == t.kind {
+ return true, nil
+ }
+ }
+ return false, nil
+ }
+ } else {
+ // if the AST isn't type-checked, short-circuit validation
+ isValidType = func(id int64, validTypes ...*types.TypeValue) (bool, error) {
+ return true, nil
+ }
+ }
+ decorators = append(decorators, interpreter.InterpolateFormattedString(isValidType))
+ }
// Enable exhaustive eval, state tracking and cost tracking last since they require a factory.
if p.evalOpts&(OptExhaustiveEval|OptTrackState|OptTrackCost) != 0 {
@@ -268,7 +298,7 @@ func (p *prog) initInterpretable(ast *Ast, decs []interpreter.InterpretableDecor
}
// Eval implements the Program interface method.
-func (p *prog) Eval(input interface{}) (v ref.Val, det *EvalDetails, err error) {
+func (p *prog) Eval(input any) (v ref.Val, det *EvalDetails, err error) {
// Configure error recovery for unexpected panics during evaluation. Note, the use of named
// return values makes it possible to modify the error response during the recovery
// function.
@@ -287,11 +317,11 @@ func (p *prog) Eval(input interface{}) (v ref.Val, det *EvalDetails, err error)
switch v := input.(type) {
case interpreter.Activation:
vars = v
- case map[string]interface{}:
+ case map[string]any:
vars = activationPool.Setup(v)
defer activationPool.Put(vars)
default:
- return nil, nil, fmt.Errorf("invalid input, wanted Activation or map[string]interface{}, got: (%T)%v", input, input)
+ return nil, nil, fmt.Errorf("invalid input, wanted Activation or map[string]any, got: (%T)%v", input, input)
}
if p.defaultVars != nil {
vars = interpreter.NewHierarchicalActivation(p.defaultVars, vars)
@@ -307,7 +337,7 @@ func (p *prog) Eval(input interface{}) (v ref.Val, det *EvalDetails, err error)
}
// ContextEval implements the Program interface.
-func (p *prog) ContextEval(ctx context.Context, input interface{}) (ref.Val, *EvalDetails, error) {
+func (p *prog) ContextEval(ctx context.Context, input any) (ref.Val, *EvalDetails, error) {
if ctx == nil {
return nil, nil, fmt.Errorf("context can not be nil")
}
@@ -318,22 +348,17 @@ func (p *prog) ContextEval(ctx context.Context, input interface{}) (ref.Val, *Ev
case interpreter.Activation:
vars = ctxActivationPool.Setup(v, ctx.Done(), p.interruptCheckFrequency)
defer ctxActivationPool.Put(vars)
- case map[string]interface{}:
+ case map[string]any:
rawVars := activationPool.Setup(v)
defer activationPool.Put(rawVars)
vars = ctxActivationPool.Setup(rawVars, ctx.Done(), p.interruptCheckFrequency)
defer ctxActivationPool.Put(vars)
default:
- return nil, nil, fmt.Errorf("invalid input, wanted Activation or map[string]interface{}, got: (%T)%v", input, input)
+ return nil, nil, fmt.Errorf("invalid input, wanted Activation or map[string]any, got: (%T)%v", input, input)
}
return p.Eval(vars)
}
-// Cost implements the Coster interface method.
-func (p *prog) Cost() (min, max int64) {
- return estimateCost(p.interpretable)
-}
-
// progFactory is a helper alias for marking a program creation factory function.
type progFactory func(interpreter.EvalState, *interpreter.CostTracker) (Program, error)
@@ -354,7 +379,7 @@ func newProgGen(factory progFactory) (Program, error) {
}
// Eval implements the Program interface method.
-func (gen *progGen) Eval(input interface{}) (ref.Val, *EvalDetails, error) {
+func (gen *progGen) Eval(input any) (ref.Val, *EvalDetails, error) {
// The factory based Eval() differs from the standard evaluation model in that it generates a
// new EvalState instance for each call to ensure that unique evaluations yield unique stateful
// results.
@@ -379,7 +404,7 @@ func (gen *progGen) Eval(input interface{}) (ref.Val, *EvalDetails, error) {
}
// ContextEval implements the Program interface method.
-func (gen *progGen) ContextEval(ctx context.Context, input interface{}) (ref.Val, *EvalDetails, error) {
+func (gen *progGen) ContextEval(ctx context.Context, input any) (ref.Val, *EvalDetails, error) {
if ctx == nil {
return nil, nil, fmt.Errorf("context can not be nil")
}
@@ -406,29 +431,6 @@ func (gen *progGen) ContextEval(ctx context.Context, input interface{}) (ref.Val
return v, det, nil
}
-// Cost implements the Coster interface method.
-func (gen *progGen) Cost() (min, max int64) {
- // Use an empty state value since no evaluation is performed.
- p, err := gen.factory(emptyEvalState, nil)
- if err != nil {
- return 0, math.MaxInt64
- }
- return estimateCost(p)
-}
-
-// EstimateCost returns the heuristic cost interval for the program.
-func EstimateCost(p Program) (min, max int64) {
- return estimateCost(p)
-}
-
-func estimateCost(i interface{}) (min, max int64) {
- c, ok := i.(interpreter.Coster)
- if !ok {
- return 0, math.MaxInt64
- }
- return c.Cost()
-}
-
type ctxEvalActivation struct {
parent interpreter.Activation
interrupt <-chan struct{}
@@ -438,7 +440,7 @@ type ctxEvalActivation struct {
// ResolveName implements the Activation interface method, but adds a special #interrupted variable
// which is capable of testing whether a 'done' signal is provided from a context.Context channel.
-func (a *ctxEvalActivation) ResolveName(name string) (interface{}, bool) {
+func (a *ctxEvalActivation) ResolveName(name string) (any, bool) {
if name == "#interrupted" {
a.interruptCheckCount++
if a.interruptCheckCount%a.interruptCheckFrequency == 0 {
@@ -461,7 +463,7 @@ func (a *ctxEvalActivation) Parent() interpreter.Activation {
func newCtxEvalActivationPool() *ctxEvalActivationPool {
return &ctxEvalActivationPool{
Pool: sync.Pool{
- New: func() interface{} {
+ New: func() any {
return &ctxEvalActivation{}
},
},
@@ -483,21 +485,21 @@ func (p *ctxEvalActivationPool) Setup(vars interpreter.Activation, done <-chan s
}
type evalActivation struct {
- vars map[string]interface{}
- lazyVars map[string]interface{}
+ vars map[string]any
+ lazyVars map[string]any
}
// ResolveName looks up the value of the input variable name, if found.
//
// Lazy bindings may be supplied within the map-based input in either of the following forms:
-// - func() interface{}
+// - func() any
// - func() ref.Val
//
// The lazy binding will only be invoked once per evaluation.
//
// Values which are not represented as ref.Val types on input may be adapted to a ref.Val using
// the ref.TypeAdapter configured in the environment.
-func (a *evalActivation) ResolveName(name string) (interface{}, bool) {
+func (a *evalActivation) ResolveName(name string) (any, bool) {
v, found := a.vars[name]
if !found {
return nil, false
@@ -510,7 +512,7 @@ func (a *evalActivation) ResolveName(name string) (interface{}, bool) {
lazy := obj()
a.lazyVars[name] = lazy
return lazy, true
- case func() interface{}:
+ case func() any:
if resolved, found := a.lazyVars[name]; found {
return resolved, true
}
@@ -530,8 +532,8 @@ func (a *evalActivation) Parent() interpreter.Activation {
func newEvalActivationPool() *evalActivationPool {
return &evalActivationPool{
Pool: sync.Pool{
- New: func() interface{} {
- return &evalActivation{lazyVars: make(map[string]interface{})}
+ New: func() any {
+ return &evalActivation{lazyVars: make(map[string]any)}
},
},
}
@@ -542,13 +544,13 @@ type evalActivationPool struct {
}
// Setup initializes a pooled Activation object with the map input.
-func (p *evalActivationPool) Setup(vars map[string]interface{}) *evalActivation {
+func (p *evalActivationPool) Setup(vars map[string]any) *evalActivation {
a := p.Pool.Get().(*evalActivation)
a.vars = vars
return a
}
-func (p *evalActivationPool) Put(value interface{}) {
+func (p *evalActivationPool) Put(value any) {
a := value.(*evalActivation)
for k := range a.lazyVars {
delete(a.lazyVars, k)
@@ -559,7 +561,7 @@ func (p *evalActivationPool) Put(value interface{}) {
var (
emptyEvalState = interpreter.NewEvalState()
- // activationPool is an internally managed pool of Activation values that wrap map[string]interface{} inputs
+ // activationPool is an internally managed pool of Activation values that wrap map[string]any inputs
activationPool = newEvalActivationPool()
// ctxActivationPool is an internally managed pool of Activation values that expose a special #interrupted variable
diff --git a/vendor/github.com/google/cel-go/checker/BUILD.bazel b/vendor/github.com/google/cel-go/checker/BUILD.bazel
index bec40b6e69..1c6ddb7f7d 100644
--- a/vendor/github.com/google/cel-go/checker/BUILD.bazel
+++ b/vendor/github.com/google/cel-go/checker/BUILD.bazel
@@ -30,7 +30,7 @@ go_library(
"//common/types/pb:go_default_library",
"//common/types/ref:go_default_library",
"//parser:go_default_library",
- "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
+ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
"@org_golang_google_protobuf//types/known/structpb:go_default_library",
@@ -54,7 +54,7 @@ go_test(
"//test:go_default_library",
"//test/proto2pb:go_default_library",
"//test/proto3pb:go_default_library",
- "@com_github_antlr_antlr4_runtime_go_antlr//:go_default_library",
+ "@com_github_antlr_antlr4_runtime_go_antlr_v4//:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
],
)
diff --git a/vendor/github.com/google/cel-go/checker/checker.go b/vendor/github.com/google/cel-go/checker/checker.go
index fcddb1b2c2..257cffecf6 100644
--- a/vendor/github.com/google/cel-go/checker/checker.go
+++ b/vendor/github.com/google/cel-go/checker/checker.go
@@ -23,6 +23,7 @@ import (
"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/operators"
"github.com/google/cel-go/common/types/ref"
"google.golang.org/protobuf/proto"
@@ -173,8 +174,8 @@ func (c *checker) checkSelect(e *exprpb.Expr) {
// Rewrite the node to be a variable reference to the resolved fully-qualified
// variable name.
- c.setType(e, ident.GetIdent().Type)
- c.setReference(e, newIdentReference(ident.GetName(), ident.GetIdent().Value))
+ c.setType(e, ident.GetIdent().GetType())
+ c.setReference(e, newIdentReference(ident.GetName(), ident.GetIdent().GetValue()))
identName := ident.GetName()
e.ExprKind = &exprpb.Expr_IdentExpr{
IdentExpr: &exprpb.Expr_Ident{
@@ -185,9 +186,37 @@ func (c *checker) checkSelect(e *exprpb.Expr) {
}
}
+ resultType := c.checkSelectField(e, sel.GetOperand(), sel.GetField(), false)
+ if sel.TestOnly {
+ resultType = decls.Bool
+ }
+ c.setType(e, substitute(c.mappings, resultType, false))
+}
+
+func (c *checker) checkOptSelect(e *exprpb.Expr) {
+ // Collect metadata related to the opt select call packaged by the parser.
+ call := e.GetCallExpr()
+ operand := call.GetArgs()[0]
+ field := call.GetArgs()[1]
+ fieldName, isString := maybeUnwrapString(field)
+ if !isString {
+ c.errors.ReportError(c.location(field), "unsupported optional field selection: %v", field)
+ return
+ }
+
+ // Perform type-checking using the field selection logic.
+ resultType := c.checkSelectField(e, operand, fieldName, true)
+ c.setType(e, substitute(c.mappings, resultType, false))
+}
+
+func (c *checker) checkSelectField(e, operand *exprpb.Expr, field string, optional bool) *exprpb.Type {
// Interpret as field selection, first traversing down the operand.
- c.check(sel.GetOperand())
- targetType := substitute(c.mappings, c.getType(sel.GetOperand()), false)
+ c.check(operand)
+ operandType := substitute(c.mappings, c.getType(operand), false)
+
+ // If the target type is 'optional', unwrap it for the sake of this check.
+ targetType, isOpt := maybeUnwrapOptional(operandType)
+
// Assume error type by default as most types do not support field selection.
resultType := decls.Error
switch kindOf(targetType) {
@@ -199,7 +228,7 @@ func (c *checker) checkSelect(e *exprpb.Expr) {
// Objects yield their field type declaration as the selection result type, but only if
// the field is defined.
messageType := targetType
- if fieldType, found := c.lookupFieldType(c.location(e), messageType.GetMessageType(), sel.GetField()); found {
+ if fieldType, found := c.lookupFieldType(c.location(e), messageType.GetMessageType(), field); found {
resultType = fieldType.Type
}
case kindTypeParam:
@@ -212,16 +241,17 @@ func (c *checker) checkSelect(e *exprpb.Expr) {
default:
// Dynamic / error values are treated as DYN type. Errors are handled this way as well
// in order to allow forward progress on the check.
- if isDynOrError(targetType) {
- resultType = decls.Dyn
- } else {
+ if !isDynOrError(targetType) {
c.errors.typeDoesNotSupportFieldSelection(c.location(e), targetType)
}
+ resultType = decls.Dyn
}
- if sel.TestOnly {
- resultType = decls.Bool
+
+ // If the target type was optional coming in, then the result must be optional going out.
+ if isOpt || optional {
+ return decls.NewOptionalType(resultType)
}
- c.setType(e, substitute(c.mappings, resultType, false))
+ return resultType
}
func (c *checker) checkCall(e *exprpb.Expr) {
@@ -229,15 +259,19 @@ func (c *checker) checkCall(e *exprpb.Expr) {
// please consider the impact on planner.go and consolidate implementations or mirror code
// as appropriate.
call := e.GetCallExpr()
- target := call.GetTarget()
- args := call.GetArgs()
fnName := call.GetFunction()
+ if fnName == operators.OptSelect {
+ c.checkOptSelect(e)
+ return
+ }
+ args := call.GetArgs()
// Traverse arguments.
for _, arg := range args {
c.check(arg)
}
+ target := call.GetTarget()
// Regular static call with simple name.
if target == nil {
// Check for the existence of the function.
@@ -359,6 +393,9 @@ func (c *checker) resolveOverload(
}
if resultType == nil {
+ for i, arg := range argTypes {
+ argTypes[i] = substitute(c.mappings, arg, true)
+ }
c.errors.noMatchingOverload(loc, fn.GetName(), argTypes, target != nil)
resultType = decls.Error
return nil
@@ -369,16 +406,29 @@ func (c *checker) resolveOverload(
func (c *checker) checkCreateList(e *exprpb.Expr) {
create := e.GetListExpr()
- var elemType *exprpb.Type
- for _, e := range create.GetElements() {
+ var elemsType *exprpb.Type
+ optionalIndices := create.GetOptionalIndices()
+ optionals := make(map[int32]bool, len(optionalIndices))
+ for _, optInd := range optionalIndices {
+ optionals[optInd] = true
+ }
+ for i, e := range create.GetElements() {
c.check(e)
- elemType = c.joinTypes(c.location(e), elemType, c.getType(e))
+ elemType := c.getType(e)
+ if optionals[int32(i)] {
+ var isOptional bool
+ elemType, isOptional = maybeUnwrapOptional(elemType)
+ if !isOptional && !isDyn(elemType) {
+ c.errors.typeMismatch(c.location(e), decls.NewOptionalType(elemType), elemType)
+ }
+ }
+ elemsType = c.joinTypes(c.location(e), elemsType, elemType)
}
- if elemType == nil {
+ if elemsType == nil {
// If the list is empty, assign free type var to elem type.
- elemType = c.newTypeVar()
+ elemsType = c.newTypeVar()
}
- c.setType(e, decls.NewListType(elemType))
+ c.setType(e, decls.NewListType(elemsType))
}
func (c *checker) checkCreateStruct(e *exprpb.Expr) {
@@ -392,22 +442,31 @@ func (c *checker) checkCreateStruct(e *exprpb.Expr) {
func (c *checker) checkCreateMap(e *exprpb.Expr) {
mapVal := e.GetStructExpr()
- var keyType *exprpb.Type
- var valueType *exprpb.Type
+ var mapKeyType *exprpb.Type
+ var mapValueType *exprpb.Type
for _, ent := range mapVal.GetEntries() {
key := ent.GetMapKey()
c.check(key)
- keyType = c.joinTypes(c.location(key), keyType, c.getType(key))
-
- c.check(ent.Value)
- valueType = c.joinTypes(c.location(ent.Value), valueType, c.getType(ent.Value))
+ mapKeyType = c.joinTypes(c.location(key), mapKeyType, c.getType(key))
+
+ val := ent.GetValue()
+ c.check(val)
+ valType := c.getType(val)
+ if ent.GetOptionalEntry() {
+ var isOptional bool
+ valType, isOptional = maybeUnwrapOptional(valType)
+ if !isOptional && !isDyn(valType) {
+ c.errors.typeMismatch(c.location(val), decls.NewOptionalType(valType), valType)
+ }
+ }
+ mapValueType = c.joinTypes(c.location(val), mapValueType, valType)
}
- if keyType == nil {
+ if mapKeyType == nil {
// If the map is empty, assign free type variables to typeKey and value type.
- keyType = c.newTypeVar()
- valueType = c.newTypeVar()
+ mapKeyType = c.newTypeVar()
+ mapValueType = c.newTypeVar()
}
- c.setType(e, decls.NewMapType(keyType, valueType))
+ c.setType(e, decls.NewMapType(mapKeyType, mapValueType))
}
func (c *checker) checkCreateMessage(e *exprpb.Expr) {
@@ -449,15 +508,21 @@ func (c *checker) checkCreateMessage(e *exprpb.Expr) {
c.check(value)
fieldType := decls.Error
- if t, found := c.lookupFieldType(
- c.locationByID(ent.GetId()),
- messageType.GetMessageType(),
- field); found {
- fieldType = t.Type
+ ft, found := c.lookupFieldType(c.locationByID(ent.GetId()), messageType.GetMessageType(), field)
+ if found {
+ fieldType = ft.Type
+ }
+
+ valType := c.getType(value)
+ if ent.GetOptionalEntry() {
+ var isOptional bool
+ valType, isOptional = maybeUnwrapOptional(valType)
+ if !isOptional && !isDyn(valType) {
+ c.errors.typeMismatch(c.location(value), decls.NewOptionalType(valType), valType)
+ }
}
- if !c.isAssignable(fieldType, c.getType(value)) {
- c.errors.fieldTypeMismatch(
- c.locationByID(ent.Id), field, fieldType, c.getType(value))
+ if !c.isAssignable(fieldType, valType) {
+ c.errors.fieldTypeMismatch(c.locationByID(ent.Id), field, fieldType, valType)
}
}
}
diff --git a/vendor/github.com/google/cel-go/checker/cost.go b/vendor/github.com/google/cel-go/checker/cost.go
index 7312d1fe2f..ef58df766b 100644
--- a/vendor/github.com/google/cel-go/checker/cost.go
+++ b/vendor/github.com/google/cel-go/checker/cost.go
@@ -92,7 +92,10 @@ func (e astNode) ComputedSize() *SizeEstimate {
case *exprpb.Expr_ConstExpr:
switch ck := ek.ConstExpr.GetConstantKind().(type) {
case *exprpb.Constant_StringValue:
- v = uint64(len(ck.StringValue))
+ // converting to runes here is an O(n) operation, but
+ // this is consistent with how size is computed at runtime,
+ // and how the language definition defines string size
+ v = uint64(len([]rune(ck.StringValue)))
case *exprpb.Constant_BytesValue:
v = uint64(len(ck.BytesValue))
case *exprpb.Constant_BoolValue, *exprpb.Constant_DoubleValue, *exprpb.Constant_DurationValue,
@@ -258,6 +261,8 @@ type coster struct {
computedSizes map[int64]SizeEstimate
checkedExpr *exprpb.CheckedExpr
estimator CostEstimator
+ // presenceTestCost will either be a zero or one based on whether has() macros count against cost computations.
+ presenceTestCost CostEstimate
}
// Use a stack of iterVar -> iterRange Expr Ids to handle shadowed variable names.
@@ -280,16 +285,39 @@ func (vs iterRangeScopes) peek(varName string) (int64, bool) {
return 0, false
}
+// CostOption configures flags which affect cost computations.
+type CostOption func(*coster) error
+
+// PresenceTestHasCost determines whether presence testing has a cost of one or zero.
+// Defaults to presence test has a cost of one.
+func PresenceTestHasCost(hasCost bool) CostOption {
+ return func(c *coster) error {
+ if hasCost {
+ c.presenceTestCost = selectAndIdentCost
+ return nil
+ }
+ c.presenceTestCost = CostEstimate{Min: 0, Max: 0}
+ return nil
+ }
+}
+
// Cost estimates the cost of the parsed and type checked CEL expression.
-func Cost(checker *exprpb.CheckedExpr, estimator CostEstimator) CostEstimate {
- c := coster{
- checkedExpr: checker,
- estimator: estimator,
- exprPath: map[int64][]string{},
- iterRanges: map[string][]int64{},
- computedSizes: map[int64]SizeEstimate{},
+func Cost(checker *exprpb.CheckedExpr, estimator CostEstimator, opts ...CostOption) (CostEstimate, error) {
+ c := &coster{
+ checkedExpr: checker,
+ estimator: estimator,
+ exprPath: map[int64][]string{},
+ iterRanges: map[string][]int64{},
+ computedSizes: map[int64]SizeEstimate{},
+ presenceTestCost: CostEstimate{Min: 1, Max: 1},
+ }
+ for _, opt := range opts {
+ err := opt(c)
+ if err != nil {
+ return CostEstimate{}, err
+ }
}
- return c.cost(checker.GetExpr())
+ return c.cost(checker.GetExpr()), nil
}
func (c *coster) cost(e *exprpb.Expr) CostEstimate {
@@ -340,6 +368,12 @@ func (c *coster) costSelect(e *exprpb.Expr) CostEstimate {
sel := e.GetSelectExpr()
var sum CostEstimate
if sel.GetTestOnly() {
+ // recurse, but do not add any cost
+ // this is equivalent to how evalTestOnly increments the runtime cost counter
+ // but does not add any additional cost for the qualifier, except here we do
+ // the reverse (ident adds cost)
+ sum = sum.Add(c.presenceTestCost)
+ sum = sum.Add(c.cost(sel.GetOperand()))
return sum
}
sum = sum.Add(c.cost(sel.GetOperand()))
@@ -499,11 +533,34 @@ func (c *coster) functionCost(function, overloadID string, target *AstNode, args
if est := c.estimator.EstimateCallCost(function, overloadID, target, args); est != nil {
callEst := *est
- return CallEstimate{CostEstimate: callEst.Add(argCostSum())}
+ return CallEstimate{CostEstimate: callEst.Add(argCostSum()), ResultSize: est.ResultSize}
}
switch overloadID {
// O(n) functions
- case overloads.StartsWithString, overloads.EndsWithString, overloads.StringToBytes, overloads.BytesToString:
+ case overloads.ExtFormatString:
+ if target != nil {
+ // ResultSize not calculated because we can't bound the max size.
+ return CallEstimate{CostEstimate: c.sizeEstimate(*target).MultiplyByCostFactor(common.StringTraversalCostFactor).Add(argCostSum())}
+ }
+ case overloads.StringToBytes:
+ if len(args) == 1 {
+ sz := c.sizeEstimate(args[0])
+ // ResultSize max is when each char converts to 4 bytes.
+ return CallEstimate{CostEstimate: sz.MultiplyByCostFactor(common.StringTraversalCostFactor).Add(argCostSum()), ResultSize: &SizeEstimate{Min: sz.Min, Max: sz.Max * 4}}
+ }
+ case overloads.BytesToString:
+ if len(args) == 1 {
+ sz := c.sizeEstimate(args[0])
+ // ResultSize min is when 4 bytes convert to 1 char.
+ return CallEstimate{CostEstimate: sz.MultiplyByCostFactor(common.StringTraversalCostFactor).Add(argCostSum()), ResultSize: &SizeEstimate{Min: sz.Min / 4, Max: sz.Max}}
+ }
+ case overloads.ExtQuoteString:
+ if len(args) == 1 {
+ sz := c.sizeEstimate(args[0])
+ // ResultSize max is when each char is escaped. 2 quote chars always added.
+ return CallEstimate{CostEstimate: sz.MultiplyByCostFactor(common.StringTraversalCostFactor).Add(argCostSum()), ResultSize: &SizeEstimate{Min: sz.Min + 2, Max: sz.Max*2 + 2}}
+ }
+ case overloads.StartsWithString, overloads.EndsWithString:
if len(args) == 1 {
return CallEstimate{CostEstimate: c.sizeEstimate(args[0]).MultiplyByCostFactor(common.StringTraversalCostFactor).Add(argCostSum())}
}
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 5a24f1da80..9384be4507 100644
--- a/vendor/github.com/google/cel-go/checker/decls/BUILD.bazel
+++ b/vendor/github.com/google/cel-go/checker/decls/BUILD.bazel
@@ -13,7 +13,7 @@ go_library(
],
importpath = "github.com/google/cel-go/checker/decls",
deps = [
- "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
+ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
"@org_golang_google_protobuf//types/known/structpb:go_default_library",
],
diff --git a/vendor/github.com/google/cel-go/checker/decls/decls.go b/vendor/github.com/google/cel-go/checker/decls/decls.go
index 88a99282d9..0d91bef514 100644
--- a/vendor/github.com/google/cel-go/checker/decls/decls.go
+++ b/vendor/github.com/google/cel-go/checker/decls/decls.go
@@ -16,9 +16,9 @@
package decls
import (
+ 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"
- exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
)
var (
@@ -64,6 +64,12 @@ func NewAbstractType(name string, paramTypes ...*exprpb.Type) *exprpb.Type {
ParameterTypes: paramTypes}}}
}
+// NewOptionalType constructs an abstract type indicating that the parameterized type
+// may be contained within the object.
+func NewOptionalType(paramType *exprpb.Type) *exprpb.Type {
+ return NewAbstractType("optional", paramType)
+}
+
// NewFunctionType creates a function invocation contract, typically only used
// by type-checking steps after overload resolution.
func NewFunctionType(resultType *exprpb.Type,
diff --git a/vendor/github.com/google/cel-go/checker/env.go b/vendor/github.com/google/cel-go/checker/env.go
index c7eeb04eee..be89d2d68d 100644
--- a/vendor/github.com/google/cel-go/checker/env.go
+++ b/vendor/github.com/google/cel-go/checker/env.go
@@ -226,7 +226,7 @@ func (e *Env) setFunction(decl *exprpb.Decl) []errorMsg {
newOverloads := []*exprpb.Decl_FunctionDecl_Overload{}
for _, overload := range overloads {
existing, found := existingOverloads[overload.GetOverloadId()]
- if !found || !proto.Equal(existing, overload) {
+ if !found || !overloadsEqual(existing, overload) {
newOverloads = append(newOverloads, overload)
}
}
@@ -264,6 +264,31 @@ func (e *Env) isOverloadDisabled(overloadID string) bool {
return found
}
+// overloadsEqual returns whether two overloads have identical signatures.
+//
+// type parameter names are ignored as they may be specified in any order and have no bearing on overload
+// equivalence
+func overloadsEqual(o1, o2 *exprpb.Decl_FunctionDecl_Overload) bool {
+ return o1.GetOverloadId() == o2.GetOverloadId() &&
+ o1.GetIsInstanceFunction() == o2.GetIsInstanceFunction() &&
+ paramsEqual(o1.GetParams(), o2.GetParams()) &&
+ proto.Equal(o1.GetResultType(), o2.GetResultType())
+}
+
+// paramsEqual returns whether two lists have equal length and all types are equal
+func paramsEqual(p1, p2 []*exprpb.Type) bool {
+ if len(p1) != len(p2) {
+ return false
+ }
+ for i, a := range p1 {
+ b := p2[i]
+ if !proto.Equal(a, b) {
+ return false
+ }
+ }
+ return true
+}
+
// sanitizeFunction replaces well-known types referenced by message name with their equivalent
// CEL built-in type instances.
func sanitizeFunction(decl *exprpb.Decl) *exprpb.Decl {
diff --git a/vendor/github.com/google/cel-go/checker/printer.go b/vendor/github.com/google/cel-go/checker/printer.go
index e2ed35be83..0cecc5210d 100644
--- a/vendor/github.com/google/cel-go/checker/printer.go
+++ b/vendor/github.com/google/cel-go/checker/printer.go
@@ -26,7 +26,7 @@ type semanticAdorner struct {
var _ debug.Adorner = &semanticAdorner{}
-func (a *semanticAdorner) GetMetadata(elem interface{}) string {
+func (a *semanticAdorner) GetMetadata(elem any) string {
result := ""
e, isExpr := elem.(*exprpb.Expr)
if !isExpr {
diff --git a/vendor/github.com/google/cel-go/checker/standard.go b/vendor/github.com/google/cel-go/checker/standard.go
index 5b48a9046a..e64337ba44 100644
--- a/vendor/github.com/google/cel-go/checker/standard.go
+++ b/vendor/github.com/google/cel-go/checker/standard.go
@@ -287,6 +287,8 @@ func init() {
decls.NewInstanceOverload(overloads.EndsWithString,
[]*exprpb.Type{decls.String, decls.String}, decls.Bool)),
decls.NewFunction(overloads.Matches,
+ decls.NewOverload(overloads.Matches,
+ []*exprpb.Type{decls.String, decls.String}, decls.Bool),
decls.NewInstanceOverload(overloads.MatchesString,
[]*exprpb.Type{decls.String, decls.String}, decls.Bool)),
decls.NewFunction(overloads.StartsWith,
diff --git a/vendor/github.com/google/cel-go/checker/types.go b/vendor/github.com/google/cel-go/checker/types.go
index 8683797d5b..28d21c9d92 100644
--- a/vendor/github.com/google/cel-go/checker/types.go
+++ b/vendor/github.com/google/cel-go/checker/types.go
@@ -90,6 +90,14 @@ func FormatCheckedType(t *exprpb.Type) string {
return "!error!"
case kindTypeParam:
return t.GetTypeParam()
+ case kindAbstract:
+ at := t.GetAbstractType()
+ params := at.GetParameterTypes()
+ paramStrs := make([]string, len(params))
+ for i, p := range params {
+ paramStrs[i] = FormatCheckedType(p)
+ }
+ return fmt.Sprintf("%s(%s)", at.GetName(), strings.Join(paramStrs, ", "))
}
return t.String()
}
@@ -110,12 +118,39 @@ func isDyn(t *exprpb.Type) bool {
// isDynOrError returns true if the input is either an Error, DYN, or well-known ANY message.
func isDynOrError(t *exprpb.Type) bool {
- switch kindOf(t) {
- case kindError:
- return true
- default:
- return isDyn(t)
+ return isError(t) || isDyn(t)
+}
+
+func isError(t *exprpb.Type) bool {
+ return kindOf(t) == kindError
+}
+
+func isOptional(t *exprpb.Type) bool {
+ if kindOf(t) == kindAbstract {
+ at := t.GetAbstractType()
+ return at.GetName() == "optional"
+ }
+ return false
+}
+
+func maybeUnwrapOptional(t *exprpb.Type) (*exprpb.Type, bool) {
+ if isOptional(t) {
+ at := t.GetAbstractType()
+ return at.GetParameterTypes()[0], true
+ }
+ return t, false
+}
+
+func maybeUnwrapString(e *exprpb.Expr) (string, bool) {
+ switch e.GetExprKind().(type) {
+ case *exprpb.Expr_ConstExpr:
+ literal := e.GetConstExpr()
+ switch literal.GetConstantKind().(type) {
+ case *exprpb.Constant_StringValue:
+ return literal.GetStringValue(), true
+ }
}
+ return "", false
}
// isEqualOrLessSpecific checks whether one type is equal or less specific than the other one.
@@ -236,7 +271,7 @@ func internalIsAssignable(m *mapping, t1 *exprpb.Type, t2 *exprpb.Type) bool {
// substitution for t1, and whether t2 has a type substitution in mapping m.
//
// The type t2 is a valid substitution for t1 if any of the following statements is true
-// - t2 has a type substitition (t2sub) equal to t1
+// - t2 has a type substitution (t2sub) equal to t1
// - t2 has a type substitution (t2sub) assignable to t1
// - t2 does not occur within t1.
func isValidTypeSubstitution(m *mapping, t1, t2 *exprpb.Type) (valid, hasSub bool) {
diff --git a/vendor/github.com/google/cel-go/common/BUILD.bazel b/vendor/github.com/google/cel-go/common/BUILD.bazel
index a0058aebe0..d6165b13af 100644
--- a/vendor/github.com/google/cel-go/common/BUILD.bazel
+++ b/vendor/github.com/google/cel-go/common/BUILD.bazel
@@ -17,7 +17,7 @@ go_library(
importpath = "github.com/google/cel-go/common",
deps = [
"//common/runes:go_default_library",
- "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
+ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
"@org_golang_x_text//width:go_default_library",
],
)
diff --git a/vendor/github.com/google/cel-go/common/containers/BUILD.bazel b/vendor/github.com/google/cel-go/common/containers/BUILD.bazel
index 18142d94ef..3f3f078871 100644
--- a/vendor/github.com/google/cel-go/common/containers/BUILD.bazel
+++ b/vendor/github.com/google/cel-go/common/containers/BUILD.bazel
@@ -12,7 +12,7 @@ go_library(
],
importpath = "github.com/google/cel-go/common/containers",
deps = [
- "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
+ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
],
)
@@ -26,6 +26,6 @@ go_test(
":go_default_library",
],
deps = [
- "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
+ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
],
)
diff --git a/vendor/github.com/google/cel-go/common/debug/BUILD.bazel b/vendor/github.com/google/cel-go/common/debug/BUILD.bazel
index cf5c5d2467..1f029839c7 100644
--- a/vendor/github.com/google/cel-go/common/debug/BUILD.bazel
+++ b/vendor/github.com/google/cel-go/common/debug/BUILD.bazel
@@ -13,6 +13,6 @@ go_library(
importpath = "github.com/google/cel-go/common/debug",
deps = [
"//common:go_default_library",
- "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
+ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
],
)
diff --git a/vendor/github.com/google/cel-go/common/debug/debug.go b/vendor/github.com/google/cel-go/common/debug/debug.go
index bec885424b..5dab156ef3 100644
--- a/vendor/github.com/google/cel-go/common/debug/debug.go
+++ b/vendor/github.com/google/cel-go/common/debug/debug.go
@@ -29,7 +29,7 @@ import (
// representation of an expression.
type Adorner interface {
// GetMetadata for the input context.
- GetMetadata(ctx interface{}) string
+ GetMetadata(ctx any) string
}
// Writer manages writing expressions to an internal string.
@@ -46,7 +46,7 @@ type emptyDebugAdorner struct {
var emptyAdorner Adorner = &emptyDebugAdorner{}
-func (a *emptyDebugAdorner) GetMetadata(e interface{}) string {
+func (a *emptyDebugAdorner) GetMetadata(e any) string {
return ""
}
@@ -170,6 +170,9 @@ func (w *debugWriter) appendObject(obj *exprpb.Expr_CreateStruct) {
w.append(",")
w.appendLine()
}
+ if entry.GetOptionalEntry() {
+ w.append("?")
+ }
w.append(entry.GetFieldKey())
w.append(":")
w.Buffer(entry.GetValue())
@@ -191,6 +194,9 @@ func (w *debugWriter) appendMap(obj *exprpb.Expr_CreateStruct) {
w.append(",")
w.appendLine()
}
+ if entry.GetOptionalEntry() {
+ w.append("?")
+ }
w.Buffer(entry.GetMapKey())
w.append(":")
w.Buffer(entry.GetValue())
@@ -269,7 +275,7 @@ func (w *debugWriter) append(s string) {
w.buffer.WriteString(s)
}
-func (w *debugWriter) appendFormat(f string, args ...interface{}) {
+func (w *debugWriter) appendFormat(f string, args ...any) {
w.append(fmt.Sprintf(f, args...))
}
@@ -280,7 +286,7 @@ func (w *debugWriter) doIndent() {
}
}
-func (w *debugWriter) adorn(e interface{}) {
+func (w *debugWriter) adorn(e any) {
w.append(w.adorner.GetMetadata(e))
}
diff --git a/vendor/github.com/google/cel-go/common/errors.go b/vendor/github.com/google/cel-go/common/errors.go
index daebba8609..1565085ab9 100644
--- a/vendor/github.com/google/cel-go/common/errors.go
+++ b/vendor/github.com/google/cel-go/common/errors.go
@@ -38,7 +38,7 @@ func NewErrors(source Source) *Errors {
}
// ReportError records an error at a source location.
-func (e *Errors) ReportError(l Location, format string, args ...interface{}) {
+func (e *Errors) ReportError(l Location, format string, args ...any) {
e.numErrors++
if e.numErrors > e.maxErrorsToReport {
return
diff --git a/vendor/github.com/google/cel-go/common/operators/operators.go b/vendor/github.com/google/cel-go/common/operators/operators.go
index fa25dfb7f0..f9b39bda3f 100644
--- a/vendor/github.com/google/cel-go/common/operators/operators.go
+++ b/vendor/github.com/google/cel-go/common/operators/operators.go
@@ -37,6 +37,8 @@ const (
Modulo = "_%_"
Negate = "-_"
Index = "_[_]"
+ OptIndex = "_[?_]"
+ OptSelect = "_?._"
// Macros, must have a valid identifier.
Has = "has"
@@ -99,6 +101,8 @@ var (
LogicalNot: {displayName: "!", precedence: 2, arity: 1},
Negate: {displayName: "-", precedence: 2, arity: 1},
Index: {displayName: "", precedence: 1, arity: 2},
+ OptIndex: {displayName: "", precedence: 1, arity: 2},
+ OptSelect: {displayName: "", precedence: 1, arity: 2},
}
)
diff --git a/vendor/github.com/google/cel-go/common/overloads/overloads.go b/vendor/github.com/google/cel-go/common/overloads/overloads.go
index 9ebaf6fabf..9d50f4367b 100644
--- a/vendor/github.com/google/cel-go/common/overloads/overloads.go
+++ b/vendor/github.com/google/cel-go/common/overloads/overloads.go
@@ -148,6 +148,11 @@ const (
StartsWith = "startsWith"
)
+// Extension function overloads with complex behaviors that need to be referenced in runtime and static analysis cost computations.
+const (
+ ExtQuoteString = "strings_quote"
+)
+
// String function overload names.
const (
ContainsString = "contains_string"
@@ -156,6 +161,11 @@ const (
StartsWithString = "starts_with_string"
)
+// Extension function overloads with complex behaviors that need to be referenced in runtime and static analysis cost computations.
+const (
+ ExtFormatString = "string_format"
+)
+
// Time-based functions.
const (
TimeGetFullYear = "getFullYear"
diff --git a/vendor/github.com/google/cel-go/common/types/BUILD.bazel b/vendor/github.com/google/cel-go/common/types/BUILD.bazel
index 5f1b1cd1fd..89c4feacbf 100644
--- a/vendor/github.com/google/cel-go/common/types/BUILD.bazel
+++ b/vendor/github.com/google/cel-go/common/types/BUILD.bazel
@@ -22,6 +22,7 @@ go_library(
"map.go",
"null.go",
"object.go",
+ "optional.go",
"overflow.go",
"provider.go",
"string.go",
@@ -38,10 +39,8 @@ go_library(
"//common/types/ref:go_default_library",
"//common/types/traits:go_default_library",
"@com_github_stoewer_go_strcase//:go_default_library",
- "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
- "@org_golang_google_genproto//googleapis/rpc/status:go_default_library",
- "@org_golang_google_grpc//codes:go_default_library",
- "@org_golang_google_grpc//status:go_default_library",
+ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
+ "@org_golang_google_genproto_googleapis_rpc//status:go_default_library",
"@org_golang_google_protobuf//encoding/protojson:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
"@org_golang_google_protobuf//reflect/protoreflect:go_default_library",
@@ -68,6 +67,7 @@ go_test(
"map_test.go",
"null_test.go",
"object_test.go",
+ "optional_test.go",
"provider_test.go",
"string_test.go",
"timestamp_test.go",
@@ -80,7 +80,7 @@ go_test(
"//common/types/ref:go_default_library",
"//test:go_default_library",
"//test/proto3pb:test_all_types_go_proto",
- "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
+ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
"@org_golang_google_protobuf//encoding/protojson:go_default_library",
"@org_golang_google_protobuf//types/known/anypb:go_default_library",
"@org_golang_google_protobuf//types/known/durationpb:go_default_library",
diff --git a/vendor/github.com/google/cel-go/common/types/bool.go b/vendor/github.com/google/cel-go/common/types/bool.go
index 1b55ba9529..a634ecc287 100644
--- a/vendor/github.com/google/cel-go/common/types/bool.go
+++ b/vendor/github.com/google/cel-go/common/types/bool.go
@@ -62,7 +62,7 @@ func (b Bool) Compare(other ref.Val) ref.Val {
}
// ConvertToNative implements the ref.Val interface method.
-func (b Bool) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
+func (b Bool) ConvertToNative(typeDesc reflect.Type) (any, error) {
switch typeDesc.Kind() {
case reflect.Bool:
return reflect.ValueOf(b).Convert(typeDesc).Interface(), nil
@@ -114,6 +114,11 @@ func (b Bool) Equal(other ref.Val) ref.Val {
return Bool(ok && b == otherBool)
}
+// IsZeroValue returns true if the boolean value is false.
+func (b Bool) IsZeroValue() bool {
+ return b == False
+}
+
// Negate implements the traits.Negater interface method.
func (b Bool) Negate() ref.Val {
return !b
@@ -125,7 +130,7 @@ func (b Bool) Type() ref.Type {
}
// Value implements the ref.Val interface method.
-func (b Bool) Value() interface{} {
+func (b Bool) Value() any {
return bool(b)
}
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 3575717ec7..bef190759f 100644
--- a/vendor/github.com/google/cel-go/common/types/bytes.go
+++ b/vendor/github.com/google/cel-go/common/types/bytes.go
@@ -63,7 +63,7 @@ func (b Bytes) Compare(other ref.Val) ref.Val {
}
// ConvertToNative implements the ref.Val interface method.
-func (b Bytes) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
+func (b Bytes) ConvertToNative(typeDesc reflect.Type) (any, error) {
switch typeDesc.Kind() {
case reflect.Array, reflect.Slice:
return reflect.ValueOf(b).Convert(typeDesc).Interface(), nil
@@ -116,6 +116,11 @@ func (b Bytes) Equal(other ref.Val) ref.Val {
return Bool(ok && bytes.Equal(b, otherBytes))
}
+// IsZeroValue returns true if the byte array is empty.
+func (b Bytes) IsZeroValue() bool {
+ return len(b) == 0
+}
+
// Size implements the traits.Sizer interface method.
func (b Bytes) Size() ref.Val {
return Int(len(b))
@@ -127,6 +132,6 @@ func (b Bytes) Type() ref.Type {
}
// Value implements the ref.Val interface method.
-func (b Bytes) Value() interface{} {
+func (b Bytes) Value() any {
return []byte(b)
}
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 a6ec52a0f9..bda9f31a6b 100644
--- a/vendor/github.com/google/cel-go/common/types/double.go
+++ b/vendor/github.com/google/cel-go/common/types/double.go
@@ -78,7 +78,7 @@ func (d Double) Compare(other ref.Val) ref.Val {
}
// ConvertToNative implements ref.Val.ConvertToNative.
-func (d Double) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
+func (d Double) ConvertToNative(typeDesc reflect.Type) (any, error) {
switch typeDesc.Kind() {
case reflect.Float32:
v := float32(d)
@@ -134,13 +134,13 @@ func (d Double) ConvertToType(typeVal ref.Type) ref.Val {
case IntType:
i, err := doubleToInt64Checked(float64(d))
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return Int(i)
case UintType:
i, err := doubleToUint64Checked(float64(d))
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return Uint(i)
case DoubleType:
@@ -182,6 +182,11 @@ func (d Double) Equal(other ref.Val) ref.Val {
}
}
+// IsZeroValue returns true if double value is 0.0
+func (d Double) IsZeroValue() bool {
+ return float64(d) == 0.0
+}
+
// Multiply implements traits.Multiplier.Multiply.
func (d Double) Multiply(other ref.Val) ref.Val {
otherDouble, ok := other.(Double)
@@ -211,6 +216,6 @@ func (d Double) Type() ref.Type {
}
// Value implements ref.Val.Value.
-func (d Double) Value() interface{} {
+func (d Double) Value() any {
return float64(d)
}
diff --git a/vendor/github.com/google/cel-go/common/types/duration.go b/vendor/github.com/google/cel-go/common/types/duration.go
index 418349fa6c..c90ac1bee9 100644
--- a/vendor/github.com/google/cel-go/common/types/duration.go
+++ b/vendor/github.com/google/cel-go/common/types/duration.go
@@ -57,14 +57,14 @@ func (d Duration) Add(other ref.Val) ref.Val {
dur2 := other.(Duration)
val, err := addDurationChecked(d.Duration, dur2.Duration)
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return durationOf(val)
case TimestampType:
ts := other.(Timestamp).Time
val, err := addTimeDurationChecked(ts, d.Duration)
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return timestampOf(val)
}
@@ -90,7 +90,7 @@ func (d Duration) Compare(other ref.Val) ref.Val {
}
// ConvertToNative implements ref.Val.ConvertToNative.
-func (d Duration) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
+func (d Duration) ConvertToNative(typeDesc reflect.Type) (any, error) {
// If the duration is already assignable to the desired type return it.
if reflect.TypeOf(d.Duration).AssignableTo(typeDesc) {
return d.Duration, nil
@@ -138,11 +138,16 @@ func (d Duration) Equal(other ref.Val) ref.Val {
return Bool(ok && d.Duration == otherDur.Duration)
}
+// IsZeroValue returns true if the duration value is zero
+func (d Duration) IsZeroValue() bool {
+ return d.Duration == 0
+}
+
// Negate implements traits.Negater.Negate.
func (d Duration) Negate() ref.Val {
val, err := negateDurationChecked(d.Duration)
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return durationOf(val)
}
@@ -165,7 +170,7 @@ func (d Duration) Subtract(subtrahend ref.Val) ref.Val {
}
val, err := subtractDurationChecked(d.Duration, subtraDur.Duration)
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return durationOf(val)
}
@@ -176,7 +181,7 @@ func (d Duration) Type() ref.Type {
}
// Value implements ref.Val.Value.
-func (d Duration) Value() interface{} {
+func (d Duration) Value() any {
return d.Duration
}
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 93d79cdcbc..b4874d9d4d 100644
--- a/vendor/github.com/google/cel-go/common/types/err.go
+++ b/vendor/github.com/google/cel-go/common/types/err.go
@@ -22,6 +22,12 @@ import (
"github.com/google/cel-go/common/types/ref"
)
+// Error interface which allows types types.Err values to be treated as error values.
+type Error interface {
+ error
+ ref.Val
+}
+
// Err type which extends the built-in go error and implements ref.Val.
type Err struct {
error
@@ -51,7 +57,7 @@ var (
// NewErr creates a new Err described by the format string and args.
// TODO: Audit the use of this function and standardize the error messages and codes.
-func NewErr(format string, args ...interface{}) ref.Val {
+func NewErr(format string, args ...any) ref.Val {
return &Err{fmt.Errorf(format, args...)}
}
@@ -62,7 +68,7 @@ func NoSuchOverloadErr() ref.Val {
// 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 {
+func UnsupportedRefValConversionErr(val any) ref.Val {
return NewErr("unsupported conversion to ref.Val: (%T)%v", val, val)
}
@@ -74,20 +80,20 @@ func MaybeNoSuchOverloadErr(val ref.Val) ref.Val {
// ValOrErr either returns the existing error or creates a new one.
// TODO: Audit the use of this function and standardize the error messages and codes.
-func ValOrErr(val ref.Val, format string, args ...interface{}) ref.Val {
+func ValOrErr(val ref.Val, format string, args ...any) ref.Val {
if val == nil || !IsUnknownOrError(val) {
return NewErr(format, args...)
}
return val
}
-// wrapErr wraps an existing Go error value into a CEL Err value.
-func wrapErr(err error) ref.Val {
+// WrapErr wraps an existing Go error value into a CEL Err value.
+func WrapErr(err error) ref.Val {
return &Err{error: err}
}
// ConvertToNative implements ref.Val.ConvertToNative.
-func (e *Err) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
+func (e *Err) ConvertToNative(typeDesc reflect.Type) (any, error) {
return nil, e.error
}
@@ -114,10 +120,15 @@ func (e *Err) Type() ref.Type {
}
// Value implements ref.Val.Value.
-func (e *Err) Value() interface{} {
+func (e *Err) Value() any {
return e.error
}
+// Is implements errors.Is.
+func (e *Err) Is(target error) bool {
+ return e.error.Error() == target.Error()
+}
+
// IsError returns whether the input element ref.Type or ref.Val is equal to
// the ErrType singleton.
func IsError(val ref.Val) bool {
diff --git a/vendor/github.com/google/cel-go/common/types/int.go b/vendor/github.com/google/cel-go/common/types/int.go
index 95f25dcd80..f5a9511c8d 100644
--- a/vendor/github.com/google/cel-go/common/types/int.go
+++ b/vendor/github.com/google/cel-go/common/types/int.go
@@ -66,7 +66,7 @@ func (i Int) Add(other ref.Val) ref.Val {
}
val, err := addInt64Checked(int64(i), int64(otherInt))
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return Int(val)
}
@@ -89,7 +89,7 @@ func (i Int) Compare(other ref.Val) ref.Val {
}
// ConvertToNative implements ref.Val.ConvertToNative.
-func (i Int) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
+func (i Int) ConvertToNative(typeDesc reflect.Type) (any, error) {
switch typeDesc.Kind() {
case reflect.Int, reflect.Int32:
// Enums are also mapped as int32 derivations.
@@ -176,7 +176,7 @@ func (i Int) ConvertToType(typeVal ref.Type) ref.Val {
case UintType:
u, err := int64ToUint64Checked(int64(i))
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return Uint(u)
case DoubleType:
@@ -204,7 +204,7 @@ func (i Int) Divide(other ref.Val) ref.Val {
}
val, err := divideInt64Checked(int64(i), int64(otherInt))
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return Int(val)
}
@@ -226,6 +226,11 @@ func (i Int) Equal(other ref.Val) ref.Val {
}
}
+// IsZeroValue returns true if integer is equal to 0
+func (i Int) IsZeroValue() bool {
+ return i == IntZero
+}
+
// Modulo implements traits.Modder.Modulo.
func (i Int) Modulo(other ref.Val) ref.Val {
otherInt, ok := other.(Int)
@@ -234,7 +239,7 @@ func (i Int) Modulo(other ref.Val) ref.Val {
}
val, err := moduloInt64Checked(int64(i), int64(otherInt))
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return Int(val)
}
@@ -247,7 +252,7 @@ func (i Int) Multiply(other ref.Val) ref.Val {
}
val, err := multiplyInt64Checked(int64(i), int64(otherInt))
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return Int(val)
}
@@ -256,7 +261,7 @@ func (i Int) Multiply(other ref.Val) ref.Val {
func (i Int) Negate() ref.Val {
val, err := negateInt64Checked(int64(i))
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return Int(val)
}
@@ -269,7 +274,7 @@ func (i Int) Subtract(subtrahend ref.Val) ref.Val {
}
val, err := subtractInt64Checked(int64(i), int64(subtraInt))
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return Int(val)
}
@@ -280,7 +285,7 @@ func (i Int) Type() ref.Type {
}
// Value implements ref.Val.Value.
-func (i Int) Value() interface{} {
+func (i Int) Value() any {
return int64(i)
}
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 4906627783..9f224ad4ff 100644
--- a/vendor/github.com/google/cel-go/common/types/iterator.go
+++ b/vendor/github.com/google/cel-go/common/types/iterator.go
@@ -34,7 +34,7 @@ var (
// interpreter.
type baseIterator struct{}
-func (*baseIterator) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
+func (*baseIterator) ConvertToNative(typeDesc reflect.Type) (any, error) {
return nil, fmt.Errorf("type conversion on iterators not supported")
}
@@ -50,6 +50,6 @@ func (*baseIterator) Type() ref.Type {
return IteratorType
}
-func (*baseIterator) Value() interface{} {
+func (*baseIterator) Value() any {
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 cd63b51944..13a4efe7ad 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
@@ -25,4 +25,5 @@ var (
jsonValueType = reflect.TypeOf(&structpb.Value{})
jsonListValueType = reflect.TypeOf(&structpb.ListValue{})
jsonStructType = reflect.TypeOf(&structpb.Struct{})
+ jsonNullType = reflect.TypeOf(structpb.NullValue_NULL_VALUE)
)
diff --git a/vendor/github.com/google/cel-go/common/types/list.go b/vendor/github.com/google/cel-go/common/types/list.go
index 7230f7ea12..de5f2099bf 100644
--- a/vendor/github.com/google/cel-go/common/types/list.go
+++ b/vendor/github.com/google/cel-go/common/types/list.go
@@ -17,12 +17,14 @@ package types
import (
"fmt"
"reflect"
+ "strings"
- "github.com/google/cel-go/common/types/ref"
- "github.com/google/cel-go/common/types/traits"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
+ "github.com/google/cel-go/common/types/ref"
+ "github.com/google/cel-go/common/types/traits"
+
anypb "google.golang.org/protobuf/types/known/anypb"
structpb "google.golang.org/protobuf/types/known/structpb"
)
@@ -40,13 +42,13 @@ var (
// NewDynamicList returns a traits.Lister with heterogenous elements.
// value should be an array of "native" types, i.e. any type that
// NativeToValue() can convert to a ref.Val.
-func NewDynamicList(adapter ref.TypeAdapter, value interface{}) traits.Lister {
+func NewDynamicList(adapter ref.TypeAdapter, value any) traits.Lister {
refValue := reflect.ValueOf(value)
return &baseList{
TypeAdapter: adapter,
value: value,
size: refValue.Len(),
- get: func(i int) interface{} {
+ get: func(i int) any {
return refValue.Index(i).Interface()
},
}
@@ -58,7 +60,7 @@ func NewStringList(adapter ref.TypeAdapter, elems []string) traits.Lister {
TypeAdapter: adapter,
value: elems,
size: len(elems),
- get: func(i int) interface{} { return elems[i] },
+ get: func(i int) any { return elems[i] },
}
}
@@ -70,7 +72,7 @@ func NewRefValList(adapter ref.TypeAdapter, elems []ref.Val) traits.Lister {
TypeAdapter: adapter,
value: elems,
size: len(elems),
- get: func(i int) interface{} { return elems[i] },
+ get: func(i int) any { return elems[i] },
}
}
@@ -80,7 +82,7 @@ func NewProtoList(adapter ref.TypeAdapter, list protoreflect.List) traits.Lister
TypeAdapter: adapter,
value: list,
size: list.Len(),
- get: func(i int) interface{} { return list.Get(i).Interface() },
+ get: func(i int) any { return list.Get(i).Interface() },
}
}
@@ -91,22 +93,25 @@ func NewJSONList(adapter ref.TypeAdapter, l *structpb.ListValue) traits.Lister {
TypeAdapter: adapter,
value: l,
size: len(vals),
- get: func(i int) interface{} { return vals[i] },
+ get: func(i int) any { return vals[i] },
}
}
// NewMutableList creates a new mutable list whose internal state can be modified.
func NewMutableList(adapter ref.TypeAdapter) traits.MutableLister {
var mutableValues []ref.Val
- return &mutableList{
+ l := &mutableList{
baseList: &baseList{
TypeAdapter: adapter,
value: mutableValues,
size: 0,
- get: func(i int) interface{} { return mutableValues[i] },
},
mutableValues: mutableValues,
}
+ l.get = func(i int) any {
+ return l.mutableValues[i]
+ }
+ return l
}
// baseList points to a list containing elements of any type.
@@ -114,7 +119,7 @@ func NewMutableList(adapter ref.TypeAdapter) traits.MutableLister {
// The `ref.TypeAdapter` enables native type to CEL type conversions.
type baseList struct {
ref.TypeAdapter
- value interface{}
+ value any
// size indicates the number of elements within the list.
// Since objects are immutable the size of a list is static.
@@ -122,7 +127,7 @@ type baseList struct {
// 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{}
+ get func(int) any
}
// Add implements the traits.Adder interface method.
@@ -157,7 +162,7 @@ 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) {
+func (l *baseList) ConvertToNative(typeDesc reflect.Type) (any, error) {
// If the underlying list value is assignable to the reflected type return it.
if reflect.TypeOf(l.value).AssignableTo(typeDesc) {
return l.value, nil
@@ -240,7 +245,7 @@ func (l *baseList) Equal(other ref.Val) ref.Val {
// Get implements the traits.Indexer interface method.
func (l *baseList) Get(index ref.Val) ref.Val {
- ind, err := indexOrError(index)
+ ind, err := IndexOrError(index)
if err != nil {
return ValOrErr(index, err.Error())
}
@@ -250,6 +255,11 @@ func (l *baseList) Get(index ref.Val) ref.Val {
return l.NativeToValue(l.get(ind))
}
+// IsZeroValue returns true if the list is empty.
+func (l *baseList) IsZeroValue() bool {
+ return l.size == 0
+}
+
// Iterator implements the traits.Iterable interface method.
func (l *baseList) Iterator() traits.Iterator {
return newListIterator(l)
@@ -266,10 +276,24 @@ func (l *baseList) Type() ref.Type {
}
// Value implements the ref.Val interface method.
-func (l *baseList) Value() interface{} {
+func (l *baseList) Value() any {
return l.value
}
+// String converts the list to a human readable string form.
+func (l *baseList) String() string {
+ var sb strings.Builder
+ sb.WriteString("[")
+ for i := 0; i < l.size; i++ {
+ sb.WriteString(fmt.Sprintf("%v", l.get(i)))
+ if i != l.size-1 {
+ sb.WriteString(", ")
+ }
+ }
+ sb.WriteString("]")
+ return sb.String()
+}
+
// mutableList aggregates values into its internal storage. For use with internal CEL variables only.
type mutableList struct {
*baseList
@@ -305,7 +329,7 @@ func (l *mutableList) ToImmutableList() traits.Lister {
// The `ref.TypeAdapter` enables native type to CEL type conversions.
type concatList struct {
ref.TypeAdapter
- value interface{}
+ value any
prevList traits.Lister
nextList traits.Lister
}
@@ -351,8 +375,8 @@ 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 := NewDynamicList(l.TypeAdapter, l.Value().([]interface{}))
+func (l *concatList) ConvertToNative(typeDesc reflect.Type) (any, error) {
+ combined := NewDynamicList(l.TypeAdapter, l.Value().([]any))
return combined.ConvertToNative(typeDesc)
}
@@ -396,7 +420,7 @@ func (l *concatList) Equal(other ref.Val) ref.Val {
// Get implements the traits.Indexer interface method.
func (l *concatList) Get(index ref.Val) ref.Val {
- ind, err := indexOrError(index)
+ ind, err := IndexOrError(index)
if err != nil {
return ValOrErr(index, err.Error())
}
@@ -408,6 +432,11 @@ func (l *concatList) Get(index ref.Val) ref.Val {
return l.nextList.Get(offset)
}
+// IsZeroValue returns true if the list is empty.
+func (l *concatList) IsZeroValue() bool {
+ return l.Size().(Int) == 0
+}
+
// Iterator implements the traits.Iterable interface method.
func (l *concatList) Iterator() traits.Iterator {
return newListIterator(l)
@@ -418,15 +447,29 @@ func (l *concatList) Size() ref.Val {
return l.prevList.Size().(Int).Add(l.nextList.Size())
}
+// String converts the concatenated list to a human-readable string.
+func (l *concatList) String() string {
+ var sb strings.Builder
+ sb.WriteString("[")
+ for i := Int(0); i < l.Size().(Int); i++ {
+ sb.WriteString(fmt.Sprintf("%v", l.Get(i)))
+ if i != l.Size().(Int)-1 {
+ sb.WriteString(", ")
+ }
+ }
+ sb.WriteString("]")
+ return sb.String()
+}
+
// Type implements the ref.Val interface method.
func (l *concatList) Type() ref.Type {
return ListType
}
// Value implements the ref.Val interface method.
-func (l *concatList) Value() interface{} {
+func (l *concatList) Value() any {
if l.value == nil {
- merged := make([]interface{}, l.Size().(Int))
+ merged := make([]any, l.Size().(Int))
prevLen := l.prevList.Size().(Int)
for i := Int(0); i < prevLen; i++ {
merged[i] = l.prevList.Get(i).Value()
@@ -469,7 +512,8 @@ func (it *listIterator) Next() ref.Val {
return nil
}
-func indexOrError(index ref.Val) (int, error) {
+// IndexOrError converts an input index value into either a lossless integer index or an error.
+func IndexOrError(index ref.Val) (int, error) {
switch iv := index.(type) {
case Int:
return int(iv), nil
diff --git a/vendor/github.com/google/cel-go/common/types/map.go b/vendor/github.com/google/cel-go/common/types/map.go
index 5865594024..213be4ac9e 100644
--- a/vendor/github.com/google/cel-go/common/types/map.go
+++ b/vendor/github.com/google/cel-go/common/types/map.go
@@ -17,20 +17,22 @@ package types
import (
"fmt"
"reflect"
+ "strings"
- "github.com/google/cel-go/common/types/pb"
- "github.com/google/cel-go/common/types/ref"
- "github.com/google/cel-go/common/types/traits"
"github.com/stoewer/go-strcase"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
+ "github.com/google/cel-go/common/types/pb"
+ "github.com/google/cel-go/common/types/ref"
+ "github.com/google/cel-go/common/types/traits"
+
anypb "google.golang.org/protobuf/types/known/anypb"
structpb "google.golang.org/protobuf/types/known/structpb"
)
// NewDynamicMap returns a traits.Mapper value with dynamic key, value pairs.
-func NewDynamicMap(adapter ref.TypeAdapter, value interface{}) traits.Mapper {
+func NewDynamicMap(adapter ref.TypeAdapter, value any) traits.Mapper {
refValue := reflect.ValueOf(value)
return &baseMap{
TypeAdapter: adapter,
@@ -65,7 +67,7 @@ func NewRefValMap(adapter ref.TypeAdapter, value map[ref.Val]ref.Val) traits.Map
}
// NewStringInterfaceMap returns a specialized traits.Mapper with string keys and interface values.
-func NewStringInterfaceMap(adapter ref.TypeAdapter, value map[string]interface{}) traits.Mapper {
+func NewStringInterfaceMap(adapter ref.TypeAdapter, value map[string]any) traits.Mapper {
return &baseMap{
TypeAdapter: adapter,
mapAccessor: newStringIfaceMapAccessor(adapter, value),
@@ -125,7 +127,7 @@ type baseMap struct {
mapAccessor
// value is the native Go value upon which the map type operators.
- value interface{}
+ value any
// size is the number of entries in the map.
size int
@@ -138,7 +140,7 @@ func (m *baseMap) Contains(index ref.Val) ref.Val {
}
// ConvertToNative implements the ref.Val interface method.
-func (m *baseMap) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
+func (m *baseMap) ConvertToNative(typeDesc reflect.Type) (any, 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) {
@@ -275,18 +277,42 @@ func (m *baseMap) Get(key ref.Val) ref.Val {
return v
}
+// IsZeroValue returns true if the map is empty.
+func (m *baseMap) IsZeroValue() bool {
+ return m.size == 0
+}
+
// Size implements the traits.Sizer interface method.
func (m *baseMap) Size() ref.Val {
return Int(m.size)
}
+// String converts the map into a human-readable string.
+func (m *baseMap) String() string {
+ var sb strings.Builder
+ sb.WriteString("{")
+ it := m.Iterator()
+ i := 0
+ for it.HasNext() == True {
+ k := it.Next()
+ v, _ := m.Find(k)
+ sb.WriteString(fmt.Sprintf("%v: %v", k, v))
+ if i != m.size-1 {
+ sb.WriteString(", ")
+ }
+ i++
+ }
+ sb.WriteString("}")
+ return sb.String()
+}
+
// 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{} {
+func (m *baseMap) Value() any {
return m.value
}
@@ -498,7 +524,7 @@ func (a *stringMapAccessor) Iterator() traits.Iterator {
}
}
-func newStringIfaceMapAccessor(adapter ref.TypeAdapter, mapVal map[string]interface{}) mapAccessor {
+func newStringIfaceMapAccessor(adapter ref.TypeAdapter, mapVal map[string]any) mapAccessor {
return &stringIfaceMapAccessor{
TypeAdapter: adapter,
mapVal: mapVal,
@@ -507,7 +533,7 @@ func newStringIfaceMapAccessor(adapter ref.TypeAdapter, mapVal map[string]interf
type stringIfaceMapAccessor struct {
ref.TypeAdapter
- mapVal map[string]interface{}
+ mapVal map[string]any
}
// Find uses native map accesses to find the key, returning (value, true) if present.
@@ -556,7 +582,7 @@ func (m *protoMap) Contains(key ref.Val) ref.Val {
// 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) {
+func (m *protoMap) ConvertToNative(typeDesc reflect.Type) (any, 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 {
@@ -601,9 +627,9 @@ func (m *protoMap) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
m.value.Range(func(key protoreflect.MapKey, val protoreflect.Value) bool {
ntvKey := key.Interface()
ntvVal := val.Interface()
- switch ntvVal.(type) {
+ switch pv := ntvVal.(type) {
case protoreflect.Message:
- ntvVal = ntvVal.(protoreflect.Message).Interface()
+ ntvVal = pv.Interface()
}
if keyType == otherKeyType && valType == otherValType {
mapVal.SetMapIndex(reflect.ValueOf(ntvKey), reflect.ValueOf(ntvVal))
@@ -732,6 +758,11 @@ func (m *protoMap) Get(key ref.Val) ref.Val {
return v
}
+// IsZeroValue returns true if the map is empty.
+func (m *protoMap) IsZeroValue() bool {
+ return m.value.Len() == 0
+}
+
// Iterator implements the traits.Iterable interface method.
func (m *protoMap) Iterator() traits.Iterator {
// Copy the keys to make their order stable.
@@ -758,7 +789,7 @@ func (m *protoMap) Type() ref.Type {
}
// Value implements the ref.Val interface method.
-func (m *protoMap) Value() interface{} {
+func (m *protoMap) Value() any {
return m.value
}
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 3d3503c275..38927a112c 100644
--- a/vendor/github.com/google/cel-go/common/types/null.go
+++ b/vendor/github.com/google/cel-go/common/types/null.go
@@ -18,9 +18,10 @@ import (
"fmt"
"reflect"
- "github.com/google/cel-go/common/types/ref"
"google.golang.org/protobuf/proto"
+ "github.com/google/cel-go/common/types/ref"
+
anypb "google.golang.org/protobuf/types/known/anypb"
structpb "google.golang.org/protobuf/types/known/structpb"
)
@@ -34,14 +35,20 @@ var (
// NullValue singleton.
NullValue = Null(structpb.NullValue_NULL_VALUE)
- jsonNullType = reflect.TypeOf(structpb.NullValue_NULL_VALUE)
+ // golang reflect type for Null values.
+ nullReflectType = reflect.TypeOf(NullValue)
)
// ConvertToNative implements ref.Val.ConvertToNative.
-func (n Null) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
+func (n Null) ConvertToNative(typeDesc reflect.Type) (any, error) {
switch typeDesc.Kind() {
case reflect.Int32:
- return reflect.ValueOf(n).Convert(typeDesc).Interface(), nil
+ switch typeDesc {
+ case jsonNullType:
+ return structpb.NullValue_NULL_VALUE, nil
+ case nullReflectType:
+ return n, nil
+ }
case reflect.Ptr:
switch typeDesc {
case anyValueType:
@@ -54,6 +61,10 @@ func (n Null) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
return anypb.New(pb.(proto.Message))
case jsonValueType:
return structpb.NewNullValue(), nil
+ case boolWrapperType, byteWrapperType, doubleWrapperType, floatWrapperType,
+ int32WrapperType, int64WrapperType, stringWrapperType, uint32WrapperType,
+ uint64WrapperType:
+ return nil, nil
}
case reflect.Interface:
nv := n.Value()
@@ -86,12 +97,17 @@ func (n Null) Equal(other ref.Val) ref.Val {
return Bool(NullType == other.Type())
}
+// IsZeroValue returns true as null always represents an absent value.
+func (n Null) IsZeroValue() bool {
+ return true
+}
+
// Type implements ref.Val.Type.
func (n Null) Type() ref.Type {
return NullType
}
// Value implements ref.Val.Value.
-func (n Null) Value() interface{} {
+func (n Null) Value() any {
return structpb.NullValue_NULL_VALUE
}
diff --git a/vendor/github.com/google/cel-go/common/types/object.go b/vendor/github.com/google/cel-go/common/types/object.go
index 5faf855110..9955e2dce5 100644
--- a/vendor/github.com/google/cel-go/common/types/object.go
+++ b/vendor/github.com/google/cel-go/common/types/object.go
@@ -18,11 +18,12 @@ import (
"fmt"
"reflect"
- "github.com/google/cel-go/common/types/pb"
- "github.com/google/cel-go/common/types/ref"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
+ "github.com/google/cel-go/common/types/pb"
+ "github.com/google/cel-go/common/types/ref"
+
anypb "google.golang.org/protobuf/types/known/anypb"
structpb "google.golang.org/protobuf/types/known/structpb"
)
@@ -52,7 +53,7 @@ func NewObject(adapter ref.TypeAdapter,
typeValue: typeValue}
}
-func (o *protoObj) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
+func (o *protoObj) ConvertToNative(typeDesc reflect.Type) (any, error) {
srcPB := o.value
if reflect.TypeOf(srcPB).AssignableTo(typeDesc) {
return srcPB, nil
@@ -133,6 +134,11 @@ func (o *protoObj) IsSet(field ref.Val) ref.Val {
return False
}
+// IsZeroValue returns true if the protobuf object is empty.
+func (o *protoObj) IsZeroValue() bool {
+ return proto.Equal(o.value, o.typeDesc.Zero())
+}
+
func (o *protoObj) Get(index ref.Val) ref.Val {
protoFieldName, ok := index.(String)
if !ok {
@@ -154,6 +160,6 @@ func (o *protoObj) Type() ref.Type {
return o.typeValue
}
-func (o *protoObj) Value() interface{} {
+func (o *protoObj) Value() any {
return o.value
}
diff --git a/vendor/github.com/google/cel-go/common/types/optional.go b/vendor/github.com/google/cel-go/common/types/optional.go
new file mode 100644
index 0000000000..54cb35b1ab
--- /dev/null
+++ b/vendor/github.com/google/cel-go/common/types/optional.go
@@ -0,0 +1,108 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+
+ "github.com/google/cel-go/common/types/ref"
+)
+
+var (
+ // OptionalType indicates the runtime type of an optional value.
+ OptionalType = NewTypeValue("optional")
+
+ // OptionalNone is a sentinel value which is used to indicate an empty optional value.
+ OptionalNone = &Optional{}
+)
+
+// OptionalOf returns an optional value which wraps a concrete CEL value.
+func OptionalOf(value ref.Val) *Optional {
+ return &Optional{value: value}
+}
+
+// Optional value which points to a value if non-empty.
+type Optional struct {
+ value ref.Val
+}
+
+// HasValue returns true if the optional has a value.
+func (o *Optional) HasValue() bool {
+ return o.value != nil
+}
+
+// GetValue returns the wrapped value contained in the optional.
+func (o *Optional) GetValue() ref.Val {
+ if !o.HasValue() {
+ return NewErr("optional.none() dereference")
+ }
+ return o.value
+}
+
+// ConvertToNative implements the ref.Val interface method.
+func (o *Optional) ConvertToNative(typeDesc reflect.Type) (any, error) {
+ if !o.HasValue() {
+ return nil, errors.New("optional.none() dereference")
+ }
+ return o.value.ConvertToNative(typeDesc)
+}
+
+// ConvertToType implements the ref.Val interface method.
+func (o *Optional) ConvertToType(typeVal ref.Type) ref.Val {
+ switch typeVal {
+ case OptionalType:
+ return o
+ case TypeType:
+ return OptionalType
+ }
+ return NewErr("type conversion error from '%s' to '%s'", OptionalType, typeVal)
+}
+
+// Equal determines whether the values contained by two optional values are equal.
+func (o *Optional) Equal(other ref.Val) ref.Val {
+ otherOpt, isOpt := other.(*Optional)
+ if !isOpt {
+ return False
+ }
+ if !o.HasValue() {
+ return Bool(!otherOpt.HasValue())
+ }
+ if !otherOpt.HasValue() {
+ return False
+ }
+ return o.value.Equal(otherOpt.value)
+}
+
+func (o *Optional) String() string {
+ if o.HasValue() {
+ return fmt.Sprintf("optional(%v)", o.GetValue())
+ }
+ return "optional.none()"
+}
+
+// Type implements the ref.Val interface method.
+func (o *Optional) Type() ref.Type {
+ return OptionalType
+}
+
+// Value returns the underlying 'Value()' of the wrapped value, if present.
+func (o *Optional) Value() any {
+ if o.value == nil {
+ return nil
+ }
+ return o.value.Value()
+}
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 f23ac9c0e2..e2b9d37b56 100644
--- a/vendor/github.com/google/cel-go/common/types/pb/BUILD.bazel
+++ b/vendor/github.com/google/cel-go/common/types/pb/BUILD.bazel
@@ -17,7 +17,7 @@ go_library(
],
importpath = "github.com/google/cel-go/common/types/pb",
deps = [
- "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
+ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
"@org_golang_google_protobuf//encoding/protowire:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
"@org_golang_google_protobuf//reflect/protoreflect:go_default_library",
diff --git a/vendor/github.com/google/cel-go/common/types/pb/enum.go b/vendor/github.com/google/cel-go/common/types/pb/enum.go
index 4a26b5c7c3..09a1546308 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
@@ -18,9 +18,9 @@ import (
"google.golang.org/protobuf/reflect/protoreflect"
)
-// NewEnumValueDescription produces an enum value description with the fully qualified enum value
+// newEnumValueDescription produces an enum value description with the fully qualified enum value
// name and the enum value descriptor.
-func NewEnumValueDescription(name string, desc protoreflect.EnumValueDescriptor) *EnumValueDescription {
+func newEnumValueDescription(name string, desc protoreflect.EnumValueDescriptor) *EnumValueDescription {
return &EnumValueDescription{
enumValueName: name,
desc: desc,
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 0bcade75f9..e323afb1df 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
@@ -18,32 +18,66 @@ import (
"fmt"
"google.golang.org/protobuf/reflect/protoreflect"
+
+ dynamicpb "google.golang.org/protobuf/types/dynamicpb"
)
-// 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 protoreflect.FileDescriptor, pbdb *Db) *FileDescription {
+// newFileDescription returns a FileDescription instance with a complete listing of all the message
+// types and enum values, as well as a map of extensions declared within any scope in the file.
+func newFileDescription(fileDesc protoreflect.FileDescriptor, pbdb *Db) (*FileDescription, extensionMap) {
metadata := collectFileMetadata(fileDesc)
enums := make(map[string]*EnumValueDescription)
for name, enumVal := range metadata.enumValues {
- enums[name] = NewEnumValueDescription(name, enumVal)
+ enums[name] = newEnumValueDescription(name, enumVal)
}
types := make(map[string]*TypeDescription)
for name, msgType := range metadata.msgTypes {
- types[name] = NewTypeDescription(name, msgType)
+ types[name] = newTypeDescription(name, msgType, pbdb.extensions)
+ }
+ fileExtMap := make(extensionMap)
+ for typeName, extensions := range metadata.msgExtensionMap {
+ messageExtMap, found := fileExtMap[typeName]
+ if !found {
+ messageExtMap = make(map[string]*FieldDescription)
+ }
+ for _, ext := range extensions {
+ extDesc := dynamicpb.NewExtensionType(ext).TypeDescriptor()
+ messageExtMap[string(ext.FullName())] = newFieldDescription(extDesc)
+ }
+ fileExtMap[typeName] = messageExtMap
}
return &FileDescription{
+ name: fileDesc.Path(),
types: types,
enums: enums,
- }
+ }, fileExtMap
}
// FileDescription holds a map of all types and enum values declared within a proto file.
type FileDescription struct {
+ name string
types map[string]*TypeDescription
enums map[string]*EnumValueDescription
}
+// Copy creates a copy of the FileDescription with updated Db references within its types.
+func (fd *FileDescription) Copy(pbdb *Db) *FileDescription {
+ typesCopy := make(map[string]*TypeDescription, len(fd.types))
+ for k, v := range fd.types {
+ typesCopy[k] = v.Copy(pbdb)
+ }
+ return &FileDescription{
+ name: fd.name,
+ types: typesCopy,
+ enums: fd.enums,
+ }
+}
+
+// GetName returns the fully qualified file path for the file.
+func (fd *FileDescription) GetName() string {
+ return fd.name
+}
+
// GetEnumDescription returns an EnumDescription for a qualified enum value
// name declared within the .proto file.
func (fd *FileDescription) GetEnumDescription(enumName string) (*EnumValueDescription, bool) {
@@ -94,6 +128,10 @@ type fileMetadata struct {
msgTypes map[string]protoreflect.MessageDescriptor
// enumValues maps from fully-qualified enum value to enum value descriptor.
enumValues map[string]protoreflect.EnumValueDescriptor
+ // msgExtensionMap maps from the protobuf message name being extended to a set of extensions
+ // for the type.
+ msgExtensionMap map[string][]protoreflect.ExtensionDescriptor
+
// TODO: support enum type definitions for use in future type-check enhancements.
}
@@ -102,28 +140,38 @@ type fileMetadata struct {
func collectFileMetadata(fileDesc protoreflect.FileDescriptor) *fileMetadata {
msgTypes := make(map[string]protoreflect.MessageDescriptor)
enumValues := make(map[string]protoreflect.EnumValueDescriptor)
- collectMsgTypes(fileDesc.Messages(), msgTypes, enumValues)
+ msgExtensionMap := make(map[string][]protoreflect.ExtensionDescriptor)
+ collectMsgTypes(fileDesc.Messages(), msgTypes, enumValues, msgExtensionMap)
collectEnumValues(fileDesc.Enums(), enumValues)
+ collectExtensions(fileDesc.Extensions(), msgExtensionMap)
return &fileMetadata{
- msgTypes: msgTypes,
- enumValues: enumValues,
+ msgTypes: msgTypes,
+ enumValues: enumValues,
+ msgExtensionMap: msgExtensionMap,
}
}
// 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) {
+func collectMsgTypes(msgTypes protoreflect.MessageDescriptors,
+ msgTypeMap map[string]protoreflect.MessageDescriptor,
+ enumValueMap map[string]protoreflect.EnumValueDescriptor,
+ msgExtensionMap map[string][]protoreflect.ExtensionDescriptor) {
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)
+ collectMsgTypes(nestedMsgTypes, msgTypeMap, enumValueMap, msgExtensionMap)
}
nestedEnumTypes := msgType.Enums()
if nestedEnumTypes.Len() != 0 {
collectEnumValues(nestedEnumTypes, enumValueMap)
}
+ nestedExtensions := msgType.Extensions()
+ if nestedExtensions.Len() != 0 {
+ collectExtensions(nestedExtensions, msgExtensionMap)
+ }
}
}
@@ -139,3 +187,16 @@ func collectEnumValues(enumTypes protoreflect.EnumDescriptors, enumValueMap map[
}
}
}
+
+func collectExtensions(extensions protoreflect.ExtensionDescriptors, msgExtensionMap map[string][]protoreflect.ExtensionDescriptor) {
+ for i := 0; i < extensions.Len(); i++ {
+ ext := extensions.Get(i)
+ extendsMsg := string(ext.ContainingMessage().FullName())
+ msgExts, found := msgExtensionMap[extendsMsg]
+ if !found {
+ msgExts = []protoreflect.ExtensionDescriptor{}
+ }
+ msgExts = append(msgExts, ext)
+ msgExtensionMap[extendsMsg] = msgExts
+ }
+}
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 457b47ceee..eadebcb04e 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
@@ -40,13 +40,19 @@ type Db struct {
revFileDescriptorMap map[string]*FileDescription
// files contains the deduped set of FileDescriptions whose types are contained in the pb.Db.
files []*FileDescription
+ // extensions contains the mapping between a given type name, extension name and its FieldDescription
+ extensions map[string]map[string]*FieldDescription
}
+// extensionsMap is a type alias to a map[typeName]map[extensionName]*FieldDescription
+type extensionMap = map[string]map[string]*FieldDescription
+
var (
// DefaultDb used at evaluation time or unless overridden at check time.
DefaultDb = &Db{
revFileDescriptorMap: make(map[string]*FileDescription),
files: []*FileDescription{},
+ extensions: make(extensionMap),
}
)
@@ -80,6 +86,7 @@ func NewDb() *Db {
pbdb := &Db{
revFileDescriptorMap: make(map[string]*FileDescription),
files: []*FileDescription{},
+ extensions: make(extensionMap),
}
// 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
@@ -96,19 +103,34 @@ func NewDb() *Db {
// Copy creates a copy of the current database with its own internal descriptor mapping.
func (pbdb *Db) Copy() *Db {
copy := NewDb()
- for k, v := range pbdb.revFileDescriptorMap {
- copy.revFileDescriptorMap[k] = v
- }
- for _, f := range pbdb.files {
+ for _, fd := range pbdb.files {
hasFile := false
- for _, f2 := range copy.files {
- if f2 == f {
+ for _, fd2 := range copy.files {
+ if fd2 == fd {
hasFile = true
}
}
if !hasFile {
- copy.files = append(copy.files, f)
+ fd = fd.Copy(copy)
+ copy.files = append(copy.files, fd)
+ }
+ for _, enumValName := range fd.GetEnumNames() {
+ copy.revFileDescriptorMap[enumValName] = fd
+ }
+ for _, msgTypeName := range fd.GetTypeNames() {
+ copy.revFileDescriptorMap[msgTypeName] = fd
+ }
+ copy.revFileDescriptorMap[fd.GetName()] = fd
+ }
+ for typeName, extFieldMap := range pbdb.extensions {
+ copyExtFieldMap, found := copy.extensions[typeName]
+ if !found {
+ copyExtFieldMap = make(map[string]*FieldDescription, len(extFieldMap))
}
+ for extFieldName, fd := range extFieldMap {
+ copyExtFieldMap[extFieldName] = fd
+ }
+ copy.extensions[typeName] = copyExtFieldMap
}
return copy
}
@@ -137,17 +159,30 @@ func (pbdb *Db) RegisterDescriptor(fileDesc protoreflect.FileDescriptor) (*FileD
if err == nil {
fileDesc = globalFD
}
- fd = NewFileDescription(fileDesc, pbdb)
+ var fileExtMap extensionMap
+ fd, fileExtMap = newFileDescription(fileDesc, pbdb)
for _, enumValName := range fd.GetEnumNames() {
pbdb.revFileDescriptorMap[enumValName] = fd
}
for _, msgTypeName := range fd.GetTypeNames() {
pbdb.revFileDescriptorMap[msgTypeName] = fd
}
- pbdb.revFileDescriptorMap[fileDesc.Path()] = fd
+ pbdb.revFileDescriptorMap[fd.GetName()] = fd
// Return the specific file descriptor registered.
pbdb.files = append(pbdb.files, fd)
+
+ // Index the protobuf message extensions from the file into the pbdb
+ for typeName, extMap := range fileExtMap {
+ typeExtMap, found := pbdb.extensions[typeName]
+ if !found {
+ pbdb.extensions[typeName] = extMap
+ continue
+ }
+ for extName, field := range extMap {
+ typeExtMap[extName] = field
+ }
+ }
return fd, nil
}
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 912076fa48..df9532156a 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
@@ -38,22 +38,23 @@ type description interface {
Zero() proto.Message
}
-// NewTypeDescription produces a TypeDescription value for the fully-qualified proto type name
+// newTypeDescription produces a TypeDescription value for the fully-qualified proto type name
// with a given descriptor.
-func NewTypeDescription(typeName string, desc protoreflect.MessageDescriptor) *TypeDescription {
+func newTypeDescription(typeName string, desc protoreflect.MessageDescriptor, extensions extensionMap) *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)
+ fieldMap[string(f.Name())] = newFieldDescription(f)
}
return &TypeDescription{
typeName: typeName,
desc: desc,
msgType: msgType,
fieldMap: fieldMap,
+ extensions: extensions,
reflectType: reflectTypeOf(msgZero),
zeroMsg: zeroValueOf(msgZero),
}
@@ -66,10 +67,24 @@ type TypeDescription struct {
desc protoreflect.MessageDescriptor
msgType protoreflect.MessageType
fieldMap map[string]*FieldDescription
+ extensions extensionMap
reflectType reflect.Type
zeroMsg proto.Message
}
+// Copy copies the type description with updated references to the Db.
+func (td *TypeDescription) Copy(pbdb *Db) *TypeDescription {
+ return &TypeDescription{
+ typeName: td.typeName,
+ desc: td.desc,
+ msgType: td.msgType,
+ fieldMap: td.fieldMap,
+ extensions: pbdb.extensions,
+ reflectType: td.reflectType,
+ zeroMsg: td.zeroMsg,
+ }
+}
+
// FieldMap returns a string field name to FieldDescription map.
func (td *TypeDescription) FieldMap() map[string]*FieldDescription {
return td.fieldMap
@@ -78,16 +93,21 @@ func (td *TypeDescription) FieldMap() map[string]*FieldDescription {
// 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 fd, true
+ }
+ extFieldMap, found := td.extensions[td.typeName]
if !found {
return nil, false
}
- return fd, true
+ fd, found = extFieldMap[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, error) {
+func (td *TypeDescription) MaybeUnwrap(msg proto.Message) (any, bool, error) {
return unwrap(td, msg)
}
@@ -111,8 +131,8 @@ func (td *TypeDescription) Zero() proto.Message {
return td.zeroMsg
}
-// NewFieldDescription creates a new field description from a protoreflect.FieldDescriptor.
-func NewFieldDescription(fieldDesc protoreflect.FieldDescriptor) *FieldDescription {
+// 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() {
@@ -124,9 +144,17 @@ func NewFieldDescription(fieldDesc protoreflect.FieldDescriptor) *FieldDescripti
default:
reflectType = reflectTypeOf(fieldDesc.Default().Interface())
if fieldDesc.IsList() {
- parentMsg := dynamicpb.NewMessage(fieldDesc.ContainingMessage())
- listField := parentMsg.NewField(fieldDesc).List()
- elem := listField.NewElement().Interface()
+ var elemValue protoreflect.Value
+ if fieldDesc.IsExtension() {
+ et := dynamicpb.NewExtensionType(fieldDesc)
+ elemValue = et.New().List().NewElement()
+ } else {
+ parentMsgType := fieldDesc.ContainingMessage()
+ parentMsg := dynamicpb.NewMessage(parentMsgType)
+ listField := parentMsg.NewField(fieldDesc).List()
+ elemValue = listField.NewElement()
+ }
+ elem := elemValue.Interface()
switch elemType := elem.(type) {
case protoreflect.Message:
elem = elemType.Interface()
@@ -140,8 +168,8 @@ func NewFieldDescription(fieldDesc protoreflect.FieldDescriptor) *FieldDescripti
}
var keyType, valType *FieldDescription
if fieldDesc.IsMap() {
- keyType = NewFieldDescription(fieldDesc.MapKey())
- valType = NewFieldDescription(fieldDesc.MapValue())
+ keyType = newFieldDescription(fieldDesc.MapKey())
+ valType = newFieldDescription(fieldDesc.MapValue())
}
return &FieldDescription{
desc: fieldDesc,
@@ -195,7 +223,7 @@ func (fd *FieldDescription) Descriptor() protoreflect.FieldDescriptor {
//
// 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 {
+func (fd *FieldDescription) IsSet(target any) bool {
switch v := target.(type) {
case proto.Message:
pbRef := v.ProtoReflect()
@@ -219,14 +247,14 @@ func (fd *FieldDescription) IsSet(target interface{}) bool {
//
// 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) {
+func (fd *FieldDescription) GetFrom(target any) (any, error) {
v, ok := target.(proto.Message)
if !ok {
return nil, fmt.Errorf("unsupported field selection target: (%T)%v", target, target)
}
pbRef := v.ProtoReflect()
pbDesc := pbRef.Descriptor()
- var fieldVal interface{}
+ var fieldVal any
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.
@@ -289,7 +317,7 @@ func (fd *FieldDescription) IsList() bool {
//
// 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, error) {
+func (fd *FieldDescription) MaybeUnwrapDynamic(msg protoreflect.Message) (any, bool, error) {
return unwrapDynamic(fd, msg)
}
@@ -362,7 +390,7 @@ func checkedWrap(t *exprpb.Type) *exprpb.Type {
// 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, error) {
+func unwrap(desc description, msg proto.Message) (any, bool, error) {
switch v := msg.(type) {
case *anypb.Any:
dynMsg, err := v.UnmarshalNew()
@@ -418,7 +446,7 @@ func unwrap(desc description, msg proto.Message) (interface{}, bool, error) {
// 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, error) {
+func unwrapDynamic(desc description, refMsg protoreflect.Message) (any, bool, error) {
msg := refMsg.Interface()
if !refMsg.IsValid() {
msg = desc.Zero()
@@ -508,7 +536,7 @@ func unwrapDynamic(desc description, refMsg protoreflect.Message) (interface{},
// 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 {
+func reflectTypeOf(val any) reflect.Type {
switch v := val.(type) {
case proto.Message:
return reflect.TypeOf(zeroValueOf(v))
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 02087d14e3..e66951f5b2 100644
--- a/vendor/github.com/google/cel-go/common/types/provider.go
+++ b/vendor/github.com/google/cel-go/common/types/provider.go
@@ -19,11 +19,12 @@ import (
"reflect"
"time"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/reflect/protoreflect"
+
"github.com/google/cel-go/common/types/pb"
"github.com/google/cel-go/common/types/ref"
"github.com/google/cel-go/common/types/traits"
- "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"
@@ -195,7 +196,7 @@ func (p *protoTypeRegistry) RegisterType(types ...ref.Type) error {
// providing support for custom proto-based types.
//
// This method should be the inverse of ref.Val.ConvertToNative.
-func (p *protoTypeRegistry) NativeToValue(value interface{}) ref.Val {
+func (p *protoTypeRegistry) NativeToValue(value any) ref.Val {
if val, found := nativeToValue(p, value); found {
return val
}
@@ -249,7 +250,7 @@ var (
)
// NativeToValue implements the ref.TypeAdapter interface.
-func (a *defaultTypeAdapter) NativeToValue(value interface{}) ref.Val {
+func (a *defaultTypeAdapter) NativeToValue(value any) ref.Val {
if val, found := nativeToValue(a, value); found {
return val
}
@@ -258,7 +259,7 @@ func (a *defaultTypeAdapter) NativeToValue(value interface{}) ref.Val {
// 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) {
+func nativeToValue(a ref.TypeAdapter, value any) (ref.Val, bool) {
switch v := value.(type) {
case nil:
return NullValue, true
@@ -364,7 +365,7 @@ func nativeToValue(a ref.TypeAdapter, value interface{}) (ref.Val, bool) {
// specializations for common map types.
case map[string]string:
return NewStringStringMap(a, v), true
- case map[string]interface{}:
+ case map[string]any:
return NewStringInterfaceMap(a, v), true
case map[ref.Val]ref.Val:
return NewRefValMap(a, v), true
@@ -479,9 +480,12 @@ func msgSetField(target protoreflect.Message, field *pb.FieldDescription, val re
if err != nil {
return fieldTypeConversionError(field, err)
}
- switch v.(type) {
+ if v == nil {
+ return nil
+ }
+ switch pv := v.(type) {
case proto.Message:
- v = v.(proto.Message).ProtoReflect()
+ v = pv.ProtoReflect()
}
target.Set(field.Descriptor(), protoreflect.ValueOf(v))
return nil
@@ -495,6 +499,9 @@ func msgSetListField(target protoreflect.List, listField *pb.FieldDescription, l
if err != nil {
return fieldTypeConversionError(listField, err)
}
+ if elemVal == nil {
+ continue
+ }
switch ev := elemVal.(type) {
case proto.Message:
elemVal = ev.ProtoReflect()
@@ -519,9 +526,12 @@ func msgSetMapField(target protoreflect.Map, mapField *pb.FieldDescription, mapV
if err != nil {
return fieldTypeConversionError(mapField, err)
}
- switch v.(type) {
+ if v == nil {
+ continue
+ }
+ switch pv := v.(type) {
case proto.Message:
- v = v.(proto.Message).ProtoReflect()
+ v = pv.ProtoReflect()
}
target.Set(protoreflect.ValueOf(k).MapKey(), protoreflect.ValueOf(v))
}
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 1d0f468993..79330c3321 100644
--- a/vendor/github.com/google/cel-go/common/types/ref/BUILD.bazel
+++ b/vendor/github.com/google/cel-go/common/types/ref/BUILD.bazel
@@ -13,7 +13,7 @@ go_library(
],
importpath = "github.com/google/cel-go/common/types/ref",
deps = [
- "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
+ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
"@org_golang_google_protobuf//reflect/protoreflect:go_default_library",
],
diff --git a/vendor/github.com/google/cel-go/common/types/ref/provider.go b/vendor/github.com/google/cel-go/common/types/ref/provider.go
index 91a711fa70..7eabbb9ca3 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
@@ -39,8 +39,6 @@ type TypeProvider interface {
// FieldFieldType returns the field type for a checked type value. Returns
// false if the field could not be found.
- //
- // Used during type-checking only.
FindFieldType(messageType string, fieldName string) (*FieldType, bool)
// NewValue creates a new type value from a qualified name and map of field
@@ -55,7 +53,7 @@ type TypeProvider interface {
// TypeAdapter converts native Go values of varying type and complexity to equivalent CEL values.
type TypeAdapter interface {
// NativeToValue converts the input `value` to a CEL `ref.Val`.
- NativeToValue(value interface{}) Val
+ NativeToValue(value any) Val
}
// TypeRegistry allows third-parties to add custom types to CEL. Not all `TypeProvider`
@@ -97,7 +95,7 @@ type FieldType struct {
}
// FieldTester is used to test field presence on an input object.
-type FieldTester func(target interface{}) bool
+type FieldTester func(target any) bool
// FieldGetter is used to get the field value from an input object, if set.
-type FieldGetter func(target interface{}) (interface{}, error)
+type FieldGetter func(target any) (any, error)
diff --git a/vendor/github.com/google/cel-go/common/types/ref/reference.go b/vendor/github.com/google/cel-go/common/types/ref/reference.go
index 3098580c91..e0d58145cd 100644
--- a/vendor/github.com/google/cel-go/common/types/ref/reference.go
+++ b/vendor/github.com/google/cel-go/common/types/ref/reference.go
@@ -37,9 +37,18 @@ type Type interface {
type Val interface {
// ConvertToNative converts the Value to a native Go struct according to the
// reflected type description, or error if the conversion is not feasible.
- ConvertToNative(typeDesc reflect.Type) (interface{}, error)
+ //
+ // The ConvertToNative method is intended to be used to support conversion between CEL types
+ // and native types during object creation expressions or by clients who need to adapt the,
+ // returned CEL value into an equivalent Go value instance.
+ //
+ // When implementing or using ConvertToNative, the following guidelines apply:
+ // - Use ConvertToNative when marshalling CEL evaluation results to native types.
+ // - Do not use ConvertToNative within CEL extension functions.
+ // - Document whether your implementation supports non-CEL field types, such as Go or Protobuf.
+ ConvertToNative(typeDesc reflect.Type) (any, error)
- // ConvertToType supports type conversions between value types supported by the expression language.
+ // ConvertToType supports type conversions between CEL value types supported by the expression language.
ConvertToType(typeValue Type) Val
// Equal returns true if the `other` value has the same type and content as the implementing struct.
@@ -50,5 +59,5 @@ type Val interface {
// Value returns the raw value of the instance which may not be directly compatible with the expression
// language types.
- Value() interface{}
+ Value() any
}
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 b6d665683c..a65cc14e4c 100644
--- a/vendor/github.com/google/cel-go/common/types/string.go
+++ b/vendor/github.com/google/cel-go/common/types/string.go
@@ -72,7 +72,7 @@ func (s String) Compare(other ref.Val) ref.Val {
}
// ConvertToNative implements ref.Val.ConvertToNative.
-func (s String) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
+func (s String) ConvertToNative(typeDesc reflect.Type) (any, error) {
switch typeDesc.Kind() {
case reflect.String:
if reflect.TypeOf(s).AssignableTo(typeDesc) {
@@ -154,6 +154,11 @@ func (s String) Equal(other ref.Val) ref.Val {
return Bool(ok && s == otherString)
}
+// IsZeroValue returns true if the string is empty.
+func (s String) IsZeroValue() bool {
+ return len(s) == 0
+}
+
// Match implements traits.Matcher.Match.
func (s String) Match(pattern ref.Val) ref.Val {
pat, ok := pattern.(String)
@@ -189,7 +194,7 @@ func (s String) Type() ref.Type {
}
// Value implements ref.Val.Value.
-func (s String) Value() interface{} {
+func (s String) Value() any {
return string(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 7513a1b210..c784f2e54b 100644
--- a/vendor/github.com/google/cel-go/common/types/timestamp.go
+++ b/vendor/github.com/google/cel-go/common/types/timestamp.go
@@ -89,7 +89,7 @@ func (t Timestamp) Compare(other ref.Val) ref.Val {
}
// ConvertToNative implements ref.Val.ConvertToNative.
-func (t Timestamp) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
+func (t Timestamp) ConvertToNative(typeDesc reflect.Type) (any, error) {
// If the timestamp is already assignable to the desired type return it.
if reflect.TypeOf(t.Time).AssignableTo(typeDesc) {
return t.Time, nil
@@ -138,6 +138,11 @@ func (t Timestamp) Equal(other ref.Val) ref.Val {
return Bool(ok && t.Time.Equal(otherTime.Time))
}
+// IsZeroValue returns true if the timestamp is epoch 0.
+func (t Timestamp) IsZeroValue() bool {
+ return t.IsZero()
+}
+
// Receive implements traits.Receiver.Receive.
func (t Timestamp) Receive(function string, overload string, args []ref.Val) ref.Val {
switch len(args) {
@@ -160,14 +165,14 @@ func (t Timestamp) Subtract(subtrahend ref.Val) ref.Val {
dur := subtrahend.(Duration)
val, err := subtractTimeDurationChecked(t.Time, dur.Duration)
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return timestampOf(val)
case TimestampType:
t2 := subtrahend.(Timestamp).Time
val, err := subtractTimeChecked(t.Time, t2)
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return durationOf(val)
}
@@ -180,7 +185,7 @@ func (t Timestamp) Type() ref.Type {
}
// Value implements ref.Val.Value.
-func (t Timestamp) Value() interface{} {
+func (t Timestamp) Value() any {
return t.Time
}
@@ -288,7 +293,7 @@ func timeZone(tz ref.Val, visitor timestampVisitor) timestampVisitor {
if ind == -1 {
loc, err := time.LoadLocation(val)
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return visitor(t.In(loc))
}
@@ -297,11 +302,11 @@ func timeZone(tz ref.Val, visitor timestampVisitor) timestampVisitor {
// in the format ^(+|-)(0[0-9]|1[0-4]):[0-5][0-9]$. The numerical input is parsed in terms of hours and minutes.
hr, err := strconv.Atoi(string(val[0:ind]))
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
min, err := strconv.Atoi(string(val[ind+1:]))
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
var offset int
if string(val[0]) == "-" {
diff --git a/vendor/github.com/google/cel-go/common/types/traits/BUILD.bazel b/vendor/github.com/google/cel-go/common/types/traits/BUILD.bazel
index 86e54af61a..b19eb8301e 100644
--- a/vendor/github.com/google/cel-go/common/types/traits/BUILD.bazel
+++ b/vendor/github.com/google/cel-go/common/types/traits/BUILD.bazel
@@ -20,6 +20,7 @@ go_library(
"receiver.go",
"sizer.go",
"traits.go",
+ "zeroer.go",
],
importpath = "github.com/google/cel-go/common/types/traits",
deps = [
diff --git a/vendor/github.com/google/cel-go/interpreter/coster.go b/vendor/github.com/google/cel-go/common/types/traits/zeroer.go
similarity index 50%
rename from vendor/github.com/google/cel-go/interpreter/coster.go
rename to vendor/github.com/google/cel-go/common/types/traits/zeroer.go
index ac573d5745..0b7c830a24 100644
--- a/vendor/github.com/google/cel-go/interpreter/coster.go
+++ b/vendor/github.com/google/cel-go/common/types/traits/zeroer.go
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,24 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package interpreter
+package traits
-import "math"
-
-// TODO: remove Coster.
-
-// Coster calculates the heuristic cost incurred during evaluation.
-// Deprecated: Please migrate cel.EstimateCost, it supports length estimates for input data and cost estimates for
-// extension functions.
-type Coster interface {
- Cost() (min, max int64)
-}
-
-// estimateCost returns the heuristic cost interval for the program.
-func estimateCost(i interface{}) (min, max int64) {
- c, ok := i.(Coster)
- if !ok {
- return 0, math.MaxInt64
- }
- return c.Cost()
+// Zeroer interface for testing whether a CEL value is a zero value for its type.
+type Zeroer interface {
+ // IsZeroValue indicates whether the object is the zero value for the type.
+ IsZeroValue() bool
}
diff --git a/vendor/github.com/google/cel-go/common/types/type.go b/vendor/github.com/google/cel-go/common/types/type.go
index 21160974bb..164a460503 100644
--- a/vendor/github.com/google/cel-go/common/types/type.go
+++ b/vendor/github.com/google/cel-go/common/types/type.go
@@ -53,7 +53,7 @@ func NewObjectTypeValue(name string) *TypeValue {
}
// ConvertToNative implements ref.Val.ConvertToNative.
-func (t *TypeValue) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
+func (t *TypeValue) ConvertToNative(typeDesc reflect.Type) (any, error) {
// TODO: replace the internal type representation with a proto-value.
return nil, fmt.Errorf("type conversion not supported for 'type'")
}
@@ -97,6 +97,6 @@ func (t *TypeValue) TypeName() string {
}
// Value implements ref.Val.Value.
-func (t *TypeValue) Value() interface{} {
+func (t *TypeValue) Value() any {
return t.name
}
diff --git a/vendor/github.com/google/cel-go/common/types/uint.go b/vendor/github.com/google/cel-go/common/types/uint.go
index ca266e0457..615c7ec523 100644
--- a/vendor/github.com/google/cel-go/common/types/uint.go
+++ b/vendor/github.com/google/cel-go/common/types/uint.go
@@ -59,7 +59,7 @@ func (i Uint) Add(other ref.Val) ref.Val {
}
val, err := addUint64Checked(uint64(i), uint64(otherUint))
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return Uint(val)
}
@@ -82,7 +82,7 @@ func (i Uint) Compare(other ref.Val) ref.Val {
}
// ConvertToNative implements ref.Val.ConvertToNative.
-func (i Uint) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
+func (i Uint) ConvertToNative(typeDesc reflect.Type) (any, error) {
switch typeDesc.Kind() {
case reflect.Uint, reflect.Uint32:
v, err := uint64ToUint32Checked(uint64(i))
@@ -149,7 +149,7 @@ func (i Uint) ConvertToType(typeVal ref.Type) ref.Val {
case IntType:
v, err := uint64ToInt64Checked(uint64(i))
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return Int(v)
case UintType:
@@ -172,7 +172,7 @@ func (i Uint) Divide(other ref.Val) ref.Val {
}
div, err := divideUint64Checked(uint64(i), uint64(otherUint))
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return Uint(div)
}
@@ -194,6 +194,11 @@ func (i Uint) Equal(other ref.Val) ref.Val {
}
}
+// IsZeroValue returns true if the uint is zero.
+func (i Uint) IsZeroValue() bool {
+ return i == 0
+}
+
// Modulo implements traits.Modder.Modulo.
func (i Uint) Modulo(other ref.Val) ref.Val {
otherUint, ok := other.(Uint)
@@ -202,7 +207,7 @@ func (i Uint) Modulo(other ref.Val) ref.Val {
}
mod, err := moduloUint64Checked(uint64(i), uint64(otherUint))
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return Uint(mod)
}
@@ -215,7 +220,7 @@ func (i Uint) Multiply(other ref.Val) ref.Val {
}
val, err := multiplyUint64Checked(uint64(i), uint64(otherUint))
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return Uint(val)
}
@@ -228,7 +233,7 @@ func (i Uint) Subtract(subtrahend ref.Val) ref.Val {
}
val, err := subtractUint64Checked(uint64(i), uint64(subtraUint))
if err != nil {
- return wrapErr(err)
+ return WrapErr(err)
}
return Uint(val)
}
@@ -239,7 +244,7 @@ func (i Uint) Type() ref.Type {
}
// Value implements ref.Val.Value.
-func (i Uint) Value() interface{} {
+func (i Uint) Value() any {
return uint64(i)
}
diff --git a/vendor/github.com/google/cel-go/common/types/unknown.go b/vendor/github.com/google/cel-go/common/types/unknown.go
index 95b47426fd..bc411c15b9 100644
--- a/vendor/github.com/google/cel-go/common/types/unknown.go
+++ b/vendor/github.com/google/cel-go/common/types/unknown.go
@@ -30,7 +30,7 @@ var (
)
// ConvertToNative implements ref.Val.ConvertToNative.
-func (u Unknown) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
+func (u Unknown) ConvertToNative(typeDesc reflect.Type) (any, error) {
return u.Value(), nil
}
@@ -50,7 +50,7 @@ func (u Unknown) Type() ref.Type {
}
// Value implements ref.Val.Value.
-func (u Unknown) Value() interface{} {
+func (u Unknown) Value() any {
return []int64(u)
}
diff --git a/vendor/github.com/google/cel-go/ext/BUILD.bazel b/vendor/github.com/google/cel-go/ext/BUILD.bazel
index 9c2520b408..4bcf8a283e 100644
--- a/vendor/github.com/google/cel-go/ext/BUILD.bazel
+++ b/vendor/github.com/google/cel-go/ext/BUILD.bazel
@@ -9,14 +9,30 @@ go_library(
srcs = [
"encoders.go",
"guards.go",
+ "math.go",
+ "native.go",
+ "protos.go",
+ "sets.go",
"strings.go",
],
importpath = "github.com/google/cel-go/ext",
visibility = ["//visibility:public"],
deps = [
"//cel:go_default_library",
+ "//checker/decls:go_default_library",
+ "//common:go_default_library",
+ "//common/overloads:go_default_library",
"//common/types:go_default_library",
+ "//common/types/pb:go_default_library",
"//common/types/ref:go_default_library",
+ "//common/types/traits:go_default_library",
+ "//interpreter:go_default_library",
+ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
+ "@org_golang_google_protobuf//proto:go_default_library",
+ "@org_golang_google_protobuf//reflect/protoreflect:go_default_library",
+ "@org_golang_google_protobuf//types/known/structpb",
+ "@org_golang_x_text//language:go_default_library",
+ "@org_golang_x_text//message:go_default_library",
],
)
@@ -25,6 +41,10 @@ go_test(
size = "small",
srcs = [
"encoders_test.go",
+ "math_test.go",
+ "native_test.go",
+ "protos_test.go",
+ "sets_test.go",
"strings_test.go",
],
embed = [
@@ -32,5 +52,17 @@ go_test(
],
deps = [
"//cel:go_default_library",
+ "//checker:go_default_library",
+ "//common:go_default_library",
+ "//common/types:go_default_library",
+ "//common/types/ref:go_default_library",
+ "//common/types/traits:go_default_library",
+ "//test:go_default_library",
+ "//test/proto2pb:go_default_library",
+ "//test/proto3pb:go_default_library",
+ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
+ "@org_golang_google_protobuf//proto:go_default_library",
+ "@org_golang_google_protobuf//types/known/wrapperspb:go_default_library",
+ "@org_golang_google_protobuf//encoding/protojson:go_default_library",
],
)
diff --git a/vendor/github.com/google/cel-go/ext/README.md b/vendor/github.com/google/cel-go/ext/README.md
index 5ddcc41510..ef0eb2ab7f 100644
--- a/vendor/github.com/google/cel-go/ext/README.md
+++ b/vendor/github.com/google/cel-go/ext/README.md
@@ -3,6 +3,30 @@
CEL extensions are a related set of constants, functions, macros, or other
features which may not be covered by the core CEL spec.
+## Bindings
+
+Returns a cel.EnvOption to configure support for local variable bindings
+in expressions.
+
+# Cel.Bind
+
+Binds a simple identifier to an initialization expression which may be used
+in a subsequenct result expression. Bindings may also be nested within each
+other.
+
+ cel.bind(, , )
+
+Examples:
+
+ cel.bind(a, 'hello',
+ cel.bind(b, 'world', a + b + b + a)) // "helloworldworldhello"
+
+ // Avoid a list allocation within the exists comprehension.
+ cel.bind(valid_values, [a, b, c],
+ [d, e, f].exists(elem, elem in valid_values))
+
+Local bindings are not guaranteed to be evaluated before use.
+
## Encoders
Encoding utilies for marshalling data into standardized representations.
@@ -31,6 +55,156 @@ Example:
base64.encode(b'hello') // return 'aGVsbG8='
+## Math
+
+Math helper macros and functions.
+
+Note, all macros use the 'math' namespace; however, at the time of macro
+expansion the namespace looks just like any other identifier. If you are
+currently using a variable named 'math', the macro will likely work just as
+intended; however, there is some chance for collision.
+
+### Math.Greatest
+
+Returns the greatest valued number present in the arguments to the macro.
+
+Greatest is a variable argument count macro which must take at least one
+argument. Simple numeric and list literals are supported as valid argument
+types; however, other literals will be flagged as errors during macro
+expansion. If the argument expression does not resolve to a numeric or
+list(numeric) type during type-checking, or during runtime then an error
+will be produced. If a list argument is empty, this too will produce an
+error.
+
+ math.greatest(, ...) ->
+
+Examples:
+
+ math.greatest(1) // 1
+ math.greatest(1u, 2u) // 2u
+ math.greatest(-42.0, -21.5, -100.0) // -21.5
+ math.greatest([-42.0, -21.5, -100.0]) // -21.5
+ math.greatest(numbers) // numbers must be list(numeric)
+
+ math.greatest() // parse error
+ math.greatest('string') // parse error
+ math.greatest(a, b) // check-time error if a or b is non-numeric
+ math.greatest(dyn('string')) // runtime error
+
+### Math.Least
+
+Returns the least valued number present in the arguments to the macro.
+
+Least is a variable argument count macro which must take at least one
+argument. Simple numeric and list literals are supported as valid argument
+types; however, other literals will be flagged as errors during macro
+expansion. If the argument expression does not resolve to a numeric or
+list(numeric) type during type-checking, or during runtime then an error
+will be produced. If a list argument is empty, this too will produce an error.
+
+ math.least(, ...) ->
+
+Examples:
+
+ math.least(1) // 1
+ math.least(1u, 2u) // 1u
+ math.least(-42.0, -21.5, -100.0) // -100.0
+ math.least([-42.0, -21.5, -100.0]) // -100.0
+ math.least(numbers) // numbers must be list(numeric)
+
+ math.least() // parse error
+ math.least('string') // parse error
+ math.least(a, b) // check-time error if a or b is non-numeric
+ math.least(dyn('string')) // runtime error
+
+## Protos
+
+Protos configure extended macros and functions for proto manipulation.
+
+Note, all macros use the 'proto' namespace; however, at the time of macro
+expansion the namespace looks just like any other identifier. If you are
+currently using a variable named 'proto', the macro will likely work just as
+you intend; however, there is some chance for collision.
+
+### Protos.GetExt
+
+Macro which generates a select expression that retrieves an extension field
+from the input proto2 syntax message. If the field is not set, the default
+value forthe extension field is returned according to safe-traversal semantics.
+
+ proto.getExt(, ) ->
+
+Example:
+
+ proto.getExt(msg, google.expr.proto2.test.int32_ext) // returns int value
+
+### Protos.HasExt
+
+Macro which generates a test-only select expression that determines whether
+an extension field is set on a proto2 syntax message.
+
+ proto.hasExt(, ) ->
+
+Example:
+
+ proto.hasExt(msg, google.expr.proto2.test.int32_ext) // returns true || false
+
+## Sets
+
+Sets provides set relationship tests.
+
+There is no set type within CEL, and while one may be introduced in the
+future, there are cases where a `list` type is known to behave like a set.
+For such cases, this library provides some basic functionality for
+determining set containment, equivalence, and intersection.
+
+### Sets.Contains
+
+Returns whether the first list argument contains all elements in the second
+list argument. The list may contain elements of any type and standard CEL
+equality is used to determine whether a value exists in both lists. If the
+second list is empty, the result will always return true.
+
+ sets.contains(list(T), list(T)) -> bool
+
+Examples:
+
+ sets.contains([], []) // true
+ sets.contains([], [1]) // false
+ sets.contains([1, 2, 3, 4], [2, 3]) // true
+ sets.contains([1, 2.0, 3u], [1.0, 2u, 3]) // true
+
+### Sets.Equivalent
+
+Returns whether the first and second list are set equivalent. Lists are set
+equivalent if for every item in the first list, there is an element in the
+second which is equal. The lists may not be of the same size as they do not
+guarantee the elements within them are unique, so size does not factor into
+the computation.
+
+ sets.equivalent(list(T), list(T)) -> bool
+
+Examples:
+
+ sets.equivalent([], []) // true
+ sets.equivalent([1], [1, 1]) // true
+ sets.equivalent([1], [1u, 1.0]) // true
+ sets.equivalent([1, 2, 3], [3u, 2.0, 1]) // true
+
+### Sets.Intersects
+
+Returns whether the first list has at least one element whose value is equal
+to an element in the second list. If either list is empty, the result will
+be false.
+
+ sets.intersects(list(T), list(T)) -> bool
+
+Examples:
+
+ sets.intersects([1], []) // false
+ sets.intersects([1], [1, 2]) // true
+ sets.intersects([[1], [2, 3]], [[1, 2], [2, 3.0]]) // true
+
## Strings
Extended functions for string manipulation. As a general note, all indices are
@@ -70,6 +244,23 @@ Examples:
'hello mellow'.indexOf('ello', 2) // returns 7
'hello mellow'.indexOf('ello', 20) // error
+### Join
+
+Returns a new string where the elements of string list are concatenated.
+
+The function also accepts an optional separator which is placed between
+elements in the resulting string.
+
+ >.join() ->
+ >.join() ->
+
+Examples:
+
+ ['hello', 'mellow'].join() // returns 'hellomellow'
+ ['hello', 'mellow'].join(' ') // returns 'hello mellow'
+ [].join() // returns ''
+ [].join('/') // returns ''
+
### LastIndexOf
Returns the integer index of the last occurrence of the search string. If the
@@ -105,6 +296,20 @@ Examples:
'TacoCat'.lowerAscii() // returns 'tacocat'
'TacoCÆt Xii'.lowerAscii() // returns 'tacocÆt xii'
+### Quote
+
+**Introduced in version 1**
+
+Takes the given string and makes it safe to print (without any formatting due to escape sequences).
+If any invalid UTF-8 characters are encountered, they are replaced with \uFFFD.
+
+ strings.quote()
+
+Examples:
+
+ strings.quote('single-quote with "double quote"') // returns '"single-quote with \"double quote\""'
+ strings.quote("two escape sequences \a\n") // returns '"two escape sequences \\a\\n"'
+
### Replace
Returns a new string based on the target, which replaces the occurrences of a
diff --git a/vendor/github.com/google/cel-go/ext/bindings.go b/vendor/github.com/google/cel-go/ext/bindings.go
new file mode 100644
index 0000000000..9cc3c3efe5
--- /dev/null
+++ b/vendor/github.com/google/cel-go/ext/bindings.go
@@ -0,0 +1,100 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package ext
+
+import (
+ "github.com/google/cel-go/cel"
+ "github.com/google/cel-go/common"
+
+ exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
+)
+
+// Bindings returns a cel.EnvOption to configure support for local variable
+// bindings in expressions.
+//
+// # Cel.Bind
+//
+// Binds a simple identifier to an initialization expression which may be used
+// in a subsequenct result expression. Bindings may also be nested within each
+// other.
+//
+// cel.bind(, , )
+//
+// Examples:
+//
+// cel.bind(a, 'hello',
+// cel.bind(b, 'world', a + b + b + a)) // "helloworldworldhello"
+//
+// // Avoid a list allocation within the exists comprehension.
+// cel.bind(valid_values, [a, b, c],
+// [d, e, f].exists(elem, elem in valid_values))
+//
+// Local bindings are not guaranteed to be evaluated before use.
+func Bindings() cel.EnvOption {
+ return cel.Lib(celBindings{})
+}
+
+const (
+ celNamespace = "cel"
+ bindMacro = "bind"
+ unusedIterVar = "#unused"
+)
+
+type celBindings struct{}
+
+func (celBindings) LibraryName() string {
+ return "cel.lib.ext.cel.bindings"
+}
+
+func (celBindings) CompileOptions() []cel.EnvOption {
+ return []cel.EnvOption{
+ cel.Macros(
+ // cel.bind(var, , )
+ cel.NewReceiverMacro(bindMacro, 3, celBind),
+ ),
+ }
+}
+
+func (celBindings) ProgramOptions() []cel.ProgramOption {
+ return []cel.ProgramOption{}
+}
+
+func celBind(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
+ if !macroTargetMatchesNamespace(celNamespace, target) {
+ return nil, nil
+ }
+ varIdent := args[0]
+ varName := ""
+ switch varIdent.GetExprKind().(type) {
+ case *exprpb.Expr_IdentExpr:
+ varName = varIdent.GetIdentExpr().GetName()
+ default:
+ return nil, &common.Error{
+ Message: "cel.bind() variable names must be simple identifers",
+ Location: meh.OffsetLocation(varIdent.GetId()),
+ }
+ }
+ varInit := args[1]
+ resultExpr := args[2]
+ return meh.Fold(
+ unusedIterVar,
+ meh.NewList(),
+ varName,
+ varInit,
+ meh.LiteralBool(false),
+ meh.Ident(varName),
+ resultExpr,
+ ), nil
+}
diff --git a/vendor/github.com/google/cel-go/ext/encoders.go b/vendor/github.com/google/cel-go/ext/encoders.go
index 22e38c39f9..d9f9cb5152 100644
--- a/vendor/github.com/google/cel-go/ext/encoders.go
+++ b/vendor/github.com/google/cel-go/ext/encoders.go
@@ -26,34 +26,38 @@ import (
// Encoders returns a cel.EnvOption to configure extended functions for string, byte, and object
// encodings.
//
-// Base64.Decode
+// # Base64.Decode
//
// Decodes base64-encoded string to bytes.
//
// This function will return an error if the string input is not base64-encoded.
//
-// base64.decode() ->
+// base64.decode() ->
//
// Examples:
//
-// base64.decode('aGVsbG8=') // return b'hello'
-// base64.decode('aGVsbG8') // error
+// base64.decode('aGVsbG8=') // return b'hello'
+// base64.decode('aGVsbG8') // error
//
-// Base64.Encode
+// # Base64.Encode
//
// Encodes bytes to a base64-encoded string.
//
-// base64.encode() ->
+// base64.encode() ->
//
// Examples:
//
-// base64.encode(b'hello') // return b'aGVsbG8='
+// base64.encode(b'hello') // return b'aGVsbG8='
func Encoders() cel.EnvOption {
return cel.Lib(encoderLib{})
}
type encoderLib struct{}
+func (encoderLib) LibraryName() string {
+ return "cel.lib.ext.encoders"
+}
+
func (encoderLib) CompileOptions() []cel.EnvOption {
return []cel.EnvOption{
cel.Function("base64.decode",
diff --git a/vendor/github.com/google/cel-go/ext/guards.go b/vendor/github.com/google/cel-go/ext/guards.go
index 0794f859b5..4c7786a690 100644
--- a/vendor/github.com/google/cel-go/ext/guards.go
+++ b/vendor/github.com/google/cel-go/ext/guards.go
@@ -17,6 +17,7 @@ package ext
import (
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
+ exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
)
// function invocation guards for common call signatures within extension functions.
@@ -48,3 +49,15 @@ func listStringOrError(strs []string, err error) ref.Val {
}
return types.DefaultTypeAdapter.NativeToValue(strs)
}
+
+func macroTargetMatchesNamespace(ns string, target *exprpb.Expr) bool {
+ switch target.GetExprKind().(type) {
+ case *exprpb.Expr_IdentExpr:
+ if target.GetIdentExpr().GetName() != ns {
+ return false
+ }
+ return true
+ default:
+ return false
+ }
+}
diff --git a/vendor/github.com/google/cel-go/ext/math.go b/vendor/github.com/google/cel-go/ext/math.go
new file mode 100644
index 0000000000..1c8ad585a1
--- /dev/null
+++ b/vendor/github.com/google/cel-go/ext/math.go
@@ -0,0 +1,388 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package ext
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/google/cel-go/cel"
+ "github.com/google/cel-go/common"
+ "github.com/google/cel-go/common/types"
+ "github.com/google/cel-go/common/types/ref"
+ "github.com/google/cel-go/common/types/traits"
+ exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
+)
+
+// Math returns a cel.EnvOption to configure namespaced math helper macros and
+// functions.
+//
+// Note, all macros use the 'math' namespace; however, at the time of macro
+// expansion the namespace looks just like any other identifier. If you are
+// currently using a variable named 'math', the macro will likely work just as
+// intended; however, there is some chance for collision.
+//
+// # Math.Greatest
+//
+// Returns the greatest valued number present in the arguments to the macro.
+//
+// Greatest is a variable argument count macro which must take at least one
+// argument. Simple numeric and list literals are supported as valid argument
+// types; however, other literals will be flagged as errors during macro
+// expansion. If the argument expression does not resolve to a numeric or
+// list(numeric) type during type-checking, or during runtime then an error
+// will be produced. If a list argument is empty, this too will produce an
+// error.
+//
+// math.greatest(, ...) ->
+//
+// Examples:
+//
+// math.greatest(1) // 1
+// math.greatest(1u, 2u) // 2u
+// math.greatest(-42.0, -21.5, -100.0) // -21.5
+// math.greatest([-42.0, -21.5, -100.0]) // -21.5
+// math.greatest(numbers) // numbers must be list(numeric)
+//
+// math.greatest() // parse error
+// math.greatest('string') // parse error
+// math.greatest(a, b) // check-time error if a or b is non-numeric
+// math.greatest(dyn('string')) // runtime error
+//
+// # Math.Least
+//
+// Returns the least valued number present in the arguments to the macro.
+//
+// Least is a variable argument count macro which must take at least one
+// argument. Simple numeric and list literals are supported as valid argument
+// types; however, other literals will be flagged as errors during macro
+// expansion. If the argument expression does not resolve to a numeric or
+// list(numeric) type during type-checking, or during runtime then an error
+// will be produced. If a list argument is empty, this too will produce an
+// error.
+//
+// math.least(, ...) ->
+//
+// Examples:
+//
+// math.least(1) // 1
+// math.least(1u, 2u) // 1u
+// math.least(-42.0, -21.5, -100.0) // -100.0
+// math.least([-42.0, -21.5, -100.0]) // -100.0
+// math.least(numbers) // numbers must be list(numeric)
+//
+// math.least() // parse error
+// math.least('string') // parse error
+// math.least(a, b) // check-time error if a or b is non-numeric
+// math.least(dyn('string')) // runtime error
+func Math() cel.EnvOption {
+ return cel.Lib(mathLib{})
+}
+
+const (
+ mathNamespace = "math"
+ leastMacro = "least"
+ greatestMacro = "greatest"
+ minFunc = "math.@min"
+ maxFunc = "math.@max"
+)
+
+type mathLib struct{}
+
+// LibraryName implements the SingletonLibrary interface method.
+func (mathLib) LibraryName() string {
+ return "cel.lib.ext.math"
+}
+
+// CompileOptions implements the Library interface method.
+func (mathLib) CompileOptions() []cel.EnvOption {
+ return []cel.EnvOption{
+ cel.Macros(
+ // math.least(num, ...)
+ cel.NewReceiverVarArgMacro(leastMacro, mathLeast),
+ // math.greatest(num, ...)
+ cel.NewReceiverVarArgMacro(greatestMacro, mathGreatest),
+ ),
+ cel.Function(minFunc,
+ cel.Overload("math_@min_double", []*cel.Type{cel.DoubleType}, cel.DoubleType,
+ cel.UnaryBinding(identity)),
+ cel.Overload("math_@min_int", []*cel.Type{cel.IntType}, cel.IntType,
+ cel.UnaryBinding(identity)),
+ cel.Overload("math_@min_uint", []*cel.Type{cel.UintType}, cel.UintType,
+ cel.UnaryBinding(identity)),
+ cel.Overload("math_@min_double_double", []*cel.Type{cel.DoubleType, cel.DoubleType}, cel.DoubleType,
+ cel.BinaryBinding(minPair)),
+ cel.Overload("math_@min_int_int", []*cel.Type{cel.IntType, cel.IntType}, cel.IntType,
+ cel.BinaryBinding(minPair)),
+ cel.Overload("math_@min_uint_uint", []*cel.Type{cel.UintType, cel.UintType}, cel.UintType,
+ cel.BinaryBinding(minPair)),
+ cel.Overload("math_@min_int_uint", []*cel.Type{cel.IntType, cel.UintType}, cel.DynType,
+ cel.BinaryBinding(minPair)),
+ cel.Overload("math_@min_int_double", []*cel.Type{cel.IntType, cel.DoubleType}, cel.DynType,
+ cel.BinaryBinding(minPair)),
+ cel.Overload("math_@min_double_int", []*cel.Type{cel.DoubleType, cel.IntType}, cel.DynType,
+ cel.BinaryBinding(minPair)),
+ cel.Overload("math_@min_double_uint", []*cel.Type{cel.DoubleType, cel.UintType}, cel.DynType,
+ cel.BinaryBinding(minPair)),
+ cel.Overload("math_@min_uint_int", []*cel.Type{cel.UintType, cel.IntType}, cel.DynType,
+ cel.BinaryBinding(minPair)),
+ cel.Overload("math_@min_uint_double", []*cel.Type{cel.UintType, cel.DoubleType}, cel.DynType,
+ cel.BinaryBinding(minPair)),
+ cel.Overload("math_@min_list_double", []*cel.Type{cel.ListType(cel.DoubleType)}, cel.DoubleType,
+ cel.UnaryBinding(minList)),
+ cel.Overload("math_@min_list_int", []*cel.Type{cel.ListType(cel.IntType)}, cel.IntType,
+ cel.UnaryBinding(minList)),
+ cel.Overload("math_@min_list_uint", []*cel.Type{cel.ListType(cel.UintType)}, cel.UintType,
+ cel.UnaryBinding(minList)),
+ ),
+ cel.Function(maxFunc,
+ cel.Overload("math_@max_double", []*cel.Type{cel.DoubleType}, cel.DoubleType,
+ cel.UnaryBinding(identity)),
+ cel.Overload("math_@max_int", []*cel.Type{cel.IntType}, cel.IntType,
+ cel.UnaryBinding(identity)),
+ cel.Overload("math_@max_uint", []*cel.Type{cel.UintType}, cel.UintType,
+ cel.UnaryBinding(identity)),
+ cel.Overload("math_@max_double_double", []*cel.Type{cel.DoubleType, cel.DoubleType}, cel.DoubleType,
+ cel.BinaryBinding(maxPair)),
+ cel.Overload("math_@max_int_int", []*cel.Type{cel.IntType, cel.IntType}, cel.IntType,
+ cel.BinaryBinding(maxPair)),
+ cel.Overload("math_@max_uint_uint", []*cel.Type{cel.UintType, cel.UintType}, cel.UintType,
+ cel.BinaryBinding(maxPair)),
+ cel.Overload("math_@max_int_uint", []*cel.Type{cel.IntType, cel.UintType}, cel.DynType,
+ cel.BinaryBinding(maxPair)),
+ cel.Overload("math_@max_int_double", []*cel.Type{cel.IntType, cel.DoubleType}, cel.DynType,
+ cel.BinaryBinding(maxPair)),
+ cel.Overload("math_@max_double_int", []*cel.Type{cel.DoubleType, cel.IntType}, cel.DynType,
+ cel.BinaryBinding(maxPair)),
+ cel.Overload("math_@max_double_uint", []*cel.Type{cel.DoubleType, cel.UintType}, cel.DynType,
+ cel.BinaryBinding(maxPair)),
+ cel.Overload("math_@max_uint_int", []*cel.Type{cel.UintType, cel.IntType}, cel.DynType,
+ cel.BinaryBinding(maxPair)),
+ cel.Overload("math_@max_uint_double", []*cel.Type{cel.UintType, cel.DoubleType}, cel.DynType,
+ cel.BinaryBinding(maxPair)),
+ cel.Overload("math_@max_list_double", []*cel.Type{cel.ListType(cel.DoubleType)}, cel.DoubleType,
+ cel.UnaryBinding(maxList)),
+ cel.Overload("math_@max_list_int", []*cel.Type{cel.ListType(cel.IntType)}, cel.IntType,
+ cel.UnaryBinding(maxList)),
+ cel.Overload("math_@max_list_uint", []*cel.Type{cel.ListType(cel.UintType)}, cel.UintType,
+ cel.UnaryBinding(maxList)),
+ ),
+ }
+}
+
+// ProgramOptions implements the Library interface method.
+func (mathLib) ProgramOptions() []cel.ProgramOption {
+ return []cel.ProgramOption{}
+}
+
+func mathLeast(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
+ if !macroTargetMatchesNamespace(mathNamespace, target) {
+ return nil, nil
+ }
+ switch len(args) {
+ case 0:
+ return nil, &common.Error{
+ Message: "math.least() requires at least one argument",
+ Location: meh.OffsetLocation(target.GetId()),
+ }
+ case 1:
+ if isListLiteralWithValidArgs(args[0]) || isValidArgType(args[0]) {
+ return meh.GlobalCall(minFunc, args[0]), nil
+ }
+ return nil, &common.Error{
+ Message: "math.least() invalid single argument value",
+ Location: meh.OffsetLocation(args[0].GetId()),
+ }
+ case 2:
+ err := checkInvalidArgs(meh, "math.least()", args)
+ if err != nil {
+ return nil, err
+ }
+ return meh.GlobalCall(minFunc, args...), nil
+ default:
+ err := checkInvalidArgs(meh, "math.least()", args)
+ if err != nil {
+ return nil, err
+ }
+ return meh.GlobalCall(minFunc, meh.NewList(args...)), nil
+ }
+}
+
+func mathGreatest(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
+ if !macroTargetMatchesNamespace(mathNamespace, target) {
+ return nil, nil
+ }
+ switch len(args) {
+ case 0:
+ return nil, &common.Error{
+ Message: "math.greatest() requires at least one argument",
+ Location: meh.OffsetLocation(target.GetId()),
+ }
+ case 1:
+ if isListLiteralWithValidArgs(args[0]) || isValidArgType(args[0]) {
+ return meh.GlobalCall(maxFunc, args[0]), nil
+ }
+ return nil, &common.Error{
+ Message: "math.greatest() invalid single argument value",
+ Location: meh.OffsetLocation(args[0].GetId()),
+ }
+ case 2:
+ err := checkInvalidArgs(meh, "math.greatest()", args)
+ if err != nil {
+ return nil, err
+ }
+ return meh.GlobalCall(maxFunc, args...), nil
+ default:
+ err := checkInvalidArgs(meh, "math.greatest()", args)
+ if err != nil {
+ return nil, err
+ }
+ return meh.GlobalCall(maxFunc, meh.NewList(args...)), nil
+ }
+}
+
+func identity(val ref.Val) ref.Val {
+ return val
+}
+
+func minPair(first, second ref.Val) ref.Val {
+ cmp, ok := first.(traits.Comparer)
+ if !ok {
+ return types.MaybeNoSuchOverloadErr(first)
+ }
+ out := cmp.Compare(second)
+ if types.IsUnknownOrError(out) {
+ return maybeSuffixError(out, "math.@min")
+ }
+ if out == types.IntOne {
+ return second
+ }
+ return first
+}
+
+func minList(numList ref.Val) ref.Val {
+ l := numList.(traits.Lister)
+ size := l.Size().(types.Int)
+ if size == types.IntZero {
+ return types.NewErr("math.@min(list) argument must not be empty")
+ }
+ min := l.Get(types.IntZero)
+ for i := types.IntOne; i < size; i++ {
+ min = minPair(min, l.Get(i))
+ }
+ switch min.Type() {
+ case types.IntType, types.DoubleType, types.UintType, types.UnknownType:
+ return min
+ default:
+ return types.NewErr("no such overload: math.@min")
+ }
+}
+
+func maxPair(first, second ref.Val) ref.Val {
+ cmp, ok := first.(traits.Comparer)
+ if !ok {
+ return types.MaybeNoSuchOverloadErr(first)
+ }
+ out := cmp.Compare(second)
+ if types.IsUnknownOrError(out) {
+ return maybeSuffixError(out, "math.@max")
+ }
+ if out == types.IntNegOne {
+ return second
+ }
+ return first
+}
+
+func maxList(numList ref.Val) ref.Val {
+ l := numList.(traits.Lister)
+ size := l.Size().(types.Int)
+ if size == types.IntZero {
+ return types.NewErr("math.@max(list) argument must not be empty")
+ }
+ max := l.Get(types.IntZero)
+ for i := types.IntOne; i < size; i++ {
+ max = maxPair(max, l.Get(i))
+ }
+ switch max.Type() {
+ case types.IntType, types.DoubleType, types.UintType, types.UnknownType:
+ return max
+ default:
+ return types.NewErr("no such overload: math.@max")
+ }
+}
+
+func checkInvalidArgs(meh cel.MacroExprHelper, funcName string, args []*exprpb.Expr) *common.Error {
+ for _, arg := range args {
+ err := checkInvalidArgLiteral(funcName, arg)
+ if err != nil {
+ return &common.Error{
+ Message: err.Error(),
+ Location: meh.OffsetLocation(arg.GetId()),
+ }
+ }
+ }
+ return nil
+}
+
+func checkInvalidArgLiteral(funcName string, arg *exprpb.Expr) error {
+ if !isValidArgType(arg) {
+ return fmt.Errorf("%s simple literal arguments must be numeric", funcName)
+ }
+ return nil
+}
+
+func isValidArgType(arg *exprpb.Expr) bool {
+ switch arg.GetExprKind().(type) {
+ case *exprpb.Expr_ConstExpr:
+ c := arg.GetConstExpr()
+ switch c.GetConstantKind().(type) {
+ case *exprpb.Constant_DoubleValue, *exprpb.Constant_Int64Value, *exprpb.Constant_Uint64Value:
+ return true
+ default:
+ return false
+ }
+ case *exprpb.Expr_ListExpr, *exprpb.Expr_StructExpr:
+ return false
+ default:
+ return true
+ }
+}
+
+func isListLiteralWithValidArgs(arg *exprpb.Expr) bool {
+ switch arg.GetExprKind().(type) {
+ case *exprpb.Expr_ListExpr:
+ list := arg.GetListExpr()
+ if len(list.GetElements()) == 0 {
+ return false
+ }
+ for _, e := range list.GetElements() {
+ if !isValidArgType(e) {
+ return false
+ }
+ }
+ return true
+ }
+ return false
+}
+
+func maybeSuffixError(val ref.Val, suffix string) ref.Val {
+ if types.IsError(val) {
+ msg := val.(*types.Err).String()
+ if !strings.Contains(msg, suffix) {
+ return types.NewErr("%s: %s", msg, suffix)
+ }
+ }
+ return val
+}
diff --git a/vendor/github.com/google/cel-go/ext/native.go b/vendor/github.com/google/cel-go/ext/native.go
new file mode 100644
index 0000000000..acbc44b6d5
--- /dev/null
+++ b/vendor/github.com/google/cel-go/ext/native.go
@@ -0,0 +1,574 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package ext
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+ "time"
+
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/reflect/protoreflect"
+
+ "github.com/google/cel-go/cel"
+ "github.com/google/cel-go/checker/decls"
+ "github.com/google/cel-go/common/types"
+ "github.com/google/cel-go/common/types/pb"
+ "github.com/google/cel-go/common/types/ref"
+ "github.com/google/cel-go/common/types/traits"
+
+ exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
+ structpb "google.golang.org/protobuf/types/known/structpb"
+)
+
+var (
+ nativeObjTraitMask = traits.FieldTesterType | traits.IndexerType
+ jsonValueType = reflect.TypeOf(&structpb.Value{})
+ jsonStructType = reflect.TypeOf(&structpb.Struct{})
+)
+
+// NativeTypes creates a type provider which uses reflect.Type and reflect.Value instances
+// to produce type definitions that can be used within CEL.
+//
+// All struct types in Go are exposed to CEL via their simple package name and struct type name:
+//
+// ```go
+// package identity
+//
+// type Account struct {
+// ID int
+// }
+//
+// ```
+//
+// The type `identity.Account` would be exported to CEL using the same qualified name, e.g.
+// `identity.Account{ID: 1234}` would create a new `Account` instance with the `ID` field
+// populated.
+//
+// Only exported fields are exposed via NativeTypes, and the type-mapping between Go and CEL
+// is as follows:
+//
+// | Go type | CEL type |
+// |-------------------------------------|-----------|
+// | bool | bool |
+// | []byte | bytes |
+// | float32, float64 | double |
+// | int, int8, int16, int32, int64 | int |
+// | string | string |
+// | uint, uint8, uint16, uint32, uint64 | uint |
+// | time.Duration | duration |
+// | time.Time | timestamp |
+// | array, slice | list |
+// | map | map |
+//
+// Please note, if you intend to configure support for proto messages in addition to native
+// types, you will need to provide the protobuf types before the golang native types. The
+// same advice holds if you are using custom type adapters and type providers. The native type
+// provider composes over whichever type adapter and provider is configured in the cel.Env at
+// the time that it is invoked.
+func NativeTypes(refTypes ...any) cel.EnvOption {
+ return func(env *cel.Env) (*cel.Env, error) {
+ tp, err := newNativeTypeProvider(env.TypeAdapter(), env.TypeProvider(), refTypes...)
+ if err != nil {
+ return nil, err
+ }
+ env, err = cel.CustomTypeAdapter(tp)(env)
+ if err != nil {
+ return nil, err
+ }
+ return cel.CustomTypeProvider(tp)(env)
+ }
+}
+
+func newNativeTypeProvider(adapter ref.TypeAdapter, provider ref.TypeProvider, refTypes ...any) (*nativeTypeProvider, error) {
+ nativeTypes := make(map[string]*nativeType, len(refTypes))
+ for _, refType := range refTypes {
+ switch rt := refType.(type) {
+ case reflect.Type:
+ t, err := newNativeType(rt)
+ if err != nil {
+ return nil, err
+ }
+ nativeTypes[t.TypeName()] = t
+ case reflect.Value:
+ t, err := newNativeType(rt.Type())
+ if err != nil {
+ return nil, err
+ }
+ nativeTypes[t.TypeName()] = t
+ default:
+ return nil, fmt.Errorf("unsupported native type: %v (%T) must be reflect.Type or reflect.Value", rt, rt)
+ }
+ }
+ return &nativeTypeProvider{
+ nativeTypes: nativeTypes,
+ baseAdapter: adapter,
+ baseProvider: provider,
+ }, nil
+}
+
+type nativeTypeProvider struct {
+ nativeTypes map[string]*nativeType
+ baseAdapter ref.TypeAdapter
+ baseProvider ref.TypeProvider
+}
+
+// EnumValue proxies to the ref.TypeProvider configured at the times the NativeTypes
+// option was configured.
+func (tp *nativeTypeProvider) EnumValue(enumName string) ref.Val {
+ return tp.baseProvider.EnumValue(enumName)
+}
+
+// FindIdent looks up natives type instances by qualified identifier, and if not found
+// proxies to the composed ref.TypeProvider.
+func (tp *nativeTypeProvider) FindIdent(typeName string) (ref.Val, bool) {
+ if t, found := tp.nativeTypes[typeName]; found {
+ return t, true
+ }
+ return tp.baseProvider.FindIdent(typeName)
+}
+
+// FindType looks up CEL type-checker type definition by qualified identifier, and if not found
+// proxies to the composed ref.TypeProvider.
+func (tp *nativeTypeProvider) FindType(typeName string) (*exprpb.Type, bool) {
+ if _, found := tp.nativeTypes[typeName]; found {
+ return decls.NewTypeType(decls.NewObjectType(typeName)), true
+ }
+ return tp.baseProvider.FindType(typeName)
+}
+
+// FindFieldType looks up a native type's field definition, and if the type name is not a native
+// type then proxies to the composed ref.TypeProvider
+func (tp *nativeTypeProvider) FindFieldType(typeName, fieldName string) (*ref.FieldType, bool) {
+ t, found := tp.nativeTypes[typeName]
+ if !found {
+ return tp.baseProvider.FindFieldType(typeName, fieldName)
+ }
+ refField, isDefined := t.hasField(fieldName)
+ if !found || !isDefined {
+ return nil, false
+ }
+ exprType, ok := convertToExprType(refField.Type)
+ if !ok {
+ return nil, false
+ }
+ return &ref.FieldType{
+ Type: exprType,
+ IsSet: func(obj any) bool {
+ refVal := reflect.Indirect(reflect.ValueOf(obj))
+ refField := refVal.FieldByName(fieldName)
+ return !refField.IsZero()
+ },
+ GetFrom: func(obj any) (any, error) {
+ refVal := reflect.Indirect(reflect.ValueOf(obj))
+ refField := refVal.FieldByName(fieldName)
+ return getFieldValue(tp, refField), nil
+ },
+ }, true
+}
+
+// NewValue implements the ref.TypeProvider interface method.
+func (tp *nativeTypeProvider) NewValue(typeName string, fields map[string]ref.Val) ref.Val {
+ t, found := tp.nativeTypes[typeName]
+ if !found {
+ return tp.baseProvider.NewValue(typeName, fields)
+ }
+ refPtr := reflect.New(t.refType)
+ refVal := refPtr.Elem()
+ for fieldName, val := range fields {
+ refFieldDef, isDefined := t.hasField(fieldName)
+ if !isDefined {
+ return types.NewErr("no such field: %s", fieldName)
+ }
+ fieldVal, err := val.ConvertToNative(refFieldDef.Type)
+ if err != nil {
+ return types.NewErr(err.Error())
+ }
+ refField := refVal.FieldByIndex(refFieldDef.Index)
+ refFieldVal := reflect.ValueOf(fieldVal)
+ refField.Set(refFieldVal)
+ }
+ return tp.NativeToValue(refPtr.Interface())
+}
+
+// NewValue adapts native values to CEL values and will proxy to the composed type adapter
+// for non-native types.
+func (tp *nativeTypeProvider) NativeToValue(val any) ref.Val {
+ if val == nil {
+ return types.NullValue
+ }
+ if v, ok := val.(ref.Val); ok {
+ return v
+ }
+ rawVal := reflect.ValueOf(val)
+ refVal := rawVal
+ if refVal.Kind() == reflect.Ptr {
+ refVal = reflect.Indirect(refVal)
+ }
+ // This isn't quite right if you're also supporting proto,
+ // but maybe an acceptable limitation.
+ switch refVal.Kind() {
+ case reflect.Array, reflect.Slice:
+ switch val := val.(type) {
+ case []byte:
+ return tp.baseAdapter.NativeToValue(val)
+ default:
+ return types.NewDynamicList(tp, val)
+ }
+ case reflect.Map:
+ return types.NewDynamicMap(tp, val)
+ case reflect.Struct:
+ switch val := val.(type) {
+ case proto.Message, *pb.Map, protoreflect.List, protoreflect.Message, protoreflect.Value,
+ time.Time:
+ return tp.baseAdapter.NativeToValue(val)
+ default:
+ return newNativeObject(tp, val, rawVal)
+ }
+ default:
+ return tp.baseAdapter.NativeToValue(val)
+ }
+}
+
+// convertToExprType converts the Golang reflect.Type to a protobuf exprpb.Type.
+func convertToExprType(refType reflect.Type) (*exprpb.Type, bool) {
+ switch refType.Kind() {
+ case reflect.Bool:
+ return decls.Bool, true
+ case reflect.Float32, reflect.Float64:
+ return decls.Double, true
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ if refType == durationType {
+ return decls.Duration, true
+ }
+ return decls.Int, true
+ case reflect.String:
+ return decls.String, true
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return decls.Uint, true
+ case reflect.Array, reflect.Slice:
+ refElem := refType.Elem()
+ if refElem == reflect.TypeOf(byte(0)) {
+ return decls.Bytes, true
+ }
+ elemType, ok := convertToExprType(refElem)
+ if !ok {
+ return nil, false
+ }
+ return decls.NewListType(elemType), true
+ case reflect.Map:
+ keyType, ok := convertToExprType(refType.Key())
+ if !ok {
+ return nil, false
+ }
+ // Ensure the key type is a int, bool, uint, string
+ elemType, ok := convertToExprType(refType.Elem())
+ if !ok {
+ return nil, false
+ }
+ return decls.NewMapType(keyType, elemType), true
+ case reflect.Struct:
+ if refType == timestampType {
+ return decls.Timestamp, true
+ }
+ return decls.NewObjectType(
+ fmt.Sprintf("%s.%s", simplePkgAlias(refType.PkgPath()), refType.Name()),
+ ), true
+ case reflect.Pointer:
+ if refType.Implements(pbMsgInterfaceType) {
+ pbMsg := reflect.New(refType.Elem()).Interface().(protoreflect.ProtoMessage)
+ return decls.NewObjectType(string(pbMsg.ProtoReflect().Descriptor().FullName())), true
+ }
+ return convertToExprType(refType.Elem())
+ }
+ return nil, false
+}
+
+func newNativeObject(adapter ref.TypeAdapter, val any, refValue reflect.Value) ref.Val {
+ valType, err := newNativeType(refValue.Type())
+ if err != nil {
+ return types.NewErr(err.Error())
+ }
+ return &nativeObj{
+ TypeAdapter: adapter,
+ val: val,
+ valType: valType,
+ refValue: refValue,
+ }
+}
+
+type nativeObj struct {
+ ref.TypeAdapter
+ val any
+ valType *nativeType
+ refValue reflect.Value
+}
+
+// ConvertToNative implements the ref.Val interface method.
+//
+// CEL does not have a notion of pointers, so whether a field is a pointer or value
+// is handled as part of this conversion step.
+func (o *nativeObj) ConvertToNative(typeDesc reflect.Type) (any, error) {
+ if o.refValue.Type() == typeDesc {
+ return o.val, nil
+ }
+ if o.refValue.Kind() == reflect.Pointer && o.refValue.Type().Elem() == typeDesc {
+ return o.refValue.Elem().Interface(), nil
+ }
+ if typeDesc.Kind() == reflect.Pointer && o.refValue.Type() == typeDesc.Elem() {
+ ptr := reflect.New(typeDesc.Elem())
+ ptr.Elem().Set(o.refValue)
+ return ptr.Interface(), nil
+ }
+ switch typeDesc {
+ case jsonValueType:
+ jsonStruct, err := o.ConvertToNative(jsonStructType)
+ if err != nil {
+ return nil, err
+ }
+ return structpb.NewStructValue(jsonStruct.(*structpb.Struct)), nil
+ case jsonStructType:
+ refVal := reflect.Indirect(o.refValue)
+ refType := refVal.Type()
+ fields := make(map[string]*structpb.Value, refVal.NumField())
+ for i := 0; i < refVal.NumField(); i++ {
+ fieldType := refType.Field(i)
+ fieldValue := refVal.Field(i)
+ if !fieldValue.IsValid() || fieldValue.IsZero() {
+ continue
+ }
+ fieldCELVal := o.NativeToValue(fieldValue.Interface())
+ fieldJSONVal, err := fieldCELVal.ConvertToNative(jsonValueType)
+ if err != nil {
+ return nil, err
+ }
+ fields[fieldType.Name] = fieldJSONVal.(*structpb.Value)
+ }
+ return &structpb.Struct{Fields: fields}, nil
+ }
+ return nil, fmt.Errorf("type conversion error from '%v' to '%v'", o.Type(), typeDesc)
+}
+
+// ConvertToType implements the ref.Val interface method.
+func (o *nativeObj) ConvertToType(typeVal ref.Type) ref.Val {
+ switch typeVal {
+ case types.TypeType:
+ return o.valType
+ default:
+ if typeVal.TypeName() == o.valType.typeName {
+ return o
+ }
+ }
+ return types.NewErr("type conversion error from '%s' to '%s'", o.Type(), typeVal)
+}
+
+// Equal implements the ref.Val interface method.
+//
+// Note, that in Golang a pointer to a value is not equal to the value it contains.
+// In CEL pointers and values to which they point are equal.
+func (o *nativeObj) Equal(other ref.Val) ref.Val {
+ otherNtv, ok := other.(*nativeObj)
+ if !ok {
+ return types.False
+ }
+ val := o.val
+ otherVal := otherNtv.val
+ refVal := o.refValue
+ otherRefVal := otherNtv.refValue
+ if refVal.Kind() != otherRefVal.Kind() {
+ if refVal.Kind() == reflect.Pointer {
+ val = refVal.Elem().Interface()
+ } else if otherRefVal.Kind() == reflect.Pointer {
+ otherVal = otherRefVal.Elem().Interface()
+ }
+ }
+ return types.Bool(reflect.DeepEqual(val, otherVal))
+}
+
+// IsZeroValue indicates whether the contained Golang value is a zero value.
+//
+// Golang largely follows proto3 semantics for zero values.
+func (o *nativeObj) IsZeroValue() bool {
+ return reflect.Indirect(o.refValue).IsZero()
+}
+
+// IsSet tests whether a field which is defined is set to a non-default value.
+func (o *nativeObj) IsSet(field ref.Val) ref.Val {
+ refField, refErr := o.getReflectedField(field)
+ if refErr != nil {
+ return refErr
+ }
+ return types.Bool(!refField.IsZero())
+}
+
+// Get returns the value fo a field name.
+func (o *nativeObj) Get(field ref.Val) ref.Val {
+ refField, refErr := o.getReflectedField(field)
+ if refErr != nil {
+ return refErr
+ }
+ return adaptFieldValue(o, refField)
+}
+
+func (o *nativeObj) getReflectedField(field ref.Val) (reflect.Value, ref.Val) {
+ fieldName, ok := field.(types.String)
+ if !ok {
+ return reflect.Value{}, types.MaybeNoSuchOverloadErr(field)
+ }
+ fieldNameStr := string(fieldName)
+ refField, isDefined := o.valType.hasField(fieldNameStr)
+ if !isDefined {
+ return reflect.Value{}, types.NewErr("no such field: %s", fieldName)
+ }
+ refVal := reflect.Indirect(o.refValue)
+ return refVal.FieldByIndex(refField.Index), nil
+}
+
+// Type implements the ref.Val interface method.
+func (o *nativeObj) Type() ref.Type {
+ return o.valType
+}
+
+// Value implements the ref.Val interface method.
+func (o *nativeObj) Value() any {
+ return o.val
+}
+
+func newNativeType(rawType reflect.Type) (*nativeType, error) {
+ refType := rawType
+ if refType.Kind() == reflect.Pointer {
+ refType = refType.Elem()
+ }
+ if !isValidObjectType(refType) {
+ return nil, fmt.Errorf("unsupported reflect.Type %v, must be reflect.Struct", rawType)
+ }
+ return &nativeType{
+ typeName: fmt.Sprintf("%s.%s", simplePkgAlias(refType.PkgPath()), refType.Name()),
+ refType: refType,
+ }, nil
+}
+
+type nativeType struct {
+ typeName string
+ refType reflect.Type
+}
+
+// ConvertToNative implements ref.Val.ConvertToNative.
+func (t *nativeType) ConvertToNative(typeDesc reflect.Type) (any, error) {
+ return nil, fmt.Errorf("type conversion error for type to '%v'", typeDesc)
+}
+
+// ConvertToType implements ref.Val.ConvertToType.
+func (t *nativeType) ConvertToType(typeVal ref.Type) ref.Val {
+ switch typeVal {
+ case types.TypeType:
+ return types.TypeType
+ }
+ return types.NewErr("type conversion error from '%s' to '%s'", types.TypeType, typeVal)
+}
+
+// Equal returns true of both type names are equal to each other.
+func (t *nativeType) Equal(other ref.Val) ref.Val {
+ otherType, ok := other.(ref.Type)
+ return types.Bool(ok && t.TypeName() == otherType.TypeName())
+}
+
+// HasTrait implements the ref.Type interface method.
+func (t *nativeType) HasTrait(trait int) bool {
+ return nativeObjTraitMask&trait == trait
+}
+
+// String implements the strings.Stringer interface method.
+func (t *nativeType) String() string {
+ return t.typeName
+}
+
+// Type implements the ref.Val interface method.
+func (t *nativeType) Type() ref.Type {
+ return types.TypeType
+}
+
+// TypeName implements the ref.Type interface method.
+func (t *nativeType) TypeName() string {
+ return t.typeName
+}
+
+// Value implements the ref.Val interface method.
+func (t *nativeType) Value() any {
+ return t.typeName
+}
+
+// hasField returns whether a field name has a corresponding Golang reflect.StructField
+func (t *nativeType) hasField(fieldName string) (reflect.StructField, bool) {
+ f, found := t.refType.FieldByName(fieldName)
+ if !found || !f.IsExported() || !isSupportedType(f.Type) {
+ return reflect.StructField{}, false
+ }
+ return f, true
+}
+
+func adaptFieldValue(adapter ref.TypeAdapter, refField reflect.Value) ref.Val {
+ return adapter.NativeToValue(getFieldValue(adapter, refField))
+}
+
+func getFieldValue(adapter ref.TypeAdapter, refField reflect.Value) any {
+ if refField.IsZero() {
+ switch refField.Kind() {
+ case reflect.Array, reflect.Slice:
+ return types.NewDynamicList(adapter, []ref.Val{})
+ case reflect.Map:
+ return types.NewDynamicMap(adapter, map[ref.Val]ref.Val{})
+ case reflect.Struct:
+ if refField.Type() == timestampType {
+ return types.Timestamp{Time: time.Unix(0, 0)}
+ }
+ return reflect.New(refField.Type()).Elem().Interface()
+ case reflect.Pointer:
+ return reflect.New(refField.Type().Elem()).Interface()
+ }
+ }
+ return refField.Interface()
+}
+
+func simplePkgAlias(pkgPath string) string {
+ paths := strings.Split(pkgPath, "/")
+ if len(paths) == 0 {
+ return ""
+ }
+ return paths[len(paths)-1]
+}
+
+func isValidObjectType(refType reflect.Type) bool {
+ return refType.Kind() == reflect.Struct
+}
+
+func isSupportedType(refType reflect.Type) bool {
+ switch refType.Kind() {
+ case reflect.Chan, reflect.Complex64, reflect.Complex128, reflect.Func, reflect.UnsafePointer, reflect.Uintptr:
+ return false
+ case reflect.Array, reflect.Slice:
+ return isSupportedType(refType.Elem())
+ case reflect.Map:
+ return isSupportedType(refType.Key()) && isSupportedType(refType.Elem())
+ }
+ return true
+}
+
+var (
+ pbMsgInterfaceType = reflect.TypeOf((*protoreflect.ProtoMessage)(nil)).Elem()
+ timestampType = reflect.TypeOf(time.Now())
+ durationType = reflect.TypeOf(time.Nanosecond)
+)
diff --git a/vendor/github.com/google/cel-go/ext/protos.go b/vendor/github.com/google/cel-go/ext/protos.go
new file mode 100644
index 0000000000..b905e710c1
--- /dev/null
+++ b/vendor/github.com/google/cel-go/ext/protos.go
@@ -0,0 +1,145 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package ext
+
+import (
+ "github.com/google/cel-go/cel"
+ "github.com/google/cel-go/common"
+
+ exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
+)
+
+// Protos returns a cel.EnvOption to configure extended macros and functions for
+// proto manipulation.
+//
+// Note, all macros use the 'proto' namespace; however, at the time of macro
+// expansion the namespace looks just like any other identifier. If you are
+// currently using a variable named 'proto', the macro will likely work just as
+// intended; however, there is some chance for collision.
+//
+// # Protos.GetExt
+//
+// Macro which generates a select expression that retrieves an extension field
+// from the input proto2 syntax message. If the field is not set, the default
+// value forthe extension field is returned according to safe-traversal semantics.
+//
+// proto.getExt(, ) ->
+//
+// Examples:
+//
+// proto.getExt(msg, google.expr.proto2.test.int32_ext) // returns int value
+//
+// # Protos.HasExt
+//
+// Macro which generates a test-only select expression that determines whether
+// an extension field is set on a proto2 syntax message.
+//
+// proto.hasExt(, ) ->
+//
+// Examples:
+//
+// proto.hasExt(msg, google.expr.proto2.test.int32_ext) // returns true || false
+func Protos() cel.EnvOption {
+ return cel.Lib(protoLib{})
+}
+
+var (
+ protoNamespace = "proto"
+ hasExtension = "hasExt"
+ getExtension = "getExt"
+)
+
+type protoLib struct{}
+
+// LibraryName implements the SingletonLibrary interface method.
+func (protoLib) LibraryName() string {
+ return "cel.lib.ext.protos"
+}
+
+// CompileOptions implements the Library interface method.
+func (protoLib) CompileOptions() []cel.EnvOption {
+ return []cel.EnvOption{
+ cel.Macros(
+ // proto.getExt(msg, select_expression)
+ cel.NewReceiverMacro(getExtension, 2, getProtoExt),
+ // proto.hasExt(msg, select_expression)
+ cel.NewReceiverMacro(hasExtension, 2, hasProtoExt),
+ ),
+ }
+}
+
+// ProgramOptions implements the Library interface method.
+func (protoLib) ProgramOptions() []cel.ProgramOption {
+ return []cel.ProgramOption{}
+}
+
+// hasProtoExt generates a test-only select expression for a fully-qualified extension name on a protobuf message.
+func hasProtoExt(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
+ if !macroTargetMatchesNamespace(protoNamespace, target) {
+ return nil, nil
+ }
+ extensionField, err := getExtFieldName(meh, args[1])
+ if err != nil {
+ return nil, err
+ }
+ return meh.PresenceTest(args[0], extensionField), nil
+}
+
+// getProtoExt generates a select expression for a fully-qualified extension name on a protobuf message.
+func getProtoExt(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
+ if !macroTargetMatchesNamespace(protoNamespace, target) {
+ return nil, nil
+ }
+ extFieldName, err := getExtFieldName(meh, args[1])
+ if err != nil {
+ return nil, err
+ }
+ return meh.Select(args[0], extFieldName), nil
+}
+
+func getExtFieldName(meh cel.MacroExprHelper, expr *exprpb.Expr) (string, *common.Error) {
+ isValid := false
+ extensionField := ""
+ switch expr.GetExprKind().(type) {
+ case *exprpb.Expr_SelectExpr:
+ extensionField, isValid = validateIdentifier(expr)
+ }
+ if !isValid {
+ return "", &common.Error{
+ Message: "invalid extension field",
+ Location: meh.OffsetLocation(expr.GetId()),
+ }
+ }
+ return extensionField, nil
+}
+
+func validateIdentifier(expr *exprpb.Expr) (string, bool) {
+ switch expr.GetExprKind().(type) {
+ case *exprpb.Expr_IdentExpr:
+ return expr.GetIdentExpr().GetName(), true
+ case *exprpb.Expr_SelectExpr:
+ sel := expr.GetSelectExpr()
+ if sel.GetTestOnly() {
+ return "", false
+ }
+ opStr, isIdent := validateIdentifier(sel.GetOperand())
+ if !isIdent {
+ return "", false
+ }
+ return opStr + "." + sel.GetField(), true
+ default:
+ return "", false
+ }
+}
diff --git a/vendor/github.com/google/cel-go/ext/sets.go b/vendor/github.com/google/cel-go/ext/sets.go
new file mode 100644
index 0000000000..4820d6199e
--- /dev/null
+++ b/vendor/github.com/google/cel-go/ext/sets.go
@@ -0,0 +1,138 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package ext
+
+import (
+ "github.com/google/cel-go/cel"
+ "github.com/google/cel-go/common/types"
+ "github.com/google/cel-go/common/types/ref"
+ "github.com/google/cel-go/common/types/traits"
+)
+
+// Sets returns a cel.EnvOption to configure namespaced set relationship
+// functions.
+//
+// There is no set type within CEL, and while one may be introduced in the
+// future, there are cases where a `list` type is known to behave like a set.
+// For such cases, this library provides some basic functionality for
+// determining set containment, equivalence, and intersection.
+//
+// # Sets.Contains
+//
+// Returns whether the first list argument contains all elements in the second
+// list argument. The list may contain elements of any type and standard CEL
+// equality is used to determine whether a value exists in both lists. If the
+// second list is empty, the result will always return true.
+//
+// sets.contains(list(T), list(T)) -> bool
+//
+// Examples:
+//
+// sets.contains([], []) // true
+// sets.contains([], [1]) // false
+// sets.contains([1, 2, 3, 4], [2, 3]) // true
+// sets.contains([1, 2.0, 3u], [1.0, 2u, 3]) // true
+//
+// # Sets.Equivalent
+//
+// Returns whether the first and second list are set equivalent. Lists are set
+// equivalent if for every item in the first list, there is an element in the
+// second which is equal. The lists may not be of the same size as they do not
+// guarantee the elements within them are unique, so size does not factor into
+// the computation.
+//
+// Examples:
+//
+// sets.equivalent([], []) // true
+// sets.equivalent([1], [1, 1]) // true
+// sets.equivalent([1], [1u, 1.0]) // true
+// sets.equivalent([1, 2, 3], [3u, 2.0, 1]) // true
+//
+// # Sets.Intersects
+//
+// Returns whether the first list has at least one element whose value is equal
+// to an element in the second list. If either list is empty, the result will
+// be false.
+//
+// Examples:
+//
+// sets.intersects([1], []) // false
+// sets.intersects([1], [1, 2]) // true
+// sets.intersects([[1], [2, 3]], [[1, 2], [2, 3.0]]) // true
+func Sets() cel.EnvOption {
+ return cel.Lib(setsLib{})
+}
+
+type setsLib struct{}
+
+// LibraryName implements the SingletonLibrary interface method.
+func (setsLib) LibraryName() string {
+ return "cel.lib.ext.sets"
+}
+
+// CompileOptions implements the Library interface method.
+func (setsLib) CompileOptions() []cel.EnvOption {
+ listType := cel.ListType(cel.TypeParamType("T"))
+ return []cel.EnvOption{
+ cel.Function("sets.contains",
+ cel.Overload("list_sets_contains_list", []*cel.Type{listType, listType}, cel.BoolType,
+ cel.BinaryBinding(setsContains))),
+ cel.Function("sets.equivalent",
+ cel.Overload("list_sets_equivalent_list", []*cel.Type{listType, listType}, cel.BoolType,
+ cel.BinaryBinding(setsEquivalent))),
+ cel.Function("sets.intersects",
+ cel.Overload("list_sets_intersects_list", []*cel.Type{listType, listType}, cel.BoolType,
+ cel.BinaryBinding(setsIntersects))),
+ }
+}
+
+// ProgramOptions implements the Library interface method.
+func (setsLib) ProgramOptions() []cel.ProgramOption {
+ return []cel.ProgramOption{}
+}
+
+func setsIntersects(listA, listB ref.Val) ref.Val {
+ lA := listA.(traits.Lister)
+ lB := listB.(traits.Lister)
+ it := lA.Iterator()
+ for it.HasNext() == types.True {
+ exists := lB.Contains(it.Next())
+ if exists == types.True {
+ return types.True
+ }
+ }
+ return types.False
+}
+
+func setsContains(list, sublist ref.Val) ref.Val {
+ l := list.(traits.Lister)
+ sub := sublist.(traits.Lister)
+ it := sub.Iterator()
+ for it.HasNext() == types.True {
+ exists := l.Contains(it.Next())
+ if exists != types.True {
+ return exists
+ }
+ }
+ return types.True
+}
+
+func setsEquivalent(listA, listB ref.Val) ref.Val {
+ aContainsB := setsContains(listA, listB)
+ if aContainsB != types.True {
+ return aContainsB
+ }
+ return setsContains(listB, listA)
+}
diff --git a/vendor/github.com/google/cel-go/ext/strings.go b/vendor/github.com/google/cel-go/ext/strings.go
index 6ce239ac2b..8455d58290 100644
--- a/vendor/github.com/google/cel-go/ext/strings.go
+++ b/vendor/github.com/google/cel-go/ext/strings.go
@@ -19,32 +19,92 @@ package ext
import (
"fmt"
+ "math"
"reflect"
+ "sort"
"strings"
"unicode"
+ "unicode/utf8"
+
+ "golang.org/x/text/language"
+ "golang.org/x/text/message"
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
+ "github.com/google/cel-go/common/types/traits"
+ "github.com/google/cel-go/interpreter"
+)
+
+const (
+ defaultLocale = "en-US"
+ defaultPrecision = 6
)
// Strings returns a cel.EnvOption to configure extended functions for string manipulation.
// As a general note, all indices are zero-based.
//
-// CharAt
+// # CharAt
//
// Returns the character at the given position. If the position is negative, or greater than
// the length of the string, the function will produce an error:
//
-// .charAt() ->
+// .charAt() ->
//
// Examples:
//
-// 'hello'.charAt(4) // return 'o'
-// 'hello'.charAt(5) // return ''
-// 'hello'.charAt(-1) // error
+// 'hello'.charAt(4) // return 'o'
+// 'hello'.charAt(5) // return ''
+// 'hello'.charAt(-1) // error
+//
+// # Format
+//
+// Introduced at version: 1
+//
+// Returns a new string with substitutions being performed, printf-style.
+// The valid formatting clauses are:
+//
+// `%s` - substitutes a string. This can also be used on bools, lists, maps, bytes,
+// Duration and Timestamp, in addition to all numerical types (int, uint, and double).
+// Note that the dot/period decimal separator will always be used when printing a list
+// or map that contains a double, and that null can be passed (which results in the
+// string "null") in addition to types.
+// `%d` - substitutes an integer.
+// `%f` - substitutes a double with fixed-point precision. The default precision is 6, but
+// this can be adjusted. The strings `Infinity`, `-Infinity`, and `NaN` are also valid input
+// for this clause.
+// `%e` - substitutes a double in scientific notation. The default precision is 6, but this
+// can be adjusted.
+// `%b` - substitutes an integer with its equivalent binary string. Can also be used on bools.
+// `%x` - substitutes an integer with its equivalent in hexadecimal, or if given a string or
+// bytes, will output each character's equivalent in hexadecimal.
+// `%X` - same as above, but with A-F capitalized.
+// `%o` - substitutes an integer with its equivalent in octal.
+//
+// .format() ->
+//
+// Examples:
//
-// IndexOf
+// "this is a string: %s\nand an integer: %d".format(["str", 42]) // returns "this is a string: str\nand an integer: 42"
+// "a double substituted with %%s: %s".format([64.2]) // returns "a double substituted with %s: 64.2"
+// "string type: %s".format([type(string)]) // returns "string type: string"
+// "timestamp: %s".format([timestamp("2023-02-03T23:31:20+00:00")]) // returns "timestamp: 2023-02-03T23:31:20Z"
+// "duration: %s".format([duration("1h45m47s")]) // returns "duration: 6347s"
+// "%f".format([3.14]) // returns "3.140000"
+// "scientific notation: %e".format([2.71828]) // returns "scientific notation: 2.718280\u202f\u00d7\u202f10\u2070\u2070"
+// "5 in binary: %b".format([5]), // returns "5 in binary; 101"
+// "26 in hex: %x".format([26]), // returns "26 in hex: 1a"
+// "26 in hex (uppercase): %X".format([26]) // returns "26 in hex (uppercase): 1A"
+// "30 in octal: %o".format([30]) // returns "30 in octal: 36"
+// "a map inside a list: %s".format([[1, 2, 3, {"a": "x", "b": "y", "c": "z"}]]) // returns "a map inside a list: [1, 2, 3, {"a":"x", "b":"y", "c":"d"}]"
+// "true bool: %s - false bool: %s\nbinary bool: %b".format([true, false, true]) // returns "true bool: true - false bool: false\nbinary bool: 1"
+//
+// Passing an incorrect type (an integer to `%s`) is considered an error, as well as attempting
+// to use more formatting clauses than there are arguments (`%d %d %d` while passing two ints, for instance).
+// If compile-time checking is enabled, and the formatting string is a constant, and the argument list is a literal,
+// then letting any arguments go unused/unformatted is also considered an error.
+//
+// # IndexOf
//
// Returns the integer index of the first occurrence of the search string. If the search string is
// not found the function returns -1.
@@ -52,19 +112,19 @@ import (
// The function also accepts an optional position from which to begin the substring search. If the
// substring is the empty string, the index where the search starts is returned (zero or custom).
//
-// .indexOf() ->
-// .indexOf(, ) ->
+// .indexOf() ->
+// .indexOf(, ) ->
//
// Examples:
//
-// 'hello mellow'.indexOf('') // returns 0
-// 'hello mellow'.indexOf('ello') // returns 1
-// 'hello mellow'.indexOf('jello') // returns -1
-// 'hello mellow'.indexOf('', 2) // returns 2
-// 'hello mellow'.indexOf('ello', 2) // returns 7
-// 'hello mellow'.indexOf('ello', 20) // error
+// 'hello mellow'.indexOf('') // returns 0
+// 'hello mellow'.indexOf('ello') // returns 1
+// 'hello mellow'.indexOf('jello') // returns -1
+// 'hello mellow'.indexOf('', 2) // returns 2
+// 'hello mellow'.indexOf('ello', 2) // returns 7
+// 'hello mellow'.indexOf('ello', 20) // error
//
-// Join
+// # Join
//
// Returns a new string where the elements of string list are concatenated.
//
@@ -75,12 +135,12 @@ import (
//
// Examples:
//
-// ['hello', 'mellow'].join() // returns 'hellomellow'
-// ['hello', 'mellow'].join(' ') // returns 'hello mellow'
-// [].join() // returns ''
-// [].join('/') // returns ''
+// ['hello', 'mellow'].join() // returns 'hellomellow'
+// ['hello', 'mellow'].join(' ') // returns 'hello mellow'
+// [].join() // returns ''
+// [].join('/') // returns ''
//
-// LastIndexOf
+// # LastIndexOf
//
// Returns the integer index at the start of the last occurrence of the search string. If the
// search string is not found the function returns -1.
@@ -89,31 +149,45 @@ import (
// considered as the beginning of the substring match. If the substring is the empty string,
// the index where the search starts is returned (string length or custom).
//
-// .lastIndexOf() ->
-// .lastIndexOf(, ) ->
+// .lastIndexOf() ->
+// .lastIndexOf(, ) ->
//
// Examples:
//
-// 'hello mellow'.lastIndexOf('') // returns 12
-// 'hello mellow'.lastIndexOf('ello') // returns 7
-// 'hello mellow'.lastIndexOf('jello') // returns -1
-// 'hello mellow'.lastIndexOf('ello', 6) // returns 1
-// 'hello mellow'.lastIndexOf('ello', -1) // error
+// 'hello mellow'.lastIndexOf('') // returns 12
+// 'hello mellow'.lastIndexOf('ello') // returns 7
+// 'hello mellow'.lastIndexOf('jello') // returns -1
+// 'hello mellow'.lastIndexOf('ello', 6) // returns 1
+// 'hello mellow'.lastIndexOf('ello', -1) // error
//
-// LowerAscii
+// # LowerAscii
//
// Returns a new string where all ASCII characters are lower-cased.
//
// This function does not perform Unicode case-mapping for characters outside the ASCII range.
//
-// .lowerAscii() ->
+// .lowerAscii() ->
+//
+// Examples:
+//
+// 'TacoCat'.lowerAscii() // returns 'tacocat'
+// 'TacoCÆt Xii'.lowerAscii() // returns 'tacocÆt xii'
+//
+// # Quote
+//
+// Introduced in version: 1
+//
+// Takes the given string and makes it safe to print (without any formatting due to escape sequences).
+// If any invalid UTF-8 characters are encountered, they are replaced with \uFFFD.
+//
+// strings.quote()
//
// Examples:
//
-// 'TacoCat'.lowerAscii() // returns 'tacocat'
-// 'TacoCÆt Xii'.lowerAscii() // returns 'tacocÆt xii'
+// strings.quote('single-quote with "double quote"') // returns '"single-quote with \"double quote\""'
+// strings.quote("two escape sequences \a\n") // returns '"two escape sequences \\a\\n"'
//
-// Replace
+// # Replace
//
// Returns a new string based on the target, which replaces the occurrences of a search string
// with a replacement string if present. The function accepts an optional limit on the number of
@@ -122,17 +196,17 @@ import (
// When the replacement limit is 0, the result is the original string. When the limit is a negative
// number, the function behaves the same as replace all.
//
-// .replace(, ) ->
-// .replace(, , ) ->
+// .replace(, ) ->
+// .replace(, , ) ->
//
// Examples:
//
-// 'hello hello'.replace('he', 'we') // returns 'wello wello'
-// 'hello hello'.replace('he', 'we', -1) // returns 'wello wello'
-// 'hello hello'.replace('he', 'we', 1) // returns 'wello hello'
-// 'hello hello'.replace('he', 'we', 0) // returns 'hello hello'
+// 'hello hello'.replace('he', 'we') // returns 'wello wello'
+// 'hello hello'.replace('he', 'we', -1) // returns 'wello wello'
+// 'hello hello'.replace('he', 'we', 1) // returns 'wello hello'
+// 'hello hello'.replace('he', 'we', 0) // returns 'hello hello'
//
-// Split
+// # Split
//
// Returns a list of strings split from the input by the given separator. The function accepts
// an optional argument specifying a limit on the number of substrings produced by the split.
@@ -141,18 +215,18 @@ import (
// target string to split. When the limit is a negative number, the function behaves the same as
// split all.
//
-// .split() -> >
-// .split(, ) -> >
+// .split() -> >
+// .split(, ) -> >
//
// Examples:
//
-// 'hello hello hello'.split(' ') // returns ['hello', 'hello', 'hello']
-// 'hello hello hello'.split(' ', 0) // returns []
-// 'hello hello hello'.split(' ', 1) // returns ['hello hello hello']
-// 'hello hello hello'.split(' ', 2) // returns ['hello', 'hello hello']
-// 'hello hello hello'.split(' ', -1) // returns ['hello', 'hello', 'hello']
+// 'hello hello hello'.split(' ') // returns ['hello', 'hello', 'hello']
+// 'hello hello hello'.split(' ', 0) // returns []
+// 'hello hello hello'.split(' ', 1) // returns ['hello hello hello']
+// 'hello hello hello'.split(' ', 2) // returns ['hello', 'hello hello']
+// 'hello hello hello'.split(' ', -1) // returns ['hello', 'hello', 'hello']
//
-// Substring
+// # Substring
//
// Returns the substring given a numeric range corresponding to character positions. Optionally
// may omit the trailing range for a substring from a given character position until the end of
@@ -162,48 +236,102 @@ import (
// error to specify an end range that is lower than the start range, or for either the start or end
// index to be negative or exceed the string length.
//
-// .substring() ->
-// .substring(, ) ->
+// .substring() ->
+// .substring(, ) ->
//
// Examples:
//
-// 'tacocat'.substring(4) // returns 'cat'
-// 'tacocat'.substring(0, 4) // returns 'taco'
-// 'tacocat'.substring(-1) // error
-// 'tacocat'.substring(2, 1) // error
+// 'tacocat'.substring(4) // returns 'cat'
+// 'tacocat'.substring(0, 4) // returns 'taco'
+// 'tacocat'.substring(-1) // error
+// 'tacocat'.substring(2, 1) // error
//
-// Trim
+// # Trim
//
// Returns a new string which removes the leading and trailing whitespace in the target string.
// The trim function uses the Unicode definition of whitespace which does not include the
// zero-width spaces. See: https://en.wikipedia.org/wiki/Whitespace_character#Unicode
//
-// .trim() ->
+// .trim() ->
//
// Examples:
//
-// ' \ttrim\n '.trim() // returns 'trim'
+// ' \ttrim\n '.trim() // returns 'trim'
//
-// UpperAscii
+// # UpperAscii
//
// Returns a new string where all ASCII characters are upper-cased.
//
// This function does not perform Unicode case-mapping for characters outside the ASCII range.
//
-// .upperAscii() ->
+// .upperAscii() ->
//
// Examples:
//
-// 'TacoCat'.upperAscii() // returns 'TACOCAT'
-// 'TacoCÆt Xii'.upperAscii() // returns 'TACOCÆT XII'
-func Strings() cel.EnvOption {
- return cel.Lib(stringLib{})
+// 'TacoCat'.upperAscii() // returns 'TACOCAT'
+// 'TacoCÆt Xii'.upperAscii() // returns 'TACOCÆT XII'
+func Strings(options ...StringsOption) cel.EnvOption {
+ s := &stringLib{version: math.MaxUint32}
+ for _, o := range options {
+ s = o(s)
+ }
+ return cel.Lib(s)
+}
+
+type stringLib struct {
+ locale string
+ version uint32
+}
+
+// LibraryName implements the SingletonLibrary interface method.
+func (*stringLib) LibraryName() string {
+ return "cel.lib.ext.strings"
}
-type stringLib struct{}
+// StringsOption is a functional interface for configuring the strings library.
+type StringsOption func(*stringLib) *stringLib
-func (stringLib) CompileOptions() []cel.EnvOption {
- return []cel.EnvOption{
+// StringsLocale configures the library with the given locale. The locale tag will
+// be checked for validity at the time that EnvOptions are configured. If this option
+// is not passed, string.format will behave as if en_US was passed as the locale.
+func StringsLocale(locale string) StringsOption {
+ return func(sl *stringLib) *stringLib {
+ sl.locale = locale
+ return sl
+ }
+}
+
+// StringsVersion configures the version of the string library. The version limits which
+// functions are available. Only functions introduced below or equal to the given
+// version included in the library. See the library documentation to determine
+// which version a function was introduced at. If the documentation does not
+// state which version a function was introduced at, it can be assumed to be
+// introduced at version 0, when the library was first created.
+// If this option is not set, all functions are available.
+func StringsVersion(version uint32) func(lib *stringLib) *stringLib {
+ return func(sl *stringLib) *stringLib {
+ sl.version = version
+ return sl
+ }
+}
+
+// CompileOptions implements the Library interface method.
+func (sl *stringLib) CompileOptions() []cel.EnvOption {
+ formatLocale := "en_US"
+ if sl.locale != "" {
+ // ensure locale is properly-formed if set
+ _, err := language.Parse(sl.locale)
+ if err != nil {
+ return []cel.EnvOption{
+ func(e *cel.Env) (*cel.Env, error) {
+ return nil, fmt.Errorf("failed to parse locale: %w", err)
+ },
+ }
+ }
+ formatLocale = sl.locale
+ }
+
+ opts := []cel.EnvOption{
cel.Function("charAt",
cel.MemberOverload("string_char_at_int", []*cel.Type{cel.StringType, cel.IntType}, cel.StringType,
cel.BinaryBinding(func(str, ind ref.Val) ref.Val {
@@ -303,28 +431,64 @@ func (stringLib) CompileOptions() []cel.EnvOption {
s := str.(types.String)
return stringOrError(upperASCII(string(s)))
}))),
- cel.Function("join",
- cel.MemberOverload("list_join", []*cel.Type{cel.ListType(cel.StringType)}, cel.StringType,
- cel.UnaryBinding(func(list ref.Val) ref.Val {
- l, err := list.ConvertToNative(stringListType)
- if err != nil {
- return types.NewErr(err.Error())
- }
- return stringOrError(join(l.([]string)))
- })),
- cel.MemberOverload("list_join_string", []*cel.Type{cel.ListType(cel.StringType), cel.StringType}, cel.StringType,
- cel.BinaryBinding(func(list, delim ref.Val) ref.Val {
- l, err := list.ConvertToNative(stringListType)
- if err != nil {
- return types.NewErr(err.Error())
- }
- d := delim.(types.String)
- return stringOrError(joinSeparator(l.([]string), string(d)))
+ }
+ if sl.version >= 1 {
+ opts = append(opts, cel.Function("format",
+ cel.MemberOverload("string_format", []*cel.Type{cel.StringType, cel.ListType(cel.DynType)}, cel.StringType,
+ cel.FunctionBinding(func(args ...ref.Val) ref.Val {
+ s := string(args[0].(types.String))
+ formatArgs := args[1].(traits.Lister)
+ return stringOrError(interpreter.ParseFormatString(s, &stringFormatter{}, &stringArgList{formatArgs}, formatLocale))
}))),
+ cel.Function("strings.quote", cel.Overload("strings_quote", []*cel.Type{cel.StringType}, cel.StringType,
+ cel.UnaryBinding(func(str ref.Val) ref.Val {
+ s := str.(types.String)
+ return stringOrError(quote(string(s)))
+ }))))
+
+ }
+ if sl.version >= 2 {
+ opts = append(opts,
+ cel.Function("join",
+ cel.MemberOverload("list_join", []*cel.Type{cel.ListType(cel.StringType)}, cel.StringType,
+ cel.UnaryBinding(func(list ref.Val) ref.Val {
+ l := list.(traits.Lister)
+ return stringOrError(joinValSeparator(l, ""))
+ })),
+ cel.MemberOverload("list_join_string", []*cel.Type{cel.ListType(cel.StringType), cel.StringType}, cel.StringType,
+ cel.BinaryBinding(func(list, delim ref.Val) ref.Val {
+ l := list.(traits.Lister)
+ d := delim.(types.String)
+ return stringOrError(joinValSeparator(l, string(d)))
+ }))),
+ )
+ } else {
+ opts = append(opts,
+ cel.Function("join",
+ cel.MemberOverload("list_join", []*cel.Type{cel.ListType(cel.StringType)}, cel.StringType,
+ cel.UnaryBinding(func(list ref.Val) ref.Val {
+ l, err := list.ConvertToNative(stringListType)
+ if err != nil {
+ return types.NewErr(err.Error())
+ }
+ return stringOrError(join(l.([]string)))
+ })),
+ cel.MemberOverload("list_join_string", []*cel.Type{cel.ListType(cel.StringType), cel.StringType}, cel.StringType,
+ cel.BinaryBinding(func(list, delim ref.Val) ref.Val {
+ l, err := list.ConvertToNative(stringListType)
+ if err != nil {
+ return types.NewErr(err.Error())
+ }
+ d := delim.(types.String)
+ return stringOrError(joinSeparator(l.([]string), string(d)))
+ }))),
+ )
}
+ return opts
}
-func (stringLib) ProgramOptions() []cel.ProgramOption {
+// ProgramOptions implements the Library interface method.
+func (*stringLib) ProgramOptions() []cel.ProgramOption {
return []cel.ProgramOption{}
}
@@ -478,6 +642,452 @@ func join(strs []string) (string, error) {
return strings.Join(strs, ""), nil
}
+func joinValSeparator(strs traits.Lister, separator string) (string, error) {
+ sz := strs.Size().(types.Int)
+ var sb strings.Builder
+ for i := types.Int(0); i < sz; i++ {
+ if i != 0 {
+ sb.WriteString(separator)
+ }
+ elem := strs.Get(i)
+ str, ok := elem.(types.String)
+ if !ok {
+ return "", fmt.Errorf("join: invalid input: %v", elem)
+ }
+ sb.WriteString(string(str))
+ }
+ return sb.String(), nil
+}
+
+type clauseImpl func(ref.Val, string) (string, error)
+
+func clauseForType(argType ref.Type) (clauseImpl, error) {
+ switch argType {
+ case types.IntType, types.UintType:
+ return formatDecimal, nil
+ case types.StringType, types.BytesType, types.BoolType, types.NullType, types.TypeType:
+ return FormatString, nil
+ case types.TimestampType, types.DurationType:
+ // special case to ensure timestamps/durations get printed as CEL literals
+ return func(arg ref.Val, locale string) (string, error) {
+ argStrVal := arg.ConvertToType(types.StringType)
+ argStr := argStrVal.Value().(string)
+ if arg.Type() == types.TimestampType {
+ return fmt.Sprintf("timestamp(%q)", argStr), nil
+ }
+ if arg.Type() == types.DurationType {
+ return fmt.Sprintf("duration(%q)", argStr), nil
+ }
+ return "", fmt.Errorf("cannot convert argument of type %s to timestamp/duration", arg.Type().TypeName())
+ }, nil
+ case types.ListType:
+ return formatList, nil
+ case types.MapType:
+ return formatMap, nil
+ case types.DoubleType:
+ // avoid formatFixed so we can output a period as the decimal separator in order
+ // to always be a valid CEL literal
+ return func(arg ref.Val, locale string) (string, error) {
+ argDouble, ok := arg.Value().(float64)
+ if !ok {
+ return "", fmt.Errorf("couldn't convert %s to float64", arg.Type().TypeName())
+ }
+ fmtStr := fmt.Sprintf("%%.%df", defaultPrecision)
+ return fmt.Sprintf(fmtStr, argDouble), nil
+ }, nil
+ case types.TypeType:
+ return func(arg ref.Val, locale string) (string, error) {
+ return fmt.Sprintf("type(%s)", arg.Value().(string)), nil
+ }, nil
+ default:
+ return nil, fmt.Errorf("no formatting function for %s", argType.TypeName())
+ }
+}
+
+func formatList(arg ref.Val, locale string) (string, error) {
+ argList := arg.(traits.Lister)
+ argIterator := argList.Iterator()
+ var listStrBuilder strings.Builder
+ _, err := listStrBuilder.WriteRune('[')
+ if err != nil {
+ return "", fmt.Errorf("error writing to list string: %w", err)
+ }
+ for argIterator.HasNext() == types.True {
+ member := argIterator.Next()
+ memberFormat, err := clauseForType(member.Type())
+ if err != nil {
+ return "", err
+ }
+ unquotedStr, err := memberFormat(member, locale)
+ if err != nil {
+ return "", err
+ }
+ str := quoteForCEL(member, unquotedStr)
+ _, err = listStrBuilder.WriteString(str)
+ if err != nil {
+ return "", fmt.Errorf("error writing to list string: %w", err)
+ }
+ if argIterator.HasNext() == types.True {
+ _, err = listStrBuilder.WriteString(", ")
+ if err != nil {
+ return "", fmt.Errorf("error writing to list string: %w", err)
+ }
+ }
+ }
+ _, err = listStrBuilder.WriteRune(']')
+ if err != nil {
+ return "", fmt.Errorf("error writing to list string: %w", err)
+ }
+ return listStrBuilder.String(), nil
+}
+
+func formatMap(arg ref.Val, locale string) (string, error) {
+ argMap := arg.(traits.Mapper)
+ argIterator := argMap.Iterator()
+ type mapPair struct {
+ key string
+ value string
+ }
+ argPairs := make([]mapPair, argMap.Size().Value().(int64))
+ i := 0
+ for argIterator.HasNext() == types.True {
+ key := argIterator.Next()
+ var keyFormat clauseImpl
+ switch key.Type() {
+ case types.StringType, types.BoolType:
+ keyFormat = FormatString
+ case types.IntType, types.UintType:
+ keyFormat = formatDecimal
+ default:
+ return "", fmt.Errorf("no formatting function for map key of type %s", key.Type().TypeName())
+ }
+ unquotedKeyStr, err := keyFormat(key, locale)
+ if err != nil {
+ return "", err
+ }
+ keyStr := quoteForCEL(key, unquotedKeyStr)
+ value, found := argMap.Find(key)
+ if !found {
+ return "", fmt.Errorf("could not find key: %q", key)
+ }
+ valueFormat, err := clauseForType(value.Type())
+ if err != nil {
+ return "", err
+ }
+ unquotedValueStr, err := valueFormat(value, locale)
+ if err != nil {
+ return "", err
+ }
+ valueStr := quoteForCEL(value, unquotedValueStr)
+ argPairs[i] = mapPair{keyStr, valueStr}
+ i++
+ }
+ sort.SliceStable(argPairs, func(x, y int) bool {
+ return argPairs[x].key < argPairs[y].key
+ })
+ var mapStrBuilder strings.Builder
+ _, err := mapStrBuilder.WriteRune('{')
+ if err != nil {
+ return "", fmt.Errorf("error writing to map string: %w", err)
+ }
+ for i, entry := range argPairs {
+ _, err = mapStrBuilder.WriteString(fmt.Sprintf("%s:%s", entry.key, entry.value))
+ if err != nil {
+ return "", fmt.Errorf("error writing to map string: %w", err)
+ }
+ if i < len(argPairs)-1 {
+ _, err = mapStrBuilder.WriteString(", ")
+ if err != nil {
+ return "", fmt.Errorf("error writing to map string: %w", err)
+ }
+ }
+ }
+ _, err = mapStrBuilder.WriteRune('}')
+ if err != nil {
+ return "", fmt.Errorf("error writing to map string: %w", err)
+ }
+ return mapStrBuilder.String(), nil
+}
+
+// quoteForCEL takes a formatted, unquoted value and quotes it in a manner
+// suitable for embedding directly in CEL.
+func quoteForCEL(refVal ref.Val, unquotedValue string) string {
+ switch refVal.Type() {
+ case types.StringType:
+ return fmt.Sprintf("%q", unquotedValue)
+ case types.BytesType:
+ return fmt.Sprintf("b%q", unquotedValue)
+ case types.DoubleType:
+ // special case to handle infinity/NaN
+ num := refVal.Value().(float64)
+ if math.IsInf(num, 1) || math.IsInf(num, -1) || math.IsNaN(num) {
+ return fmt.Sprintf("%q", unquotedValue)
+ }
+ return unquotedValue
+ default:
+ return unquotedValue
+ }
+}
+
+// FormatString returns the string representation of a CEL value.
+// It is used to implement the %s specifier in the (string).format() extension
+// function.
+func FormatString(arg ref.Val, locale string) (string, error) {
+ switch arg.Type() {
+ case types.ListType:
+ return formatList(arg, locale)
+ case types.MapType:
+ return formatMap(arg, locale)
+ case types.IntType, types.UintType, types.DoubleType,
+ types.BoolType, types.StringType, types.TimestampType, types.BytesType, types.DurationType, types.TypeType:
+ argStrVal := arg.ConvertToType(types.StringType)
+ argStr, ok := argStrVal.Value().(string)
+ if !ok {
+ return "", fmt.Errorf("could not convert argument %q to string", argStrVal)
+ }
+ return argStr, nil
+ case types.NullType:
+ return "null", nil
+ default:
+ return "", fmt.Errorf("string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps, was given %s", arg.Type().TypeName())
+ }
+}
+
+func formatDecimal(arg ref.Val, locale string) (string, error) {
+ switch arg.Type() {
+ case types.IntType:
+ argInt, ok := arg.ConvertToType(types.IntType).Value().(int64)
+ if !ok {
+ return "", fmt.Errorf("could not convert \"%s\" to int64", arg.Value())
+ }
+ return fmt.Sprintf("%d", argInt), nil
+ case types.UintType:
+ argInt, ok := arg.ConvertToType(types.UintType).Value().(uint64)
+ if !ok {
+ return "", fmt.Errorf("could not convert \"%s\" to uint64", arg.Value())
+ }
+ return fmt.Sprintf("%d", argInt), nil
+ default:
+ return "", fmt.Errorf("decimal clause can only be used on integers, was given %s", arg.Type().TypeName())
+ }
+}
+
+func matchLanguage(locale string) (language.Tag, error) {
+ matcher, err := makeMatcher(locale)
+ if err != nil {
+ return language.Und, err
+ }
+ tag, _ := language.MatchStrings(matcher, locale)
+ return tag, nil
+}
+
+func makeMatcher(locale string) (language.Matcher, error) {
+ tags := make([]language.Tag, 0)
+ tag, err := language.Parse(locale)
+ if err != nil {
+ return nil, err
+ }
+ tags = append(tags, tag)
+ return language.NewMatcher(tags), nil
+}
+
+// quote implements a string quoting function. The string will be wrapped in
+// double quotes, and all valid CEL escape sequences will be escaped to show up
+// literally if printed. If the input contains any invalid UTF-8, the invalid runes
+// will be replaced with utf8.RuneError.
+func quote(s string) (string, error) {
+ var quotedStrBuilder strings.Builder
+ for _, c := range sanitize(s) {
+ switch c {
+ case '\a':
+ quotedStrBuilder.WriteString("\\a")
+ case '\b':
+ quotedStrBuilder.WriteString("\\b")
+ case '\f':
+ quotedStrBuilder.WriteString("\\f")
+ case '\n':
+ quotedStrBuilder.WriteString("\\n")
+ case '\r':
+ quotedStrBuilder.WriteString("\\r")
+ case '\t':
+ quotedStrBuilder.WriteString("\\t")
+ case '\v':
+ quotedStrBuilder.WriteString("\\v")
+ case '\\':
+ quotedStrBuilder.WriteString("\\\\")
+ case '"':
+ quotedStrBuilder.WriteString("\\\"")
+ default:
+ quotedStrBuilder.WriteRune(c)
+ }
+ }
+ escapedStr := quotedStrBuilder.String()
+ return "\"" + escapedStr + "\"", nil
+}
+
+// sanitize replaces all invalid runes in the given string with utf8.RuneError.
+func sanitize(s string) string {
+ var sanitizedStringBuilder strings.Builder
+ for _, r := range s {
+ if !utf8.ValidRune(r) {
+ sanitizedStringBuilder.WriteRune(utf8.RuneError)
+ } else {
+ sanitizedStringBuilder.WriteRune(r)
+ }
+ }
+ return sanitizedStringBuilder.String()
+}
+
+type stringFormatter struct{}
+
+func (c *stringFormatter) String(arg ref.Val, locale string) (string, error) {
+ return FormatString(arg, locale)
+}
+
+func (c *stringFormatter) Decimal(arg ref.Val, locale string) (string, error) {
+ return formatDecimal(arg, locale)
+}
+
+func (c *stringFormatter) Fixed(precision *int) func(ref.Val, string) (string, error) {
+ if precision == nil {
+ precision = new(int)
+ *precision = defaultPrecision
+ }
+ return func(arg ref.Val, locale string) (string, error) {
+ strException := false
+ if arg.Type() == types.StringType {
+ argStr := arg.Value().(string)
+ if argStr == "NaN" || argStr == "Infinity" || argStr == "-Infinity" {
+ strException = true
+ }
+ }
+ if arg.Type() != types.DoubleType && !strException {
+ return "", fmt.Errorf("fixed-point clause can only be used on doubles, was given %s", arg.Type().TypeName())
+ }
+ argFloatVal := arg.ConvertToType(types.DoubleType)
+ argFloat, ok := argFloatVal.Value().(float64)
+ if !ok {
+ return "", fmt.Errorf("could not convert \"%s\" to float64", argFloatVal.Value())
+ }
+ fmtStr := fmt.Sprintf("%%.%df", *precision)
+
+ matchedLocale, err := matchLanguage(locale)
+ if err != nil {
+ return "", fmt.Errorf("error matching locale: %w", err)
+ }
+ return message.NewPrinter(matchedLocale).Sprintf(fmtStr, argFloat), nil
+ }
+}
+
+func (c *stringFormatter) Scientific(precision *int) func(ref.Val, string) (string, error) {
+ if precision == nil {
+ precision = new(int)
+ *precision = defaultPrecision
+ }
+ return func(arg ref.Val, locale string) (string, error) {
+ strException := false
+ if arg.Type() == types.StringType {
+ argStr := arg.Value().(string)
+ if argStr == "NaN" || argStr == "Infinity" || argStr == "-Infinity" {
+ strException = true
+ }
+ }
+ if arg.Type() != types.DoubleType && !strException {
+ return "", fmt.Errorf("scientific clause can only be used on doubles, was given %s", arg.Type().TypeName())
+ }
+ argFloatVal := arg.ConvertToType(types.DoubleType)
+ argFloat, ok := argFloatVal.Value().(float64)
+ if !ok {
+ return "", fmt.Errorf("could not convert \"%s\" to float64", argFloatVal.Value())
+ }
+ matchedLocale, err := matchLanguage(locale)
+ if err != nil {
+ return "", fmt.Errorf("error matching locale: %w", err)
+ }
+ fmtStr := fmt.Sprintf("%%%de", *precision)
+ return message.NewPrinter(matchedLocale).Sprintf(fmtStr, argFloat), nil
+ }
+}
+
+func (c *stringFormatter) Binary(arg ref.Val, locale string) (string, error) {
+ switch arg.Type() {
+ case types.IntType:
+ argInt := arg.Value().(int64)
+ // locale is intentionally unused as integers formatted as binary
+ // strings are locale-independent
+ return fmt.Sprintf("%b", argInt), nil
+ case types.UintType:
+ argInt := arg.Value().(uint64)
+ return fmt.Sprintf("%b", argInt), nil
+ case types.BoolType:
+ argBool := arg.Value().(bool)
+ if argBool {
+ return "1", nil
+ }
+ return "0", nil
+ default:
+ return "", fmt.Errorf("only integers and bools can be formatted as binary, was given %s", arg.Type().TypeName())
+ }
+}
+
+func (c *stringFormatter) Hex(useUpper bool) func(ref.Val, string) (string, error) {
+ return func(arg ref.Val, locale string) (string, error) {
+ fmtStr := "%x"
+ if useUpper {
+ fmtStr = "%X"
+ }
+ switch arg.Type() {
+ case types.StringType, types.BytesType:
+ if arg.Type() == types.BytesType {
+ return fmt.Sprintf(fmtStr, arg.Value().([]byte)), nil
+ }
+ return fmt.Sprintf(fmtStr, arg.Value().(string)), nil
+ case types.IntType:
+ argInt, ok := arg.Value().(int64)
+ if !ok {
+ return "", fmt.Errorf("could not convert \"%s\" to int64", arg.Value())
+ }
+ return fmt.Sprintf(fmtStr, argInt), nil
+ case types.UintType:
+ argInt, ok := arg.Value().(uint64)
+ if !ok {
+ return "", fmt.Errorf("could not convert \"%s\" to uint64", arg.Value())
+ }
+ return fmt.Sprintf(fmtStr, argInt), nil
+ default:
+ return "", fmt.Errorf("only integers, byte buffers, and strings can be formatted as hex, was given %s", arg.Type().TypeName())
+ }
+ }
+}
+
+func (c *stringFormatter) Octal(arg ref.Val, locale string) (string, error) {
+ switch arg.Type() {
+ case types.IntType:
+ argInt := arg.Value().(int64)
+ return fmt.Sprintf("%o", argInt), nil
+ case types.UintType:
+ argInt := arg.Value().(uint64)
+ return fmt.Sprintf("%o", argInt), nil
+ default:
+ return "", fmt.Errorf("octal clause can only be used on integers, was given %s", arg.Type().TypeName())
+ }
+}
+
+type stringArgList struct {
+ args traits.Lister
+}
+
+func (c *stringArgList) Arg(index int64) (ref.Val, error) {
+ if index >= c.args.Size().Value().(int64) {
+ return nil, fmt.Errorf("index %d out of range", index)
+ }
+ return c.args.Get(types.Int(index)), nil
+}
+
+func (c *stringArgList) ArgSize() int64 {
+ return c.args.Size().Value().(int64)
+}
+
var (
stringListType = reflect.TypeOf([]string{})
)
diff --git a/vendor/github.com/google/cel-go/interpreter/BUILD.bazel b/vendor/github.com/google/cel-go/interpreter/BUILD.bazel
index 04a3ec7441..b6d04e0003 100644
--- a/vendor/github.com/google/cel-go/interpreter/BUILD.bazel
+++ b/vendor/github.com/google/cel-go/interpreter/BUILD.bazel
@@ -11,10 +11,10 @@ go_library(
"activation.go",
"attribute_patterns.go",
"attributes.go",
- "coster.go",
"decorators.go",
"dispatcher.go",
"evalstate.go",
+ "formatting.go",
"interpretable.go",
"interpreter.go",
"optimizations.go",
@@ -32,7 +32,7 @@ go_library(
"//common/types/ref:go_default_library",
"//common/types/traits:go_default_library",
"//interpreter/functions:go_default_library",
- "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
+ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
"@org_golang_google_protobuf//types/known/durationpb:go_default_library",
"@org_golang_google_protobuf//types/known/structpb:go_default_library",
@@ -49,6 +49,7 @@ go_test(
"attributes_test.go",
"interpreter_test.go",
"prune_test.go",
+ "runtimecost_test.go",
],
embed = [
":go_default_library",
@@ -65,7 +66,7 @@ go_test(
"//test:go_default_library",
"//test/proto2pb:go_default_library",
"//test/proto3pb:go_default_library",
- "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
+ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
"@org_golang_google_protobuf//types/known/anypb:go_default_library",
],
diff --git a/vendor/github.com/google/cel-go/interpreter/activation.go b/vendor/github.com/google/cel-go/interpreter/activation.go
index 8686d4f04f..f82e4e9038 100644
--- a/vendor/github.com/google/cel-go/interpreter/activation.go
+++ b/vendor/github.com/google/cel-go/interpreter/activation.go
@@ -28,7 +28,7 @@ import (
type Activation interface {
// ResolveName returns a value from the activation by qualified name, or false if the name
// could not be found.
- ResolveName(name string) (interface{}, bool)
+ ResolveName(name string) (any, bool)
// Parent returns the parent of the current activation, may be nil.
// If non-nil, the parent will be searched during resolve calls.
@@ -43,23 +43,23 @@ func EmptyActivation() Activation {
// emptyActivation is a variable-free activation.
type emptyActivation struct{}
-func (emptyActivation) ResolveName(string) (interface{}, bool) { return nil, false }
-func (emptyActivation) Parent() Activation { return nil }
+func (emptyActivation) ResolveName(string) (any, bool) { return nil, false }
+func (emptyActivation) Parent() Activation { return nil }
// NewActivation returns an activation based on a map-based binding where the map keys are
// expected to be qualified names used with ResolveName calls.
//
-// The input `bindings` may either be of type `Activation` or `map[string]interface{}`.
+// The input `bindings` may either be of type `Activation` or `map[string]any`.
//
// Lazy bindings may be supplied within the map-based input in either of the following forms:
-// - func() interface{}
+// - func() any
// - func() ref.Val
//
// The output of the lazy binding will overwrite the variable reference in the internal map.
//
// Values which are not represented as ref.Val types on input may be adapted to a ref.Val using
// the ref.TypeAdapter configured in the environment.
-func NewActivation(bindings interface{}) (Activation, error) {
+func NewActivation(bindings any) (Activation, error) {
if bindings == nil {
return nil, errors.New("bindings must be non-nil")
}
@@ -67,7 +67,7 @@ func NewActivation(bindings interface{}) (Activation, error) {
if isActivation {
return a, nil
}
- m, isMap := bindings.(map[string]interface{})
+ m, isMap := bindings.(map[string]any)
if !isMap {
return nil, fmt.Errorf(
"activation input must be an activation or map[string]interface: got %T",
@@ -81,7 +81,7 @@ 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 {
- bindings map[string]interface{}
+ bindings map[string]any
}
// Parent implements the Activation interface method.
@@ -90,7 +90,7 @@ func (a *mapActivation) Parent() Activation {
}
// ResolveName implements the Activation interface method.
-func (a *mapActivation) ResolveName(name string) (interface{}, bool) {
+func (a *mapActivation) ResolveName(name string) (any, bool) {
obj, found := a.bindings[name]
if !found {
return nil, false
@@ -100,7 +100,7 @@ func (a *mapActivation) ResolveName(name string) (interface{}, bool) {
obj = fn()
a.bindings[name] = obj
}
- fnRaw, isLazy := obj.(func() interface{})
+ fnRaw, isLazy := obj.(func() any)
if isLazy {
obj = fnRaw()
a.bindings[name] = obj
@@ -121,7 +121,7 @@ func (a *hierarchicalActivation) Parent() Activation {
}
// ResolveName implements the Activation interface method.
-func (a *hierarchicalActivation) ResolveName(name string) (interface{}, bool) {
+func (a *hierarchicalActivation) ResolveName(name string) (any, bool) {
if object, found := a.child.ResolveName(name); found {
return object, found
}
@@ -138,8 +138,8 @@ func NewHierarchicalActivation(parent Activation, child Activation) Activation {
// representing field and index operations that should result in a 'types.Unknown' result.
//
// The `bindings` value may be any value type supported by the interpreter.NewActivation call,
-// but is typically either an existing Activation or map[string]interface{}.
-func NewPartialActivation(bindings interface{},
+// but is typically either an existing Activation or map[string]any.
+func NewPartialActivation(bindings any,
unknowns ...*AttributePattern) (PartialActivation, error) {
a, err := NewActivation(bindings)
if err != nil {
@@ -184,7 +184,7 @@ func (v *varActivation) Parent() Activation {
}
// ResolveName implements the Activation interface method.
-func (v *varActivation) ResolveName(name string) (interface{}, bool) {
+func (v *varActivation) ResolveName(name string) (any, bool) {
if name == v.name {
return v.val, true
}
@@ -194,7 +194,7 @@ func (v *varActivation) ResolveName(name string) (interface{}, bool) {
var (
// pool of var activations to reduce allocations during folds.
varActivationPool = &sync.Pool{
- New: func() interface{} {
+ New: func() any {
return &varActivation{}
},
}
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 b33f7f7fd9..afb7c8d5bf 100644
--- a/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go
+++ b/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go
@@ -15,8 +15,6 @@
package interpreter
import (
- "fmt"
-
"github.com/google/cel-go/common/containers"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
@@ -36,9 +34,9 @@ import (
//
// Examples:
//
-// 1. ns.myvar["complex-value"]
-// 2. ns.myvar["complex-value"][0]
-// 3. ns.myvar["complex-value"].*.name
+// 1. ns.myvar["complex-value"]
+// 2. ns.myvar["complex-value"][0]
+// 3. ns.myvar["complex-value"].*.name
//
// The first example is simple: match an attribute where the variable is 'ns.myvar' with a
// field access on 'complex-value'. The second example expands the match to indicate that only
@@ -108,7 +106,7 @@ func (apat *AttributePattern) QualifierPatterns() []*AttributeQualifierPattern {
// AttributeQualifierPattern holds a wildcard or valued qualifier pattern.
type AttributeQualifierPattern struct {
wildcard bool
- value interface{}
+ value any
}
// Matches returns true if the qualifier pattern is a wildcard, or the Qualifier implements the
@@ -134,44 +132,44 @@ func (qpat *AttributeQualifierPattern) Matches(q Qualifier) bool {
type qualifierValueEquator interface {
// QualifierValueEquals returns true if the input value is equal to the value held in the
// Qualifier.
- QualifierValueEquals(value interface{}) bool
+ QualifierValueEquals(value any) bool
}
// QualifierValueEquals implementation for boolean qualifiers.
-func (q *boolQualifier) QualifierValueEquals(value interface{}) bool {
+func (q *boolQualifier) QualifierValueEquals(value any) bool {
bval, ok := value.(bool)
return ok && q.value == bval
}
// QualifierValueEquals implementation for field qualifiers.
-func (q *fieldQualifier) QualifierValueEquals(value interface{}) bool {
+func (q *fieldQualifier) QualifierValueEquals(value any) bool {
sval, ok := value.(string)
return ok && q.Name == sval
}
// QualifierValueEquals implementation for string qualifiers.
-func (q *stringQualifier) QualifierValueEquals(value interface{}) bool {
+func (q *stringQualifier) QualifierValueEquals(value any) bool {
sval, ok := value.(string)
return ok && q.value == sval
}
// QualifierValueEquals implementation for int qualifiers.
-func (q *intQualifier) QualifierValueEquals(value interface{}) bool {
+func (q *intQualifier) QualifierValueEquals(value any) bool {
return numericValueEquals(value, q.celValue)
}
// QualifierValueEquals implementation for uint qualifiers.
-func (q *uintQualifier) QualifierValueEquals(value interface{}) bool {
+func (q *uintQualifier) QualifierValueEquals(value any) bool {
return numericValueEquals(value, q.celValue)
}
// QualifierValueEquals implementation for double qualifiers.
-func (q *doubleQualifier) QualifierValueEquals(value interface{}) bool {
+func (q *doubleQualifier) QualifierValueEquals(value any) bool {
return numericValueEquals(value, q.celValue)
}
// numericValueEquals uses CEL equality to determine whether two number values are
-func numericValueEquals(value interface{}, celValue ref.Val) bool {
+func numericValueEquals(value any, celValue ref.Val) bool {
val := types.DefaultTypeAdapter.NativeToValue(value)
return celValue.Equal(val) == types.True
}
@@ -272,13 +270,9 @@ func (fac *partialAttributeFactory) matchesUnknownPatterns(
if err != nil {
return nil, err
}
- unk, isUnk := val.(types.Unknown)
- if isUnk {
- return unk, nil
- }
// If this resolution behavior ever changes, new implementations of the
// qualifierValueEquator may be required to handle proper resolution.
- qual, err = fac.NewQualifier(nil, qual.ID(), val)
+ qual, err = fac.NewQualifier(nil, qual.ID(), val, attr.IsOptional())
if err != nil {
return nil, err
}
@@ -338,24 +332,10 @@ func (m *attributeMatcher) AddQualifier(qual Qualifier) (Attribute, error) {
return m, nil
}
-// Resolve is an implementation of the Attribute interface method which uses the
-// attributeMatcher TryResolve implementation rather than the embedded NamespacedAttribute
-// Resolve implementation.
-func (m *attributeMatcher) Resolve(vars Activation) (interface{}, error) {
- obj, found, err := m.TryResolve(vars)
- if err != nil {
- return nil, err
- }
- if !found {
- return nil, fmt.Errorf("no such attribute: %v", m.NamespacedAttribute)
- }
- return obj, nil
-}
-
-// TryResolve is an implementation of the NamespacedAttribute interface method which tests
+// Resolve is an implementation of the NamespacedAttribute interface method which tests
// for matching unknown attribute patterns and returns types.Unknown if present. Otherwise,
// the standard Resolve logic applies.
-func (m *attributeMatcher) TryResolve(vars Activation) (interface{}, bool, error) {
+func (m *attributeMatcher) Resolve(vars Activation) (any, error) {
id := m.NamespacedAttribute.ID()
// Bug in how partial activation is resolved, should search parents as well.
partial, isPartial := toPartialActivation(vars)
@@ -366,30 +346,23 @@ func (m *attributeMatcher) TryResolve(vars Activation) (interface{}, bool, error
m.CandidateVariableNames(),
m.qualifiers)
if err != nil {
- return nil, true, err
+ return nil, err
}
if unk != nil {
- return unk, true, nil
+ return unk, nil
}
}
- return m.NamespacedAttribute.TryResolve(vars)
+ return m.NamespacedAttribute.Resolve(vars)
}
// Qualify is an implementation of the Qualifier interface method.
-func (m *attributeMatcher) Qualify(vars Activation, obj interface{}) (interface{}, error) {
- val, err := m.Resolve(vars)
- if err != nil {
- return nil, err
- }
- unk, isUnk := val.(types.Unknown)
- if isUnk {
- return unk, nil
- }
- qual, err := m.fac.NewQualifier(nil, m.ID(), val)
- if err != nil {
- return nil, err
- }
- return qual.Qualify(vars, obj)
+func (m *attributeMatcher) Qualify(vars Activation, obj any) (any, error) {
+ return attrQualify(m.fac, vars, obj, m)
+}
+
+// QualifyIfPresent is an implementation of the Qualifier interface method.
+func (m *attributeMatcher) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) {
+ return attrQualifyIfPresent(m.fac, vars, obj, m, presenceOnly)
}
func toPartialActivation(vars Activation) (PartialActivation, bool) {
diff --git a/vendor/github.com/google/cel-go/interpreter/attributes.go b/vendor/github.com/google/cel-go/interpreter/attributes.go
index 4f1772ea39..1b19dc2b57 100644
--- a/vendor/github.com/google/cel-go/interpreter/attributes.go
+++ b/vendor/github.com/google/cel-go/interpreter/attributes.go
@@ -16,7 +16,7 @@ package interpreter
import (
"fmt"
- "math"
+ "strings"
"github.com/google/cel-go/common/containers"
"github.com/google/cel-go/common/types"
@@ -61,7 +61,7 @@ type AttributeFactory interface {
// The qualifier may consider the object type being qualified, if present. If absent, the
// qualification should be considered dynamic and the qualification should still work, though
// it may be sub-optimal.
- NewQualifier(objType *exprpb.Type, qualID int64, val interface{}) (Qualifier, error)
+ NewQualifier(objType *exprpb.Type, qualID int64, val any, opt bool) (Qualifier, error)
}
// Qualifier marker interface for designating different qualifier values and where they appear
@@ -70,9 +70,21 @@ type Qualifier interface {
// ID where the qualifier appears within an expression.
ID() int64
+ // IsOptional specifies whether the qualifier is optional.
+ // Instead of a direct qualification, an optional qualifier will be resolved via QualifyIfPresent
+ // rather than Qualify. A non-optional qualifier may also be resolved through QualifyIfPresent if
+ // the object to qualify is itself optional.
+ IsOptional() bool
+
// Qualify performs a qualification, e.g. field selection, on the input object and returns
- // the value or error that results.
- Qualify(vars Activation, obj interface{}) (interface{}, error)
+ // the value of the access and whether the value was set. A non-nil value with a false presence
+ // test result indicates that the value being returned is the default value.
+ Qualify(vars Activation, obj any) (any, error)
+
+ // QualifyIfPresent qualifies the object if the qualifier is declared or defined on the object.
+ // The 'presenceOnly' flag indicates that the value is not necessary, just a boolean status as
+ // to whether the qualifier is present.
+ QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error)
}
// ConstantQualifier interface embeds the Qualifier interface and provides an option to inspect the
@@ -82,6 +94,7 @@ type Qualifier interface {
type ConstantQualifier interface {
Qualifier
+ // Value returns the constant value associated with the qualifier.
Value() ref.Val
}
@@ -90,12 +103,16 @@ type ConstantQualifier interface {
type Attribute interface {
Qualifier
- // AddQualifier adds a qualifier on the Attribute or error if the qualification is not a valid
- // qualifier type.
+ // AddQualifier adds a qualifier on the Attribute or error if the qualification is not a valid qualifier type.
AddQualifier(Qualifier) (Attribute, error)
- // Resolve returns the value of the Attribute given the current Activation.
- Resolve(Activation) (interface{}, error)
+ // Resolve returns the value of the Attribute and whether it was present given an Activation.
+ // For objects which support safe traversal, the value may be non-nil and the presence flag be false.
+ //
+ // If an error is encountered during attribute resolution, it will be returned immediately.
+ // If the attribute cannot be resolved within the Activation, the result must be: `nil`, `error`
+ // with the error indicating which variable was missing.
+ Resolve(Activation) (any, error)
}
// NamespacedAttribute values are a variable within a namespace, and an optional set of qualifiers
@@ -107,22 +124,14 @@ type NamespacedAttribute interface {
// the CEL namespace resolution order.
CandidateVariableNames() []string
- // Qualifiers returns the list of qualifiers associated with the Attribute.s
+ // Qualifiers returns the list of qualifiers associated with the Attribute.
Qualifiers() []Qualifier
-
- // TryResolve attempts to return the value of the attribute given the current Activation.
- // If an error is encountered during attribute resolution, it will be returned immediately.
- // If the attribute cannot be resolved within the Activation, the result must be: `nil`,
- // `false`, `nil`.
- TryResolve(Activation) (interface{}, bool, error)
}
// NewAttributeFactory returns a default AttributeFactory which is produces Attribute values
// capable of resolving types by simple names and qualify the values using the supported qualifier
// types: bool, int, string, and uint.
-func NewAttributeFactory(cont *containers.Container,
- a ref.TypeAdapter,
- p ref.TypeProvider) AttributeFactory {
+func NewAttributeFactory(cont *containers.Container, a ref.TypeAdapter, p ref.TypeProvider) AttributeFactory {
return &attrFactory{
container: cont,
adapter: a,
@@ -190,9 +199,7 @@ func (r *attrFactory) RelativeAttribute(id int64, operand Interpretable) Attribu
}
// NewQualifier is an implementation of the AttributeFactory interface.
-func (r *attrFactory) NewQualifier(objType *exprpb.Type,
- qualID int64,
- val interface{}) (Qualifier, error) {
+func (r *attrFactory) NewQualifier(objType *exprpb.Type, qualID int64, val any, opt bool) (Qualifier, error) {
// Before creating a new qualifier check to see if this is a protobuf message field access.
// If so, use the precomputed GetFrom qualification method rather than the standard
// stringQualifier.
@@ -205,10 +212,11 @@ func (r *attrFactory) NewQualifier(objType *exprpb.Type,
Name: str,
FieldType: ft,
adapter: r.adapter,
+ optional: opt,
}, nil
}
}
- return newQualifier(r.adapter, qualID, val)
+ return newQualifier(r.adapter, qualID, val, opt)
}
type absoluteAttribute struct {
@@ -224,19 +232,18 @@ type absoluteAttribute struct {
// ID implements the Attribute interface method.
func (a *absoluteAttribute) ID() int64 {
- return a.id
+ qualCount := len(a.qualifiers)
+ if qualCount == 0 {
+ return a.id
+ }
+ return a.qualifiers[qualCount-1].ID()
}
-// Cost implements the Coster interface method.
-func (a *absoluteAttribute) Cost() (min, max int64) {
- for _, q := range a.qualifiers {
- minQ, maxQ := estimateCost(q)
- min += minQ
- max += maxQ
- }
- min++ // For object retrieval.
- max++
- return
+// IsOptional returns trivially false for an attribute as the attribute represents a fully
+// qualified variable name. If the attribute is used in an optional manner, then an attrQualifier
+// is created and marks the attribute as optional.
+func (a *absoluteAttribute) IsOptional() bool {
+ return false
}
// AddQualifier implements the Attribute interface method.
@@ -256,33 +263,13 @@ func (a *absoluteAttribute) Qualifiers() []Qualifier {
}
// Qualify is an implementation of the Qualifier interface method.
-func (a *absoluteAttribute) Qualify(vars Activation, obj interface{}) (interface{}, error) {
- val, err := a.Resolve(vars)
- if err != nil {
- return nil, err
- }
- unk, isUnk := val.(types.Unknown)
- if isUnk {
- return unk, nil
- }
- qual, err := a.fac.NewQualifier(nil, a.id, val)
- if err != nil {
- return nil, err
- }
- return qual.Qualify(vars, obj)
+func (a *absoluteAttribute) Qualify(vars Activation, obj any) (any, error) {
+ return attrQualify(a.fac, vars, obj, a)
}
-// Resolve returns the resolved Attribute value given the Activation, or error if the Attribute
-// variable is not found, or if its Qualifiers cannot be applied successfully.
-func (a *absoluteAttribute) Resolve(vars Activation) (interface{}, error) {
- obj, found, err := a.TryResolve(vars)
- if err != nil {
- return nil, err
- }
- if found {
- return obj, nil
- }
- return nil, fmt.Errorf("no such attribute: %v", a)
+// QualifyIfPresent is an implementation of the Qualifier interface method.
+func (a *absoluteAttribute) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) {
+ return attrQualifyIfPresent(a.fac, vars, obj, a, presenceOnly)
}
// String implements the Stringer interface method.
@@ -290,36 +277,47 @@ func (a *absoluteAttribute) String() string {
return fmt.Sprintf("id: %v, names: %v", a.id, a.namespaceNames)
}
-// TryResolve iterates through the namespaced variable names until one is found within the
-// Activation or TypeProvider.
+// Resolve returns the resolved Attribute value given the Activation, or error if the Attribute
+// variable is not found, or if its Qualifiers cannot be applied successfully.
//
// If the variable name cannot be found as an Activation variable or in the TypeProvider as
-// a type, then the result is `nil`, `false`, `nil` per the interface requirement.
-func (a *absoluteAttribute) TryResolve(vars Activation) (interface{}, bool, error) {
+// a type, then the result is `nil`, `error` with the error indicating the name of the first
+// variable searched as missing.
+func (a *absoluteAttribute) Resolve(vars Activation) (any, error) {
for _, nm := range a.namespaceNames {
// If the variable is found, process it. Otherwise, wait until the checks to
// determine whether the type is unknown before returning.
- op, found := vars.ResolveName(nm)
+ obj, found := vars.ResolveName(nm)
if found {
- var err error
- for _, qual := range a.qualifiers {
- op, err = qual.Qualify(vars, op)
- if err != nil {
- return nil, true, err
+ obj, isOpt, err := applyQualifiers(vars, obj, a.qualifiers)
+ if err != nil {
+ return nil, err
+ }
+ if isOpt {
+ val := a.adapter.NativeToValue(obj)
+ if types.IsUnknown(val) {
+ return val, nil
}
+ return types.OptionalOf(val), nil
}
- return op, true, nil
+ return obj, nil
}
// Attempt to resolve the qualified type name if the name is not a variable identifier.
typ, found := a.provider.FindIdent(nm)
if found {
if len(a.qualifiers) == 0 {
- return typ, true, nil
+ return typ, nil
}
- return nil, true, fmt.Errorf("no such attribute: %v", typ)
}
}
- return nil, false, nil
+ var attrNames strings.Builder
+ for i, nm := range a.namespaceNames {
+ if i != 0 {
+ attrNames.WriteString(", ")
+ }
+ attrNames.WriteString(nm)
+ }
+ return nil, missingAttribute(attrNames.String())
}
type conditionalAttribute struct {
@@ -333,17 +331,19 @@ type conditionalAttribute struct {
// ID is an implementation of the Attribute interface method.
func (a *conditionalAttribute) ID() int64 {
+ // There's a field access after the conditional.
+ if a.truthy.ID() == a.falsy.ID() {
+ return a.truthy.ID()
+ }
+ // Otherwise return the conditional id as the consistent id being tracked.
return a.id
}
-// Cost provides the heuristic cost of a ternary operation ? : .
-// The cost is computed as cost(expr) plus the min/max costs of evaluating either
-// `t` or `f`.
-func (a *conditionalAttribute) Cost() (min, max int64) {
- tMin, tMax := estimateCost(a.truthy)
- fMin, fMax := estimateCost(a.falsy)
- eMin, eMax := estimateCost(a.expr)
- return eMin + findMin(tMin, fMin), eMax + findMax(tMax, fMax)
+// IsOptional returns trivially false for an attribute as the attribute represents a fully
+// qualified variable name. If the attribute is used in an optional manner, then an attrQualifier
+// is created and marks the attribute as optional.
+func (a *conditionalAttribute) IsOptional() bool {
+ return false
}
// AddQualifier appends the same qualifier to both sides of the conditional, in effect managing
@@ -361,28 +361,18 @@ func (a *conditionalAttribute) AddQualifier(qual Qualifier) (Attribute, error) {
}
// Qualify is an implementation of the Qualifier interface method.
-func (a *conditionalAttribute) Qualify(vars Activation, obj interface{}) (interface{}, error) {
- val, err := a.Resolve(vars)
- if err != nil {
- return nil, err
- }
- unk, isUnk := val.(types.Unknown)
- if isUnk {
- return unk, nil
- }
- qual, err := a.fac.NewQualifier(nil, a.id, val)
- if err != nil {
- return nil, err
- }
- return qual.Qualify(vars, obj)
+func (a *conditionalAttribute) Qualify(vars Activation, obj any) (any, error) {
+ return attrQualify(a.fac, vars, obj, a)
+}
+
+// QualifyIfPresent is an implementation of the Qualifier interface method.
+func (a *conditionalAttribute) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) {
+ return attrQualifyIfPresent(a.fac, vars, obj, a, presenceOnly)
}
// Resolve evaluates the condition, and then resolves the truthy or falsy branch accordingly.
-func (a *conditionalAttribute) Resolve(vars Activation) (interface{}, error) {
+func (a *conditionalAttribute) Resolve(vars Activation) (any, error) {
val := a.expr.Eval(vars)
- if types.IsError(val) {
- return nil, val.(*types.Err)
- }
if val == types.True {
return a.truthy.Resolve(vars)
}
@@ -410,33 +400,14 @@ type maybeAttribute struct {
// ID is an implementation of the Attribute interface method.
func (a *maybeAttribute) ID() int64 {
- return a.id
+ return a.attrs[0].ID()
}
-// Cost implements the Coster interface method. The min cost is computed as the minimal cost among
-// all the possible attributes, the max cost ditto.
-func (a *maybeAttribute) Cost() (min, max int64) {
- min, max = math.MaxInt64, 0
- for _, a := range a.attrs {
- minA, maxA := estimateCost(a)
- min = findMin(min, minA)
- max = findMax(max, maxA)
- }
- return
-}
-
-func findMin(x, y int64) int64 {
- if x < y {
- return x
- }
- return y
-}
-
-func findMax(x, y int64) int64 {
- if x > y {
- return x
- }
- return y
+// IsOptional returns trivially false for an attribute as the attribute represents a fully
+// qualified variable name. If the attribute is used in an optional manner, then an attrQualifier
+// is created and marks the attribute as optional.
+func (a *maybeAttribute) IsOptional() bool {
+ return false
}
// AddQualifier adds a qualifier to each possible attribute variant, and also creates
@@ -446,21 +417,21 @@ func findMax(x, y int64) int64 {
//
// 1. Create a maybe attribute from a simple identifier when it occurs in a parsed-only expression
//
-// mb = MaybeAttribute(, "a")
+// mb = MaybeAttribute(, "a")
//
-// Initializing the maybe attribute creates an absolute attribute internally which includes the
-// possible namespaced names of the attribute. In this example, let's assume we are in namespace
-// 'ns', then the maybe is either one of the following variable names:
+// Initializing the maybe attribute creates an absolute attribute internally which includes the
+// possible namespaced names of the attribute. In this example, let's assume we are in namespace
+// 'ns', then the maybe is either one of the following variable names:
//
-// possible variables names -- ns.a, a
+// possible variables names -- ns.a, a
//
// 2. Adding a qualifier to the maybe means that the variable name could be a longer qualified
-// name, or a field selection on one of the possible variable names produced earlier:
+// name, or a field selection on one of the possible variable names produced earlier:
//
-// mb.AddQualifier("b")
+// mb.AddQualifier("b")
//
-// possible variables names -- ns.a.b, a.b
-// possible field selection -- ns.a['b'], a['b']
+// possible variables names -- ns.a.b, a.b
+// possible field selection -- ns.a['b'], a['b']
//
// If none of the attributes within the maybe resolves a value, the result is an error.
func (a *maybeAttribute) AddQualifier(qual Qualifier) (Attribute, error) {
@@ -486,43 +457,49 @@ func (a *maybeAttribute) AddQualifier(qual Qualifier) (Attribute, error) {
}
}
// Next, ensure the most specific variable / type reference is searched first.
- a.attrs = append([]NamespacedAttribute{a.fac.AbsoluteAttribute(qual.ID(), augmentedNames...)}, a.attrs...)
+ if len(augmentedNames) != 0 {
+ a.attrs = append([]NamespacedAttribute{a.fac.AbsoluteAttribute(qual.ID(), augmentedNames...)}, a.attrs...)
+ }
return a, nil
}
// Qualify is an implementation of the Qualifier interface method.
-func (a *maybeAttribute) Qualify(vars Activation, obj interface{}) (interface{}, error) {
- val, err := a.Resolve(vars)
- if err != nil {
- return nil, err
- }
- unk, isUnk := val.(types.Unknown)
- if isUnk {
- return unk, nil
- }
- qual, err := a.fac.NewQualifier(nil, a.id, val)
- if err != nil {
- return nil, err
- }
- return qual.Qualify(vars, obj)
+func (a *maybeAttribute) Qualify(vars Activation, obj any) (any, error) {
+ return attrQualify(a.fac, vars, obj, a)
+}
+
+// QualifyIfPresent is an implementation of the Qualifier interface method.
+func (a *maybeAttribute) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) {
+ return attrQualifyIfPresent(a.fac, vars, obj, a, presenceOnly)
}
// Resolve follows the variable resolution rules to determine whether the attribute is a variable
// or a field selection.
-func (a *maybeAttribute) Resolve(vars Activation) (interface{}, error) {
+func (a *maybeAttribute) Resolve(vars Activation) (any, error) {
+ var maybeErr error
for _, attr := range a.attrs {
- obj, found, err := attr.TryResolve(vars)
+ obj, err := attr.Resolve(vars)
// Return an error if one is encountered.
if err != nil {
- return nil, err
- }
- // If the object was found, return it.
- if found {
- return obj, nil
+ resErr, ok := err.(*resolutionError)
+ if !ok {
+ return nil, err
+ }
+ // If this was not a missing variable error, return it.
+ if !resErr.isMissingAttribute() {
+ return nil, err
+ }
+ // When the variable is missing in a maybe attribute we defer erroring.
+ if maybeErr == nil {
+ maybeErr = resErr
+ }
+ // Continue attempting to resolve possible variables.
+ continue
}
+ return obj, nil
}
// Else, produce a no such attribute error.
- return nil, fmt.Errorf("no such attribute: %v", a)
+ return nil, maybeErr
}
// String is an implementation of the Stringer interface method.
@@ -540,18 +517,18 @@ type relativeAttribute struct {
// ID is an implementation of the Attribute interface method.
func (a *relativeAttribute) ID() int64 {
- return a.id
+ qualCount := len(a.qualifiers)
+ if qualCount == 0 {
+ return a.id
+ }
+ return a.qualifiers[qualCount-1].ID()
}
-// Cost implements the Coster interface method.
-func (a *relativeAttribute) Cost() (min, max int64) {
- min, max = estimateCost(a.operand)
- for _, qual := range a.qualifiers {
- minQ, maxQ := estimateCost(qual)
- min += minQ
- max += maxQ
- }
- return
+// IsOptional returns trivially false for an attribute as the attribute represents a fully
+// qualified variable name. If the attribute is used in an optional manner, then an attrQualifier
+// is created and marks the attribute as optional.
+func (a *relativeAttribute) IsOptional() bool {
+ return false
}
// AddQualifier implements the Attribute interface method.
@@ -561,24 +538,17 @@ func (a *relativeAttribute) AddQualifier(qual Qualifier) (Attribute, error) {
}
// Qualify is an implementation of the Qualifier interface method.
-func (a *relativeAttribute) Qualify(vars Activation, obj interface{}) (interface{}, error) {
- val, err := a.Resolve(vars)
- if err != nil {
- return nil, err
- }
- unk, isUnk := val.(types.Unknown)
- if isUnk {
- return unk, nil
- }
- qual, err := a.fac.NewQualifier(nil, a.id, val)
- if err != nil {
- return nil, err
- }
- return qual.Qualify(vars, obj)
+func (a *relativeAttribute) Qualify(vars Activation, obj any) (any, error) {
+ return attrQualify(a.fac, vars, obj, a)
+}
+
+// QualifyIfPresent is an implementation of the Qualifier interface method.
+func (a *relativeAttribute) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) {
+ return attrQualifyIfPresent(a.fac, vars, obj, a, presenceOnly)
}
// Resolve expression value and qualifier relative to the expression result.
-func (a *relativeAttribute) Resolve(vars Activation) (interface{}, error) {
+func (a *relativeAttribute) Resolve(vars Activation) (any, error) {
// First, evaluate the operand.
v := a.operand.Eval(vars)
if types.IsError(v) {
@@ -587,14 +557,16 @@ func (a *relativeAttribute) Resolve(vars Activation) (interface{}, error) {
if types.IsUnknown(v) {
return v, nil
}
- // Next, qualify it. Qualification handles unknowns as well, so there's no need to recheck.
- var err error
- var obj interface{} = v
- for _, qual := range a.qualifiers {
- obj, err = qual.Qualify(vars, obj)
- if err != nil {
- return nil, err
+ obj, isOpt, err := applyQualifiers(vars, v, a.qualifiers)
+ if err != nil {
+ return nil, err
+ }
+ if isOpt {
+ val := a.adapter.NativeToValue(obj)
+ if types.IsUnknown(val) {
+ return val, nil
}
+ return types.OptionalOf(val), nil
}
return obj, nil
}
@@ -604,42 +576,93 @@ func (a *relativeAttribute) String() string {
return fmt.Sprintf("id: %v, operand: %v", a.id, a.operand)
}
-func newQualifier(adapter ref.TypeAdapter, id int64, v interface{}) (Qualifier, error) {
+func newQualifier(adapter ref.TypeAdapter, id int64, v any, opt bool) (Qualifier, error) {
var qual Qualifier
switch val := v.(type) {
case Attribute:
- return &attrQualifier{id: id, Attribute: val}, nil
+ // Note, attributes are initially identified as non-optional since they represent a top-level
+ // field access; however, when used as a relative qualifier, e.g. a[?b.c], then an attrQualifier
+ // is created which intercepts the IsOptional check for the attribute in order to return the
+ // correct result.
+ return &attrQualifier{
+ id: id,
+ Attribute: val,
+ optional: opt,
+ }, nil
case string:
- qual = &stringQualifier{id: id, value: val, celValue: types.String(val), adapter: adapter}
+ qual = &stringQualifier{
+ id: id,
+ value: val,
+ celValue: types.String(val),
+ adapter: adapter,
+ optional: opt,
+ }
case int:
- qual = &intQualifier{id: id, value: int64(val), celValue: types.Int(val), adapter: adapter}
+ qual = &intQualifier{
+ id: id, value: int64(val), celValue: types.Int(val), adapter: adapter, optional: opt,
+ }
case int32:
- qual = &intQualifier{id: id, value: int64(val), celValue: types.Int(val), adapter: adapter}
+ qual = &intQualifier{
+ id: id, value: int64(val), celValue: types.Int(val), adapter: adapter, optional: opt,
+ }
case int64:
- qual = &intQualifier{id: id, value: val, celValue: types.Int(val), adapter: adapter}
+ qual = &intQualifier{
+ id: id, value: val, celValue: types.Int(val), adapter: adapter, optional: opt,
+ }
case uint:
- qual = &uintQualifier{id: id, value: uint64(val), celValue: types.Uint(val), adapter: adapter}
+ qual = &uintQualifier{
+ id: id, value: uint64(val), celValue: types.Uint(val), adapter: adapter, optional: opt,
+ }
case uint32:
- qual = &uintQualifier{id: id, value: uint64(val), celValue: types.Uint(val), adapter: adapter}
+ qual = &uintQualifier{
+ id: id, value: uint64(val), celValue: types.Uint(val), adapter: adapter, optional: opt,
+ }
case uint64:
- qual = &uintQualifier{id: id, value: val, celValue: types.Uint(val), adapter: adapter}
+ qual = &uintQualifier{
+ id: id, value: val, celValue: types.Uint(val), adapter: adapter, optional: opt,
+ }
case bool:
- qual = &boolQualifier{id: id, value: val, celValue: types.Bool(val), adapter: adapter}
+ qual = &boolQualifier{
+ id: id, value: val, celValue: types.Bool(val), adapter: adapter, optional: opt,
+ }
case float32:
- qual = &doubleQualifier{id: id, value: float64(val), celValue: types.Double(val), adapter: adapter}
+ qual = &doubleQualifier{
+ id: id,
+ value: float64(val),
+ celValue: types.Double(val),
+ adapter: adapter,
+ optional: opt,
+ }
case float64:
- qual = &doubleQualifier{id: id, value: val, celValue: types.Double(val), adapter: adapter}
+ qual = &doubleQualifier{
+ id: id, value: val, celValue: types.Double(val), adapter: adapter, optional: opt,
+ }
case types.String:
- qual = &stringQualifier{id: id, value: string(val), celValue: val, adapter: adapter}
+ qual = &stringQualifier{
+ id: id, value: string(val), celValue: val, adapter: adapter, optional: opt,
+ }
case types.Int:
- qual = &intQualifier{id: id, value: int64(val), celValue: val, adapter: adapter}
+ qual = &intQualifier{
+ id: id, value: int64(val), celValue: val, adapter: adapter, optional: opt,
+ }
case types.Uint:
- qual = &uintQualifier{id: id, value: uint64(val), celValue: val, adapter: adapter}
+ qual = &uintQualifier{
+ id: id, value: uint64(val), celValue: val, adapter: adapter, optional: opt,
+ }
case types.Bool:
- qual = &boolQualifier{id: id, value: bool(val), celValue: val, adapter: adapter}
+ qual = &boolQualifier{
+ id: id, value: bool(val), celValue: val, adapter: adapter, optional: opt,
+ }
case types.Double:
- qual = &doubleQualifier{id: id, value: float64(val), celValue: val, adapter: adapter}
+ qual = &doubleQualifier{
+ id: id, value: float64(val), celValue: val, adapter: adapter, optional: opt,
+ }
+ case types.Unknown:
+ qual = &unknownQualifier{id: id, value: val}
default:
+ if q, ok := v.(Qualifier); ok {
+ return q, nil
+ }
return nil, fmt.Errorf("invalid qualifier type: %T", v)
}
return qual, nil
@@ -648,15 +671,18 @@ func newQualifier(adapter ref.TypeAdapter, id int64, v interface{}) (Qualifier,
type attrQualifier struct {
id int64
Attribute
+ optional bool
}
+// ID implements the Qualifier interface method and returns the qualification instruction id
+// rather than the attribute id.
func (q *attrQualifier) ID() int64 {
return q.id
}
-// Cost returns zero for constant field qualifiers
-func (q *attrQualifier) Cost() (min, max int64) {
- return estimateCost(q.Attribute)
+// IsOptional implements the Qualifier interface method.
+func (q *attrQualifier) IsOptional() bool {
+ return q.optional
}
type stringQualifier struct {
@@ -664,6 +690,7 @@ type stringQualifier struct {
value string
celValue ref.Val
adapter ref.TypeAdapter
+ optional bool
}
// ID is an implementation of the Qualifier interface method.
@@ -671,58 +698,87 @@ func (q *stringQualifier) ID() int64 {
return q.id
}
+// IsOptional implements the Qualifier interface method.
+func (q *stringQualifier) IsOptional() bool {
+ return q.optional
+}
+
// Qualify implements the Qualifier interface method.
-func (q *stringQualifier) Qualify(vars Activation, obj interface{}) (interface{}, error) {
+func (q *stringQualifier) Qualify(vars Activation, obj any) (any, error) {
+ val, _, err := q.qualifyInternal(vars, obj, false, false)
+ return val, err
+}
+
+// QualifyIfPresent is an implementation of the Qualifier interface method.
+func (q *stringQualifier) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) {
+ return q.qualifyInternal(vars, obj, true, presenceOnly)
+}
+
+func (q *stringQualifier) qualifyInternal(vars Activation, obj any, presenceTest, presenceOnly bool) (any, bool, error) {
s := q.value
- isMap := false
- isKey := false
switch o := obj.(type) {
- case map[string]interface{}:
- isMap = true
- obj, isKey = o[s]
+ case map[string]any:
+ obj, isKey := o[s]
+ if isKey {
+ return obj, true, nil
+ }
case map[string]string:
- isMap = true
- obj, isKey = o[s]
+ obj, isKey := o[s]
+ if isKey {
+ return obj, true, nil
+ }
case map[string]int:
- isMap = true
- obj, isKey = o[s]
+ obj, isKey := o[s]
+ if isKey {
+ return obj, true, nil
+ }
case map[string]int32:
- isMap = true
- obj, isKey = o[s]
+ obj, isKey := o[s]
+ if isKey {
+ return obj, true, nil
+ }
case map[string]int64:
- isMap = true
- obj, isKey = o[s]
+ obj, isKey := o[s]
+ if isKey {
+ return obj, true, nil
+ }
case map[string]uint:
- isMap = true
- obj, isKey = o[s]
+ obj, isKey := o[s]
+ if isKey {
+ return obj, true, nil
+ }
case map[string]uint32:
- isMap = true
- obj, isKey = o[s]
+ obj, isKey := o[s]
+ if isKey {
+ return obj, true, nil
+ }
case map[string]uint64:
- isMap = true
- obj, isKey = o[s]
+ obj, isKey := o[s]
+ if isKey {
+ return obj, true, nil
+ }
case map[string]float32:
- isMap = true
- obj, isKey = o[s]
+ obj, isKey := o[s]
+ if isKey {
+ return obj, true, nil
+ }
case map[string]float64:
- isMap = true
- obj, isKey = o[s]
+ obj, isKey := o[s]
+ if isKey {
+ return obj, true, nil
+ }
case map[string]bool:
- isMap = true
- obj, isKey = o[s]
- case types.Unknown:
- return o, nil
- default:
- elem, err := refResolve(q.adapter, q.celValue, obj)
- if err != nil {
- return nil, err
+ obj, isKey := o[s]
+ if isKey {
+ return obj, true, nil
}
- return elem, nil
+ default:
+ return refQualify(q.adapter, obj, q.celValue, presenceTest, presenceOnly)
}
- if isMap && !isKey {
- return nil, fmt.Errorf("no such key: %v", s)
+ if presenceTest {
+ return nil, false, nil
}
- return obj, nil
+ return nil, false, missingKey(q.celValue)
}
// Value implements the ConstantQualifier interface
@@ -730,16 +786,12 @@ func (q *stringQualifier) Value() ref.Val {
return q.celValue
}
-// Cost returns zero for constant field qualifiers
-func (q *stringQualifier) Cost() (min, max int64) {
- return 0, 0
-}
-
type intQualifier struct {
id int64
value int64
celValue ref.Val
adapter ref.TypeAdapter
+ optional bool
}
// ID is an implementation of the Qualifier interface method.
@@ -747,97 +799,113 @@ func (q *intQualifier) ID() int64 {
return q.id
}
+// IsOptional implements the Qualifier interface method.
+func (q *intQualifier) IsOptional() bool {
+ return q.optional
+}
+
// Qualify implements the Qualifier interface method.
-func (q *intQualifier) Qualify(vars Activation, obj interface{}) (interface{}, error) {
+func (q *intQualifier) Qualify(vars Activation, obj any) (any, error) {
+ val, _, err := q.qualifyInternal(vars, obj, false, false)
+ return val, err
+}
+
+// QualifyIfPresent is an implementation of the Qualifier interface method.
+func (q *intQualifier) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) {
+ return q.qualifyInternal(vars, obj, true, presenceOnly)
+}
+
+func (q *intQualifier) qualifyInternal(vars Activation, obj any, presenceTest, presenceOnly bool) (any, bool, error) {
i := q.value
- isMap := false
- isKey := false
- isIndex := false
+ var isMap bool
switch o := obj.(type) {
// The specialized map types supported by an int qualifier are considerably fewer than the set
// of specialized map types supported by string qualifiers since they are less frequently used
// than string-based map keys. Additional specializations may be added in the future if
// desired.
- case map[int]interface{}:
+ case map[int]any:
isMap = true
- obj, isKey = o[int(i)]
- case map[int32]interface{}:
+ obj, isKey := o[int(i)]
+ if isKey {
+ return obj, true, nil
+ }
+ case map[int32]any:
isMap = true
- obj, isKey = o[int32(i)]
- case map[int64]interface{}:
+ obj, isKey := o[int32(i)]
+ if isKey {
+ return obj, true, nil
+ }
+ case map[int64]any:
isMap = true
- obj, isKey = o[i]
- case []interface{}:
- isIndex = i >= 0 && i < int64(len(o))
+ obj, isKey := o[i]
+ if isKey {
+ return obj, true, nil
+ }
+ case []any:
+ isIndex := i >= 0 && i < int64(len(o))
if isIndex {
- obj = o[i]
+ return o[i], true, nil
}
case []string:
- isIndex = i >= 0 && i < int64(len(o))
+ isIndex := i >= 0 && i < int64(len(o))
if isIndex {
- obj = o[i]
+ return o[i], true, nil
}
case []int:
- isIndex = i >= 0 && i < int64(len(o))
+ isIndex := i >= 0 && i < int64(len(o))
if isIndex {
- obj = o[i]
+ return o[i], true, nil
}
case []int32:
- isIndex = i >= 0 && i < int64(len(o))
+ isIndex := i >= 0 && i < int64(len(o))
if isIndex {
- obj = o[i]
+ return o[i], true, nil
}
case []int64:
- isIndex = i >= 0 && i < int64(len(o))
+ isIndex := i >= 0 && i < int64(len(o))
if isIndex {
- obj = o[i]
+ return o[i], true, nil
}
case []uint:
- isIndex = i >= 0 && i < int64(len(o))
+ isIndex := i >= 0 && i < int64(len(o))
if isIndex {
- obj = o[i]
+ return o[i], true, nil
}
case []uint32:
- isIndex = i >= 0 && i < int64(len(o))
+ isIndex := i >= 0 && i < int64(len(o))
if isIndex {
- obj = o[i]
+ return o[i], true, nil
}
case []uint64:
- isIndex = i >= 0 && i < int64(len(o))
+ isIndex := i >= 0 && i < int64(len(o))
if isIndex {
- obj = o[i]
+ return o[i], true, nil
}
case []float32:
- isIndex = i >= 0 && i < int64(len(o))
+ isIndex := i >= 0 && i < int64(len(o))
if isIndex {
- obj = o[i]
+ return o[i], true, nil
}
case []float64:
- isIndex = i >= 0 && i < int64(len(o))
+ isIndex := i >= 0 && i < int64(len(o))
if isIndex {
- obj = o[i]
+ return o[i], true, nil
}
case []bool:
- isIndex = i >= 0 && i < int64(len(o))
+ isIndex := i >= 0 && i < int64(len(o))
if isIndex {
- obj = o[i]
+ return o[i], true, nil
}
- case types.Unknown:
- return o, nil
default:
- elem, err := refResolve(q.adapter, q.celValue, obj)
- if err != nil {
- return nil, err
- }
- return elem, nil
+ return refQualify(q.adapter, obj, q.celValue, presenceTest, presenceOnly)
}
- if isMap && !isKey {
- return nil, fmt.Errorf("no such key: %v", i)
+ if presenceTest {
+ return nil, false, nil
}
- if !isMap && !isIndex {
- return nil, fmt.Errorf("index out of bounds: %v", i)
+ if isMap {
+ return nil, false, missingKey(q.celValue)
}
- return obj, nil
+ return nil, false, missingIndex(q.celValue)
}
// Value implements the ConstantQualifier interface
@@ -845,16 +913,12 @@ func (q *intQualifier) Value() ref.Val {
return q.celValue
}
-// Cost returns zero for constant field qualifiers
-func (q *intQualifier) Cost() (min, max int64) {
- return 0, 0
-}
-
type uintQualifier struct {
id int64
value uint64
celValue ref.Val
adapter ref.TypeAdapter
+ optional bool
}
// ID is an implementation of the Qualifier interface method.
@@ -862,38 +926,51 @@ func (q *uintQualifier) ID() int64 {
return q.id
}
+// IsOptional implements the Qualifier interface method.
+func (q *uintQualifier) IsOptional() bool {
+ return q.optional
+}
+
// Qualify implements the Qualifier interface method.
-func (q *uintQualifier) Qualify(vars Activation, obj interface{}) (interface{}, error) {
+func (q *uintQualifier) Qualify(vars Activation, obj any) (any, error) {
+ val, _, err := q.qualifyInternal(vars, obj, false, false)
+ return val, err
+}
+
+// QualifyIfPresent is an implementation of the Qualifier interface method.
+func (q *uintQualifier) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) {
+ return q.qualifyInternal(vars, obj, true, presenceOnly)
+}
+
+func (q *uintQualifier) qualifyInternal(vars Activation, obj any, presenceTest, presenceOnly bool) (any, bool, error) {
u := q.value
- isMap := false
- isKey := false
switch o := obj.(type) {
// The specialized map types supported by a uint qualifier are considerably fewer than the set
// of specialized map types supported by string qualifiers since they are less frequently used
// than string-based map keys. Additional specializations may be added in the future if
// desired.
- case map[uint]interface{}:
- isMap = true
- obj, isKey = o[uint(u)]
- case map[uint32]interface{}:
- isMap = true
- obj, isKey = o[uint32(u)]
- case map[uint64]interface{}:
- isMap = true
- obj, isKey = o[u]
- case types.Unknown:
- return o, nil
- default:
- elem, err := refResolve(q.adapter, q.celValue, obj)
- if err != nil {
- return nil, err
+ case map[uint]any:
+ obj, isKey := o[uint(u)]
+ if isKey {
+ return obj, true, nil
+ }
+ case map[uint32]any:
+ obj, isKey := o[uint32(u)]
+ if isKey {
+ return obj, true, nil
}
- return elem, nil
+ case map[uint64]any:
+ obj, isKey := o[u]
+ if isKey {
+ return obj, true, nil
+ }
+ default:
+ return refQualify(q.adapter, obj, q.celValue, presenceTest, presenceOnly)
}
- if isMap && !isKey {
- return nil, fmt.Errorf("no such key: %v", u)
+ if presenceTest {
+ return nil, false, nil
}
- return obj, nil
+ return nil, false, missingKey(q.celValue)
}
// Value implements the ConstantQualifier interface
@@ -901,16 +978,12 @@ func (q *uintQualifier) Value() ref.Val {
return q.celValue
}
-// Cost returns zero for constant field qualifiers
-func (q *uintQualifier) Cost() (min, max int64) {
- return 0, 0
-}
-
type boolQualifier struct {
id int64
value bool
celValue ref.Val
adapter ref.TypeAdapter
+ optional bool
}
// ID is an implementation of the Qualifier interface method.
@@ -918,30 +991,37 @@ func (q *boolQualifier) ID() int64 {
return q.id
}
+// IsOptional implements the Qualifier interface method.
+func (q *boolQualifier) IsOptional() bool {
+ return q.optional
+}
+
// Qualify implements the Qualifier interface method.
-func (q *boolQualifier) Qualify(vars Activation, obj interface{}) (interface{}, error) {
+func (q *boolQualifier) Qualify(vars Activation, obj any) (any, error) {
+ val, _, err := q.qualifyInternal(vars, obj, false, false)
+ return val, err
+}
+
+// QualifyIfPresent is an implementation of the Qualifier interface method.
+func (q *boolQualifier) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) {
+ return q.qualifyInternal(vars, obj, true, presenceOnly)
+}
+
+func (q *boolQualifier) qualifyInternal(vars Activation, obj any, presenceTest, presenceOnly bool) (any, bool, error) {
b := q.value
- isKey := false
switch o := obj.(type) {
- // The specialized map types supported by a bool qualifier are considerably fewer than the set
- // of specialized map types supported by string qualifiers since they are less frequently used
- // than string-based map keys. Additional specializations may be added in the future if
- // desired.
- case map[bool]interface{}:
- obj, isKey = o[b]
- case types.Unknown:
- return o, nil
- default:
- elem, err := refResolve(q.adapter, q.celValue, obj)
- if err != nil {
- return nil, err
+ case map[bool]any:
+ obj, isKey := o[b]
+ if isKey {
+ return obj, true, nil
}
- return elem, nil
+ default:
+ return refQualify(q.adapter, obj, q.celValue, presenceTest, presenceOnly)
}
- if !isKey {
- return nil, fmt.Errorf("no such key: %v", b)
+ if presenceTest {
+ return nil, false, nil
}
- return obj, nil
+ return nil, false, missingKey(q.celValue)
}
// Value implements the ConstantQualifier interface
@@ -949,11 +1029,6 @@ func (q *boolQualifier) Value() ref.Val {
return q.celValue
}
-// Cost returns zero for constant field qualifiers
-func (q *boolQualifier) Cost() (min, max int64) {
- return 0, 0
-}
-
// fieldQualifier indicates that the qualification is a well-defined field with a known
// field type. When the field type is known this can be used to improve the speed and
// efficiency of field resolution.
@@ -962,6 +1037,7 @@ type fieldQualifier struct {
Name string
FieldType *ref.FieldType
adapter ref.TypeAdapter
+ optional bool
}
// ID is an implementation of the Qualifier interface method.
@@ -969,12 +1045,39 @@ func (q *fieldQualifier) ID() int64 {
return q.id
}
+// IsOptional implements the Qualifier interface method.
+func (q *fieldQualifier) IsOptional() bool {
+ return q.optional
+}
+
// Qualify implements the Qualifier interface method.
-func (q *fieldQualifier) Qualify(vars Activation, obj interface{}) (interface{}, error) {
+func (q *fieldQualifier) Qualify(vars Activation, obj any) (any, error) {
if rv, ok := obj.(ref.Val); ok {
obj = rv.Value()
}
- return q.FieldType.GetFrom(obj)
+ val, err := q.FieldType.GetFrom(obj)
+ if err != nil {
+ return nil, err
+ }
+ return val, nil
+}
+
+// QualifyIfPresent is an implementation of the Qualifier interface method.
+func (q *fieldQualifier) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) {
+ if rv, ok := obj.(ref.Val); ok {
+ obj = rv.Value()
+ }
+ if !q.FieldType.IsSet(obj) {
+ return nil, false, nil
+ }
+ if presenceOnly {
+ return nil, true, nil
+ }
+ val, err := q.FieldType.GetFrom(obj)
+ if err != nil {
+ return nil, false, err
+ }
+ return val, true, nil
}
// Value implements the ConstantQualifier interface
@@ -982,11 +1085,6 @@ func (q *fieldQualifier) Value() ref.Val {
return types.String(q.Name)
}
-// Cost returns zero for constant field qualifiers
-func (q *fieldQualifier) Cost() (min, max int64) {
- return 0, 0
-}
-
// doubleQualifier qualifies a CEL object, map, or list using a double value.
//
// This qualifier is used for working with dynamic data like JSON or protobuf.Any where the value
@@ -997,6 +1095,7 @@ type doubleQualifier struct {
value float64
celValue ref.Val
adapter ref.TypeAdapter
+ optional bool
}
// ID is an implementation of the Qualifier interface method.
@@ -1004,48 +1103,237 @@ func (q *doubleQualifier) ID() int64 {
return q.id
}
+// IsOptional implements the Qualifier interface method.
+func (q *doubleQualifier) IsOptional() bool {
+ return q.optional
+}
+
// Qualify implements the Qualifier interface method.
-func (q *doubleQualifier) Qualify(vars Activation, obj interface{}) (interface{}, error) {
- switch o := obj.(type) {
- case types.Unknown:
- return o, nil
- default:
- elem, err := refResolve(q.adapter, q.celValue, obj)
- if err != nil {
- return nil, err
+func (q *doubleQualifier) Qualify(vars Activation, obj any) (any, error) {
+ val, _, err := q.qualifyInternal(vars, obj, false, false)
+ return val, err
+}
+
+func (q *doubleQualifier) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) {
+ return q.qualifyInternal(vars, obj, true, presenceOnly)
+}
+
+func (q *doubleQualifier) qualifyInternal(vars Activation, obj any, presenceTest, presenceOnly bool) (any, bool, error) {
+ return refQualify(q.adapter, obj, q.celValue, presenceTest, presenceOnly)
+}
+
+// Value implements the ConstantQualifier interface
+func (q *doubleQualifier) Value() ref.Val {
+ return q.celValue
+}
+
+// unknownQualifier is a simple qualifier which always returns a preconfigured set of unknown values
+// for any value subject to qualification. This is consistent with CEL's unknown handling elsewhere.
+type unknownQualifier struct {
+ id int64
+ value types.Unknown
+}
+
+// ID is an implementation of the Qualifier interface method.
+func (q *unknownQualifier) ID() int64 {
+ return q.id
+}
+
+// IsOptional returns trivially false as an the unknown value is always returned.
+func (q *unknownQualifier) IsOptional() bool {
+ return false
+}
+
+// Qualify returns the unknown value associated with this qualifier.
+func (q *unknownQualifier) Qualify(vars Activation, obj any) (any, error) {
+ return q.value, nil
+}
+
+// QualifyIfPresent is an implementation of the Qualifier interface method.
+func (q *unknownQualifier) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) {
+ return q.value, true, nil
+}
+
+// Value implements the ConstantQualifier interface
+func (q *unknownQualifier) Value() ref.Val {
+ return q.value
+}
+
+func applyQualifiers(vars Activation, obj any, qualifiers []Qualifier) (any, bool, error) {
+ optObj, isOpt := obj.(*types.Optional)
+ if isOpt {
+ if !optObj.HasValue() {
+ return optObj, false, nil
}
- return elem, nil
+ obj = optObj.GetValue().Value()
}
+
+ var err error
+ for _, qual := range qualifiers {
+ var qualObj any
+ isOpt = isOpt || qual.IsOptional()
+ if isOpt {
+ var present bool
+ qualObj, present, err = qual.QualifyIfPresent(vars, obj, false)
+ if err != nil {
+ return nil, false, err
+ }
+ if !present {
+ // We return optional none here with a presence of 'false' as the layers
+ // above will attempt to call types.OptionalOf() on a present value if any
+ // of the qualifiers is optional.
+ return types.OptionalNone, false, nil
+ }
+ } else {
+ qualObj, err = qual.Qualify(vars, obj)
+ if err != nil {
+ return nil, false, err
+ }
+ }
+ obj = qualObj
+ }
+ return obj, isOpt, nil
+}
+
+// attrQualify performs a qualification using the result of an attribute evaluation.
+func attrQualify(fac AttributeFactory, vars Activation, obj any, qualAttr Attribute) (any, error) {
+ val, err := qualAttr.Resolve(vars)
+ if err != nil {
+ return nil, err
+ }
+ qual, err := fac.NewQualifier(nil, qualAttr.ID(), val, qualAttr.IsOptional())
+ if err != nil {
+ return nil, err
+ }
+ return qual.Qualify(vars, obj)
}
-// refResolve attempts to convert the value to a CEL value and then uses reflection methods
-// to try and resolve the qualifier.
-func refResolve(adapter ref.TypeAdapter, idx ref.Val, obj interface{}) (ref.Val, error) {
+// attrQualifyIfPresent conditionally performs the qualification of the result of attribute is present
+// on the target object.
+func attrQualifyIfPresent(fac AttributeFactory, vars Activation, obj any, qualAttr Attribute,
+ presenceOnly bool) (any, bool, error) {
+ val, err := qualAttr.Resolve(vars)
+ if err != nil {
+ return nil, false, err
+ }
+ qual, err := fac.NewQualifier(nil, qualAttr.ID(), val, qualAttr.IsOptional())
+ if err != nil {
+ return nil, false, err
+ }
+ return qual.QualifyIfPresent(vars, obj, presenceOnly)
+}
+
+// refQualify attempts to convert the value to a CEL value and then uses reflection methods to try and
+// apply the qualifier with the option to presence test field accesses before retrieving field values.
+func refQualify(adapter ref.TypeAdapter, obj any, idx ref.Val, presenceTest, presenceOnly bool) (ref.Val, bool, error) {
celVal := adapter.NativeToValue(obj)
- mapper, isMapper := celVal.(traits.Mapper)
- if isMapper {
- elem, found := mapper.Find(idx)
- if !found {
- return nil, fmt.Errorf("no such key: %v", idx)
+ switch v := celVal.(type) {
+ case types.Unknown:
+ return v, true, nil
+ case *types.Err:
+ return nil, false, v
+ case traits.Mapper:
+ val, found := v.Find(idx)
+ // If the index is of the wrong type for the map, then it is possible
+ // for the Find call to produce an error.
+ if types.IsError(val) {
+ return nil, false, val.(*types.Err)
}
- return elem, nil
- }
- indexer, isIndexer := celVal.(traits.Indexer)
- if isIndexer {
- elem := indexer.Get(idx)
- if types.IsError(elem) {
- return nil, elem.(*types.Err)
+ if found {
+ return val, true, nil
+ }
+ if presenceTest {
+ return nil, false, nil
+ }
+ return nil, false, missingKey(idx)
+ case traits.Lister:
+ // If the index argument is not a valid numeric type, then it is possible
+ // for the index operation to produce an error.
+ i, err := types.IndexOrError(idx)
+ if err != nil {
+ return nil, false, err
+ }
+ celIndex := types.Int(i)
+ if i >= 0 && celIndex < v.Size().(types.Int) {
+ return v.Get(idx), true, nil
+ }
+ if presenceTest {
+ return nil, false, nil
+ }
+ return nil, false, missingIndex(idx)
+ case traits.Indexer:
+ if presenceTest {
+ ft, ok := v.(traits.FieldTester)
+ if ok {
+ presence := ft.IsSet(idx)
+ if types.IsError(presence) {
+ return nil, false, presence.(*types.Err)
+ }
+ // If not found or presence only test, then return.
+ // Otherwise, if found, obtain the value later on.
+ if presenceOnly || presence == types.False {
+ return nil, presence == types.True, nil
+ }
+ }
+ }
+ val := v.Get(idx)
+ if types.IsError(val) {
+ return nil, false, val.(*types.Err)
+ }
+ return val, true, nil
+ default:
+ if presenceTest {
+ return nil, false, nil
}
- return elem, nil
+ return nil, false, missingKey(idx)
}
- if types.IsUnknown(celVal) {
- return celVal, nil
+}
+
+// resolutionError is a custom error type which encodes the different error states which may
+// occur during attribute resolution.
+type resolutionError struct {
+ missingAttribute string
+ missingIndex ref.Val
+ missingKey ref.Val
+}
+
+func (e *resolutionError) isMissingAttribute() bool {
+ return e.missingAttribute != ""
+}
+
+func missingIndex(missing ref.Val) *resolutionError {
+ return &resolutionError{
+ missingIndex: missing,
+ }
+}
+
+func missingKey(missing ref.Val) *resolutionError {
+ return &resolutionError{
+ missingKey: missing,
}
- // TODO: If the types.Err value contains more than just an error message at some point in the
- // 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.(*types.Err)
+}
+
+func missingAttribute(attr string) *resolutionError {
+ return &resolutionError{
+ missingAttribute: attr,
+ }
+}
+
+// Error implements the error interface method.
+func (e *resolutionError) Error() string {
+ if e.missingKey != nil {
+ return fmt.Sprintf("no such key: %v", e.missingKey)
}
- return nil, fmt.Errorf("no such key: %v", idx)
+ if e.missingIndex != nil {
+ return fmt.Sprintf("index out of bounds: %v", e.missingIndex)
+ }
+ if e.missingAttribute != "" {
+ return fmt.Sprintf("no such attribute(s): %s", e.missingAttribute)
+ }
+ return "invalid attribute"
+}
+
+// Is implements the errors.Is() method used by more recent versions of Go.
+func (e *resolutionError) Is(err error) bool {
+ return err.Error() == e.Error()
}
diff --git a/vendor/github.com/google/cel-go/interpreter/decorators.go b/vendor/github.com/google/cel-go/interpreter/decorators.go
index bdbbad43e2..208487b7d3 100644
--- a/vendor/github.com/google/cel-go/interpreter/decorators.go
+++ b/vendor/github.com/google/cel-go/interpreter/decorators.go
@@ -29,7 +29,7 @@ type InterpretableDecorator func(Interpretable) (Interpretable, error)
func decObserveEval(observer EvalObserver) InterpretableDecorator {
return func(i Interpretable) (Interpretable, error) {
switch inst := i.(type) {
- case *evalWatch, *evalWatchAttr, *evalWatchConst:
+ case *evalWatch, *evalWatchAttr, *evalWatchConst, *evalWatchConstructor:
// these instruction are already watching, return straight-away.
return i, nil
case InterpretableAttribute:
@@ -42,6 +42,11 @@ func decObserveEval(observer EvalObserver) InterpretableDecorator {
InterpretableConst: inst,
observer: observer,
}, nil
+ case InterpretableConstructor:
+ return &evalWatchConstructor{
+ constructor: inst,
+ observer: observer,
+ }, nil
default:
return &evalWatch{
Interpretable: i,
@@ -224,8 +229,8 @@ func maybeOptimizeSetMembership(i Interpretable, inlist InterpretableCall) (Inte
valueSet := make(map[ref.Val]ref.Val)
for it.HasNext() == types.True {
elem := it.Next()
- if !types.IsPrimitiveType(elem) {
- // Note, non-primitive type are not yet supported.
+ if !types.IsPrimitiveType(elem) || elem.Type() == types.BytesType {
+ // Note, non-primitive type are not yet supported, and []byte isn't hashable.
return i, nil
}
valueSet[elem] = types.True
diff --git a/vendor/github.com/google/cel-go/interpreter/formatting.go b/vendor/github.com/google/cel-go/interpreter/formatting.go
new file mode 100644
index 0000000000..6a98f6fa56
--- /dev/null
+++ b/vendor/github.com/google/cel-go/interpreter/formatting.go
@@ -0,0 +1,383 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package interpreter
+
+import (
+ "errors"
+ "fmt"
+ "strconv"
+ "strings"
+ "unicode"
+
+ "github.com/google/cel-go/common/types"
+ "github.com/google/cel-go/common/types/ref"
+)
+
+type typeVerifier func(int64, ...*types.TypeValue) (bool, error)
+
+// InterpolateFormattedString checks the syntax and cardinality of any string.format calls present in the expression and reports
+// any errors at compile time.
+func InterpolateFormattedString(verifier typeVerifier) InterpretableDecorator {
+ return func(inter Interpretable) (Interpretable, error) {
+ call, ok := inter.(InterpretableCall)
+ if !ok {
+ return inter, nil
+ }
+ if call.OverloadID() != "string_format" {
+ return inter, nil
+ }
+ args := call.Args()
+ if len(args) != 2 {
+ return nil, fmt.Errorf("wrong number of arguments to string.format (expected 2, got %d)", len(args))
+ }
+ fmtStrInter, ok := args[0].(InterpretableConst)
+ if !ok {
+ return inter, nil
+ }
+ var fmtArgsInter InterpretableConstructor
+ fmtArgsInter, ok = args[1].(InterpretableConstructor)
+ if !ok {
+ return inter, nil
+ }
+ if fmtArgsInter.Type() != types.ListType {
+ // don't necessarily return an error since the list may be DynType
+ return inter, nil
+ }
+ formatStr := fmtStrInter.Value().Value().(string)
+ initVals := fmtArgsInter.InitVals()
+
+ formatCheck := &formatCheck{
+ args: initVals,
+ verifier: verifier,
+ }
+ // use a placeholder locale, since locale doesn't affect syntax
+ _, err := ParseFormatString(formatStr, formatCheck, formatCheck, "en_US")
+ if err != nil {
+ return nil, err
+ }
+ seenArgs := formatCheck.argsRequested
+ if len(initVals) > seenArgs {
+ return nil, fmt.Errorf("too many arguments supplied to string.format (expected %d, got %d)", seenArgs, len(initVals))
+ }
+ return inter, nil
+ }
+}
+
+type formatCheck struct {
+ args []Interpretable
+ argsRequested int
+ curArgIndex int64
+ enableCheckArgTypes bool
+ verifier typeVerifier
+}
+
+func (c *formatCheck) String(arg ref.Val, locale string) (string, error) {
+ valid, err := verifyString(c.args[c.curArgIndex], c.verifier)
+ if err != nil {
+ return "", err
+ }
+ if !valid {
+ return "", errors.New("string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps")
+ }
+ return "", nil
+}
+
+func (c *formatCheck) Decimal(arg ref.Val, locale string) (string, error) {
+ id := c.args[c.curArgIndex].ID()
+ valid, err := c.verifier(id, types.IntType, types.UintType)
+ if err != nil {
+ return "", err
+ }
+ if !valid {
+ return "", errors.New("integer clause can only be used on integers")
+ }
+ return "", nil
+}
+
+func (c *formatCheck) Fixed(precision *int) func(ref.Val, string) (string, error) {
+ return func(arg ref.Val, locale string) (string, error) {
+ id := c.args[c.curArgIndex].ID()
+ // we allow StringType since "NaN", "Infinity", and "-Infinity" are also valid values
+ valid, err := c.verifier(id, types.DoubleType, types.StringType)
+ if err != nil {
+ return "", err
+ }
+ if !valid {
+ return "", errors.New("fixed-point clause can only be used on doubles")
+ }
+ return "", nil
+ }
+}
+
+func (c *formatCheck) Scientific(precision *int) func(ref.Val, string) (string, error) {
+ return func(arg ref.Val, locale string) (string, error) {
+ id := c.args[c.curArgIndex].ID()
+ valid, err := c.verifier(id, types.DoubleType, types.StringType)
+ if err != nil {
+ return "", err
+ }
+ if !valid {
+ return "", errors.New("scientific clause can only be used on doubles")
+ }
+ return "", nil
+ }
+}
+
+func (c *formatCheck) Binary(arg ref.Val, locale string) (string, error) {
+ id := c.args[c.curArgIndex].ID()
+ valid, err := c.verifier(id, types.IntType, types.UintType, types.BoolType)
+ if err != nil {
+ return "", err
+ }
+ if !valid {
+ return "", errors.New("only integers and bools can be formatted as binary")
+ }
+ return "", nil
+}
+
+func (c *formatCheck) Hex(useUpper bool) func(ref.Val, string) (string, error) {
+ return func(arg ref.Val, locale string) (string, error) {
+ id := c.args[c.curArgIndex].ID()
+ valid, err := c.verifier(id, types.IntType, types.UintType, types.StringType, types.BytesType)
+ if err != nil {
+ return "", err
+ }
+ if !valid {
+ return "", errors.New("only integers, byte buffers, and strings can be formatted as hex")
+ }
+ return "", nil
+ }
+}
+
+func (c *formatCheck) Octal(arg ref.Val, locale string) (string, error) {
+ id := c.args[c.curArgIndex].ID()
+ valid, err := c.verifier(id, types.IntType, types.UintType)
+ if err != nil {
+ return "", err
+ }
+ if !valid {
+ return "", errors.New("octal clause can only be used on integers")
+ }
+ return "", nil
+}
+
+func (c *formatCheck) Arg(index int64) (ref.Val, error) {
+ c.argsRequested++
+ c.curArgIndex = index
+ // return a dummy value - this is immediately passed to back to us
+ // through one of the FormatCallback functions, so anything will do
+ return types.Int(0), nil
+}
+
+func (c *formatCheck) ArgSize() int64 {
+ return int64(len(c.args))
+}
+
+func verifyString(sub Interpretable, verifier typeVerifier) (bool, error) {
+ subVerified, err := verifier(sub.ID(),
+ types.ListType, types.MapType, types.IntType, types.UintType, types.DoubleType,
+ types.BoolType, types.StringType, types.TimestampType, types.BytesType, types.DurationType, types.TypeType, types.NullType)
+ if err != nil {
+ return false, err
+ }
+ if !subVerified {
+ return false, nil
+ }
+ con, ok := sub.(InterpretableConstructor)
+ if ok {
+ members := con.InitVals()
+ for _, m := range members {
+ // recursively verify if we're dealing with a list/map
+ verified, err := verifyString(m, verifier)
+ if err != nil {
+ return false, err
+ }
+ if !verified {
+ return false, nil
+ }
+ }
+ }
+ return true, nil
+
+}
+
+// FormatStringInterpolator is an interface that allows user-defined behavior
+// for formatting clause implementations, as well as argument retrieval.
+// Each function is expected to support the appropriate types as laid out in
+// the string.format documentation, and to return an error if given an inappropriate type.
+type FormatStringInterpolator interface {
+ // String takes a ref.Val and a string representing the current locale identifier
+ // and returns the Val formatted as a string, or an error if one occurred.
+ String(ref.Val, string) (string, error)
+
+ // Decimal takes a ref.Val and a string representing the current locale identifier
+ // and returns the Val formatted as a decimal integer, or an error if one occurred.
+ Decimal(ref.Val, string) (string, error)
+
+ // Fixed takes an int pointer representing precision (or nil if none was given) and
+ // returns a function operating in a similar manner to String and Decimal, taking a
+ // ref.Val and locale and returning the appropriate string. A closure is returned
+ // so precision can be set without needing an additional function call/configuration.
+ Fixed(*int) func(ref.Val, string) (string, error)
+
+ // Scientific functions identically to Fixed, except the string returned from the closure
+ // is expected to be in scientific notation.
+ Scientific(*int) func(ref.Val, string) (string, error)
+
+ // Binary takes a ref.Val and a string representing the current locale identifier
+ // and returns the Val formatted as a binary integer, or an error if one occurred.
+ Binary(ref.Val, string) (string, error)
+
+ // Hex takes a boolean that, if true, indicates the hex string output by the returned
+ // closure should use uppercase letters for A-F.
+ Hex(bool) func(ref.Val, string) (string, error)
+
+ // Octal takes a ref.Val and a string representing the current locale identifier and
+ // returns the Val formatted in octal, or an error if one occurred.
+ Octal(ref.Val, string) (string, error)
+}
+
+// FormatList is an interface that allows user-defined list-like datatypes to be used
+// for formatting clause implementations.
+type FormatList interface {
+ // Arg returns the ref.Val at the given index, or an error if one occurred.
+ Arg(int64) (ref.Val, error)
+ // ArgSize returns the length of the argument list.
+ ArgSize() int64
+}
+
+type clauseImpl func(ref.Val, string) (string, error)
+
+// ParseFormatString formats a string according to the string.format syntax, taking the clause implementations
+// from the provided FormatCallback and the args from the given FormatList.
+func ParseFormatString(formatStr string, callback FormatStringInterpolator, list FormatList, locale string) (string, error) {
+ i := 0
+ argIndex := 0
+ var builtStr strings.Builder
+ for i < len(formatStr) {
+ if formatStr[i] == '%' {
+ if i+1 < len(formatStr) && formatStr[i+1] == '%' {
+ err := builtStr.WriteByte('%')
+ if err != nil {
+ return "", fmt.Errorf("error writing format string: %w", err)
+ }
+ i += 2
+ continue
+ } else {
+ argAny, err := list.Arg(int64(argIndex))
+ if err != nil {
+ return "", err
+ }
+ if i+1 >= len(formatStr) {
+ return "", errors.New("unexpected end of string")
+ }
+ if int64(argIndex) >= list.ArgSize() {
+ return "", fmt.Errorf("index %d out of range", argIndex)
+ }
+ numRead, val, refErr := parseAndFormatClause(formatStr[i:], argAny, callback, list, locale)
+ if refErr != nil {
+ return "", refErr
+ }
+ _, err = builtStr.WriteString(val)
+ if err != nil {
+ return "", fmt.Errorf("error writing format string: %w", err)
+ }
+ i += numRead
+ argIndex++
+ }
+ } else {
+ err := builtStr.WriteByte(formatStr[i])
+ if err != nil {
+ return "", fmt.Errorf("error writing format string: %w", err)
+ }
+ i++
+ }
+ }
+ return builtStr.String(), nil
+}
+
+// parseAndFormatClause parses the format clause at the start of the given string with val, and returns
+// how many characters were consumed and the substituted string form of val, or an error if one occurred.
+func parseAndFormatClause(formatStr string, val ref.Val, callback FormatStringInterpolator, list FormatList, locale string) (int, string, error) {
+ i := 1
+ read, formatter, err := parseFormattingClause(formatStr[i:], callback)
+ i += read
+ if err != nil {
+ return -1, "", fmt.Errorf("could not parse formatting clause: %s", err)
+ }
+
+ valStr, err := formatter(val, locale)
+ if err != nil {
+ return -1, "", fmt.Errorf("error during formatting: %s", err)
+ }
+ return i, valStr, nil
+}
+
+func parseFormattingClause(formatStr string, callback FormatStringInterpolator) (int, clauseImpl, error) {
+ i := 0
+ read, precision, err := parsePrecision(formatStr[i:])
+ i += read
+ if err != nil {
+ return -1, nil, fmt.Errorf("error while parsing precision: %w", err)
+ }
+ r := rune(formatStr[i])
+ i++
+ switch r {
+ case 's':
+ return i, callback.String, nil
+ case 'd':
+ return i, callback.Decimal, nil
+ case 'f':
+ return i, callback.Fixed(precision), nil
+ case 'e':
+ return i, callback.Scientific(precision), nil
+ case 'b':
+ return i, callback.Binary, nil
+ case 'x', 'X':
+ return i, callback.Hex(unicode.IsUpper(r)), nil
+ case 'o':
+ return i, callback.Octal, nil
+ default:
+ return -1, nil, fmt.Errorf("unrecognized formatting clause \"%c\"", r)
+ }
+}
+
+func parsePrecision(formatStr string) (int, *int, error) {
+ i := 0
+ if formatStr[i] != '.' {
+ return i, nil, nil
+ }
+ i++
+ var buffer strings.Builder
+ for {
+ if i >= len(formatStr) {
+ return -1, nil, errors.New("could not find end of precision specifier")
+ }
+ if !isASCIIDigit(rune(formatStr[i])) {
+ break
+ }
+ buffer.WriteByte(formatStr[i])
+ i++
+ }
+ precision, err := strconv.Atoi(buffer.String())
+ if err != nil {
+ return -1, nil, fmt.Errorf("error while converting precision to integer: %w", err)
+ }
+ return i, &precision, nil
+}
+
+func isASCIIDigit(r rune) bool {
+ return r <= unicode.MaxASCII && unicode.IsDigit(r)
+}
diff --git a/vendor/github.com/google/cel-go/interpreter/functions/functions.go b/vendor/github.com/google/cel-go/interpreter/functions/functions.go
index dd1e9ddd5f..9816017522 100644
--- a/vendor/github.com/google/cel-go/interpreter/functions/functions.go
+++ b/vendor/github.com/google/cel-go/interpreter/functions/functions.go
@@ -58,5 +58,5 @@ type UnaryOp func(value ref.Val) ref.Val
type BinaryOp func(lhs ref.Val, rhs ref.Val) ref.Val
// FunctionOp is a function with accepts zero or more arguments and produces
-// an value (as interface{}) or error as a result.
+// a value or error as a result.
type FunctionOp func(values ...ref.Val) ref.Val
diff --git a/vendor/github.com/google/cel-go/interpreter/interpretable.go b/vendor/github.com/google/cel-go/interpreter/interpretable.go
index 4fdd12028b..32e2bcb7de 100644
--- a/vendor/github.com/google/cel-go/interpreter/interpretable.go
+++ b/vendor/github.com/google/cel-go/interpreter/interpretable.go
@@ -15,7 +15,7 @@
package interpreter
import (
- "math"
+ "fmt"
"github.com/google/cel-go/common/operators"
"github.com/google/cel-go/common/overloads"
@@ -64,10 +64,18 @@ type InterpretableAttribute interface {
// Qualify replicates the Attribute.Qualify method to permit extension and interception
// of object qualification.
- Qualify(vars Activation, obj interface{}) (interface{}, error)
+ Qualify(vars Activation, obj any) (any, error)
+
+ // QualifyIfPresent qualifies the object if the qualifier is declared or defined on the object.
+ // The 'presenceOnly' flag indicates that the value is not necessary, just a boolean status as
+ // to whether the qualifier is present.
+ QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error)
+
+ // IsOptional indicates whether the resulting value is an optional type.
+ IsOptional() bool
// Resolve returns the value of the Attribute given the current Activation.
- Resolve(Activation) (interface{}, error)
+ Resolve(Activation) (any, error)
}
// InterpretableCall interface for inspecting Interpretable instructions related to function calls.
@@ -103,10 +111,8 @@ type InterpretableConstructor interface {
// Core Interpretable implementations used during the program planning phase.
type evalTestOnly struct {
- id int64
- op Interpretable
- field types.String
- fieldType *ref.FieldType
+ id int64
+ InterpretableAttribute
}
// ID implements the Interpretable interface method.
@@ -116,44 +122,55 @@ func (test *evalTestOnly) ID() int64 {
// Eval implements the Interpretable interface method.
func (test *evalTestOnly) Eval(ctx Activation) ref.Val {
- // Handle field selection on a proto in the most efficient way possible.
- if test.fieldType != nil {
- opAttr, ok := test.op.(InterpretableAttribute)
- if ok {
- opVal, err := opAttr.Resolve(ctx)
- if err != nil {
- return types.NewErr(err.Error())
- }
- refVal, ok := opVal.(ref.Val)
- if ok {
- opVal = refVal.Value()
- }
- if test.fieldType.IsSet(opVal) {
- return types.True
- }
- return types.False
- }
+ val, err := test.Resolve(ctx)
+ // Return an error if the resolve step fails
+ if err != nil {
+ return types.WrapErr(err)
}
+ if optVal, isOpt := val.(*types.Optional); isOpt {
+ return types.Bool(optVal.HasValue())
+ }
+ return test.Adapter().NativeToValue(val)
+}
+
+// AddQualifier appends a qualifier that will always and only perform a presence test.
+func (test *evalTestOnly) AddQualifier(q Qualifier) (Attribute, error) {
+ cq, ok := q.(ConstantQualifier)
+ if !ok {
+ return nil, fmt.Errorf("test only expressions must have constant qualifiers: %v", q)
+ }
+ return test.InterpretableAttribute.AddQualifier(&testOnlyQualifier{ConstantQualifier: cq})
+}
+
+type testOnlyQualifier struct {
+ ConstantQualifier
+}
- obj := test.op.Eval(ctx)
- tester, ok := obj.(traits.FieldTester)
- if ok {
- return tester.IsSet(test.field)
+// Qualify determines whether the test-only qualifier is present on the input object.
+func (q *testOnlyQualifier) Qualify(vars Activation, obj any) (any, error) {
+ out, present, err := q.ConstantQualifier.QualifyIfPresent(vars, obj, true)
+ if err != nil {
+ return nil, err
+ }
+ if unk, isUnk := out.(types.Unknown); isUnk {
+ return unk, nil
}
- container, ok := obj.(traits.Container)
- if ok {
- return container.Contains(test.field)
+ if opt, isOpt := out.(types.Optional); isOpt {
+ return opt.HasValue(), nil
}
- return types.ValOrErr(obj, "invalid type for field selection.")
+ return present, nil
}
-// Cost provides the heuristic cost of a `has(field)` macro. The cost has at least 1 for determining
-// if the field exists, apart from the cost of accessing the field.
-func (test *evalTestOnly) Cost() (min, max int64) {
- min, max = estimateCost(test.op)
- min++
- max++
- return
+// QualifyIfPresent returns whether the target field in the test-only expression is present.
+func (q *testOnlyQualifier) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) {
+ // Only ever test for presence.
+ return q.ConstantQualifier.QualifyIfPresent(vars, obj, true)
+}
+
+// QualifierValueEquals determines whether the test-only constant qualifier equals the input value.
+func (q *testOnlyQualifier) QualifierValueEquals(value any) bool {
+ // The input qualifier will always be of type string
+ return q.ConstantQualifier.Value().Value() == value
}
// NewConstValue creates a new constant valued Interpretable.
@@ -179,11 +196,6 @@ func (cons *evalConst) Eval(ctx Activation) ref.Val {
return cons.val
}
-// Cost returns zero for a constant valued Interpretable.
-func (cons *evalConst) Cost() (min, max int64) {
- return 0, 0
-}
-
// Value implements the InterpretableConst interface method.
func (cons *evalConst) Value() ref.Val {
return cons.val
@@ -233,12 +245,6 @@ func (or *evalOr) Eval(ctx Activation) ref.Val {
return types.ValOrErr(rVal, "no such overload")
}
-// Cost implements the Coster interface method. The minimum possible cost incurs when the left-hand
-// side expr is sufficient in determining the evaluation result.
-func (or *evalOr) Cost() (min, max int64) {
- return calShortCircuitBinaryOpsCost(or.lhs, or.rhs)
-}
-
type evalAnd struct {
id int64
lhs Interpretable
@@ -283,18 +289,6 @@ func (and *evalAnd) Eval(ctx Activation) ref.Val {
return types.ValOrErr(rVal, "no such overload")
}
-// Cost implements the Coster interface method. The minimum possible cost incurs when the left-hand
-// side expr is sufficient in determining the evaluation result.
-func (and *evalAnd) Cost() (min, max int64) {
- return calShortCircuitBinaryOpsCost(and.lhs, and.rhs)
-}
-
-func calShortCircuitBinaryOpsCost(lhs, rhs Interpretable) (min, max int64) {
- lMin, lMax := estimateCost(lhs)
- _, rMax := estimateCost(rhs)
- return lMin, lMax + rMax + 1
-}
-
type evalEq struct {
id int64
lhs Interpretable
@@ -319,11 +313,6 @@ func (eq *evalEq) Eval(ctx Activation) ref.Val {
return types.Equal(lVal, rVal)
}
-// Cost implements the Coster interface method.
-func (eq *evalEq) Cost() (min, max int64) {
- return calExhaustiveBinaryOpsCost(eq.lhs, eq.rhs)
-}
-
// Function implements the InterpretableCall interface method.
func (*evalEq) Function() string {
return operators.Equals
@@ -363,11 +352,6 @@ func (ne *evalNe) Eval(ctx Activation) ref.Val {
return types.Bool(types.Equal(lVal, rVal) != types.True)
}
-// Cost implements the Coster interface method.
-func (ne *evalNe) Cost() (min, max int64) {
- return calExhaustiveBinaryOpsCost(ne.lhs, ne.rhs)
-}
-
// Function implements the InterpretableCall interface method.
func (*evalNe) Function() string {
return operators.NotEquals
@@ -400,11 +384,6 @@ func (zero *evalZeroArity) Eval(ctx Activation) ref.Val {
return zero.impl()
}
-// Cost returns 1 representing the heuristic cost of the function.
-func (zero *evalZeroArity) Cost() (min, max int64) {
- return 1, 1
-}
-
// Function implements the InterpretableCall interface method.
func (zero *evalZeroArity) Function() string {
return zero.function
@@ -456,14 +435,6 @@ func (un *evalUnary) Eval(ctx Activation) ref.Val {
return types.NewErr("no such overload: %s", un.function)
}
-// Cost implements the Coster interface method.
-func (un *evalUnary) Cost() (min, max int64) {
- min, max = estimateCost(un.arg)
- min++ // add cost for function
- max++
- return
-}
-
// Function implements the InterpretableCall interface method.
func (un *evalUnary) Function() string {
return un.function
@@ -522,11 +493,6 @@ func (bin *evalBinary) Eval(ctx Activation) ref.Val {
return types.NewErr("no such overload: %s", bin.function)
}
-// Cost implements the Coster interface method.
-func (bin *evalBinary) Cost() (min, max int64) {
- return calExhaustiveBinaryOpsCost(bin.lhs, bin.rhs)
-}
-
// Function implements the InterpretableCall interface method.
func (bin *evalBinary) Function() string {
return bin.function
@@ -593,14 +559,6 @@ func (fn *evalVarArgs) Eval(ctx Activation) ref.Val {
return types.NewErr("no such overload: %s", fn.function)
}
-// Cost implements the Coster interface method.
-func (fn *evalVarArgs) Cost() (min, max int64) {
- min, max = sumOfCost(fn.args)
- min++ // add cost for function
- max++
- return
-}
-
// Function implements the InterpretableCall interface method.
func (fn *evalVarArgs) Function() string {
return fn.function
@@ -617,9 +575,11 @@ func (fn *evalVarArgs) Args() []Interpretable {
}
type evalList struct {
- id int64
- elems []Interpretable
- adapter ref.TypeAdapter
+ id int64
+ elems []Interpretable
+ optionals []bool
+ hasOptionals bool
+ adapter ref.TypeAdapter
}
// ID implements the Interpretable interface method.
@@ -629,14 +589,24 @@ func (l *evalList) ID() int64 {
// Eval implements the Interpretable interface method.
func (l *evalList) Eval(ctx Activation) ref.Val {
- elemVals := make([]ref.Val, len(l.elems))
+ elemVals := make([]ref.Val, 0, len(l.elems))
// If any argument is unknown or error early terminate.
for i, elem := range l.elems {
elemVal := elem.Eval(ctx)
if types.IsUnknownOrError(elemVal) {
return elemVal
}
- elemVals[i] = elemVal
+ if l.hasOptionals && l.optionals[i] {
+ optVal, ok := elemVal.(*types.Optional)
+ if !ok {
+ return invalidOptionalElementInit(elemVal)
+ }
+ if !optVal.HasValue() {
+ continue
+ }
+ elemVal = optVal.GetValue()
+ }
+ elemVals = append(elemVals, elemVal)
}
return l.adapter.NativeToValue(elemVals)
}
@@ -649,16 +619,13 @@ func (l *evalList) Type() ref.Type {
return types.ListType
}
-// Cost implements the Coster interface method.
-func (l *evalList) Cost() (min, max int64) {
- return sumOfCost(l.elems)
-}
-
type evalMap struct {
- id int64
- keys []Interpretable
- vals []Interpretable
- adapter ref.TypeAdapter
+ id int64
+ keys []Interpretable
+ vals []Interpretable
+ optionals []bool
+ hasOptionals bool
+ adapter ref.TypeAdapter
}
// ID implements the Interpretable interface method.
@@ -679,6 +646,17 @@ func (m *evalMap) Eval(ctx Activation) ref.Val {
if types.IsUnknownOrError(valVal) {
return valVal
}
+ if m.hasOptionals && m.optionals[i] {
+ optVal, ok := valVal.(*types.Optional)
+ if !ok {
+ return invalidOptionalEntryInit(keyVal, valVal)
+ }
+ if !optVal.HasValue() {
+ delete(entries, keyVal)
+ continue
+ }
+ valVal = optVal.GetValue()
+ }
entries[keyVal] = valVal
}
return m.adapter.NativeToValue(entries)
@@ -704,19 +682,14 @@ func (m *evalMap) Type() ref.Type {
return types.MapType
}
-// Cost implements the Coster interface method.
-func (m *evalMap) Cost() (min, max int64) {
- kMin, kMax := sumOfCost(m.keys)
- vMin, vMax := sumOfCost(m.vals)
- return kMin + vMin, kMax + vMax
-}
-
type evalObj struct {
- id int64
- typeName string
- fields []string
- vals []Interpretable
- provider ref.TypeProvider
+ id int64
+ typeName string
+ fields []string
+ vals []Interpretable
+ optionals []bool
+ hasOptionals bool
+ provider ref.TypeProvider
}
// ID implements the Interpretable interface method.
@@ -733,6 +706,17 @@ func (o *evalObj) Eval(ctx Activation) ref.Val {
if types.IsUnknownOrError(val) {
return val
}
+ if o.hasOptionals && o.optionals[i] {
+ optVal, ok := val.(*types.Optional)
+ if !ok {
+ return invalidOptionalEntryInit(field, val)
+ }
+ if !optVal.HasValue() {
+ delete(fieldVals, field)
+ continue
+ }
+ val = optVal.GetValue()
+ }
fieldVals[field] = val
}
return o.provider.NewValue(o.typeName, fieldVals)
@@ -746,21 +730,6 @@ func (o *evalObj) Type() ref.Type {
return types.NewObjectTypeValue(o.typeName)
}
-// Cost implements the Coster interface method.
-func (o *evalObj) Cost() (min, max int64) {
- return sumOfCost(o.vals)
-}
-
-func sumOfCost(interps []Interpretable) (min, max int64) {
- min, max = 0, 0
- for _, in := range interps {
- minT, maxT := estimateCost(in)
- min += minT
- max += maxT
- }
- return
-}
-
type evalFold struct {
id int64
accuVar string
@@ -842,38 +811,6 @@ func (fold *evalFold) Eval(ctx Activation) ref.Val {
return res
}
-// Cost implements the Coster interface method.
-func (fold *evalFold) Cost() (min, max int64) {
- // Compute the cost for evaluating iterRange.
- iMin, iMax := estimateCost(fold.iterRange)
-
- // Compute the size of iterRange. If the size depends on the input, return the maximum possible
- // cost range.
- foldRange := fold.iterRange.Eval(EmptyActivation())
- if !foldRange.Type().HasTrait(traits.IterableType) {
- return 0, math.MaxInt64
- }
- var rangeCnt int64
- it := foldRange.(traits.Iterable).Iterator()
- for it.HasNext() == types.True {
- it.Next()
- rangeCnt++
- }
- aMin, aMax := estimateCost(fold.accu)
- cMin, cMax := estimateCost(fold.cond)
- sMin, sMax := estimateCost(fold.step)
- rMin, rMax := estimateCost(fold.result)
- if fold.exhaustive {
- cMin = cMin * rangeCnt
- sMin = sMin * rangeCnt
- }
-
- // The cond and step costs are multiplied by size(iterRange). The minimum possible cost incurs
- // when the evaluation result can be determined by the first iteration.
- return iMin + aMin + cMin + sMin + rMin,
- iMax + aMax + cMax*rangeCnt + sMax*rangeCnt + rMax
-}
-
// Optional Interpretable implementations that specialize, subsume, or extend the core evaluation
// plan via decorators.
@@ -893,17 +830,15 @@ func (e *evalSetMembership) ID() int64 {
// Eval implements the Interpretable interface method.
func (e *evalSetMembership) Eval(ctx Activation) ref.Val {
val := e.arg.Eval(ctx)
+ if types.IsUnknownOrError(val) {
+ return val
+ }
if ret, found := e.valueSet[val]; found {
return ret
}
return types.False
}
-// Cost implements the Coster interface method.
-func (e *evalSetMembership) Cost() (min, max int64) {
- return estimateCost(e.arg)
-}
-
// evalWatch is an Interpretable implementation that wraps the execution of a given
// expression so that it may observe the computed value and send it to an observer.
type evalWatch struct {
@@ -918,15 +853,10 @@ func (e *evalWatch) Eval(ctx Activation) ref.Val {
return val
}
-// Cost implements the Coster interface method.
-func (e *evalWatch) Cost() (min, max int64) {
- return estimateCost(e.Interpretable)
-}
-
-// evalWatchAttr describes a watcher of an instAttr Interpretable.
+// evalWatchAttr describes a watcher of an InterpretableAttribute Interpretable.
//
// Since the watcher may be selected against at a later stage in program planning, the watcher
-// must implement the instAttr interface by proxy.
+// must implement the InterpretableAttribute interface by proxy.
type evalWatchAttr struct {
InterpretableAttribute
observer EvalObserver
@@ -953,11 +883,6 @@ func (e *evalWatchAttr) AddQualifier(q Qualifier) (Attribute, error) {
return e, err
}
-// Cost implements the Coster interface method.
-func (e *evalWatchAttr) Cost() (min, max int64) {
- return estimateCost(e.InterpretableAttribute)
-}
-
// Eval implements the Interpretable interface method.
func (e *evalWatchAttr) Eval(vars Activation) ref.Val {
val := e.InterpretableAttribute.Eval(vars)
@@ -973,17 +898,12 @@ type evalWatchConstQual struct {
adapter ref.TypeAdapter
}
-// Cost implements the Coster interface method.
-func (e *evalWatchConstQual) Cost() (min, max int64) {
- return estimateCost(e.ConstantQualifier)
-}
-
// Qualify observes the qualification of a object via a constant boolean, int, string, or uint.
-func (e *evalWatchConstQual) Qualify(vars Activation, obj interface{}) (interface{}, error) {
+func (e *evalWatchConstQual) Qualify(vars Activation, obj any) (any, error) {
out, err := e.ConstantQualifier.Qualify(vars, obj)
var val ref.Val
if err != nil {
- val = types.NewErr(err.Error())
+ val = types.WrapErr(err)
} else {
val = e.adapter.NativeToValue(out)
}
@@ -991,8 +911,25 @@ func (e *evalWatchConstQual) Qualify(vars Activation, obj interface{}) (interfac
return out, err
}
+// QualifyIfPresent conditionally qualifies the variable and only records a value if one is present.
+func (e *evalWatchConstQual) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) {
+ out, present, err := e.ConstantQualifier.QualifyIfPresent(vars, obj, presenceOnly)
+ var val ref.Val
+ if err != nil {
+ val = types.WrapErr(err)
+ } else if out != nil {
+ val = e.adapter.NativeToValue(out)
+ } else if presenceOnly {
+ val = types.Bool(present)
+ }
+ if present || presenceOnly {
+ e.observer(e.ID(), e.ConstantQualifier, val)
+ }
+ return out, present, err
+}
+
// QualifierValueEquals tests whether the incoming value is equal to the qualifying constant.
-func (e *evalWatchConstQual) QualifierValueEquals(value interface{}) bool {
+func (e *evalWatchConstQual) QualifierValueEquals(value any) bool {
qve, ok := e.ConstantQualifier.(qualifierValueEquator)
return ok && qve.QualifierValueEquals(value)
}
@@ -1004,17 +941,12 @@ type evalWatchQual struct {
adapter ref.TypeAdapter
}
-// Cost implements the Coster interface method.
-func (e *evalWatchQual) Cost() (min, max int64) {
- return estimateCost(e.Qualifier)
-}
-
// Qualify observes the qualification of a object via a value computed at runtime.
-func (e *evalWatchQual) Qualify(vars Activation, obj interface{}) (interface{}, error) {
+func (e *evalWatchQual) Qualify(vars Activation, obj any) (any, error) {
out, err := e.Qualifier.Qualify(vars, obj)
var val ref.Val
if err != nil {
- val = types.NewErr(err.Error())
+ val = types.WrapErr(err)
} else {
val = e.adapter.NativeToValue(out)
}
@@ -1022,6 +954,23 @@ func (e *evalWatchQual) Qualify(vars Activation, obj interface{}) (interface{},
return out, err
}
+// QualifyIfPresent conditionally qualifies the variable and only records a value if one is present.
+func (e *evalWatchQual) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) {
+ out, present, err := e.Qualifier.QualifyIfPresent(vars, obj, presenceOnly)
+ var val ref.Val
+ if err != nil {
+ val = types.WrapErr(err)
+ } else if out != nil {
+ val = e.adapter.NativeToValue(out)
+ } else if presenceOnly {
+ val = types.Bool(present)
+ }
+ if present || presenceOnly {
+ e.observer(e.ID(), e.Qualifier, val)
+ }
+ return out, present, err
+}
+
// evalWatchConst describes a watcher of an instConst Interpretable.
type evalWatchConst struct {
InterpretableConst
@@ -1035,11 +984,6 @@ func (e *evalWatchConst) Eval(vars Activation) ref.Val {
return val
}
-// Cost implements the Coster interface method.
-func (e *evalWatchConst) Cost() (min, max int64) {
- return estimateCost(e.InterpretableConst)
-}
-
// evalExhaustiveOr is just like evalOr, but does not short-circuit argument evaluation.
type evalExhaustiveOr struct {
id int64
@@ -1078,12 +1022,7 @@ func (or *evalExhaustiveOr) Eval(ctx Activation) ref.Val {
if types.IsError(lVal) {
return lVal
}
- return types.ValOrErr(rVal, "no such overload")
-}
-
-// Cost implements the Coster interface method.
-func (or *evalExhaustiveOr) Cost() (min, max int64) {
- return calExhaustiveBinaryOpsCost(or.lhs, or.rhs)
+ return types.MaybeNoSuchOverloadErr(rVal)
}
// evalExhaustiveAnd is just like evalAnd, but does not short-circuit argument evaluation.
@@ -1124,18 +1063,7 @@ func (and *evalExhaustiveAnd) Eval(ctx Activation) ref.Val {
if types.IsError(lVal) {
return lVal
}
- return types.ValOrErr(rVal, "no such overload")
-}
-
-// Cost implements the Coster interface method.
-func (and *evalExhaustiveAnd) Cost() (min, max int64) {
- return calExhaustiveBinaryOpsCost(and.lhs, and.rhs)
-}
-
-func calExhaustiveBinaryOpsCost(lhs, rhs Interpretable) (min, max int64) {
- lMin, lMax := estimateCost(lhs)
- rMin, rMax := estimateCost(rhs)
- return lMin + rMin + 1, lMax + rMax + 1
+ return types.MaybeNoSuchOverloadErr(rVal)
}
// evalExhaustiveConditional is like evalConditional, but does not short-circuit argument
@@ -1154,77 +1082,114 @@ func (cond *evalExhaustiveConditional) ID() int64 {
// Eval implements the Interpretable interface method.
func (cond *evalExhaustiveConditional) Eval(ctx Activation) ref.Val {
cVal := cond.attr.expr.Eval(ctx)
- tVal, err := cond.attr.truthy.Resolve(ctx)
- if err != nil {
- return types.NewErr(err.Error())
- }
- fVal, err := cond.attr.falsy.Resolve(ctx)
- if err != nil {
- return types.NewErr(err.Error())
- }
+ tVal, tErr := cond.attr.truthy.Resolve(ctx)
+ fVal, fErr := cond.attr.falsy.Resolve(ctx)
cBool, ok := cVal.(types.Bool)
if !ok {
return types.ValOrErr(cVal, "no such overload")
}
if cBool {
+ if tErr != nil {
+ return types.WrapErr(tErr)
+ }
return cond.adapter.NativeToValue(tVal)
}
+ if fErr != nil {
+ return types.WrapErr(fErr)
+ }
return cond.adapter.NativeToValue(fVal)
}
-// Cost implements the Coster interface method.
-func (cond *evalExhaustiveConditional) Cost() (min, max int64) {
- return cond.attr.Cost()
-}
-
// evalAttr evaluates an Attribute value.
type evalAttr struct {
- adapter ref.TypeAdapter
- attr Attribute
+ adapter ref.TypeAdapter
+ attr Attribute
+ optional bool
}
+var _ InterpretableAttribute = &evalAttr{}
+
// ID of the attribute instruction.
func (a *evalAttr) ID() int64 {
return a.attr.ID()
}
-// AddQualifier implements the instAttr interface method.
+// AddQualifier implements the InterpretableAttribute interface method.
func (a *evalAttr) AddQualifier(qual Qualifier) (Attribute, error) {
attr, err := a.attr.AddQualifier(qual)
a.attr = attr
return attr, err
}
-// Attr implements the instAttr interface method.
+// Attr implements the InterpretableAttribute interface method.
func (a *evalAttr) Attr() Attribute {
return a.attr
}
-// Adapter implements the instAttr interface method.
+// Adapter implements the InterpretableAttribute interface method.
func (a *evalAttr) Adapter() ref.TypeAdapter {
return a.adapter
}
-// Cost implements the Coster interface method.
-func (a *evalAttr) Cost() (min, max int64) {
- return estimateCost(a.attr)
-}
-
// Eval implements the Interpretable interface method.
func (a *evalAttr) Eval(ctx Activation) ref.Val {
v, err := a.attr.Resolve(ctx)
if err != nil {
- return types.NewErr(err.Error())
+ return types.WrapErr(err)
}
return a.adapter.NativeToValue(v)
}
// Qualify proxies to the Attribute's Qualify method.
-func (a *evalAttr) Qualify(ctx Activation, obj interface{}) (interface{}, error) {
+func (a *evalAttr) Qualify(ctx Activation, obj any) (any, error) {
return a.attr.Qualify(ctx, obj)
}
+// QualifyIfPresent proxies to the Attribute's QualifyIfPresent method.
+func (a *evalAttr) QualifyIfPresent(ctx Activation, obj any, presenceOnly bool) (any, bool, error) {
+ return a.attr.QualifyIfPresent(ctx, obj, presenceOnly)
+}
+
+func (a *evalAttr) IsOptional() bool {
+ return a.optional
+}
+
// Resolve proxies to the Attribute's Resolve method.
-func (a *evalAttr) Resolve(ctx Activation) (interface{}, error) {
+func (a *evalAttr) Resolve(ctx Activation) (any, error) {
return a.attr.Resolve(ctx)
}
+
+type evalWatchConstructor struct {
+ constructor InterpretableConstructor
+ observer EvalObserver
+}
+
+// InitVals implements the InterpretableConstructor InitVals function.
+func (c *evalWatchConstructor) InitVals() []Interpretable {
+ return c.constructor.InitVals()
+}
+
+// Type implements the InterpretableConstructor Type function.
+func (c *evalWatchConstructor) Type() ref.Type {
+ return c.constructor.Type()
+}
+
+// ID implements the Interpretable ID function.
+func (c *evalWatchConstructor) ID() int64 {
+ return c.constructor.ID()
+}
+
+// Eval implements the Interpretable Eval function.
+func (c *evalWatchConstructor) Eval(ctx Activation) ref.Val {
+ val := c.constructor.Eval(ctx)
+ c.observer(c.ID(), c.constructor, val)
+ return val
+}
+
+func invalidOptionalEntryInit(field any, value ref.Val) ref.Val {
+ return types.NewErr("cannot initialize optional entry '%v' from non-optional value %v", field, value)
+}
+
+func invalidOptionalElementInit(value ref.Val) ref.Val {
+ return types.NewErr("cannot initialize optional list element from non-optional value %v", value)
+}
diff --git a/vendor/github.com/google/cel-go/interpreter/interpreter.go b/vendor/github.com/google/cel-go/interpreter/interpreter.go
index b3fd14f8b3..707a6105a1 100644
--- a/vendor/github.com/google/cel-go/interpreter/interpreter.go
+++ b/vendor/github.com/google/cel-go/interpreter/interpreter.go
@@ -29,19 +29,17 @@ import (
type Interpreter interface {
// NewInterpretable creates an Interpretable from a checked expression and an
// optional list of InterpretableDecorator values.
- NewInterpretable(checked *exprpb.CheckedExpr,
- decorators ...InterpretableDecorator) (Interpretable, error)
+ NewInterpretable(checked *exprpb.CheckedExpr, decorators ...InterpretableDecorator) (Interpretable, error)
// NewUncheckedInterpretable returns an Interpretable from a parsed expression
// and an optional list of InterpretableDecorator values.
- NewUncheckedInterpretable(expr *exprpb.Expr,
- decorators ...InterpretableDecorator) (Interpretable, error)
+ NewUncheckedInterpretable(expr *exprpb.Expr, decorators ...InterpretableDecorator) (Interpretable, error)
}
// EvalObserver is a functional interface that accepts an expression id and an observed value.
// The id identifies the expression that was evaluated, the programStep is the Interpretable or Qualifier that
// was evaluated and value is the result of the evaluation.
-type EvalObserver func(id int64, programStep interface{}, value ref.Val)
+type EvalObserver func(id int64, programStep any, value ref.Val)
// Observe constructs a decorator that calls all the provided observers in order after evaluating each Interpretable
// or Qualifier during program evaluation.
@@ -49,7 +47,7 @@ func Observe(observers ...EvalObserver) InterpretableDecorator {
if len(observers) == 1 {
return decObserveEval(observers[0])
}
- observeFn := func(id int64, programStep interface{}, val ref.Val) {
+ observeFn := func(id int64, programStep any, val ref.Val) {
for _, observer := range observers {
observer(id, programStep, val)
}
@@ -96,7 +94,7 @@ func TrackState(state EvalState) InterpretableDecorator {
// This decorator is not thread-safe, and the EvalState must be reset between Eval()
// calls.
func EvalStateObserver(state EvalState) EvalObserver {
- return func(id int64, programStep interface{}, val ref.Val) {
+ return func(id int64, programStep any, val ref.Val) {
state.SetValue(id, val)
}
}
diff --git a/vendor/github.com/google/cel-go/interpreter/planner.go b/vendor/github.com/google/cel-go/interpreter/planner.go
index 882e0419a5..0b65d0fa90 100644
--- a/vendor/github.com/google/cel-go/interpreter/planner.go
+++ b/vendor/github.com/google/cel-go/interpreter/planner.go
@@ -20,7 +20,6 @@ import (
"github.com/google/cel-go/common/containers"
"github.com/google/cel-go/common/operators"
- "github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"github.com/google/cel-go/interpreter/functions"
@@ -189,16 +188,7 @@ func (p *planner) planSelect(expr *exprpb.Expr) (Interpretable, error) {
if err != nil {
return nil, err
}
-
- // Determine the field type if this is a proto message type.
- var fieldType *ref.FieldType
opType := p.typeMap[sel.GetOperand().GetId()]
- if opType.GetMessageType() != "" {
- ft, found := p.provider.FindFieldType(opType.GetMessageType(), sel.GetField())
- if found && ft.IsSet != nil && ft.GetFrom != nil {
- fieldType = ft
- }
- }
// If the Select was marked TestOnly, this is a presence test.
//
@@ -211,37 +201,31 @@ func (p *planner) planSelect(expr *exprpb.Expr) (Interpretable, error) {
// If a string named 'a.b.c' is declared in the environment and referenced within `has(a.b.c)`,
// it is not clear whether has should error or follow the convention defined for structured
// values.
- if sel.TestOnly {
- // Return the test only eval expression.
- return &evalTestOnly{
- id: expr.GetId(),
- field: types.String(sel.GetField()),
- fieldType: fieldType,
- op: op,
- }, nil
- }
- // Build a qualifier.
- qual, err := p.attrFactory.NewQualifier(
- opType, expr.GetId(), sel.GetField())
- if err != nil {
- return nil, err
- }
- // Lastly, create a field selection Interpretable.
+
+ // Establish the attribute reference.
attr, isAttr := op.(InterpretableAttribute)
- if isAttr {
- _, err = attr.AddQualifier(qual)
- return attr, err
+ if !isAttr {
+ attr, err = p.relativeAttr(op.ID(), op, false)
+ if err != nil {
+ return nil, err
+ }
}
- relAttr, err := p.relativeAttr(op.ID(), op)
+ // Build a qualifier for the attribute.
+ qual, err := p.attrFactory.NewQualifier(opType, expr.GetId(), sel.GetField(), false)
if err != nil {
return nil, err
}
- _, err = relAttr.AddQualifier(qual)
- if err != nil {
- return nil, err
+ // Modify the attribute to be test-only.
+ if sel.GetTestOnly() {
+ attr = &evalTestOnly{
+ id: expr.GetId(),
+ InterpretableAttribute: attr,
+ }
}
- return relAttr, nil
+ // Append the qualifier on the attribute.
+ _, err = attr.AddQualifier(qual)
+ return attr, err
}
// planCall creates a callable Interpretable while specializing for common functions and invocation
@@ -286,7 +270,9 @@ func (p *planner) planCall(expr *exprpb.Expr) (Interpretable, error) {
case operators.NotEquals:
return p.planCallNotEqual(expr, args)
case operators.Index:
- return p.planCallIndex(expr, args)
+ return p.planCallIndex(expr, args, false)
+ case operators.OptSelect, operators.OptIndex:
+ return p.planCallIndex(expr, args, true)
}
// Otherwise, generate Interpretable calls specialized by argument count.
@@ -423,8 +409,7 @@ func (p *planner) planCallVarArgs(expr *exprpb.Expr,
}
// planCallEqual generates an equals (==) Interpretable.
-func (p *planner) planCallEqual(expr *exprpb.Expr,
- args []Interpretable) (Interpretable, error) {
+func (p *planner) planCallEqual(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) {
return &evalEq{
id: expr.GetId(),
lhs: args[0],
@@ -433,8 +418,7 @@ func (p *planner) planCallEqual(expr *exprpb.Expr,
}
// planCallNotEqual generates a not equals (!=) Interpretable.
-func (p *planner) planCallNotEqual(expr *exprpb.Expr,
- args []Interpretable) (Interpretable, error) {
+func (p *planner) planCallNotEqual(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) {
return &evalNe{
id: expr.GetId(),
lhs: args[0],
@@ -443,8 +427,7 @@ func (p *planner) planCallNotEqual(expr *exprpb.Expr,
}
// planCallLogicalAnd generates a logical and (&&) Interpretable.
-func (p *planner) planCallLogicalAnd(expr *exprpb.Expr,
- args []Interpretable) (Interpretable, error) {
+func (p *planner) planCallLogicalAnd(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) {
return &evalAnd{
id: expr.GetId(),
lhs: args[0],
@@ -453,8 +436,7 @@ func (p *planner) planCallLogicalAnd(expr *exprpb.Expr,
}
// planCallLogicalOr generates a logical or (||) Interpretable.
-func (p *planner) planCallLogicalOr(expr *exprpb.Expr,
- args []Interpretable) (Interpretable, error) {
+func (p *planner) planCallLogicalOr(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) {
return &evalOr{
id: expr.GetId(),
lhs: args[0],
@@ -463,10 +445,8 @@ func (p *planner) planCallLogicalOr(expr *exprpb.Expr,
}
// planCallConditional generates a conditional / ternary (c ? t : f) Interpretable.
-func (p *planner) planCallConditional(expr *exprpb.Expr,
- args []Interpretable) (Interpretable, error) {
+func (p *planner) planCallConditional(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) {
cond := args[0]
-
t := args[1]
var tAttr Attribute
truthyAttr, isTruthyAttr := t.(InterpretableAttribute)
@@ -493,48 +473,54 @@ func (p *planner) planCallConditional(expr *exprpb.Expr,
// planCallIndex either extends an attribute with the argument to the index operation, or creates
// a relative attribute based on the return of a function call or operation.
-func (p *planner) planCallIndex(expr *exprpb.Expr,
- args []Interpretable) (Interpretable, error) {
+func (p *planner) planCallIndex(expr *exprpb.Expr, args []Interpretable, optional bool) (Interpretable, error) {
op := args[0]
ind := args[1]
- opAttr, err := p.relativeAttr(op.ID(), op)
- if err != nil {
- return nil, err
- }
opType := p.typeMap[expr.GetCallExpr().GetTarget().GetId()]
- indConst, isIndConst := ind.(InterpretableConst)
- if isIndConst {
- qual, err := p.attrFactory.NewQualifier(
- opType, expr.GetId(), indConst.Value())
+
+ // Establish the attribute reference.
+ var err error
+ attr, isAttr := op.(InterpretableAttribute)
+ if !isAttr {
+ attr, err = p.relativeAttr(op.ID(), op, false)
if err != nil {
return nil, err
}
- _, err = opAttr.AddQualifier(qual)
- return opAttr, err
}
- indAttr, isIndAttr := ind.(InterpretableAttribute)
- if isIndAttr {
- qual, err := p.attrFactory.NewQualifier(
- opType, expr.GetId(), indAttr)
- if err != nil {
- return nil, err
- }
- _, err = opAttr.AddQualifier(qual)
- return opAttr, err
+
+ // Construct the qualifier type.
+ var qual Qualifier
+ switch ind := ind.(type) {
+ case InterpretableConst:
+ qual, err = p.attrFactory.NewQualifier(opType, expr.GetId(), ind.Value(), optional)
+ case InterpretableAttribute:
+ qual, err = p.attrFactory.NewQualifier(opType, expr.GetId(), ind, optional)
+ default:
+ qual, err = p.relativeAttr(expr.GetId(), ind, optional)
}
- indQual, err := p.relativeAttr(expr.GetId(), ind)
if err != nil {
return nil, err
}
- _, err = opAttr.AddQualifier(indQual)
- return opAttr, err
+
+ // Add the qualifier to the attribute
+ _, err = attr.AddQualifier(qual)
+ return attr, err
}
// planCreateList generates a list construction Interpretable.
func (p *planner) planCreateList(expr *exprpb.Expr) (Interpretable, error) {
list := expr.GetListExpr()
- elems := make([]Interpretable, len(list.GetElements()))
- for i, elem := range list.GetElements() {
+ optionalIndices := list.GetOptionalIndices()
+ elements := list.GetElements()
+ optionals := make([]bool, len(elements))
+ for _, index := range optionalIndices {
+ if index < 0 || index >= int32(len(elements)) {
+ return nil, fmt.Errorf("optional index %d out of element bounds [0, %d]", index, len(elements))
+ }
+ optionals[index] = true
+ }
+ elems := make([]Interpretable, len(elements))
+ for i, elem := range elements {
elemVal, err := p.Plan(elem)
if err != nil {
return nil, err
@@ -542,9 +528,11 @@ func (p *planner) planCreateList(expr *exprpb.Expr) (Interpretable, error) {
elems[i] = elemVal
}
return &evalList{
- id: expr.GetId(),
- elems: elems,
- adapter: p.adapter,
+ id: expr.GetId(),
+ elems: elems,
+ optionals: optionals,
+ hasOptionals: len(optionals) != 0,
+ adapter: p.adapter,
}, nil
}
@@ -555,6 +543,7 @@ func (p *planner) planCreateStruct(expr *exprpb.Expr) (Interpretable, error) {
return p.planCreateObj(expr)
}
entries := str.GetEntries()
+ optionals := make([]bool, len(entries))
keys := make([]Interpretable, len(entries))
vals := make([]Interpretable, len(entries))
for i, entry := range entries {
@@ -569,23 +558,27 @@ func (p *planner) planCreateStruct(expr *exprpb.Expr) (Interpretable, error) {
return nil, err
}
vals[i] = valVal
+ optionals[i] = entry.GetOptionalEntry()
}
return &evalMap{
- id: expr.GetId(),
- keys: keys,
- vals: vals,
- adapter: p.adapter,
+ id: expr.GetId(),
+ keys: keys,
+ vals: vals,
+ optionals: optionals,
+ hasOptionals: len(optionals) != 0,
+ adapter: p.adapter,
}, nil
}
// planCreateObj generates an object construction Interpretable.
func (p *planner) planCreateObj(expr *exprpb.Expr) (Interpretable, error) {
obj := expr.GetStructExpr()
- typeName, defined := p.resolveTypeName(obj.MessageName)
+ typeName, defined := p.resolveTypeName(obj.GetMessageName())
if !defined {
- return nil, fmt.Errorf("unknown type: %s", typeName)
+ return nil, fmt.Errorf("unknown type: %s", obj.GetMessageName())
}
entries := obj.GetEntries()
+ optionals := make([]bool, len(entries))
fields := make([]string, len(entries))
vals := make([]Interpretable, len(entries))
for i, entry := range entries {
@@ -595,13 +588,16 @@ func (p *planner) planCreateObj(expr *exprpb.Expr) (Interpretable, error) {
return nil, err
}
vals[i] = val
+ optionals[i] = entry.GetOptionalEntry()
}
return &evalObj{
- id: expr.GetId(),
- typeName: typeName,
- fields: fields,
- vals: vals,
- provider: p.provider,
+ id: expr.GetId(),
+ typeName: typeName,
+ fields: fields,
+ vals: vals,
+ optionals: optionals,
+ hasOptionals: len(optionals) != 0,
+ provider: p.provider,
}, nil
}
@@ -753,14 +749,18 @@ func (p *planner) resolveFunction(expr *exprpb.Expr) (*exprpb.Expr, string, stri
return target, fnName, ""
}
-func (p *planner) relativeAttr(id int64, eval Interpretable) (InterpretableAttribute, error) {
+// relativeAttr indicates that the attribute in this case acts as a qualifier and as such needs to
+// be observed to ensure that it's evaluation value is properly recorded for state tracking.
+func (p *planner) relativeAttr(id int64, eval Interpretable, opt bool) (InterpretableAttribute, error) {
eAttr, ok := eval.(InterpretableAttribute)
if !ok {
eAttr = &evalAttr{
- adapter: p.adapter,
- attr: p.attrFactory.RelativeAttribute(id, eval),
+ adapter: p.adapter,
+ attr: p.attrFactory.RelativeAttribute(id, eval),
+ optional: opt,
}
}
+ // This looks like it should either decorate the new evalAttr node, or early return the InterpretableAttribute
decAttr, err := p.decorate(eAttr, nil)
if err != nil {
return nil, err
diff --git a/vendor/github.com/google/cel-go/interpreter/prune.go b/vendor/github.com/google/cel-go/interpreter/prune.go
index eab46e0c06..d1b5d6bd6b 100644
--- a/vendor/github.com/google/cel-go/interpreter/prune.go
+++ b/vendor/github.com/google/cel-go/interpreter/prune.go
@@ -16,6 +16,7 @@ package interpreter
import (
"github.com/google/cel-go/common/operators"
+ "github.com/google/cel-go/common/overloads"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"github.com/google/cel-go/common/types/traits"
@@ -26,6 +27,7 @@ import (
type astPruner struct {
expr *exprpb.Expr
+ macroCalls map[int64]*exprpb.Expr
state EvalState
nextExprID int64
}
@@ -65,13 +67,22 @@ type astPruner struct {
// compiled and constant folded expressions, but is not willing to constant
// fold(and thus cache results of) some external calls, then they can prepare
// the overloads accordingly.
-func PruneAst(expr *exprpb.Expr, state EvalState) *exprpb.Expr {
+func PruneAst(expr *exprpb.Expr, macroCalls map[int64]*exprpb.Expr, state EvalState) *exprpb.ParsedExpr {
+ pruneState := NewEvalState()
+ for _, id := range state.IDs() {
+ v, _ := state.Value(id)
+ pruneState.SetValue(id, v)
+ }
pruner := &astPruner{
expr: expr,
- state: state,
- nextExprID: 1}
- newExpr, _ := pruner.prune(expr)
- return newExpr
+ macroCalls: macroCalls,
+ state: pruneState,
+ nextExprID: getMaxID(expr)}
+ newExpr, _ := pruner.maybePrune(expr)
+ return &exprpb.ParsedExpr{
+ Expr: newExpr,
+ SourceInfo: &exprpb.SourceInfo{MacroCalls: pruner.macroCalls},
+ }
}
func (p *astPruner) createLiteral(id int64, val *exprpb.Constant) *exprpb.Expr {
@@ -84,28 +95,50 @@ func (p *astPruner) createLiteral(id int64, val *exprpb.Constant) *exprpb.Expr {
}
func (p *astPruner) maybeCreateLiteral(id int64, val ref.Val) (*exprpb.Expr, bool) {
- switch val.Type() {
- case types.BoolType:
+ switch v := val.(type) {
+ case types.Bool:
+ p.state.SetValue(id, val)
return p.createLiteral(id,
- &exprpb.Constant{ConstantKind: &exprpb.Constant_BoolValue{BoolValue: val.Value().(bool)}}), true
- case types.IntType:
+ &exprpb.Constant{ConstantKind: &exprpb.Constant_BoolValue{BoolValue: bool(v)}}), true
+ case types.Bytes:
+ p.state.SetValue(id, val)
return p.createLiteral(id,
- &exprpb.Constant{ConstantKind: &exprpb.Constant_Int64Value{Int64Value: val.Value().(int64)}}), true
- case types.UintType:
+ &exprpb.Constant{ConstantKind: &exprpb.Constant_BytesValue{BytesValue: []byte(v)}}), true
+ case types.Double:
+ p.state.SetValue(id, val)
return p.createLiteral(id,
- &exprpb.Constant{ConstantKind: &exprpb.Constant_Uint64Value{Uint64Value: val.Value().(uint64)}}), true
- case types.StringType:
+ &exprpb.Constant{ConstantKind: &exprpb.Constant_DoubleValue{DoubleValue: float64(v)}}), true
+ case types.Duration:
+ p.state.SetValue(id, val)
+ durationString := string(v.ConvertToType(types.StringType).(types.String))
+ return &exprpb.Expr{
+ Id: id,
+ ExprKind: &exprpb.Expr_CallExpr{
+ CallExpr: &exprpb.Expr_Call{
+ Function: overloads.TypeConvertDuration,
+ Args: []*exprpb.Expr{
+ p.createLiteral(p.nextID(),
+ &exprpb.Constant{ConstantKind: &exprpb.Constant_StringValue{StringValue: durationString}}),
+ },
+ },
+ },
+ }, true
+ case types.Int:
+ p.state.SetValue(id, val)
return p.createLiteral(id,
- &exprpb.Constant{ConstantKind: &exprpb.Constant_StringValue{StringValue: val.Value().(string)}}), true
- case types.DoubleType:
+ &exprpb.Constant{ConstantKind: &exprpb.Constant_Int64Value{Int64Value: int64(v)}}), true
+ case types.Uint:
+ p.state.SetValue(id, val)
return p.createLiteral(id,
- &exprpb.Constant{ConstantKind: &exprpb.Constant_DoubleValue{DoubleValue: val.Value().(float64)}}), true
- case types.BytesType:
+ &exprpb.Constant{ConstantKind: &exprpb.Constant_Uint64Value{Uint64Value: uint64(v)}}), true
+ case types.String:
+ p.state.SetValue(id, val)
return p.createLiteral(id,
- &exprpb.Constant{ConstantKind: &exprpb.Constant_BytesValue{BytesValue: val.Value().([]byte)}}), true
- case types.NullType:
+ &exprpb.Constant{ConstantKind: &exprpb.Constant_StringValue{StringValue: string(v)}}), true
+ case types.Null:
+ p.state.SetValue(id, val)
return p.createLiteral(id,
- &exprpb.Constant{ConstantKind: &exprpb.Constant_NullValue{NullValue: val.Value().(structpb.NullValue)}}), true
+ &exprpb.Constant{ConstantKind: &exprpb.Constant_NullValue{NullValue: v.Value().(structpb.NullValue)}}), true
}
// Attempt to build a list literal.
@@ -123,6 +156,7 @@ func (p *astPruner) maybeCreateLiteral(id int64, val ref.Val) (*exprpb.Expr, boo
}
elemExprs[i] = elemExpr
}
+ p.state.SetValue(id, val)
return &exprpb.Expr{
Id: id,
ExprKind: &exprpb.Expr_ListExpr{
@@ -162,6 +196,7 @@ func (p *astPruner) maybeCreateLiteral(id int64, val ref.Val) (*exprpb.Expr, boo
entries[i] = entry
i++
}
+ p.state.SetValue(id, val)
return &exprpb.Expr{
Id: id,
ExprKind: &exprpb.Expr_StructExpr{
@@ -177,70 +212,147 @@ func (p *astPruner) maybeCreateLiteral(id int64, val ref.Val) (*exprpb.Expr, boo
return nil, false
}
-func (p *astPruner) maybePruneAndOr(node *exprpb.Expr) (*exprpb.Expr, bool) {
- if !p.existsWithUnknownValue(node.GetId()) {
+func (p *astPruner) maybePruneOptional(elem *exprpb.Expr) (*exprpb.Expr, bool) {
+ elemVal, found := p.value(elem.GetId())
+ if found && elemVal.Type() == types.OptionalType {
+ opt := elemVal.(*types.Optional)
+ if !opt.HasValue() {
+ return nil, true
+ }
+ if newElem, pruned := p.maybeCreateLiteral(elem.GetId(), opt.GetValue()); pruned {
+ return newElem, true
+ }
+ }
+ return elem, false
+}
+
+func (p *astPruner) maybePruneIn(node *exprpb.Expr) (*exprpb.Expr, bool) {
+ // elem in list
+ call := node.GetCallExpr()
+ val, exists := p.maybeValue(call.GetArgs()[1].GetId())
+ if !exists {
return nil, false
}
+ if sz, ok := val.(traits.Sizer); ok && sz.Size() == types.IntZero {
+ return p.maybeCreateLiteral(node.GetId(), types.False)
+ }
+ return nil, false
+}
+func (p *astPruner) maybePruneLogicalNot(node *exprpb.Expr) (*exprpb.Expr, bool) {
+ call := node.GetCallExpr()
+ arg := call.GetArgs()[0]
+ val, exists := p.maybeValue(arg.GetId())
+ if !exists {
+ return nil, false
+ }
+ if b, ok := val.(types.Bool); ok {
+ return p.maybeCreateLiteral(node.GetId(), !b)
+ }
+ return nil, false
+}
+
+func (p *astPruner) maybePruneOr(node *exprpb.Expr) (*exprpb.Expr, bool) {
call := node.GetCallExpr()
// We know result is unknown, so we have at least one unknown arg
// and if one side is a known value, we know we can ignore it.
- if p.existsWithKnownValue(call.Args[0].GetId()) {
- return call.Args[1], true
+ if v, exists := p.maybeValue(call.GetArgs()[0].GetId()); exists {
+ if v == types.True {
+ return p.maybeCreateLiteral(node.GetId(), types.True)
+ }
+ return call.GetArgs()[1], true
}
- if p.existsWithKnownValue(call.Args[1].GetId()) {
- return call.Args[0], true
+ if v, exists := p.maybeValue(call.GetArgs()[1].GetId()); exists {
+ if v == types.True {
+ return p.maybeCreateLiteral(node.GetId(), types.True)
+ }
+ return call.GetArgs()[0], true
}
return nil, false
}
-func (p *astPruner) maybePruneConditional(node *exprpb.Expr) (*exprpb.Expr, bool) {
- if !p.existsWithUnknownValue(node.GetId()) {
- return nil, false
+func (p *astPruner) maybePruneAnd(node *exprpb.Expr) (*exprpb.Expr, bool) {
+ call := node.GetCallExpr()
+ // We know result is unknown, so we have at least one unknown arg
+ // and if one side is a known value, we know we can ignore it.
+ if v, exists := p.maybeValue(call.GetArgs()[0].GetId()); exists {
+ if v == types.False {
+ return p.maybeCreateLiteral(node.GetId(), types.False)
+ }
+ return call.GetArgs()[1], true
+ }
+ if v, exists := p.maybeValue(call.GetArgs()[1].GetId()); exists {
+ if v == types.False {
+ return p.maybeCreateLiteral(node.GetId(), types.False)
+ }
+ return call.GetArgs()[0], true
}
+ return nil, false
+}
+func (p *astPruner) maybePruneConditional(node *exprpb.Expr) (*exprpb.Expr, bool) {
call := node.GetCallExpr()
- condVal, condValueExists := p.value(call.Args[0].GetId())
- if !condValueExists || types.IsUnknownOrError(condVal) {
+ cond, exists := p.maybeValue(call.GetArgs()[0].GetId())
+ if !exists {
return nil, false
}
-
- if condVal.Value().(bool) {
- return call.Args[1], true
+ if cond.Value().(bool) {
+ return call.GetArgs()[1], true
}
- return call.Args[2], true
+ return call.GetArgs()[2], true
}
func (p *astPruner) maybePruneFunction(node *exprpb.Expr) (*exprpb.Expr, bool) {
+ if _, exists := p.value(node.GetId()); !exists {
+ return nil, false
+ }
call := node.GetCallExpr()
- if call.Function == operators.LogicalOr || call.Function == operators.LogicalAnd {
- return p.maybePruneAndOr(node)
+ if call.Function == operators.LogicalOr {
+ return p.maybePruneOr(node)
+ }
+ if call.Function == operators.LogicalAnd {
+ return p.maybePruneAnd(node)
}
if call.Function == operators.Conditional {
return p.maybePruneConditional(node)
}
-
+ if call.Function == operators.In {
+ return p.maybePruneIn(node)
+ }
+ if call.Function == operators.LogicalNot {
+ return p.maybePruneLogicalNot(node)
+ }
return nil, false
}
+func (p *astPruner) maybePrune(node *exprpb.Expr) (*exprpb.Expr, bool) {
+ return p.prune(node)
+}
+
func (p *astPruner) prune(node *exprpb.Expr) (*exprpb.Expr, bool) {
if node == nil {
return node, false
}
- val, valueExists := p.value(node.GetId())
- if valueExists && !types.IsUnknownOrError(val) {
+ val, valueExists := p.maybeValue(node.GetId())
+ if valueExists {
if newNode, ok := p.maybeCreateLiteral(node.GetId(), val); ok {
+ delete(p.macroCalls, node.GetId())
return newNode, true
}
}
+ if macro, found := p.macroCalls[node.GetId()]; found {
+ // prune the expression in terms of the macro call instead of the expanded form.
+ if newMacro, pruned := p.prune(macro); pruned {
+ p.macroCalls[node.GetId()] = newMacro
+ }
+ }
// We have either an unknown/error value, or something we don't want to
// transform, or expression was not evaluated. If possible, drill down
// more.
-
switch node.GetExprKind().(type) {
case *exprpb.Expr_SelectExpr:
- if operand, pruned := p.prune(node.GetSelectExpr().GetOperand()); pruned {
+ if operand, pruned := p.maybePrune(node.GetSelectExpr().GetOperand()); pruned {
return &exprpb.Expr{
Id: node.GetId(),
ExprKind: &exprpb.Expr_SelectExpr{
@@ -253,10 +365,6 @@ func (p *astPruner) prune(node *exprpb.Expr) (*exprpb.Expr, bool) {
}, true
}
case *exprpb.Expr_CallExpr:
- if newExpr, pruned := p.maybePruneFunction(node); pruned {
- newExpr, _ = p.prune(newExpr)
- return newExpr, true
- }
var prunedCall bool
call := node.GetCallExpr()
args := call.GetArgs()
@@ -268,40 +376,75 @@ func (p *astPruner) prune(node *exprpb.Expr) (*exprpb.Expr, bool) {
}
for i, arg := range args {
newArgs[i] = arg
- if newArg, prunedArg := p.prune(arg); prunedArg {
+ if newArg, prunedArg := p.maybePrune(arg); prunedArg {
prunedCall = true
newArgs[i] = newArg
}
}
- if newTarget, prunedTarget := p.prune(call.GetTarget()); prunedTarget {
+ if newTarget, prunedTarget := p.maybePrune(call.GetTarget()); prunedTarget {
prunedCall = true
newCall.Target = newTarget
}
+ newNode := &exprpb.Expr{
+ Id: node.GetId(),
+ ExprKind: &exprpb.Expr_CallExpr{
+ CallExpr: newCall,
+ },
+ }
+ if newExpr, pruned := p.maybePruneFunction(newNode); pruned {
+ newExpr, _ = p.maybePrune(newExpr)
+ return newExpr, true
+ }
if prunedCall {
- return &exprpb.Expr{
- Id: node.GetId(),
- ExprKind: &exprpb.Expr_CallExpr{
- CallExpr: newCall,
- },
- }, true
+ return newNode, true
}
case *exprpb.Expr_ListExpr:
elems := node.GetListExpr().GetElements()
- newElems := make([]*exprpb.Expr, len(elems))
+ optIndices := node.GetListExpr().GetOptionalIndices()
+ optIndexMap := map[int32]bool{}
+ for _, i := range optIndices {
+ optIndexMap[i] = true
+ }
+ newOptIndexMap := make(map[int32]bool, len(optIndexMap))
+ newElems := make([]*exprpb.Expr, 0, len(elems))
var prunedList bool
+
+ prunedIdx := 0
for i, elem := range elems {
- newElems[i] = elem
- if newElem, prunedElem := p.prune(elem); prunedElem {
- newElems[i] = newElem
+ _, isOpt := optIndexMap[int32(i)]
+ if isOpt {
+ newElem, pruned := p.maybePruneOptional(elem)
+ if pruned {
+ prunedList = true
+ if newElem != nil {
+ newElems = append(newElems, newElem)
+ prunedIdx++
+ }
+ continue
+ }
+ newOptIndexMap[int32(prunedIdx)] = true
+ }
+ if newElem, prunedElem := p.maybePrune(elem); prunedElem {
+ newElems = append(newElems, newElem)
prunedList = true
+ } else {
+ newElems = append(newElems, elem)
}
+ prunedIdx++
+ }
+ optIndices = make([]int32, len(newOptIndexMap))
+ idx := 0
+ for i := range newOptIndexMap {
+ optIndices[idx] = i
+ idx++
}
if prunedList {
return &exprpb.Expr{
Id: node.GetId(),
ExprKind: &exprpb.Expr_ListExpr{
ListExpr: &exprpb.Expr_CreateList{
- Elements: newElems,
+ Elements: newElems,
+ OptionalIndices: optIndices,
},
},
}, true
@@ -313,8 +456,8 @@ func (p *astPruner) prune(node *exprpb.Expr) (*exprpb.Expr, bool) {
newEntries := make([]*exprpb.Expr_CreateStruct_Entry, len(entries))
for i, entry := range entries {
newEntries[i] = entry
- newKey, prunedKey := p.prune(entry.GetMapKey())
- newValue, prunedValue := p.prune(entry.GetValue())
+ newKey, prunedKey := p.maybePrune(entry.GetMapKey())
+ newValue, prunedValue := p.maybePrune(entry.GetValue())
if !prunedKey && !prunedValue {
continue
}
@@ -331,6 +474,7 @@ func (p *astPruner) prune(node *exprpb.Expr) (*exprpb.Expr, bool) {
MapKey: newKey,
}
}
+ newEntry.OptionalEntry = entry.GetOptionalEntry()
newEntries[i] = newEntry
}
if prunedStruct {
@@ -344,27 +488,6 @@ func (p *astPruner) prune(node *exprpb.Expr) (*exprpb.Expr, bool) {
},
}, true
}
- case *exprpb.Expr_ComprehensionExpr:
- compre := node.GetComprehensionExpr()
- // Only the range of the comprehension is pruned since the state tracking only records
- // the last iteration of the comprehension and not each step in the evaluation which
- // means that the any residuals computed in between might be inaccurate.
- if newRange, pruned := p.prune(compre.GetIterRange()); pruned {
- return &exprpb.Expr{
- Id: node.GetId(),
- ExprKind: &exprpb.Expr_ComprehensionExpr{
- ComprehensionExpr: &exprpb.Expr_Comprehension{
- IterVar: compre.GetIterVar(),
- IterRange: newRange,
- AccuVar: compre.GetAccuVar(),
- AccuInit: compre.GetAccuInit(),
- LoopCondition: compre.GetLoopCondition(),
- LoopStep: compre.GetLoopStep(),
- Result: compre.GetResult(),
- },
- },
- }, true
- }
}
return node, false
}
@@ -374,24 +497,82 @@ func (p *astPruner) value(id int64) (ref.Val, bool) {
return val, (found && val != nil)
}
-func (p *astPruner) existsWithUnknownValue(id int64) bool {
- val, valueExists := p.value(id)
- return valueExists && types.IsUnknown(val)
+func (p *astPruner) maybeValue(id int64) (ref.Val, bool) {
+ val, found := p.value(id)
+ if !found || types.IsUnknownOrError(val) {
+ return nil, false
+ }
+ return val, true
}
-func (p *astPruner) existsWithKnownValue(id int64) bool {
- val, valueExists := p.value(id)
- return valueExists && !types.IsUnknown(val)
+func (p *astPruner) nextID() int64 {
+ next := p.nextExprID
+ p.nextExprID++
+ return next
}
-func (p *astPruner) nextID() int64 {
- for {
- _, found := p.state.Value(p.nextExprID)
- if !found {
- next := p.nextExprID
- p.nextExprID++
- return next
+type astVisitor struct {
+ // visitEntry is called on every expr node, including those within a map/struct entry.
+ visitExpr func(expr *exprpb.Expr)
+ // visitEntry is called before entering the key, value of a map/struct entry.
+ visitEntry func(entry *exprpb.Expr_CreateStruct_Entry)
+}
+
+func getMaxID(expr *exprpb.Expr) int64 {
+ maxID := int64(1)
+ visit(expr, maxIDVisitor(&maxID))
+ return maxID
+}
+
+func maxIDVisitor(maxID *int64) astVisitor {
+ return astVisitor{
+ visitExpr: func(e *exprpb.Expr) {
+ if e.GetId() >= *maxID {
+ *maxID = e.GetId() + 1
+ }
+ },
+ visitEntry: func(e *exprpb.Expr_CreateStruct_Entry) {
+ if e.GetId() >= *maxID {
+ *maxID = e.GetId() + 1
+ }
+ },
+ }
+}
+
+func visit(expr *exprpb.Expr, visitor astVisitor) {
+ exprs := []*exprpb.Expr{expr}
+ for len(exprs) != 0 {
+ e := exprs[0]
+ visitor.visitExpr(e)
+ exprs = exprs[1:]
+ switch e.GetExprKind().(type) {
+ case *exprpb.Expr_SelectExpr:
+ exprs = append(exprs, e.GetSelectExpr().GetOperand())
+ case *exprpb.Expr_CallExpr:
+ call := e.GetCallExpr()
+ if call.GetTarget() != nil {
+ exprs = append(exprs, call.GetTarget())
+ }
+ exprs = append(exprs, call.GetArgs()...)
+ case *exprpb.Expr_ComprehensionExpr:
+ compre := e.GetComprehensionExpr()
+ exprs = append(exprs,
+ compre.GetIterRange(),
+ compre.GetAccuInit(),
+ compre.GetLoopCondition(),
+ compre.GetLoopStep(),
+ compre.GetResult())
+ case *exprpb.Expr_ListExpr:
+ list := e.GetListExpr()
+ exprs = append(exprs, list.GetElements()...)
+ case *exprpb.Expr_StructExpr:
+ for _, entry := range e.GetStructExpr().GetEntries() {
+ visitor.visitEntry(entry)
+ if entry.GetMapKey() != nil {
+ exprs = append(exprs, entry.GetMapKey())
+ }
+ exprs = append(exprs, entry.GetValue())
+ }
}
- p.nextExprID++
}
}
diff --git a/vendor/github.com/google/cel-go/interpreter/runtimecost.go b/vendor/github.com/google/cel-go/interpreter/runtimecost.go
index 06b6b27ef1..80e7f61344 100644
--- a/vendor/github.com/google/cel-go/interpreter/runtimecost.go
+++ b/vendor/github.com/google/cel-go/interpreter/runtimecost.go
@@ -36,7 +36,7 @@ type ActualCostEstimator interface {
// CostObserver provides an observer that tracks runtime cost.
func CostObserver(tracker *CostTracker) EvalObserver {
- observer := func(id int64, programStep interface{}, val ref.Val) {
+ observer := func(id int64, programStep any, val ref.Val) {
switch t := programStep.(type) {
case ConstantQualifier:
// TODO: Push identifiers on to the stack before observing constant qualifiers that apply to them
@@ -53,6 +53,11 @@ func CostObserver(tracker *CostTracker) EvalObserver {
tracker.stack.drop(t.Attr().ID())
tracker.cost += common.SelectAndIdentCost
}
+ if !tracker.presenceTestHasCost {
+ if _, isTestOnly := programStep.(*evalTestOnly); isTestOnly {
+ tracker.cost -= common.SelectAndIdentCost
+ }
+ }
case *evalExhaustiveConditional:
// Ternary has no direct cost. All cost is from the conditional and the true/false branch expressions.
tracker.stack.drop(t.attr.falsy.ID(), t.attr.truthy.ID(), t.attr.expr.ID())
@@ -95,21 +100,58 @@ func CostObserver(tracker *CostTracker) EvalObserver {
return observer
}
-// CostTracker represents the information needed for tacking runtime cost
+// CostTrackerOption configures the behavior of CostTracker objects.
+type CostTrackerOption func(*CostTracker) error
+
+// CostTrackerLimit sets the runtime limit on the evaluation cost during execution and will terminate the expression
+// evaluation if the limit is exceeded.
+func CostTrackerLimit(limit uint64) CostTrackerOption {
+ return func(tracker *CostTracker) error {
+ tracker.Limit = &limit
+ return nil
+ }
+}
+
+// PresenceTestHasCost determines whether presence testing has a cost of one or zero.
+// Defaults to presence test has a cost of one.
+func PresenceTestHasCost(hasCost bool) CostTrackerOption {
+ return func(tracker *CostTracker) error {
+ tracker.presenceTestHasCost = hasCost
+ return nil
+ }
+}
+
+// NewCostTracker creates a new CostTracker with a given estimator and a set of functional CostTrackerOption values.
+func NewCostTracker(estimator ActualCostEstimator, opts ...CostTrackerOption) (*CostTracker, error) {
+ tracker := &CostTracker{
+ Estimator: estimator,
+ presenceTestHasCost: true,
+ }
+ for _, opt := range opts {
+ err := opt(tracker)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return tracker, nil
+}
+
+// CostTracker represents the information needed for tracking runtime cost.
type CostTracker struct {
- Estimator ActualCostEstimator
- Limit *uint64
+ Estimator ActualCostEstimator
+ Limit *uint64
+ presenceTestHasCost bool
cost uint64
stack refValStack
}
// ActualCost returns the runtime cost
-func (c CostTracker) ActualCost() uint64 {
+func (c *CostTracker) ActualCost() uint64 {
return c.cost
}
-func (c CostTracker) costCall(call InterpretableCall, argValues []ref.Val, result ref.Val) uint64 {
+func (c *CostTracker) costCall(call InterpretableCall, argValues []ref.Val, result ref.Val) uint64 {
var cost uint64
if c.Estimator != nil {
callCost := c.Estimator.CallCost(call.Function(), call.OverloadID(), argValues, result)
@@ -122,7 +164,7 @@ func (c CostTracker) costCall(call InterpretableCall, argValues []ref.Val, resul
// if user has their own implementation of ActualCostEstimator, make sure to cover the mapping between overloadId and cost calculation
switch call.OverloadID() {
// O(n) functions
- case overloads.StartsWithString, overloads.EndsWithString, overloads.StringToBytes, overloads.BytesToString:
+ case overloads.StartsWithString, overloads.EndsWithString, overloads.StringToBytes, overloads.BytesToString, overloads.ExtQuoteString, overloads.ExtFormatString:
cost += uint64(math.Ceil(float64(c.actualSize(argValues[0])) * common.StringTraversalCostFactor))
case overloads.InList:
// If a list is composed entirely of constant values this is O(1), but we don't account for that here.
@@ -179,7 +221,7 @@ func (c CostTracker) costCall(call InterpretableCall, argValues []ref.Val, resul
}
// actualSize returns the size of value
-func (c CostTracker) actualSize(value ref.Val) uint64 {
+func (c *CostTracker) actualSize(value ref.Val) uint64 {
if sz, ok := value.(traits.Sizer); ok {
return uint64(sz.Size().(types.Int))
}
diff --git a/vendor/github.com/google/cel-go/parser/BUILD.bazel b/vendor/github.com/google/cel-go/parser/BUILD.bazel
index b76e6e4844..67ecc95543 100644
--- a/vendor/github.com/google/cel-go/parser/BUILD.bazel
+++ b/vendor/github.com/google/cel-go/parser/BUILD.bazel
@@ -23,8 +23,8 @@ go_library(
"//common/operators:go_default_library",
"//common/runes:go_default_library",
"//parser/gen:go_default_library",
- "@com_github_antlr_antlr4_runtime_go_antlr//:go_default_library",
- "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
+ "@com_github_antlr_antlr4_runtime_go_antlr_v4//:go_default_library",
+ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
"@org_golang_google_protobuf//types/known/structpb:go_default_library",
],
@@ -34,6 +34,7 @@ go_test(
name = "go_default_test",
size = "small",
srcs = [
+ "helper_test.go",
"parser_test.go",
"unescape_test.go",
"unparser_test.go",
@@ -45,7 +46,8 @@ go_test(
"//common/debug:go_default_library",
"//parser/gen:go_default_library",
"//test:go_default_library",
- "@com_github_antlr_antlr4_runtime_go_antlr//:go_default_library",
+ "@com_github_antlr_antlr4_runtime_go_antlr_v4//:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
+ "@org_golang_google_protobuf//testing/protocmp:go_default_library",
],
)
diff --git a/vendor/github.com/google/cel-go/parser/gen/BUILD.bazel b/vendor/github.com/google/cel-go/parser/gen/BUILD.bazel
index 22711310ce..654d1de7aa 100644
--- a/vendor/github.com/google/cel-go/parser/gen/BUILD.bazel
+++ b/vendor/github.com/google/cel-go/parser/gen/BUILD.bazel
@@ -21,6 +21,6 @@ go_library(
],
importpath = "github.com/google/cel-go/parser/gen",
deps = [
- "@com_github_antlr_antlr4_runtime_go_antlr//:go_default_library",
+ "@com_github_antlr_antlr4_runtime_go_antlr_v4//:go_default_library",
],
)
diff --git a/vendor/github.com/google/cel-go/parser/gen/CEL.g4 b/vendor/github.com/google/cel-go/parser/gen/CEL.g4
index 11145ec374..b011da803c 100644
--- a/vendor/github.com/google/cel-go/parser/gen/CEL.g4
+++ b/vendor/github.com/google/cel-go/parser/gen/CEL.g4
@@ -52,16 +52,18 @@ unary
member
: primary # PrimaryExpr
- | member op='.' id=IDENTIFIER (open='(' args=exprList? ')')? # SelectOrCall
- | member op='[' index=expr ']' # Index
- | member op='{' entries=fieldInitializerList? ','? '}' # CreateMessage
+ | member op='.' (opt='?')? id=IDENTIFIER # Select
+ | member op='.' id=IDENTIFIER open='(' args=exprList? ')' # MemberCall
+ | member op='[' (opt='?')? index=expr ']' # Index
;
primary
: leadingDot='.'? id=IDENTIFIER (op='(' args=exprList? ')')? # IdentOrGlobalCall
| '(' e=expr ')' # Nested
- | op='[' elems=exprList? ','? ']' # CreateList
+ | op='[' elems=listInit? ','? ']' # CreateList
| op='{' entries=mapInitializerList? ','? '}' # CreateStruct
+ | leadingDot='.'? ids+=IDENTIFIER (ops+='.' ids+=IDENTIFIER)*
+ op='{' entries=fieldInitializerList? ','? '}' # CreateMessage
| literal # ConstantLiteral
;
@@ -69,23 +71,35 @@ exprList
: e+=expr (',' e+=expr)*
;
+listInit
+ : elems+=optExpr (',' elems+=optExpr)*
+ ;
+
fieldInitializerList
- : fields+=IDENTIFIER cols+=':' values+=expr (',' fields+=IDENTIFIER cols+=':' values+=expr)*
+ : fields+=optField cols+=':' values+=expr (',' fields+=optField cols+=':' values+=expr)*
+ ;
+
+optField
+ : (opt='?')? IDENTIFIER
;
mapInitializerList
- : keys+=expr cols+=':' values+=expr (',' keys+=expr cols+=':' values+=expr)*
+ : keys+=optExpr cols+=':' values+=expr (',' keys+=optExpr cols+=':' values+=expr)*
+ ;
+
+optExpr
+ : (opt='?')? e=expr
;
literal
: sign=MINUS? tok=NUM_INT # Int
- | tok=NUM_UINT # Uint
+ | tok=NUM_UINT # Uint
| sign=MINUS? tok=NUM_FLOAT # Double
- | tok=STRING # String
- | tok=BYTES # Bytes
- | tok=CEL_TRUE # BoolTrue
- | tok=CEL_FALSE # BoolFalse
- | tok=NUL # Null
+ | tok=STRING # String
+ | tok=BYTES # Bytes
+ | tok=CEL_TRUE # BoolTrue
+ | tok=CEL_FALSE # BoolFalse
+ | tok=NUL # Null
;
// Lexer Rules
diff --git a/vendor/github.com/google/cel-go/parser/gen/CEL.interp b/vendor/github.com/google/cel-go/parser/gen/CEL.interp
index 13e3a10d17..75b8bb3e20 100644
--- a/vendor/github.com/google/cel-go/parser/gen/CEL.interp
+++ b/vendor/github.com/google/cel-go/parser/gen/CEL.interp
@@ -87,10 +87,13 @@ unary
member
primary
exprList
+listInit
fieldInitializerList
+optField
mapInitializerList
+optExpr
literal
atn:
-[4, 1, 36, 209, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 36, 8, 1, 1, 2, 1, 2, 1, 2, 5, 2, 41, 8, 2, 10, 2, 12, 2, 44, 9, 2, 1, 3, 1, 3, 1, 3, 5, 3, 49, 8, 3, 10, 3, 12, 3, 52, 9, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 5, 4, 60, 8, 4, 10, 4, 12, 4, 63, 9, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 74, 8, 5, 10, 5, 12, 5, 77, 9, 5, 1, 6, 1, 6, 4, 6, 81, 8, 6, 11, 6, 12, 6, 82, 1, 6, 1, 6, 4, 6, 87, 8, 6, 11, 6, 12, 6, 88, 1, 6, 3, 6, 92, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 102, 8, 7, 1, 7, 3, 7, 105, 8, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 115, 8, 7, 1, 7, 3, 7, 118, 8, 7, 1, 7, 5, 7, 121, 8, 7, 10, 7, 12, 7, 124, 9, 7, 1, 8, 3, 8, 127, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 132, 8, 8, 1, 8, 3, 8, 135, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 143, 8, 8, 1, 8, 3, 8, 146, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 151, 8, 8, 1, 8, 3, 8, 154, 8, 8, 1, 8, 1, 8, 3, 8, 158, 8, 8, 1, 9, 1, 9, 1, 9, 5, 9, 163, 8, 9, 10, 9, 12, 9, 166, 9, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 5, 10, 175, 8, 10, 10, 10, 12, 10, 178, 9, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 5, 11, 188, 8, 11, 10, 11, 12, 11, 191, 9, 11, 1, 12, 3, 12, 194, 8, 12, 1, 12, 1, 12, 1, 12, 3, 12, 199, 8, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 207, 8, 12, 1, 12, 0, 3, 8, 10, 14, 13, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 0, 3, 1, 0, 1, 7, 1, 0, 23, 25, 2, 0, 18, 18, 22, 22, 235, 0, 26, 1, 0, 0, 0, 2, 29, 1, 0, 0, 0, 4, 37, 1, 0, 0, 0, 6, 45, 1, 0, 0, 0, 8, 53, 1, 0, 0, 0, 10, 64, 1, 0, 0, 0, 12, 91, 1, 0, 0, 0, 14, 93, 1, 0, 0, 0, 16, 157, 1, 0, 0, 0, 18, 159, 1, 0, 0, 0, 20, 167, 1, 0, 0, 0, 22, 179, 1, 0, 0, 0, 24, 206, 1, 0, 0, 0, 26, 27, 3, 2, 1, 0, 27, 28, 5, 0, 0, 1, 28, 1, 1, 0, 0, 0, 29, 35, 3, 4, 2, 0, 30, 31, 5, 20, 0, 0, 31, 32, 3, 4, 2, 0, 32, 33, 5, 21, 0, 0, 33, 34, 3, 2, 1, 0, 34, 36, 1, 0, 0, 0, 35, 30, 1, 0, 0, 0, 35, 36, 1, 0, 0, 0, 36, 3, 1, 0, 0, 0, 37, 42, 3, 6, 3, 0, 38, 39, 5, 9, 0, 0, 39, 41, 3, 6, 3, 0, 40, 38, 1, 0, 0, 0, 41, 44, 1, 0, 0, 0, 42, 40, 1, 0, 0, 0, 42, 43, 1, 0, 0, 0, 43, 5, 1, 0, 0, 0, 44, 42, 1, 0, 0, 0, 45, 50, 3, 8, 4, 0, 46, 47, 5, 8, 0, 0, 47, 49, 3, 8, 4, 0, 48, 46, 1, 0, 0, 0, 49, 52, 1, 0, 0, 0, 50, 48, 1, 0, 0, 0, 50, 51, 1, 0, 0, 0, 51, 7, 1, 0, 0, 0, 52, 50, 1, 0, 0, 0, 53, 54, 6, 4, -1, 0, 54, 55, 3, 10, 5, 0, 55, 61, 1, 0, 0, 0, 56, 57, 10, 1, 0, 0, 57, 58, 7, 0, 0, 0, 58, 60, 3, 8, 4, 2, 59, 56, 1, 0, 0, 0, 60, 63, 1, 0, 0, 0, 61, 59, 1, 0, 0, 0, 61, 62, 1, 0, 0, 0, 62, 9, 1, 0, 0, 0, 63, 61, 1, 0, 0, 0, 64, 65, 6, 5, -1, 0, 65, 66, 3, 12, 6, 0, 66, 75, 1, 0, 0, 0, 67, 68, 10, 2, 0, 0, 68, 69, 7, 1, 0, 0, 69, 74, 3, 10, 5, 3, 70, 71, 10, 1, 0, 0, 71, 72, 7, 2, 0, 0, 72, 74, 3, 10, 5, 2, 73, 67, 1, 0, 0, 0, 73, 70, 1, 0, 0, 0, 74, 77, 1, 0, 0, 0, 75, 73, 1, 0, 0, 0, 75, 76, 1, 0, 0, 0, 76, 11, 1, 0, 0, 0, 77, 75, 1, 0, 0, 0, 78, 92, 3, 14, 7, 0, 79, 81, 5, 19, 0, 0, 80, 79, 1, 0, 0, 0, 81, 82, 1, 0, 0, 0, 82, 80, 1, 0, 0, 0, 82, 83, 1, 0, 0, 0, 83, 84, 1, 0, 0, 0, 84, 92, 3, 14, 7, 0, 85, 87, 5, 18, 0, 0, 86, 85, 1, 0, 0, 0, 87, 88, 1, 0, 0, 0, 88, 86, 1, 0, 0, 0, 88, 89, 1, 0, 0, 0, 89, 90, 1, 0, 0, 0, 90, 92, 3, 14, 7, 0, 91, 78, 1, 0, 0, 0, 91, 80, 1, 0, 0, 0, 91, 86, 1, 0, 0, 0, 92, 13, 1, 0, 0, 0, 93, 94, 6, 7, -1, 0, 94, 95, 3, 16, 8, 0, 95, 122, 1, 0, 0, 0, 96, 97, 10, 3, 0, 0, 97, 98, 5, 16, 0, 0, 98, 104, 5, 36, 0, 0, 99, 101, 5, 14, 0, 0, 100, 102, 3, 18, 9, 0, 101, 100, 1, 0, 0, 0, 101, 102, 1, 0, 0, 0, 102, 103, 1, 0, 0, 0, 103, 105, 5, 15, 0, 0, 104, 99, 1, 0, 0, 0, 104, 105, 1, 0, 0, 0, 105, 121, 1, 0, 0, 0, 106, 107, 10, 2, 0, 0, 107, 108, 5, 10, 0, 0, 108, 109, 3, 2, 1, 0, 109, 110, 5, 11, 0, 0, 110, 121, 1, 0, 0, 0, 111, 112, 10, 1, 0, 0, 112, 114, 5, 12, 0, 0, 113, 115, 3, 20, 10, 0, 114, 113, 1, 0, 0, 0, 114, 115, 1, 0, 0, 0, 115, 117, 1, 0, 0, 0, 116, 118, 5, 17, 0, 0, 117, 116, 1, 0, 0, 0, 117, 118, 1, 0, 0, 0, 118, 119, 1, 0, 0, 0, 119, 121, 5, 13, 0, 0, 120, 96, 1, 0, 0, 0, 120, 106, 1, 0, 0, 0, 120, 111, 1, 0, 0, 0, 121, 124, 1, 0, 0, 0, 122, 120, 1, 0, 0, 0, 122, 123, 1, 0, 0, 0, 123, 15, 1, 0, 0, 0, 124, 122, 1, 0, 0, 0, 125, 127, 5, 16, 0, 0, 126, 125, 1, 0, 0, 0, 126, 127, 1, 0, 0, 0, 127, 128, 1, 0, 0, 0, 128, 134, 5, 36, 0, 0, 129, 131, 5, 14, 0, 0, 130, 132, 3, 18, 9, 0, 131, 130, 1, 0, 0, 0, 131, 132, 1, 0, 0, 0, 132, 133, 1, 0, 0, 0, 133, 135, 5, 15, 0, 0, 134, 129, 1, 0, 0, 0, 134, 135, 1, 0, 0, 0, 135, 158, 1, 0, 0, 0, 136, 137, 5, 14, 0, 0, 137, 138, 3, 2, 1, 0, 138, 139, 5, 15, 0, 0, 139, 158, 1, 0, 0, 0, 140, 142, 5, 10, 0, 0, 141, 143, 3, 18, 9, 0, 142, 141, 1, 0, 0, 0, 142, 143, 1, 0, 0, 0, 143, 145, 1, 0, 0, 0, 144, 146, 5, 17, 0, 0, 145, 144, 1, 0, 0, 0, 145, 146, 1, 0, 0, 0, 146, 147, 1, 0, 0, 0, 147, 158, 5, 11, 0, 0, 148, 150, 5, 12, 0, 0, 149, 151, 3, 22, 11, 0, 150, 149, 1, 0, 0, 0, 150, 151, 1, 0, 0, 0, 151, 153, 1, 0, 0, 0, 152, 154, 5, 17, 0, 0, 153, 152, 1, 0, 0, 0, 153, 154, 1, 0, 0, 0, 154, 155, 1, 0, 0, 0, 155, 158, 5, 13, 0, 0, 156, 158, 3, 24, 12, 0, 157, 126, 1, 0, 0, 0, 157, 136, 1, 0, 0, 0, 157, 140, 1, 0, 0, 0, 157, 148, 1, 0, 0, 0, 157, 156, 1, 0, 0, 0, 158, 17, 1, 0, 0, 0, 159, 164, 3, 2, 1, 0, 160, 161, 5, 17, 0, 0, 161, 163, 3, 2, 1, 0, 162, 160, 1, 0, 0, 0, 163, 166, 1, 0, 0, 0, 164, 162, 1, 0, 0, 0, 164, 165, 1, 0, 0, 0, 165, 19, 1, 0, 0, 0, 166, 164, 1, 0, 0, 0, 167, 168, 5, 36, 0, 0, 168, 169, 5, 21, 0, 0, 169, 176, 3, 2, 1, 0, 170, 171, 5, 17, 0, 0, 171, 172, 5, 36, 0, 0, 172, 173, 5, 21, 0, 0, 173, 175, 3, 2, 1, 0, 174, 170, 1, 0, 0, 0, 175, 178, 1, 0, 0, 0, 176, 174, 1, 0, 0, 0, 176, 177, 1, 0, 0, 0, 177, 21, 1, 0, 0, 0, 178, 176, 1, 0, 0, 0, 179, 180, 3, 2, 1, 0, 180, 181, 5, 21, 0, 0, 181, 189, 3, 2, 1, 0, 182, 183, 5, 17, 0, 0, 183, 184, 3, 2, 1, 0, 184, 185, 5, 21, 0, 0, 185, 186, 3, 2, 1, 0, 186, 188, 1, 0, 0, 0, 187, 182, 1, 0, 0, 0, 188, 191, 1, 0, 0, 0, 189, 187, 1, 0, 0, 0, 189, 190, 1, 0, 0, 0, 190, 23, 1, 0, 0, 0, 191, 189, 1, 0, 0, 0, 192, 194, 5, 18, 0, 0, 193, 192, 1, 0, 0, 0, 193, 194, 1, 0, 0, 0, 194, 195, 1, 0, 0, 0, 195, 207, 5, 32, 0, 0, 196, 207, 5, 33, 0, 0, 197, 199, 5, 18, 0, 0, 198, 197, 1, 0, 0, 0, 198, 199, 1, 0, 0, 0, 199, 200, 1, 0, 0, 0, 200, 207, 5, 31, 0, 0, 201, 207, 5, 34, 0, 0, 202, 207, 5, 35, 0, 0, 203, 207, 5, 26, 0, 0, 204, 207, 5, 27, 0, 0, 205, 207, 5, 28, 0, 0, 206, 193, 1, 0, 0, 0, 206, 196, 1, 0, 0, 0, 206, 198, 1, 0, 0, 0, 206, 201, 1, 0, 0, 0, 206, 202, 1, 0, 0, 0, 206, 203, 1, 0, 0, 0, 206, 204, 1, 0, 0, 0, 206, 205, 1, 0, 0, 0, 207, 25, 1, 0, 0, 0, 29, 35, 42, 50, 61, 73, 75, 82, 88, 91, 101, 104, 114, 117, 120, 122, 126, 131, 134, 142, 145, 150, 153, 157, 164, 176, 189, 193, 198, 206]
\ No newline at end of file
+[4, 1, 36, 251, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 42, 8, 1, 1, 2, 1, 2, 1, 2, 5, 2, 47, 8, 2, 10, 2, 12, 2, 50, 9, 2, 1, 3, 1, 3, 1, 3, 5, 3, 55, 8, 3, 10, 3, 12, 3, 58, 9, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 5, 4, 66, 8, 4, 10, 4, 12, 4, 69, 9, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 80, 8, 5, 10, 5, 12, 5, 83, 9, 5, 1, 6, 1, 6, 4, 6, 87, 8, 6, 11, 6, 12, 6, 88, 1, 6, 1, 6, 4, 6, 93, 8, 6, 11, 6, 12, 6, 94, 1, 6, 3, 6, 98, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 106, 8, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 114, 8, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 120, 8, 7, 1, 7, 1, 7, 1, 7, 5, 7, 125, 8, 7, 10, 7, 12, 7, 128, 9, 7, 1, 8, 3, 8, 131, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 136, 8, 8, 1, 8, 3, 8, 139, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 147, 8, 8, 1, 8, 3, 8, 150, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 155, 8, 8, 1, 8, 3, 8, 158, 8, 8, 1, 8, 1, 8, 3, 8, 162, 8, 8, 1, 8, 1, 8, 1, 8, 5, 8, 167, 8, 8, 10, 8, 12, 8, 170, 9, 8, 1, 8, 1, 8, 3, 8, 174, 8, 8, 1, 8, 3, 8, 177, 8, 8, 1, 8, 1, 8, 3, 8, 181, 8, 8, 1, 9, 1, 9, 1, 9, 5, 9, 186, 8, 9, 10, 9, 12, 9, 189, 9, 9, 1, 10, 1, 10, 1, 10, 5, 10, 194, 8, 10, 10, 10, 12, 10, 197, 9, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 5, 11, 207, 8, 11, 10, 11, 12, 11, 210, 9, 11, 1, 12, 3, 12, 213, 8, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 5, 13, 225, 8, 13, 10, 13, 12, 13, 228, 9, 13, 1, 14, 3, 14, 231, 8, 14, 1, 14, 1, 14, 1, 15, 3, 15, 236, 8, 15, 1, 15, 1, 15, 1, 15, 3, 15, 241, 8, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 249, 8, 15, 1, 15, 0, 3, 8, 10, 14, 16, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 0, 3, 1, 0, 1, 7, 1, 0, 23, 25, 2, 0, 18, 18, 22, 22, 281, 0, 32, 1, 0, 0, 0, 2, 35, 1, 0, 0, 0, 4, 43, 1, 0, 0, 0, 6, 51, 1, 0, 0, 0, 8, 59, 1, 0, 0, 0, 10, 70, 1, 0, 0, 0, 12, 97, 1, 0, 0, 0, 14, 99, 1, 0, 0, 0, 16, 180, 1, 0, 0, 0, 18, 182, 1, 0, 0, 0, 20, 190, 1, 0, 0, 0, 22, 198, 1, 0, 0, 0, 24, 212, 1, 0, 0, 0, 26, 216, 1, 0, 0, 0, 28, 230, 1, 0, 0, 0, 30, 248, 1, 0, 0, 0, 32, 33, 3, 2, 1, 0, 33, 34, 5, 0, 0, 1, 34, 1, 1, 0, 0, 0, 35, 41, 3, 4, 2, 0, 36, 37, 5, 20, 0, 0, 37, 38, 3, 4, 2, 0, 38, 39, 5, 21, 0, 0, 39, 40, 3, 2, 1, 0, 40, 42, 1, 0, 0, 0, 41, 36, 1, 0, 0, 0, 41, 42, 1, 0, 0, 0, 42, 3, 1, 0, 0, 0, 43, 48, 3, 6, 3, 0, 44, 45, 5, 9, 0, 0, 45, 47, 3, 6, 3, 0, 46, 44, 1, 0, 0, 0, 47, 50, 1, 0, 0, 0, 48, 46, 1, 0, 0, 0, 48, 49, 1, 0, 0, 0, 49, 5, 1, 0, 0, 0, 50, 48, 1, 0, 0, 0, 51, 56, 3, 8, 4, 0, 52, 53, 5, 8, 0, 0, 53, 55, 3, 8, 4, 0, 54, 52, 1, 0, 0, 0, 55, 58, 1, 0, 0, 0, 56, 54, 1, 0, 0, 0, 56, 57, 1, 0, 0, 0, 57, 7, 1, 0, 0, 0, 58, 56, 1, 0, 0, 0, 59, 60, 6, 4, -1, 0, 60, 61, 3, 10, 5, 0, 61, 67, 1, 0, 0, 0, 62, 63, 10, 1, 0, 0, 63, 64, 7, 0, 0, 0, 64, 66, 3, 8, 4, 2, 65, 62, 1, 0, 0, 0, 66, 69, 1, 0, 0, 0, 67, 65, 1, 0, 0, 0, 67, 68, 1, 0, 0, 0, 68, 9, 1, 0, 0, 0, 69, 67, 1, 0, 0, 0, 70, 71, 6, 5, -1, 0, 71, 72, 3, 12, 6, 0, 72, 81, 1, 0, 0, 0, 73, 74, 10, 2, 0, 0, 74, 75, 7, 1, 0, 0, 75, 80, 3, 10, 5, 3, 76, 77, 10, 1, 0, 0, 77, 78, 7, 2, 0, 0, 78, 80, 3, 10, 5, 2, 79, 73, 1, 0, 0, 0, 79, 76, 1, 0, 0, 0, 80, 83, 1, 0, 0, 0, 81, 79, 1, 0, 0, 0, 81, 82, 1, 0, 0, 0, 82, 11, 1, 0, 0, 0, 83, 81, 1, 0, 0, 0, 84, 98, 3, 14, 7, 0, 85, 87, 5, 19, 0, 0, 86, 85, 1, 0, 0, 0, 87, 88, 1, 0, 0, 0, 88, 86, 1, 0, 0, 0, 88, 89, 1, 0, 0, 0, 89, 90, 1, 0, 0, 0, 90, 98, 3, 14, 7, 0, 91, 93, 5, 18, 0, 0, 92, 91, 1, 0, 0, 0, 93, 94, 1, 0, 0, 0, 94, 92, 1, 0, 0, 0, 94, 95, 1, 0, 0, 0, 95, 96, 1, 0, 0, 0, 96, 98, 3, 14, 7, 0, 97, 84, 1, 0, 0, 0, 97, 86, 1, 0, 0, 0, 97, 92, 1, 0, 0, 0, 98, 13, 1, 0, 0, 0, 99, 100, 6, 7, -1, 0, 100, 101, 3, 16, 8, 0, 101, 126, 1, 0, 0, 0, 102, 103, 10, 3, 0, 0, 103, 105, 5, 16, 0, 0, 104, 106, 5, 20, 0, 0, 105, 104, 1, 0, 0, 0, 105, 106, 1, 0, 0, 0, 106, 107, 1, 0, 0, 0, 107, 125, 5, 36, 0, 0, 108, 109, 10, 2, 0, 0, 109, 110, 5, 16, 0, 0, 110, 111, 5, 36, 0, 0, 111, 113, 5, 14, 0, 0, 112, 114, 3, 18, 9, 0, 113, 112, 1, 0, 0, 0, 113, 114, 1, 0, 0, 0, 114, 115, 1, 0, 0, 0, 115, 125, 5, 15, 0, 0, 116, 117, 10, 1, 0, 0, 117, 119, 5, 10, 0, 0, 118, 120, 5, 20, 0, 0, 119, 118, 1, 0, 0, 0, 119, 120, 1, 0, 0, 0, 120, 121, 1, 0, 0, 0, 121, 122, 3, 2, 1, 0, 122, 123, 5, 11, 0, 0, 123, 125, 1, 0, 0, 0, 124, 102, 1, 0, 0, 0, 124, 108, 1, 0, 0, 0, 124, 116, 1, 0, 0, 0, 125, 128, 1, 0, 0, 0, 126, 124, 1, 0, 0, 0, 126, 127, 1, 0, 0, 0, 127, 15, 1, 0, 0, 0, 128, 126, 1, 0, 0, 0, 129, 131, 5, 16, 0, 0, 130, 129, 1, 0, 0, 0, 130, 131, 1, 0, 0, 0, 131, 132, 1, 0, 0, 0, 132, 138, 5, 36, 0, 0, 133, 135, 5, 14, 0, 0, 134, 136, 3, 18, 9, 0, 135, 134, 1, 0, 0, 0, 135, 136, 1, 0, 0, 0, 136, 137, 1, 0, 0, 0, 137, 139, 5, 15, 0, 0, 138, 133, 1, 0, 0, 0, 138, 139, 1, 0, 0, 0, 139, 181, 1, 0, 0, 0, 140, 141, 5, 14, 0, 0, 141, 142, 3, 2, 1, 0, 142, 143, 5, 15, 0, 0, 143, 181, 1, 0, 0, 0, 144, 146, 5, 10, 0, 0, 145, 147, 3, 20, 10, 0, 146, 145, 1, 0, 0, 0, 146, 147, 1, 0, 0, 0, 147, 149, 1, 0, 0, 0, 148, 150, 5, 17, 0, 0, 149, 148, 1, 0, 0, 0, 149, 150, 1, 0, 0, 0, 150, 151, 1, 0, 0, 0, 151, 181, 5, 11, 0, 0, 152, 154, 5, 12, 0, 0, 153, 155, 3, 26, 13, 0, 154, 153, 1, 0, 0, 0, 154, 155, 1, 0, 0, 0, 155, 157, 1, 0, 0, 0, 156, 158, 5, 17, 0, 0, 157, 156, 1, 0, 0, 0, 157, 158, 1, 0, 0, 0, 158, 159, 1, 0, 0, 0, 159, 181, 5, 13, 0, 0, 160, 162, 5, 16, 0, 0, 161, 160, 1, 0, 0, 0, 161, 162, 1, 0, 0, 0, 162, 163, 1, 0, 0, 0, 163, 168, 5, 36, 0, 0, 164, 165, 5, 16, 0, 0, 165, 167, 5, 36, 0, 0, 166, 164, 1, 0, 0, 0, 167, 170, 1, 0, 0, 0, 168, 166, 1, 0, 0, 0, 168, 169, 1, 0, 0, 0, 169, 171, 1, 0, 0, 0, 170, 168, 1, 0, 0, 0, 171, 173, 5, 12, 0, 0, 172, 174, 3, 22, 11, 0, 173, 172, 1, 0, 0, 0, 173, 174, 1, 0, 0, 0, 174, 176, 1, 0, 0, 0, 175, 177, 5, 17, 0, 0, 176, 175, 1, 0, 0, 0, 176, 177, 1, 0, 0, 0, 177, 178, 1, 0, 0, 0, 178, 181, 5, 13, 0, 0, 179, 181, 3, 30, 15, 0, 180, 130, 1, 0, 0, 0, 180, 140, 1, 0, 0, 0, 180, 144, 1, 0, 0, 0, 180, 152, 1, 0, 0, 0, 180, 161, 1, 0, 0, 0, 180, 179, 1, 0, 0, 0, 181, 17, 1, 0, 0, 0, 182, 187, 3, 2, 1, 0, 183, 184, 5, 17, 0, 0, 184, 186, 3, 2, 1, 0, 185, 183, 1, 0, 0, 0, 186, 189, 1, 0, 0, 0, 187, 185, 1, 0, 0, 0, 187, 188, 1, 0, 0, 0, 188, 19, 1, 0, 0, 0, 189, 187, 1, 0, 0, 0, 190, 195, 3, 28, 14, 0, 191, 192, 5, 17, 0, 0, 192, 194, 3, 28, 14, 0, 193, 191, 1, 0, 0, 0, 194, 197, 1, 0, 0, 0, 195, 193, 1, 0, 0, 0, 195, 196, 1, 0, 0, 0, 196, 21, 1, 0, 0, 0, 197, 195, 1, 0, 0, 0, 198, 199, 3, 24, 12, 0, 199, 200, 5, 21, 0, 0, 200, 208, 3, 2, 1, 0, 201, 202, 5, 17, 0, 0, 202, 203, 3, 24, 12, 0, 203, 204, 5, 21, 0, 0, 204, 205, 3, 2, 1, 0, 205, 207, 1, 0, 0, 0, 206, 201, 1, 0, 0, 0, 207, 210, 1, 0, 0, 0, 208, 206, 1, 0, 0, 0, 208, 209, 1, 0, 0, 0, 209, 23, 1, 0, 0, 0, 210, 208, 1, 0, 0, 0, 211, 213, 5, 20, 0, 0, 212, 211, 1, 0, 0, 0, 212, 213, 1, 0, 0, 0, 213, 214, 1, 0, 0, 0, 214, 215, 5, 36, 0, 0, 215, 25, 1, 0, 0, 0, 216, 217, 3, 28, 14, 0, 217, 218, 5, 21, 0, 0, 218, 226, 3, 2, 1, 0, 219, 220, 5, 17, 0, 0, 220, 221, 3, 28, 14, 0, 221, 222, 5, 21, 0, 0, 222, 223, 3, 2, 1, 0, 223, 225, 1, 0, 0, 0, 224, 219, 1, 0, 0, 0, 225, 228, 1, 0, 0, 0, 226, 224, 1, 0, 0, 0, 226, 227, 1, 0, 0, 0, 227, 27, 1, 0, 0, 0, 228, 226, 1, 0, 0, 0, 229, 231, 5, 20, 0, 0, 230, 229, 1, 0, 0, 0, 230, 231, 1, 0, 0, 0, 231, 232, 1, 0, 0, 0, 232, 233, 3, 2, 1, 0, 233, 29, 1, 0, 0, 0, 234, 236, 5, 18, 0, 0, 235, 234, 1, 0, 0, 0, 235, 236, 1, 0, 0, 0, 236, 237, 1, 0, 0, 0, 237, 249, 5, 32, 0, 0, 238, 249, 5, 33, 0, 0, 239, 241, 5, 18, 0, 0, 240, 239, 1, 0, 0, 0, 240, 241, 1, 0, 0, 0, 241, 242, 1, 0, 0, 0, 242, 249, 5, 31, 0, 0, 243, 249, 5, 34, 0, 0, 244, 249, 5, 35, 0, 0, 245, 249, 5, 26, 0, 0, 246, 249, 5, 27, 0, 0, 247, 249, 5, 28, 0, 0, 248, 235, 1, 0, 0, 0, 248, 238, 1, 0, 0, 0, 248, 240, 1, 0, 0, 0, 248, 243, 1, 0, 0, 0, 248, 244, 1, 0, 0, 0, 248, 245, 1, 0, 0, 0, 248, 246, 1, 0, 0, 0, 248, 247, 1, 0, 0, 0, 249, 31, 1, 0, 0, 0, 35, 41, 48, 56, 67, 79, 81, 88, 94, 97, 105, 113, 119, 124, 126, 130, 135, 138, 146, 149, 154, 157, 161, 168, 173, 176, 180, 187, 195, 208, 212, 226, 230, 235, 240, 248]
\ No newline at end of file
diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go b/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go
index 969a598618..0247f470a7 100644
--- a/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go
+++ b/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go
@@ -1,7 +1,7 @@
-// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.10.1. DO NOT EDIT.
+// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.12.0. DO NOT EDIT.
package gen // CEL
-import "github.com/antlr/antlr4/runtime/Go/antlr"
+import "github.com/antlr/antlr4/runtime/Go/antlr/v4"
// BaseCELListener is a complete listener for a parse tree produced by CELParser.
type BaseCELListener struct{}
@@ -74,11 +74,17 @@ func (s *BaseCELListener) EnterNegate(ctx *NegateContext) {}
// ExitNegate is called when production Negate is exited.
func (s *BaseCELListener) ExitNegate(ctx *NegateContext) {}
-// EnterSelectOrCall is called when production SelectOrCall is entered.
-func (s *BaseCELListener) EnterSelectOrCall(ctx *SelectOrCallContext) {}
+// EnterMemberCall is called when production MemberCall is entered.
+func (s *BaseCELListener) EnterMemberCall(ctx *MemberCallContext) {}
-// ExitSelectOrCall is called when production SelectOrCall is exited.
-func (s *BaseCELListener) ExitSelectOrCall(ctx *SelectOrCallContext) {}
+// ExitMemberCall is called when production MemberCall is exited.
+func (s *BaseCELListener) ExitMemberCall(ctx *MemberCallContext) {}
+
+// EnterSelect is called when production Select is entered.
+func (s *BaseCELListener) EnterSelect(ctx *SelectContext) {}
+
+// ExitSelect is called when production Select is exited.
+func (s *BaseCELListener) ExitSelect(ctx *SelectContext) {}
// EnterPrimaryExpr is called when production PrimaryExpr is entered.
func (s *BaseCELListener) EnterPrimaryExpr(ctx *PrimaryExprContext) {}
@@ -92,12 +98,6 @@ func (s *BaseCELListener) EnterIndex(ctx *IndexContext) {}
// ExitIndex is called when production Index is exited.
func (s *BaseCELListener) ExitIndex(ctx *IndexContext) {}
-// EnterCreateMessage is called when production CreateMessage is entered.
-func (s *BaseCELListener) EnterCreateMessage(ctx *CreateMessageContext) {}
-
-// ExitCreateMessage is called when production CreateMessage is exited.
-func (s *BaseCELListener) ExitCreateMessage(ctx *CreateMessageContext) {}
-
// EnterIdentOrGlobalCall is called when production IdentOrGlobalCall is entered.
func (s *BaseCELListener) EnterIdentOrGlobalCall(ctx *IdentOrGlobalCallContext) {}
@@ -122,6 +122,12 @@ func (s *BaseCELListener) EnterCreateStruct(ctx *CreateStructContext) {}
// ExitCreateStruct is called when production CreateStruct is exited.
func (s *BaseCELListener) ExitCreateStruct(ctx *CreateStructContext) {}
+// EnterCreateMessage is called when production CreateMessage is entered.
+func (s *BaseCELListener) EnterCreateMessage(ctx *CreateMessageContext) {}
+
+// ExitCreateMessage is called when production CreateMessage is exited.
+func (s *BaseCELListener) ExitCreateMessage(ctx *CreateMessageContext) {}
+
// EnterConstantLiteral is called when production ConstantLiteral is entered.
func (s *BaseCELListener) EnterConstantLiteral(ctx *ConstantLiteralContext) {}
@@ -134,18 +140,36 @@ func (s *BaseCELListener) EnterExprList(ctx *ExprListContext) {}
// ExitExprList is called when production exprList is exited.
func (s *BaseCELListener) ExitExprList(ctx *ExprListContext) {}
+// EnterListInit is called when production listInit is entered.
+func (s *BaseCELListener) EnterListInit(ctx *ListInitContext) {}
+
+// ExitListInit is called when production listInit is exited.
+func (s *BaseCELListener) ExitListInit(ctx *ListInitContext) {}
+
// EnterFieldInitializerList is called when production fieldInitializerList is entered.
func (s *BaseCELListener) EnterFieldInitializerList(ctx *FieldInitializerListContext) {}
// ExitFieldInitializerList is called when production fieldInitializerList is exited.
func (s *BaseCELListener) ExitFieldInitializerList(ctx *FieldInitializerListContext) {}
+// EnterOptField is called when production optField is entered.
+func (s *BaseCELListener) EnterOptField(ctx *OptFieldContext) {}
+
+// ExitOptField is called when production optField is exited.
+func (s *BaseCELListener) ExitOptField(ctx *OptFieldContext) {}
+
// EnterMapInitializerList is called when production mapInitializerList is entered.
func (s *BaseCELListener) EnterMapInitializerList(ctx *MapInitializerListContext) {}
// ExitMapInitializerList is called when production mapInitializerList is exited.
func (s *BaseCELListener) ExitMapInitializerList(ctx *MapInitializerListContext) {}
+// EnterOptExpr is called when production optExpr is entered.
+func (s *BaseCELListener) EnterOptExpr(ctx *OptExprContext) {}
+
+// ExitOptExpr is called when production optExpr is exited.
+func (s *BaseCELListener) ExitOptExpr(ctx *OptExprContext) {}
+
// EnterInt is called when production Int is entered.
func (s *BaseCELListener) EnterInt(ctx *IntContext) {}
diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go b/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go
index 8e84579ed1..52a7f4dc57 100644
--- a/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go
+++ b/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go
@@ -1,7 +1,7 @@
-// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.10.1. DO NOT EDIT.
+// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.12.0. DO NOT EDIT.
package gen // CEL
-import "github.com/antlr/antlr4/runtime/Go/antlr"
+import "github.com/antlr/antlr4/runtime/Go/antlr/v4"
type BaseCELVisitor struct {
*antlr.BaseParseTreeVisitor
@@ -43,19 +43,19 @@ func (v *BaseCELVisitor) VisitNegate(ctx *NegateContext) interface{} {
return v.VisitChildren(ctx)
}
-func (v *BaseCELVisitor) VisitSelectOrCall(ctx *SelectOrCallContext) interface{} {
+func (v *BaseCELVisitor) VisitMemberCall(ctx *MemberCallContext) interface{} {
return v.VisitChildren(ctx)
}
-func (v *BaseCELVisitor) VisitPrimaryExpr(ctx *PrimaryExprContext) interface{} {
+func (v *BaseCELVisitor) VisitSelect(ctx *SelectContext) interface{} {
return v.VisitChildren(ctx)
}
-func (v *BaseCELVisitor) VisitIndex(ctx *IndexContext) interface{} {
+func (v *BaseCELVisitor) VisitPrimaryExpr(ctx *PrimaryExprContext) interface{} {
return v.VisitChildren(ctx)
}
-func (v *BaseCELVisitor) VisitCreateMessage(ctx *CreateMessageContext) interface{} {
+func (v *BaseCELVisitor) VisitIndex(ctx *IndexContext) interface{} {
return v.VisitChildren(ctx)
}
@@ -75,6 +75,10 @@ func (v *BaseCELVisitor) VisitCreateStruct(ctx *CreateStructContext) interface{}
return v.VisitChildren(ctx)
}
+func (v *BaseCELVisitor) VisitCreateMessage(ctx *CreateMessageContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
func (v *BaseCELVisitor) VisitConstantLiteral(ctx *ConstantLiteralContext) interface{} {
return v.VisitChildren(ctx)
}
@@ -83,14 +87,26 @@ func (v *BaseCELVisitor) VisitExprList(ctx *ExprListContext) interface{} {
return v.VisitChildren(ctx)
}
+func (v *BaseCELVisitor) VisitListInit(ctx *ListInitContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
func (v *BaseCELVisitor) VisitFieldInitializerList(ctx *FieldInitializerListContext) interface{} {
return v.VisitChildren(ctx)
}
+func (v *BaseCELVisitor) VisitOptField(ctx *OptFieldContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
func (v *BaseCELVisitor) VisitMapInitializerList(ctx *MapInitializerListContext) interface{} {
return v.VisitChildren(ctx)
}
+func (v *BaseCELVisitor) VisitOptExpr(ctx *OptExprContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
func (v *BaseCELVisitor) VisitInt(ctx *IntContext) interface{} {
return v.VisitChildren(ctx)
}
diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go b/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go
index 7b4cca62e6..98ddc06d0b 100644
--- a/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go
+++ b/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go
@@ -1,4 +1,4 @@
-// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.10.1. DO NOT EDIT.
+// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.12.0. DO NOT EDIT.
package gen
@@ -7,7 +7,7 @@ import (
"sync"
"unicode"
- "github.com/antlr/antlr4/runtime/Go/antlr"
+ "github.com/antlr/antlr4/runtime/Go/antlr/v4"
)
// Suppress unused import error
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 1b631b6e1b..73b7f1d39f 100644
--- a/vendor/github.com/google/cel-go/parser/gen/cel_listener.go
+++ b/vendor/github.com/google/cel-go/parser/gen/cel_listener.go
@@ -1,7 +1,7 @@
-// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.10.1. DO NOT EDIT.
+// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.12.0. DO NOT EDIT.
package gen // CEL
-import "github.com/antlr/antlr4/runtime/Go/antlr"
+import "github.com/antlr/antlr4/runtime/Go/antlr/v4"
// CELListener is a complete listener for a parse tree produced by CELParser.
type CELListener interface {
@@ -34,8 +34,11 @@ type CELListener interface {
// EnterNegate is called when entering the Negate production.
EnterNegate(c *NegateContext)
- // EnterSelectOrCall is called when entering the SelectOrCall production.
- EnterSelectOrCall(c *SelectOrCallContext)
+ // EnterMemberCall is called when entering the MemberCall production.
+ EnterMemberCall(c *MemberCallContext)
+
+ // EnterSelect is called when entering the Select production.
+ EnterSelect(c *SelectContext)
// EnterPrimaryExpr is called when entering the PrimaryExpr production.
EnterPrimaryExpr(c *PrimaryExprContext)
@@ -43,9 +46,6 @@ type CELListener interface {
// EnterIndex is called when entering the Index production.
EnterIndex(c *IndexContext)
- // EnterCreateMessage is called when entering the CreateMessage production.
- EnterCreateMessage(c *CreateMessageContext)
-
// EnterIdentOrGlobalCall is called when entering the IdentOrGlobalCall production.
EnterIdentOrGlobalCall(c *IdentOrGlobalCallContext)
@@ -58,18 +58,30 @@ type CELListener interface {
// EnterCreateStruct is called when entering the CreateStruct production.
EnterCreateStruct(c *CreateStructContext)
+ // EnterCreateMessage is called when entering the CreateMessage production.
+ EnterCreateMessage(c *CreateMessageContext)
+
// EnterConstantLiteral is called when entering the ConstantLiteral production.
EnterConstantLiteral(c *ConstantLiteralContext)
// EnterExprList is called when entering the exprList production.
EnterExprList(c *ExprListContext)
+ // EnterListInit is called when entering the listInit production.
+ EnterListInit(c *ListInitContext)
+
// EnterFieldInitializerList is called when entering the fieldInitializerList production.
EnterFieldInitializerList(c *FieldInitializerListContext)
+ // EnterOptField is called when entering the optField production.
+ EnterOptField(c *OptFieldContext)
+
// EnterMapInitializerList is called when entering the mapInitializerList production.
EnterMapInitializerList(c *MapInitializerListContext)
+ // EnterOptExpr is called when entering the optExpr production.
+ EnterOptExpr(c *OptExprContext)
+
// EnterInt is called when entering the Int production.
EnterInt(c *IntContext)
@@ -121,8 +133,11 @@ type CELListener interface {
// ExitNegate is called when exiting the Negate production.
ExitNegate(c *NegateContext)
- // ExitSelectOrCall is called when exiting the SelectOrCall production.
- ExitSelectOrCall(c *SelectOrCallContext)
+ // ExitMemberCall is called when exiting the MemberCall production.
+ ExitMemberCall(c *MemberCallContext)
+
+ // ExitSelect is called when exiting the Select production.
+ ExitSelect(c *SelectContext)
// ExitPrimaryExpr is called when exiting the PrimaryExpr production.
ExitPrimaryExpr(c *PrimaryExprContext)
@@ -130,9 +145,6 @@ type CELListener interface {
// ExitIndex is called when exiting the Index production.
ExitIndex(c *IndexContext)
- // ExitCreateMessage is called when exiting the CreateMessage production.
- ExitCreateMessage(c *CreateMessageContext)
-
// ExitIdentOrGlobalCall is called when exiting the IdentOrGlobalCall production.
ExitIdentOrGlobalCall(c *IdentOrGlobalCallContext)
@@ -145,18 +157,30 @@ type CELListener interface {
// ExitCreateStruct is called when exiting the CreateStruct production.
ExitCreateStruct(c *CreateStructContext)
+ // ExitCreateMessage is called when exiting the CreateMessage production.
+ ExitCreateMessage(c *CreateMessageContext)
+
// ExitConstantLiteral is called when exiting the ConstantLiteral production.
ExitConstantLiteral(c *ConstantLiteralContext)
// ExitExprList is called when exiting the exprList production.
ExitExprList(c *ExprListContext)
+ // ExitListInit is called when exiting the listInit production.
+ ExitListInit(c *ListInitContext)
+
// ExitFieldInitializerList is called when exiting the fieldInitializerList production.
ExitFieldInitializerList(c *FieldInitializerListContext)
+ // ExitOptField is called when exiting the optField production.
+ ExitOptField(c *OptFieldContext)
+
// ExitMapInitializerList is called when exiting the mapInitializerList production.
ExitMapInitializerList(c *MapInitializerListContext)
+ // ExitOptExpr is called when exiting the optExpr production.
+ ExitOptExpr(c *OptExprContext)
+
// ExitInt is called when exiting the Int production.
ExitInt(c *IntContext)
diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_parser.go b/vendor/github.com/google/cel-go/parser/gen/cel_parser.go
index afb3fe0d1c..0cb6c8eae8 100644
--- a/vendor/github.com/google/cel-go/parser/gen/cel_parser.go
+++ b/vendor/github.com/google/cel-go/parser/gen/cel_parser.go
@@ -1,4 +1,4 @@
-// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.10.1. DO NOT EDIT.
+// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.12.0. DO NOT EDIT.
package gen // CEL
import (
@@ -6,7 +6,7 @@ import (
"strconv"
"sync"
- "github.com/antlr/antlr4/runtime/Go/antlr"
+ "github.com/antlr/antlr4/runtime/Go/antlr/v4"
)
// Suppress unused import errors
@@ -46,106 +46,125 @@ func celParserInit() {
}
staticData.ruleNames = []string{
"start", "expr", "conditionalOr", "conditionalAnd", "relation", "calc",
- "unary", "member", "primary", "exprList", "fieldInitializerList", "mapInitializerList",
- "literal",
+ "unary", "member", "primary", "exprList", "listInit", "fieldInitializerList",
+ "optField", "mapInitializerList", "optExpr", "literal",
}
staticData.predictionContextCache = antlr.NewPredictionContextCache()
staticData.serializedATN = []int32{
- 4, 1, 36, 209, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7,
+ 4, 1, 36, 251, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7,
4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7,
- 10, 2, 11, 7, 11, 2, 12, 7, 12, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 3, 1, 36, 8, 1, 1, 2, 1, 2, 1, 2, 5, 2, 41, 8, 2, 10, 2,
- 12, 2, 44, 9, 2, 1, 3, 1, 3, 1, 3, 5, 3, 49, 8, 3, 10, 3, 12, 3, 52, 9,
- 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 5, 4, 60, 8, 4, 10, 4, 12, 4, 63,
- 9, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 74, 8,
- 5, 10, 5, 12, 5, 77, 9, 5, 1, 6, 1, 6, 4, 6, 81, 8, 6, 11, 6, 12, 6, 82,
- 1, 6, 1, 6, 4, 6, 87, 8, 6, 11, 6, 12, 6, 88, 1, 6, 3, 6, 92, 8, 6, 1,
- 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 102, 8, 7, 1, 7, 3,
- 7, 105, 8, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 115,
- 8, 7, 1, 7, 3, 7, 118, 8, 7, 1, 7, 5, 7, 121, 8, 7, 10, 7, 12, 7, 124,
- 9, 7, 1, 8, 3, 8, 127, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 132, 8, 8, 1, 8, 3,
- 8, 135, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 143, 8, 8, 1, 8,
- 3, 8, 146, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 151, 8, 8, 1, 8, 3, 8, 154, 8,
- 8, 1, 8, 1, 8, 3, 8, 158, 8, 8, 1, 9, 1, 9, 1, 9, 5, 9, 163, 8, 9, 10,
- 9, 12, 9, 166, 9, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 5,
- 10, 175, 8, 10, 10, 10, 12, 10, 178, 9, 10, 1, 11, 1, 11, 1, 11, 1, 11,
- 1, 11, 1, 11, 1, 11, 1, 11, 5, 11, 188, 8, 11, 10, 11, 12, 11, 191, 9,
- 11, 1, 12, 3, 12, 194, 8, 12, 1, 12, 1, 12, 1, 12, 3, 12, 199, 8, 12, 1,
- 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 207, 8, 12, 1, 12, 0, 3,
- 8, 10, 14, 13, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 0, 3, 1,
- 0, 1, 7, 1, 0, 23, 25, 2, 0, 18, 18, 22, 22, 235, 0, 26, 1, 0, 0, 0, 2,
- 29, 1, 0, 0, 0, 4, 37, 1, 0, 0, 0, 6, 45, 1, 0, 0, 0, 8, 53, 1, 0, 0, 0,
- 10, 64, 1, 0, 0, 0, 12, 91, 1, 0, 0, 0, 14, 93, 1, 0, 0, 0, 16, 157, 1,
- 0, 0, 0, 18, 159, 1, 0, 0, 0, 20, 167, 1, 0, 0, 0, 22, 179, 1, 0, 0, 0,
- 24, 206, 1, 0, 0, 0, 26, 27, 3, 2, 1, 0, 27, 28, 5, 0, 0, 1, 28, 1, 1,
- 0, 0, 0, 29, 35, 3, 4, 2, 0, 30, 31, 5, 20, 0, 0, 31, 32, 3, 4, 2, 0, 32,
- 33, 5, 21, 0, 0, 33, 34, 3, 2, 1, 0, 34, 36, 1, 0, 0, 0, 35, 30, 1, 0,
- 0, 0, 35, 36, 1, 0, 0, 0, 36, 3, 1, 0, 0, 0, 37, 42, 3, 6, 3, 0, 38, 39,
- 5, 9, 0, 0, 39, 41, 3, 6, 3, 0, 40, 38, 1, 0, 0, 0, 41, 44, 1, 0, 0, 0,
- 42, 40, 1, 0, 0, 0, 42, 43, 1, 0, 0, 0, 43, 5, 1, 0, 0, 0, 44, 42, 1, 0,
- 0, 0, 45, 50, 3, 8, 4, 0, 46, 47, 5, 8, 0, 0, 47, 49, 3, 8, 4, 0, 48, 46,
- 1, 0, 0, 0, 49, 52, 1, 0, 0, 0, 50, 48, 1, 0, 0, 0, 50, 51, 1, 0, 0, 0,
- 51, 7, 1, 0, 0, 0, 52, 50, 1, 0, 0, 0, 53, 54, 6, 4, -1, 0, 54, 55, 3,
- 10, 5, 0, 55, 61, 1, 0, 0, 0, 56, 57, 10, 1, 0, 0, 57, 58, 7, 0, 0, 0,
- 58, 60, 3, 8, 4, 2, 59, 56, 1, 0, 0, 0, 60, 63, 1, 0, 0, 0, 61, 59, 1,
- 0, 0, 0, 61, 62, 1, 0, 0, 0, 62, 9, 1, 0, 0, 0, 63, 61, 1, 0, 0, 0, 64,
- 65, 6, 5, -1, 0, 65, 66, 3, 12, 6, 0, 66, 75, 1, 0, 0, 0, 67, 68, 10, 2,
- 0, 0, 68, 69, 7, 1, 0, 0, 69, 74, 3, 10, 5, 3, 70, 71, 10, 1, 0, 0, 71,
- 72, 7, 2, 0, 0, 72, 74, 3, 10, 5, 2, 73, 67, 1, 0, 0, 0, 73, 70, 1, 0,
- 0, 0, 74, 77, 1, 0, 0, 0, 75, 73, 1, 0, 0, 0, 75, 76, 1, 0, 0, 0, 76, 11,
- 1, 0, 0, 0, 77, 75, 1, 0, 0, 0, 78, 92, 3, 14, 7, 0, 79, 81, 5, 19, 0,
- 0, 80, 79, 1, 0, 0, 0, 81, 82, 1, 0, 0, 0, 82, 80, 1, 0, 0, 0, 82, 83,
- 1, 0, 0, 0, 83, 84, 1, 0, 0, 0, 84, 92, 3, 14, 7, 0, 85, 87, 5, 18, 0,
- 0, 86, 85, 1, 0, 0, 0, 87, 88, 1, 0, 0, 0, 88, 86, 1, 0, 0, 0, 88, 89,
- 1, 0, 0, 0, 89, 90, 1, 0, 0, 0, 90, 92, 3, 14, 7, 0, 91, 78, 1, 0, 0, 0,
- 91, 80, 1, 0, 0, 0, 91, 86, 1, 0, 0, 0, 92, 13, 1, 0, 0, 0, 93, 94, 6,
- 7, -1, 0, 94, 95, 3, 16, 8, 0, 95, 122, 1, 0, 0, 0, 96, 97, 10, 3, 0, 0,
- 97, 98, 5, 16, 0, 0, 98, 104, 5, 36, 0, 0, 99, 101, 5, 14, 0, 0, 100, 102,
- 3, 18, 9, 0, 101, 100, 1, 0, 0, 0, 101, 102, 1, 0, 0, 0, 102, 103, 1, 0,
- 0, 0, 103, 105, 5, 15, 0, 0, 104, 99, 1, 0, 0, 0, 104, 105, 1, 0, 0, 0,
- 105, 121, 1, 0, 0, 0, 106, 107, 10, 2, 0, 0, 107, 108, 5, 10, 0, 0, 108,
- 109, 3, 2, 1, 0, 109, 110, 5, 11, 0, 0, 110, 121, 1, 0, 0, 0, 111, 112,
- 10, 1, 0, 0, 112, 114, 5, 12, 0, 0, 113, 115, 3, 20, 10, 0, 114, 113, 1,
- 0, 0, 0, 114, 115, 1, 0, 0, 0, 115, 117, 1, 0, 0, 0, 116, 118, 5, 17, 0,
- 0, 117, 116, 1, 0, 0, 0, 117, 118, 1, 0, 0, 0, 118, 119, 1, 0, 0, 0, 119,
- 121, 5, 13, 0, 0, 120, 96, 1, 0, 0, 0, 120, 106, 1, 0, 0, 0, 120, 111,
- 1, 0, 0, 0, 121, 124, 1, 0, 0, 0, 122, 120, 1, 0, 0, 0, 122, 123, 1, 0,
- 0, 0, 123, 15, 1, 0, 0, 0, 124, 122, 1, 0, 0, 0, 125, 127, 5, 16, 0, 0,
- 126, 125, 1, 0, 0, 0, 126, 127, 1, 0, 0, 0, 127, 128, 1, 0, 0, 0, 128,
- 134, 5, 36, 0, 0, 129, 131, 5, 14, 0, 0, 130, 132, 3, 18, 9, 0, 131, 130,
- 1, 0, 0, 0, 131, 132, 1, 0, 0, 0, 132, 133, 1, 0, 0, 0, 133, 135, 5, 15,
- 0, 0, 134, 129, 1, 0, 0, 0, 134, 135, 1, 0, 0, 0, 135, 158, 1, 0, 0, 0,
- 136, 137, 5, 14, 0, 0, 137, 138, 3, 2, 1, 0, 138, 139, 5, 15, 0, 0, 139,
- 158, 1, 0, 0, 0, 140, 142, 5, 10, 0, 0, 141, 143, 3, 18, 9, 0, 142, 141,
- 1, 0, 0, 0, 142, 143, 1, 0, 0, 0, 143, 145, 1, 0, 0, 0, 144, 146, 5, 17,
- 0, 0, 145, 144, 1, 0, 0, 0, 145, 146, 1, 0, 0, 0, 146, 147, 1, 0, 0, 0,
- 147, 158, 5, 11, 0, 0, 148, 150, 5, 12, 0, 0, 149, 151, 3, 22, 11, 0, 150,
- 149, 1, 0, 0, 0, 150, 151, 1, 0, 0, 0, 151, 153, 1, 0, 0, 0, 152, 154,
- 5, 17, 0, 0, 153, 152, 1, 0, 0, 0, 153, 154, 1, 0, 0, 0, 154, 155, 1, 0,
- 0, 0, 155, 158, 5, 13, 0, 0, 156, 158, 3, 24, 12, 0, 157, 126, 1, 0, 0,
- 0, 157, 136, 1, 0, 0, 0, 157, 140, 1, 0, 0, 0, 157, 148, 1, 0, 0, 0, 157,
- 156, 1, 0, 0, 0, 158, 17, 1, 0, 0, 0, 159, 164, 3, 2, 1, 0, 160, 161, 5,
- 17, 0, 0, 161, 163, 3, 2, 1, 0, 162, 160, 1, 0, 0, 0, 163, 166, 1, 0, 0,
- 0, 164, 162, 1, 0, 0, 0, 164, 165, 1, 0, 0, 0, 165, 19, 1, 0, 0, 0, 166,
- 164, 1, 0, 0, 0, 167, 168, 5, 36, 0, 0, 168, 169, 5, 21, 0, 0, 169, 176,
- 3, 2, 1, 0, 170, 171, 5, 17, 0, 0, 171, 172, 5, 36, 0, 0, 172, 173, 5,
- 21, 0, 0, 173, 175, 3, 2, 1, 0, 174, 170, 1, 0, 0, 0, 175, 178, 1, 0, 0,
- 0, 176, 174, 1, 0, 0, 0, 176, 177, 1, 0, 0, 0, 177, 21, 1, 0, 0, 0, 178,
- 176, 1, 0, 0, 0, 179, 180, 3, 2, 1, 0, 180, 181, 5, 21, 0, 0, 181, 189,
- 3, 2, 1, 0, 182, 183, 5, 17, 0, 0, 183, 184, 3, 2, 1, 0, 184, 185, 5, 21,
- 0, 0, 185, 186, 3, 2, 1, 0, 186, 188, 1, 0, 0, 0, 187, 182, 1, 0, 0, 0,
- 188, 191, 1, 0, 0, 0, 189, 187, 1, 0, 0, 0, 189, 190, 1, 0, 0, 0, 190,
- 23, 1, 0, 0, 0, 191, 189, 1, 0, 0, 0, 192, 194, 5, 18, 0, 0, 193, 192,
- 1, 0, 0, 0, 193, 194, 1, 0, 0, 0, 194, 195, 1, 0, 0, 0, 195, 207, 5, 32,
- 0, 0, 196, 207, 5, 33, 0, 0, 197, 199, 5, 18, 0, 0, 198, 197, 1, 0, 0,
- 0, 198, 199, 1, 0, 0, 0, 199, 200, 1, 0, 0, 0, 200, 207, 5, 31, 0, 0, 201,
- 207, 5, 34, 0, 0, 202, 207, 5, 35, 0, 0, 203, 207, 5, 26, 0, 0, 204, 207,
- 5, 27, 0, 0, 205, 207, 5, 28, 0, 0, 206, 193, 1, 0, 0, 0, 206, 196, 1,
- 0, 0, 0, 206, 198, 1, 0, 0, 0, 206, 201, 1, 0, 0, 0, 206, 202, 1, 0, 0,
- 0, 206, 203, 1, 0, 0, 0, 206, 204, 1, 0, 0, 0, 206, 205, 1, 0, 0, 0, 207,
- 25, 1, 0, 0, 0, 29, 35, 42, 50, 61, 73, 75, 82, 88, 91, 101, 104, 114,
- 117, 120, 122, 126, 131, 134, 142, 145, 150, 153, 157, 164, 176, 189, 193,
- 198, 206,
+ 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15,
+ 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 42, 8, 1, 1,
+ 2, 1, 2, 1, 2, 5, 2, 47, 8, 2, 10, 2, 12, 2, 50, 9, 2, 1, 3, 1, 3, 1, 3,
+ 5, 3, 55, 8, 3, 10, 3, 12, 3, 58, 9, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1,
+ 4, 5, 4, 66, 8, 4, 10, 4, 12, 4, 69, 9, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5,
+ 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 80, 8, 5, 10, 5, 12, 5, 83, 9, 5, 1, 6, 1,
+ 6, 4, 6, 87, 8, 6, 11, 6, 12, 6, 88, 1, 6, 1, 6, 4, 6, 93, 8, 6, 11, 6,
+ 12, 6, 94, 1, 6, 3, 6, 98, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3,
+ 7, 106, 8, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 114, 8, 7, 1, 7,
+ 1, 7, 1, 7, 1, 7, 3, 7, 120, 8, 7, 1, 7, 1, 7, 1, 7, 5, 7, 125, 8, 7, 10,
+ 7, 12, 7, 128, 9, 7, 1, 8, 3, 8, 131, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 136,
+ 8, 8, 1, 8, 3, 8, 139, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8,
+ 147, 8, 8, 1, 8, 3, 8, 150, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 155, 8, 8, 1,
+ 8, 3, 8, 158, 8, 8, 1, 8, 1, 8, 3, 8, 162, 8, 8, 1, 8, 1, 8, 1, 8, 5, 8,
+ 167, 8, 8, 10, 8, 12, 8, 170, 9, 8, 1, 8, 1, 8, 3, 8, 174, 8, 8, 1, 8,
+ 3, 8, 177, 8, 8, 1, 8, 1, 8, 3, 8, 181, 8, 8, 1, 9, 1, 9, 1, 9, 5, 9, 186,
+ 8, 9, 10, 9, 12, 9, 189, 9, 9, 1, 10, 1, 10, 1, 10, 5, 10, 194, 8, 10,
+ 10, 10, 12, 10, 197, 9, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1,
+ 11, 1, 11, 5, 11, 207, 8, 11, 10, 11, 12, 11, 210, 9, 11, 1, 12, 3, 12,
+ 213, 8, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1,
+ 13, 1, 13, 5, 13, 225, 8, 13, 10, 13, 12, 13, 228, 9, 13, 1, 14, 3, 14,
+ 231, 8, 14, 1, 14, 1, 14, 1, 15, 3, 15, 236, 8, 15, 1, 15, 1, 15, 1, 15,
+ 3, 15, 241, 8, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 249,
+ 8, 15, 1, 15, 0, 3, 8, 10, 14, 16, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20,
+ 22, 24, 26, 28, 30, 0, 3, 1, 0, 1, 7, 1, 0, 23, 25, 2, 0, 18, 18, 22, 22,
+ 281, 0, 32, 1, 0, 0, 0, 2, 35, 1, 0, 0, 0, 4, 43, 1, 0, 0, 0, 6, 51, 1,
+ 0, 0, 0, 8, 59, 1, 0, 0, 0, 10, 70, 1, 0, 0, 0, 12, 97, 1, 0, 0, 0, 14,
+ 99, 1, 0, 0, 0, 16, 180, 1, 0, 0, 0, 18, 182, 1, 0, 0, 0, 20, 190, 1, 0,
+ 0, 0, 22, 198, 1, 0, 0, 0, 24, 212, 1, 0, 0, 0, 26, 216, 1, 0, 0, 0, 28,
+ 230, 1, 0, 0, 0, 30, 248, 1, 0, 0, 0, 32, 33, 3, 2, 1, 0, 33, 34, 5, 0,
+ 0, 1, 34, 1, 1, 0, 0, 0, 35, 41, 3, 4, 2, 0, 36, 37, 5, 20, 0, 0, 37, 38,
+ 3, 4, 2, 0, 38, 39, 5, 21, 0, 0, 39, 40, 3, 2, 1, 0, 40, 42, 1, 0, 0, 0,
+ 41, 36, 1, 0, 0, 0, 41, 42, 1, 0, 0, 0, 42, 3, 1, 0, 0, 0, 43, 48, 3, 6,
+ 3, 0, 44, 45, 5, 9, 0, 0, 45, 47, 3, 6, 3, 0, 46, 44, 1, 0, 0, 0, 47, 50,
+ 1, 0, 0, 0, 48, 46, 1, 0, 0, 0, 48, 49, 1, 0, 0, 0, 49, 5, 1, 0, 0, 0,
+ 50, 48, 1, 0, 0, 0, 51, 56, 3, 8, 4, 0, 52, 53, 5, 8, 0, 0, 53, 55, 3,
+ 8, 4, 0, 54, 52, 1, 0, 0, 0, 55, 58, 1, 0, 0, 0, 56, 54, 1, 0, 0, 0, 56,
+ 57, 1, 0, 0, 0, 57, 7, 1, 0, 0, 0, 58, 56, 1, 0, 0, 0, 59, 60, 6, 4, -1,
+ 0, 60, 61, 3, 10, 5, 0, 61, 67, 1, 0, 0, 0, 62, 63, 10, 1, 0, 0, 63, 64,
+ 7, 0, 0, 0, 64, 66, 3, 8, 4, 2, 65, 62, 1, 0, 0, 0, 66, 69, 1, 0, 0, 0,
+ 67, 65, 1, 0, 0, 0, 67, 68, 1, 0, 0, 0, 68, 9, 1, 0, 0, 0, 69, 67, 1, 0,
+ 0, 0, 70, 71, 6, 5, -1, 0, 71, 72, 3, 12, 6, 0, 72, 81, 1, 0, 0, 0, 73,
+ 74, 10, 2, 0, 0, 74, 75, 7, 1, 0, 0, 75, 80, 3, 10, 5, 3, 76, 77, 10, 1,
+ 0, 0, 77, 78, 7, 2, 0, 0, 78, 80, 3, 10, 5, 2, 79, 73, 1, 0, 0, 0, 79,
+ 76, 1, 0, 0, 0, 80, 83, 1, 0, 0, 0, 81, 79, 1, 0, 0, 0, 81, 82, 1, 0, 0,
+ 0, 82, 11, 1, 0, 0, 0, 83, 81, 1, 0, 0, 0, 84, 98, 3, 14, 7, 0, 85, 87,
+ 5, 19, 0, 0, 86, 85, 1, 0, 0, 0, 87, 88, 1, 0, 0, 0, 88, 86, 1, 0, 0, 0,
+ 88, 89, 1, 0, 0, 0, 89, 90, 1, 0, 0, 0, 90, 98, 3, 14, 7, 0, 91, 93, 5,
+ 18, 0, 0, 92, 91, 1, 0, 0, 0, 93, 94, 1, 0, 0, 0, 94, 92, 1, 0, 0, 0, 94,
+ 95, 1, 0, 0, 0, 95, 96, 1, 0, 0, 0, 96, 98, 3, 14, 7, 0, 97, 84, 1, 0,
+ 0, 0, 97, 86, 1, 0, 0, 0, 97, 92, 1, 0, 0, 0, 98, 13, 1, 0, 0, 0, 99, 100,
+ 6, 7, -1, 0, 100, 101, 3, 16, 8, 0, 101, 126, 1, 0, 0, 0, 102, 103, 10,
+ 3, 0, 0, 103, 105, 5, 16, 0, 0, 104, 106, 5, 20, 0, 0, 105, 104, 1, 0,
+ 0, 0, 105, 106, 1, 0, 0, 0, 106, 107, 1, 0, 0, 0, 107, 125, 5, 36, 0, 0,
+ 108, 109, 10, 2, 0, 0, 109, 110, 5, 16, 0, 0, 110, 111, 5, 36, 0, 0, 111,
+ 113, 5, 14, 0, 0, 112, 114, 3, 18, 9, 0, 113, 112, 1, 0, 0, 0, 113, 114,
+ 1, 0, 0, 0, 114, 115, 1, 0, 0, 0, 115, 125, 5, 15, 0, 0, 116, 117, 10,
+ 1, 0, 0, 117, 119, 5, 10, 0, 0, 118, 120, 5, 20, 0, 0, 119, 118, 1, 0,
+ 0, 0, 119, 120, 1, 0, 0, 0, 120, 121, 1, 0, 0, 0, 121, 122, 3, 2, 1, 0,
+ 122, 123, 5, 11, 0, 0, 123, 125, 1, 0, 0, 0, 124, 102, 1, 0, 0, 0, 124,
+ 108, 1, 0, 0, 0, 124, 116, 1, 0, 0, 0, 125, 128, 1, 0, 0, 0, 126, 124,
+ 1, 0, 0, 0, 126, 127, 1, 0, 0, 0, 127, 15, 1, 0, 0, 0, 128, 126, 1, 0,
+ 0, 0, 129, 131, 5, 16, 0, 0, 130, 129, 1, 0, 0, 0, 130, 131, 1, 0, 0, 0,
+ 131, 132, 1, 0, 0, 0, 132, 138, 5, 36, 0, 0, 133, 135, 5, 14, 0, 0, 134,
+ 136, 3, 18, 9, 0, 135, 134, 1, 0, 0, 0, 135, 136, 1, 0, 0, 0, 136, 137,
+ 1, 0, 0, 0, 137, 139, 5, 15, 0, 0, 138, 133, 1, 0, 0, 0, 138, 139, 1, 0,
+ 0, 0, 139, 181, 1, 0, 0, 0, 140, 141, 5, 14, 0, 0, 141, 142, 3, 2, 1, 0,
+ 142, 143, 5, 15, 0, 0, 143, 181, 1, 0, 0, 0, 144, 146, 5, 10, 0, 0, 145,
+ 147, 3, 20, 10, 0, 146, 145, 1, 0, 0, 0, 146, 147, 1, 0, 0, 0, 147, 149,
+ 1, 0, 0, 0, 148, 150, 5, 17, 0, 0, 149, 148, 1, 0, 0, 0, 149, 150, 1, 0,
+ 0, 0, 150, 151, 1, 0, 0, 0, 151, 181, 5, 11, 0, 0, 152, 154, 5, 12, 0,
+ 0, 153, 155, 3, 26, 13, 0, 154, 153, 1, 0, 0, 0, 154, 155, 1, 0, 0, 0,
+ 155, 157, 1, 0, 0, 0, 156, 158, 5, 17, 0, 0, 157, 156, 1, 0, 0, 0, 157,
+ 158, 1, 0, 0, 0, 158, 159, 1, 0, 0, 0, 159, 181, 5, 13, 0, 0, 160, 162,
+ 5, 16, 0, 0, 161, 160, 1, 0, 0, 0, 161, 162, 1, 0, 0, 0, 162, 163, 1, 0,
+ 0, 0, 163, 168, 5, 36, 0, 0, 164, 165, 5, 16, 0, 0, 165, 167, 5, 36, 0,
+ 0, 166, 164, 1, 0, 0, 0, 167, 170, 1, 0, 0, 0, 168, 166, 1, 0, 0, 0, 168,
+ 169, 1, 0, 0, 0, 169, 171, 1, 0, 0, 0, 170, 168, 1, 0, 0, 0, 171, 173,
+ 5, 12, 0, 0, 172, 174, 3, 22, 11, 0, 173, 172, 1, 0, 0, 0, 173, 174, 1,
+ 0, 0, 0, 174, 176, 1, 0, 0, 0, 175, 177, 5, 17, 0, 0, 176, 175, 1, 0, 0,
+ 0, 176, 177, 1, 0, 0, 0, 177, 178, 1, 0, 0, 0, 178, 181, 5, 13, 0, 0, 179,
+ 181, 3, 30, 15, 0, 180, 130, 1, 0, 0, 0, 180, 140, 1, 0, 0, 0, 180, 144,
+ 1, 0, 0, 0, 180, 152, 1, 0, 0, 0, 180, 161, 1, 0, 0, 0, 180, 179, 1, 0,
+ 0, 0, 181, 17, 1, 0, 0, 0, 182, 187, 3, 2, 1, 0, 183, 184, 5, 17, 0, 0,
+ 184, 186, 3, 2, 1, 0, 185, 183, 1, 0, 0, 0, 186, 189, 1, 0, 0, 0, 187,
+ 185, 1, 0, 0, 0, 187, 188, 1, 0, 0, 0, 188, 19, 1, 0, 0, 0, 189, 187, 1,
+ 0, 0, 0, 190, 195, 3, 28, 14, 0, 191, 192, 5, 17, 0, 0, 192, 194, 3, 28,
+ 14, 0, 193, 191, 1, 0, 0, 0, 194, 197, 1, 0, 0, 0, 195, 193, 1, 0, 0, 0,
+ 195, 196, 1, 0, 0, 0, 196, 21, 1, 0, 0, 0, 197, 195, 1, 0, 0, 0, 198, 199,
+ 3, 24, 12, 0, 199, 200, 5, 21, 0, 0, 200, 208, 3, 2, 1, 0, 201, 202, 5,
+ 17, 0, 0, 202, 203, 3, 24, 12, 0, 203, 204, 5, 21, 0, 0, 204, 205, 3, 2,
+ 1, 0, 205, 207, 1, 0, 0, 0, 206, 201, 1, 0, 0, 0, 207, 210, 1, 0, 0, 0,
+ 208, 206, 1, 0, 0, 0, 208, 209, 1, 0, 0, 0, 209, 23, 1, 0, 0, 0, 210, 208,
+ 1, 0, 0, 0, 211, 213, 5, 20, 0, 0, 212, 211, 1, 0, 0, 0, 212, 213, 1, 0,
+ 0, 0, 213, 214, 1, 0, 0, 0, 214, 215, 5, 36, 0, 0, 215, 25, 1, 0, 0, 0,
+ 216, 217, 3, 28, 14, 0, 217, 218, 5, 21, 0, 0, 218, 226, 3, 2, 1, 0, 219,
+ 220, 5, 17, 0, 0, 220, 221, 3, 28, 14, 0, 221, 222, 5, 21, 0, 0, 222, 223,
+ 3, 2, 1, 0, 223, 225, 1, 0, 0, 0, 224, 219, 1, 0, 0, 0, 225, 228, 1, 0,
+ 0, 0, 226, 224, 1, 0, 0, 0, 226, 227, 1, 0, 0, 0, 227, 27, 1, 0, 0, 0,
+ 228, 226, 1, 0, 0, 0, 229, 231, 5, 20, 0, 0, 230, 229, 1, 0, 0, 0, 230,
+ 231, 1, 0, 0, 0, 231, 232, 1, 0, 0, 0, 232, 233, 3, 2, 1, 0, 233, 29, 1,
+ 0, 0, 0, 234, 236, 5, 18, 0, 0, 235, 234, 1, 0, 0, 0, 235, 236, 1, 0, 0,
+ 0, 236, 237, 1, 0, 0, 0, 237, 249, 5, 32, 0, 0, 238, 249, 5, 33, 0, 0,
+ 239, 241, 5, 18, 0, 0, 240, 239, 1, 0, 0, 0, 240, 241, 1, 0, 0, 0, 241,
+ 242, 1, 0, 0, 0, 242, 249, 5, 31, 0, 0, 243, 249, 5, 34, 0, 0, 244, 249,
+ 5, 35, 0, 0, 245, 249, 5, 26, 0, 0, 246, 249, 5, 27, 0, 0, 247, 249, 5,
+ 28, 0, 0, 248, 235, 1, 0, 0, 0, 248, 238, 1, 0, 0, 0, 248, 240, 1, 0, 0,
+ 0, 248, 243, 1, 0, 0, 0, 248, 244, 1, 0, 0, 0, 248, 245, 1, 0, 0, 0, 248,
+ 246, 1, 0, 0, 0, 248, 247, 1, 0, 0, 0, 249, 31, 1, 0, 0, 0, 35, 41, 48,
+ 56, 67, 79, 81, 88, 94, 97, 105, 113, 119, 124, 126, 130, 135, 138, 146,
+ 149, 154, 157, 161, 168, 173, 176, 180, 187, 195, 208, 212, 226, 230, 235,
+ 240, 248,
}
deserializer := antlr.NewATNDeserializer(nil)
staticData.atn = deserializer.Deserialize(staticData.serializedATN)
@@ -234,9 +253,12 @@ const (
CELParserRULE_member = 7
CELParserRULE_primary = 8
CELParserRULE_exprList = 9
- CELParserRULE_fieldInitializerList = 10
- CELParserRULE_mapInitializerList = 11
- CELParserRULE_literal = 12
+ CELParserRULE_listInit = 10
+ CELParserRULE_fieldInitializerList = 11
+ CELParserRULE_optField = 12
+ CELParserRULE_mapInitializerList = 13
+ CELParserRULE_optExpr = 14
+ CELParserRULE_literal = 15
)
// IStartContext is an interface to support dynamic dispatch.
@@ -252,6 +274,10 @@ type IStartContext interface {
// SetE sets the e rule contexts.
SetE(IExprContext)
+ // Getter signatures
+ EOF() antlr.TerminalNode
+ Expr() IExprContext
+
// IsStartContext differentiates from other interfaces.
IsStartContext()
}
@@ -363,14 +389,14 @@ func (p *CELParser) Start() (localctx IStartContext) {
p.EnterOuterAlt(localctx, 1)
{
- p.SetState(26)
+ p.SetState(32)
var _x = p.Expr()
localctx.(*StartContext).e = _x
}
{
- p.SetState(27)
+ p.SetState(33)
p.Match(CELParserEOF)
}
@@ -408,6 +434,13 @@ type IExprContext interface {
// SetE2 sets the e2 rule contexts.
SetE2(IExprContext)
+ // Getter signatures
+ AllConditionalOr() []IConditionalOrContext
+ ConditionalOr(i int) IConditionalOrContext
+ COLON() antlr.TerminalNode
+ QUESTIONMARK() antlr.TerminalNode
+ Expr() IExprContext
+
// IsExprContext differentiates from other interfaces.
IsExprContext()
}
@@ -580,37 +613,37 @@ func (p *CELParser) Expr() (localctx IExprContext) {
p.EnterOuterAlt(localctx, 1)
{
- p.SetState(29)
+ p.SetState(35)
var _x = p.ConditionalOr()
localctx.(*ExprContext).e = _x
}
- p.SetState(35)
+ p.SetState(41)
p.GetErrorHandler().Sync(p)
_la = p.GetTokenStream().LA(1)
if _la == CELParserQUESTIONMARK {
{
- p.SetState(30)
+ p.SetState(36)
var _m = p.Match(CELParserQUESTIONMARK)
localctx.(*ExprContext).op = _m
}
{
- p.SetState(31)
+ p.SetState(37)
var _x = p.ConditionalOr()
localctx.(*ExprContext).e1 = _x
}
{
- p.SetState(32)
+ p.SetState(38)
p.Match(CELParserCOLON)
}
{
- p.SetState(33)
+ p.SetState(39)
var _x = p.Expr()
@@ -659,6 +692,12 @@ type IConditionalOrContext interface {
// SetE1 sets the e1 rule context list.
SetE1([]IConditionalAndContext)
+ // Getter signatures
+ AllConditionalAnd() []IConditionalAndContext
+ ConditionalAnd(i int) IConditionalAndContext
+ AllLOGICAL_OR() []antlr.TerminalNode
+ LOGICAL_OR(i int) antlr.TerminalNode
+
// IsConditionalOrContext differentiates from other interfaces.
IsConditionalOrContext()
}
@@ -820,19 +859,19 @@ func (p *CELParser) ConditionalOr() (localctx IConditionalOrContext) {
p.EnterOuterAlt(localctx, 1)
{
- p.SetState(37)
+ p.SetState(43)
var _x = p.ConditionalAnd()
localctx.(*ConditionalOrContext).e = _x
}
- p.SetState(42)
+ p.SetState(48)
p.GetErrorHandler().Sync(p)
_la = p.GetTokenStream().LA(1)
for _la == CELParserLOGICAL_OR {
{
- p.SetState(38)
+ p.SetState(44)
var _m = p.Match(CELParserLOGICAL_OR)
@@ -840,7 +879,7 @@ func (p *CELParser) ConditionalOr() (localctx IConditionalOrContext) {
}
localctx.(*ConditionalOrContext).ops = append(localctx.(*ConditionalOrContext).ops, localctx.(*ConditionalOrContext).s9)
{
- p.SetState(39)
+ p.SetState(45)
var _x = p.ConditionalAnd()
@@ -848,7 +887,7 @@ func (p *CELParser) ConditionalOr() (localctx IConditionalOrContext) {
}
localctx.(*ConditionalOrContext).e1 = append(localctx.(*ConditionalOrContext).e1, localctx.(*ConditionalOrContext)._conditionalAnd)
- p.SetState(44)
+ p.SetState(50)
p.GetErrorHandler().Sync(p)
_la = p.GetTokenStream().LA(1)
}
@@ -893,6 +932,12 @@ type IConditionalAndContext interface {
// SetE1 sets the e1 rule context list.
SetE1([]IRelationContext)
+ // Getter signatures
+ AllRelation() []IRelationContext
+ Relation(i int) IRelationContext
+ AllLOGICAL_AND() []antlr.TerminalNode
+ LOGICAL_AND(i int) antlr.TerminalNode
+
// IsConditionalAndContext differentiates from other interfaces.
IsConditionalAndContext()
}
@@ -1054,19 +1099,19 @@ func (p *CELParser) ConditionalAnd() (localctx IConditionalAndContext) {
p.EnterOuterAlt(localctx, 1)
{
- p.SetState(45)
+ p.SetState(51)
var _x = p.relation(0)
localctx.(*ConditionalAndContext).e = _x
}
- p.SetState(50)
+ p.SetState(56)
p.GetErrorHandler().Sync(p)
_la = p.GetTokenStream().LA(1)
for _la == CELParserLOGICAL_AND {
{
- p.SetState(46)
+ p.SetState(52)
var _m = p.Match(CELParserLOGICAL_AND)
@@ -1074,7 +1119,7 @@ func (p *CELParser) ConditionalAnd() (localctx IConditionalAndContext) {
}
localctx.(*ConditionalAndContext).ops = append(localctx.(*ConditionalAndContext).ops, localctx.(*ConditionalAndContext).s8)
{
- p.SetState(47)
+ p.SetState(53)
var _x = p.relation(0)
@@ -1082,7 +1127,7 @@ func (p *CELParser) ConditionalAnd() (localctx IConditionalAndContext) {
}
localctx.(*ConditionalAndContext).e1 = append(localctx.(*ConditionalAndContext).e1, localctx.(*ConditionalAndContext)._relation)
- p.SetState(52)
+ p.SetState(58)
p.GetErrorHandler().Sync(p)
_la = p.GetTokenStream().LA(1)
}
@@ -1103,6 +1148,18 @@ type IRelationContext interface {
// SetOp sets the op token.
SetOp(antlr.Token)
+ // Getter signatures
+ Calc() ICalcContext
+ AllRelation() []IRelationContext
+ Relation(i int) IRelationContext
+ LESS() antlr.TerminalNode
+ LESS_EQUALS() antlr.TerminalNode
+ GREATER_EQUALS() antlr.TerminalNode
+ GREATER() antlr.TerminalNode
+ EQUALS() antlr.TerminalNode
+ NOT_EQUALS() antlr.TerminalNode
+ IN() antlr.TerminalNode
+
// IsRelationContext differentiates from other interfaces.
IsRelationContext()
}
@@ -1291,12 +1348,12 @@ func (p *CELParser) relation(_p int) (localctx IRelationContext) {
p.EnterOuterAlt(localctx, 1)
{
- p.SetState(54)
+ p.SetState(60)
p.calc(0)
}
p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1))
- p.SetState(61)
+ p.SetState(67)
p.GetErrorHandler().Sync(p)
_alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 3, p.GetParserRuleContext())
@@ -1308,13 +1365,13 @@ func (p *CELParser) relation(_p int) (localctx IRelationContext) {
_prevctx = localctx
localctx = NewRelationContext(p, _parentctx, _parentState)
p.PushNewRecursionContext(localctx, _startState, CELParserRULE_relation)
- p.SetState(56)
+ p.SetState(62)
if !(p.Precpred(p.GetParserRuleContext(), 1)) {
panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 1)", ""))
}
{
- p.SetState(57)
+ p.SetState(63)
var _lt = p.GetTokenStream().LT(1)
@@ -1322,7 +1379,7 @@ func (p *CELParser) relation(_p int) (localctx IRelationContext) {
_la = p.GetTokenStream().LA(1)
- if !(((_la)&-(0x1f+1)) == 0 && ((1<.map(, )
-// .map(, , )
+//
+// .map(, )
+// .map(, , )
+//
// In the second form only iterVar values which return true when provided to the predicate expression
// are transformed.
func MakeMap(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
diff --git a/vendor/github.com/google/cel-go/parser/options.go b/vendor/github.com/google/cel-go/parser/options.go
index b50686a912..674c697c5c 100644
--- a/vendor/github.com/google/cel-go/parser/options.go
+++ b/vendor/github.com/google/cel-go/parser/options.go
@@ -18,11 +18,13 @@ import "fmt"
type options struct {
maxRecursionDepth int
+ errorReportingLimit int
errorRecoveryTokenLookaheadLimit int
errorRecoveryLimit int
expressionSizeCodePointLimit int
macros map[string]Macro
populateMacroCalls bool
+ enableOptionalSyntax bool
}
// Option configures the behavior of the parser.
@@ -45,7 +47,7 @@ func MaxRecursionDepth(limit int) Option {
// successfully resume. In some pathological cases, the parser can look through quite a large set of input which
// in turn generates a lot of back-tracking and performance degredation.
//
-// The limit must be > 1, and is recommended to be less than the default of 256.
+// The limit must be >= 1, and is recommended to be less than the default of 256.
func ErrorRecoveryLookaheadTokenLimit(limit int) Option {
return func(opts *options) error {
if limit < 1 {
@@ -67,6 +69,19 @@ func ErrorRecoveryLimit(limit int) Option {
}
}
+// ErrorReportingLimit limits the number of syntax error reports before terminating parsing.
+//
+// The limit must be at least 1. If unset, the limit will be 100.
+func ErrorReportingLimit(limit int) Option {
+ return func(opts *options) error {
+ if limit < 1 {
+ return fmt.Errorf("error reporting limit must be at least 1: %d", limit)
+ }
+ opts.errorReportingLimit = limit
+ return nil
+ }
+}
+
// ExpressionSizeCodePointLimit is an option which limits the maximum code point count of an
// expression.
func ExpressionSizeCodePointLimit(expressionSizeCodePointLimit int) Option {
@@ -102,3 +117,11 @@ func PopulateMacroCalls(populateMacroCalls bool) Option {
return nil
}
}
+
+// EnableOptionalSyntax enables syntax for optional field and index selection.
+func EnableOptionalSyntax(optionalSyntax bool) Option {
+ return func(opts *options) error {
+ opts.enableOptionalSyntax = optionalSyntax
+ return nil
+ }
+}
diff --git a/vendor/github.com/google/cel-go/parser/parser.go b/vendor/github.com/google/cel-go/parser/parser.go
index 072f624574..e6f70f9060 100644
--- a/vendor/github.com/google/cel-go/parser/parser.go
+++ b/vendor/github.com/google/cel-go/parser/parser.go
@@ -18,11 +18,13 @@ package parser
import (
"fmt"
+ "regexp"
"strconv"
"strings"
"sync"
- "github.com/antlr/antlr4/runtime/Go/antlr"
+ antlr "github.com/antlr/antlr4/runtime/Go/antlr/v4"
+
"github.com/google/cel-go/common"
"github.com/google/cel-go/common/operators"
"github.com/google/cel-go/common/runes"
@@ -45,6 +47,9 @@ func NewParser(opts ...Option) (*Parser, error) {
return nil, err
}
}
+ if p.errorReportingLimit == 0 {
+ p.errorReportingLimit = 100
+ }
if p.maxRecursionDepth == 0 {
p.maxRecursionDepth = 250
}
@@ -89,9 +94,11 @@ func (p *Parser) Parse(source common.Source) (*exprpb.ParsedExpr, *common.Errors
helper: newParserHelper(source),
macros: p.macros,
maxRecursionDepth: p.maxRecursionDepth,
+ errorReportingLimit: p.errorReportingLimit,
errorRecoveryLimit: p.errorRecoveryLimit,
errorRecoveryLookaheadTokenLimit: p.errorRecoveryTokenLookaheadLimit,
populateMacroCalls: p.populateMacroCalls,
+ enableOptionalSyntax: p.enableOptionalSyntax,
}
buf, ok := source.(runes.Buffer)
if !ok {
@@ -178,7 +185,7 @@ func (rl *recursionListener) EnterEveryRule(ctx antlr.ParserRuleContext) {
} else {
*depth++
}
- if *depth >= rl.maxDepth {
+ if *depth > rl.maxDepth {
panic(&recursionError{
message: fmt.Sprintf("expression recursion limit exceeded: %d", rl.maxDepth),
})
@@ -197,6 +204,16 @@ func (rl *recursionListener) ExitEveryRule(ctx antlr.ParserRuleContext) {
var _ antlr.ParseTreeListener = &recursionListener{}
+type tooManyErrors struct {
+ errorReportingLimit int
+}
+
+func (t *tooManyErrors) Error() string {
+ return fmt.Sprintf("More than %d syntax errors", t.errorReportingLimit)
+}
+
+var _ error = &tooManyErrors{}
+
type recoveryLimitError struct {
message string
}
@@ -271,17 +288,20 @@ type parser struct {
helper *parserHelper
macros map[string]Macro
recursionDepth int
+ errorReports int
maxRecursionDepth int
+ errorReportingLimit int
errorRecoveryLimit int
errorRecoveryLookaheadTokenLimit int
populateMacroCalls bool
+ enableOptionalSyntax bool
}
var (
_ gen.CELVisitor = (*parser)(nil)
lexerPool *sync.Pool = &sync.Pool{
- New: func() interface{} {
+ New: func() any {
l := gen.NewCELLexer(nil)
l.RemoveErrorListeners()
return l
@@ -289,7 +309,7 @@ var (
}
parserPool *sync.Pool = &sync.Pool{
- New: func() interface{} {
+ New: func() any {
p := gen.NewCELParser(nil)
p.RemoveErrorListeners()
return p
@@ -302,14 +322,14 @@ func (p *parser) parse(expr runes.Buffer, desc string) *exprpb.Expr {
lexer := lexerPool.Get().(*gen.CELLexer)
prsr := parserPool.Get().(*gen.CELParser)
- // Unfortunately ANTLR Go runtime is missing (*antlr.BaseParser).RemoveParseListeners, so this is
- // good enough until that is exported.
prsrListener := &recursionListener{
maxDepth: p.maxRecursionDepth,
ruleTypeDepth: map[int]*int{},
}
defer func() {
+ // Unfortunately ANTLR Go runtime is missing (*antlr.BaseParser).RemoveParseListeners,
+ // so this is good enough until that is exported.
// Reset the lexer and parser before putting them back in the pool.
lexer.RemoveErrorListeners()
prsr.RemoveParseListener(prsrListener)
@@ -340,6 +360,8 @@ func (p *parser) parse(expr runes.Buffer, desc string) *exprpb.Expr {
p.errors.ReportError(common.NoLocation, err.Error())
case *recursionError:
p.errors.ReportError(common.NoLocation, err.Error())
+ case *tooManyErrors:
+ // do nothing
case *recoveryLimitError:
// do nothing, listeners already notified and error reported.
default:
@@ -352,57 +374,85 @@ func (p *parser) parse(expr runes.Buffer, desc string) *exprpb.Expr {
}
// Visitor implementations.
-func (p *parser) Visit(tree antlr.ParseTree) interface{} {
- p.recursionDepth++
- if p.recursionDepth > p.maxRecursionDepth {
- panic(&recursionError{message: "max recursion depth exceeded"})
- }
- defer func() {
- p.recursionDepth--
- }()
- switch tree.(type) {
+func (p *parser) Visit(tree antlr.ParseTree) any {
+ t := unnest(tree)
+ switch tree := t.(type) {
case *gen.StartContext:
- return p.VisitStart(tree.(*gen.StartContext))
+ return p.VisitStart(tree)
case *gen.ExprContext:
- return p.VisitExpr(tree.(*gen.ExprContext))
+ p.checkAndIncrementRecursionDepth()
+ out := p.VisitExpr(tree)
+ p.decrementRecursionDepth()
+ return out
case *gen.ConditionalAndContext:
- return p.VisitConditionalAnd(tree.(*gen.ConditionalAndContext))
+ return p.VisitConditionalAnd(tree)
case *gen.ConditionalOrContext:
- return p.VisitConditionalOr(tree.(*gen.ConditionalOrContext))
+ return p.VisitConditionalOr(tree)
case *gen.RelationContext:
- return p.VisitRelation(tree.(*gen.RelationContext))
+ p.checkAndIncrementRecursionDepth()
+ out := p.VisitRelation(tree)
+ p.decrementRecursionDepth()
+ return out
case *gen.CalcContext:
- return p.VisitCalc(tree.(*gen.CalcContext))
+ p.checkAndIncrementRecursionDepth()
+ out := p.VisitCalc(tree)
+ p.decrementRecursionDepth()
+ return out
case *gen.LogicalNotContext:
- return p.VisitLogicalNot(tree.(*gen.LogicalNotContext))
- case *gen.MemberExprContext:
- return p.VisitMemberExpr(tree.(*gen.MemberExprContext))
- case *gen.PrimaryExprContext:
- return p.VisitPrimaryExpr(tree.(*gen.PrimaryExprContext))
- case *gen.SelectOrCallContext:
- return p.VisitSelectOrCall(tree.(*gen.SelectOrCallContext))
+ return p.VisitLogicalNot(tree)
+ case *gen.IdentOrGlobalCallContext:
+ return p.VisitIdentOrGlobalCall(tree)
+ case *gen.SelectContext:
+ p.checkAndIncrementRecursionDepth()
+ out := p.VisitSelect(tree)
+ p.decrementRecursionDepth()
+ return out
+ case *gen.MemberCallContext:
+ p.checkAndIncrementRecursionDepth()
+ out := p.VisitMemberCall(tree)
+ p.decrementRecursionDepth()
+ return out
case *gen.MapInitializerListContext:
- return p.VisitMapInitializerList(tree.(*gen.MapInitializerListContext))
+ return p.VisitMapInitializerList(tree)
case *gen.NegateContext:
- return p.VisitNegate(tree.(*gen.NegateContext))
+ return p.VisitNegate(tree)
case *gen.IndexContext:
- return p.VisitIndex(tree.(*gen.IndexContext))
+ p.checkAndIncrementRecursionDepth()
+ out := p.VisitIndex(tree)
+ p.decrementRecursionDepth()
+ return out
case *gen.UnaryContext:
- return p.VisitUnary(tree.(*gen.UnaryContext))
+ return p.VisitUnary(tree)
case *gen.CreateListContext:
- return p.VisitCreateList(tree.(*gen.CreateListContext))
+ return p.VisitCreateList(tree)
case *gen.CreateMessageContext:
- return p.VisitCreateMessage(tree.(*gen.CreateMessageContext))
+ return p.VisitCreateMessage(tree)
case *gen.CreateStructContext:
- return p.VisitCreateStruct(tree.(*gen.CreateStructContext))
+ return p.VisitCreateStruct(tree)
+ case *gen.IntContext:
+ return p.VisitInt(tree)
+ case *gen.UintContext:
+ return p.VisitUint(tree)
+ case *gen.DoubleContext:
+ return p.VisitDouble(tree)
+ case *gen.StringContext:
+ return p.VisitString(tree)
+ case *gen.BytesContext:
+ return p.VisitBytes(tree)
+ case *gen.BoolFalseContext:
+ return p.VisitBoolFalse(tree)
+ case *gen.BoolTrueContext:
+ return p.VisitBoolTrue(tree)
+ case *gen.NullContext:
+ return p.VisitNull(tree)
}
// Report at least one error if the parser reaches an unknown parse element.
// Typically, this happens if the parser has already encountered a syntax error elsewhere.
if len(p.errors.GetErrors()) == 0 {
txt := "<>"
- if tree != nil {
- txt = fmt.Sprintf("<<%T>>", tree)
+ if t != nil {
+ txt = fmt.Sprintf("<<%T>>", t)
}
return p.reportError(common.NoLocation, "unknown parse element encountered: %s", txt)
}
@@ -411,12 +461,12 @@ func (p *parser) Visit(tree antlr.ParseTree) interface{} {
}
// Visit a parse tree produced by CELParser#start.
-func (p *parser) VisitStart(ctx *gen.StartContext) interface{} {
+func (p *parser) VisitStart(ctx *gen.StartContext) any {
return p.Visit(ctx.Expr())
}
// Visit a parse tree produced by CELParser#expr.
-func (p *parser) VisitExpr(ctx *gen.ExprContext) interface{} {
+func (p *parser) VisitExpr(ctx *gen.ExprContext) any {
result := p.Visit(ctx.GetE()).(*exprpb.Expr)
if ctx.GetOp() == nil {
return result
@@ -428,11 +478,8 @@ func (p *parser) VisitExpr(ctx *gen.ExprContext) interface{} {
}
// Visit a parse tree produced by CELParser#conditionalOr.
-func (p *parser) VisitConditionalOr(ctx *gen.ConditionalOrContext) interface{} {
+func (p *parser) VisitConditionalOr(ctx *gen.ConditionalOrContext) any {
result := p.Visit(ctx.GetE()).(*exprpb.Expr)
- if ctx.GetOps() == nil {
- return result
- }
b := newBalancer(p.helper, operators.LogicalOr, result)
rest := ctx.GetE1()
for i, op := range ctx.GetOps() {
@@ -447,11 +494,8 @@ func (p *parser) VisitConditionalOr(ctx *gen.ConditionalOrContext) interface{} {
}
// Visit a parse tree produced by CELParser#conditionalAnd.
-func (p *parser) VisitConditionalAnd(ctx *gen.ConditionalAndContext) interface{} {
+func (p *parser) VisitConditionalAnd(ctx *gen.ConditionalAndContext) any {
result := p.Visit(ctx.GetE()).(*exprpb.Expr)
- if ctx.GetOps() == nil {
- return result
- }
b := newBalancer(p.helper, operators.LogicalAnd, result)
rest := ctx.GetE1()
for i, op := range ctx.GetOps() {
@@ -466,10 +510,7 @@ func (p *parser) VisitConditionalAnd(ctx *gen.ConditionalAndContext) interface{}
}
// Visit a parse tree produced by CELParser#relation.
-func (p *parser) VisitRelation(ctx *gen.RelationContext) interface{} {
- if ctx.Calc() != nil {
- return p.Visit(ctx.Calc())
- }
+func (p *parser) VisitRelation(ctx *gen.RelationContext) any {
opText := ""
if ctx.GetOp() != nil {
opText = ctx.GetOp().GetText()
@@ -484,10 +525,7 @@ func (p *parser) VisitRelation(ctx *gen.RelationContext) interface{} {
}
// Visit a parse tree produced by CELParser#calc.
-func (p *parser) VisitCalc(ctx *gen.CalcContext) interface{} {
- if ctx.Unary() != nil {
- return p.Visit(ctx.Unary())
- }
+func (p *parser) VisitCalc(ctx *gen.CalcContext) any {
opText := ""
if ctx.GetOp() != nil {
opText = ctx.GetOp().GetText()
@@ -501,27 +539,12 @@ func (p *parser) VisitCalc(ctx *gen.CalcContext) interface{} {
return p.reportError(ctx, "operator not found")
}
-func (p *parser) VisitUnary(ctx *gen.UnaryContext) interface{} {
+func (p *parser) VisitUnary(ctx *gen.UnaryContext) any {
return p.helper.newLiteralString(ctx, "<>")
}
-// Visit a parse tree produced by CELParser#MemberExpr.
-func (p *parser) VisitMemberExpr(ctx *gen.MemberExprContext) interface{} {
- switch ctx.Member().(type) {
- case *gen.PrimaryExprContext:
- return p.VisitPrimaryExpr(ctx.Member().(*gen.PrimaryExprContext))
- case *gen.SelectOrCallContext:
- return p.VisitSelectOrCall(ctx.Member().(*gen.SelectOrCallContext))
- case *gen.IndexContext:
- return p.VisitIndex(ctx.Member().(*gen.IndexContext))
- case *gen.CreateMessageContext:
- return p.VisitCreateMessage(ctx.Member().(*gen.CreateMessageContext))
- }
- return p.reportError(ctx, "unsupported simple expression")
-}
-
// Visit a parse tree produced by CELParser#LogicalNot.
-func (p *parser) VisitLogicalNot(ctx *gen.LogicalNotContext) interface{} {
+func (p *parser) VisitLogicalNot(ctx *gen.LogicalNotContext) any {
if len(ctx.GetOps())%2 == 0 {
return p.Visit(ctx.Member())
}
@@ -530,7 +553,7 @@ func (p *parser) VisitLogicalNot(ctx *gen.LogicalNotContext) interface{} {
return p.globalCallOrMacro(opID, operators.LogicalNot, target)
}
-func (p *parser) VisitNegate(ctx *gen.NegateContext) interface{} {
+func (p *parser) VisitNegate(ctx *gen.NegateContext) any {
if len(ctx.GetOps())%2 == 0 {
return p.Visit(ctx.Member())
}
@@ -539,60 +562,77 @@ func (p *parser) VisitNegate(ctx *gen.NegateContext) interface{} {
return p.globalCallOrMacro(opID, operators.Negate, target)
}
-// Visit a parse tree produced by CELParser#SelectOrCall.
-func (p *parser) VisitSelectOrCall(ctx *gen.SelectOrCallContext) interface{} {
+// VisitSelect visits a parse tree produced by CELParser#Select.
+func (p *parser) VisitSelect(ctx *gen.SelectContext) any {
operand := p.Visit(ctx.Member()).(*exprpb.Expr)
// Handle the error case where no valid identifier is specified.
- if ctx.GetId() == nil {
+ if ctx.GetId() == nil || ctx.GetOp() == nil {
return p.helper.newExpr(ctx)
}
id := ctx.GetId().GetText()
- if ctx.GetOpen() != nil {
- opID := p.helper.id(ctx.GetOpen())
- return p.receiverCallOrMacro(opID, id, operand, p.visitList(ctx.GetArgs())...)
+ if ctx.GetOpt() != nil {
+ if !p.enableOptionalSyntax {
+ return p.reportError(ctx.GetOp(), "unsupported syntax '.?'")
+ }
+ return p.helper.newGlobalCall(
+ ctx.GetOp(),
+ operators.OptSelect,
+ operand,
+ p.helper.newLiteralString(ctx.GetId(), id))
}
return p.helper.newSelect(ctx.GetOp(), operand, id)
}
-// Visit a parse tree produced by CELParser#PrimaryExpr.
-func (p *parser) VisitPrimaryExpr(ctx *gen.PrimaryExprContext) interface{} {
- switch ctx.Primary().(type) {
- case *gen.NestedContext:
- return p.VisitNested(ctx.Primary().(*gen.NestedContext))
- case *gen.IdentOrGlobalCallContext:
- return p.VisitIdentOrGlobalCall(ctx.Primary().(*gen.IdentOrGlobalCallContext))
- case *gen.CreateListContext:
- return p.VisitCreateList(ctx.Primary().(*gen.CreateListContext))
- case *gen.CreateStructContext:
- return p.VisitCreateStruct(ctx.Primary().(*gen.CreateStructContext))
- case *gen.ConstantLiteralContext:
- return p.VisitConstantLiteral(ctx.Primary().(*gen.ConstantLiteralContext))
+// VisitMemberCall visits a parse tree produced by CELParser#MemberCall.
+func (p *parser) VisitMemberCall(ctx *gen.MemberCallContext) any {
+ operand := p.Visit(ctx.Member()).(*exprpb.Expr)
+ // Handle the error case where no valid identifier is specified.
+ if ctx.GetId() == nil {
+ return p.helper.newExpr(ctx)
}
-
- return p.reportError(ctx, "invalid primary expression")
+ id := ctx.GetId().GetText()
+ opID := p.helper.id(ctx.GetOpen())
+ return p.receiverCallOrMacro(opID, id, operand, p.visitExprList(ctx.GetArgs())...)
}
// Visit a parse tree produced by CELParser#Index.
-func (p *parser) VisitIndex(ctx *gen.IndexContext) interface{} {
+func (p *parser) VisitIndex(ctx *gen.IndexContext) any {
target := p.Visit(ctx.Member()).(*exprpb.Expr)
+ // Handle the error case where no valid identifier is specified.
+ if ctx.GetOp() == nil {
+ return p.helper.newExpr(ctx)
+ }
opID := p.helper.id(ctx.GetOp())
index := p.Visit(ctx.GetIndex()).(*exprpb.Expr)
- return p.globalCallOrMacro(opID, operators.Index, target, index)
+ operator := operators.Index
+ if ctx.GetOpt() != nil {
+ if !p.enableOptionalSyntax {
+ return p.reportError(ctx.GetOp(), "unsupported syntax '[?'")
+ }
+ operator = operators.OptIndex
+ }
+ return p.globalCallOrMacro(opID, operator, target, index)
}
// Visit a parse tree produced by CELParser#CreateMessage.
-func (p *parser) VisitCreateMessage(ctx *gen.CreateMessageContext) interface{} {
- target := p.Visit(ctx.Member()).(*exprpb.Expr)
- objID := p.helper.id(ctx.GetOp())
- if messageName, found := p.extractQualifiedName(target); found {
- entries := p.VisitIFieldInitializerList(ctx.GetEntries()).([]*exprpb.Expr_CreateStruct_Entry)
- return p.helper.newObject(objID, messageName, entries...)
+func (p *parser) VisitCreateMessage(ctx *gen.CreateMessageContext) any {
+ messageName := ""
+ for _, id := range ctx.GetIds() {
+ if len(messageName) != 0 {
+ messageName += "."
+ }
+ messageName += id.GetText()
+ }
+ if ctx.GetLeadingDot() != nil {
+ messageName = "." + messageName
}
- return p.helper.newExpr(objID)
+ objID := p.helper.id(ctx.GetOp())
+ entries := p.VisitIFieldInitializerList(ctx.GetEntries()).([]*exprpb.Expr_CreateStruct_Entry)
+ return p.helper.newObject(objID, messageName, entries...)
}
// Visit a parse tree of field initializers.
-func (p *parser) VisitIFieldInitializerList(ctx gen.IFieldInitializerListContext) interface{} {
+func (p *parser) VisitIFieldInitializerList(ctx gen.IFieldInitializerListContext) any {
if ctx == nil || ctx.GetFields() == nil {
// This is the result of a syntax error handled elswhere, return empty.
return []*exprpb.Expr_CreateStruct_Entry{}
@@ -607,15 +647,27 @@ func (p *parser) VisitIFieldInitializerList(ctx gen.IFieldInitializerListContext
return []*exprpb.Expr_CreateStruct_Entry{}
}
initID := p.helper.id(cols[i])
+ optField := f.(*gen.OptFieldContext)
+ optional := optField.GetOpt() != nil
+ if !p.enableOptionalSyntax && optional {
+ p.reportError(optField, "unsupported syntax '?'")
+ continue
+ }
+ // The field may be empty due to a prior error.
+ id := optField.IDENTIFIER()
+ if id == nil {
+ return []*exprpb.Expr_CreateStruct_Entry{}
+ }
+ fieldName := id.GetText()
value := p.Visit(vals[i]).(*exprpb.Expr)
- field := p.helper.newObjectField(initID, f.GetText(), value)
+ field := p.helper.newObjectField(initID, fieldName, value, optional)
result[i] = field
}
return result
}
// Visit a parse tree produced by CELParser#IdentOrGlobalCall.
-func (p *parser) VisitIdentOrGlobalCall(ctx *gen.IdentOrGlobalCallContext) interface{} {
+func (p *parser) VisitIdentOrGlobalCall(ctx *gen.IdentOrGlobalCallContext) any {
identName := ""
if ctx.GetLeadingDot() != nil {
identName = "."
@@ -632,24 +684,20 @@ func (p *parser) VisitIdentOrGlobalCall(ctx *gen.IdentOrGlobalCallContext) inter
identName += id
if ctx.GetOp() != nil {
opID := p.helper.id(ctx.GetOp())
- return p.globalCallOrMacro(opID, identName, p.visitList(ctx.GetArgs())...)
+ return p.globalCallOrMacro(opID, identName, p.visitExprList(ctx.GetArgs())...)
}
return p.helper.newIdent(ctx.GetId(), identName)
}
-// Visit a parse tree produced by CELParser#Nested.
-func (p *parser) VisitNested(ctx *gen.NestedContext) interface{} {
- return p.Visit(ctx.GetE())
-}
-
// Visit a parse tree produced by CELParser#CreateList.
-func (p *parser) VisitCreateList(ctx *gen.CreateListContext) interface{} {
+func (p *parser) VisitCreateList(ctx *gen.CreateListContext) any {
listID := p.helper.id(ctx.GetOp())
- return p.helper.newList(listID, p.visitList(ctx.GetElems())...)
+ elems, optionals := p.visitListInit(ctx.GetElems())
+ return p.helper.newList(listID, elems, optionals...)
}
// Visit a parse tree produced by CELParser#CreateStruct.
-func (p *parser) VisitCreateStruct(ctx *gen.CreateStructContext) interface{} {
+func (p *parser) VisitCreateStruct(ctx *gen.CreateStructContext) any {
structID := p.helper.id(ctx.GetOp())
entries := []*exprpb.Expr_CreateStruct_Entry{}
if ctx.GetEntries() != nil {
@@ -658,31 +706,8 @@ func (p *parser) VisitCreateStruct(ctx *gen.CreateStructContext) interface{} {
return p.helper.newMap(structID, entries...)
}
-// Visit a parse tree produced by CELParser#ConstantLiteral.
-func (p *parser) VisitConstantLiteral(ctx *gen.ConstantLiteralContext) interface{} {
- switch ctx.Literal().(type) {
- case *gen.IntContext:
- return p.VisitInt(ctx.Literal().(*gen.IntContext))
- case *gen.UintContext:
- return p.VisitUint(ctx.Literal().(*gen.UintContext))
- case *gen.DoubleContext:
- return p.VisitDouble(ctx.Literal().(*gen.DoubleContext))
- case *gen.StringContext:
- return p.VisitString(ctx.Literal().(*gen.StringContext))
- case *gen.BytesContext:
- return p.VisitBytes(ctx.Literal().(*gen.BytesContext))
- case *gen.BoolFalseContext:
- return p.VisitBoolFalse(ctx.Literal().(*gen.BoolFalseContext))
- case *gen.BoolTrueContext:
- return p.VisitBoolTrue(ctx.Literal().(*gen.BoolTrueContext))
- case *gen.NullContext:
- return p.VisitNull(ctx.Literal().(*gen.NullContext))
- }
- return p.reportError(ctx, "invalid literal")
-}
-
// Visit a parse tree produced by CELParser#mapInitializerList.
-func (p *parser) VisitMapInitializerList(ctx *gen.MapInitializerListContext) interface{} {
+func (p *parser) VisitMapInitializerList(ctx *gen.MapInitializerListContext) any {
if ctx == nil || ctx.GetKeys() == nil {
// This is the result of a syntax error handled elswhere, return empty.
return []*exprpb.Expr_CreateStruct_Entry{}
@@ -697,16 +722,22 @@ func (p *parser) VisitMapInitializerList(ctx *gen.MapInitializerListContext) int
// This is the result of a syntax error detected elsewhere.
return []*exprpb.Expr_CreateStruct_Entry{}
}
- key := p.Visit(keys[i]).(*exprpb.Expr)
+ optKey := keys[i]
+ optional := optKey.GetOpt() != nil
+ if !p.enableOptionalSyntax && optional {
+ p.reportError(optKey, "unsupported syntax '?'")
+ continue
+ }
+ key := p.Visit(optKey.GetE()).(*exprpb.Expr)
value := p.Visit(vals[i]).(*exprpb.Expr)
- entry := p.helper.newMapEntry(colID, key, value)
+ entry := p.helper.newMapEntry(colID, key, value, optional)
result[i] = entry
}
return result
}
// Visit a parse tree produced by CELParser#Int.
-func (p *parser) VisitInt(ctx *gen.IntContext) interface{} {
+func (p *parser) VisitInt(ctx *gen.IntContext) any {
text := ctx.GetTok().GetText()
base := 10
if strings.HasPrefix(text, "0x") {
@@ -724,7 +755,7 @@ func (p *parser) VisitInt(ctx *gen.IntContext) interface{} {
}
// Visit a parse tree produced by CELParser#Uint.
-func (p *parser) VisitUint(ctx *gen.UintContext) interface{} {
+func (p *parser) VisitUint(ctx *gen.UintContext) any {
text := ctx.GetTok().GetText()
// trim the 'u' designator included in the uint literal.
text = text[:len(text)-1]
@@ -741,7 +772,7 @@ func (p *parser) VisitUint(ctx *gen.UintContext) interface{} {
}
// Visit a parse tree produced by CELParser#Double.
-func (p *parser) VisitDouble(ctx *gen.DoubleContext) interface{} {
+func (p *parser) VisitDouble(ctx *gen.DoubleContext) any {
txt := ctx.GetTok().GetText()
if ctx.GetSign() != nil {
txt = ctx.GetSign().GetText() + txt
@@ -755,42 +786,66 @@ func (p *parser) VisitDouble(ctx *gen.DoubleContext) interface{} {
}
// Visit a parse tree produced by CELParser#String.
-func (p *parser) VisitString(ctx *gen.StringContext) interface{} {
+func (p *parser) VisitString(ctx *gen.StringContext) any {
s := p.unquote(ctx, ctx.GetText(), false)
return p.helper.newLiteralString(ctx, s)
}
// Visit a parse tree produced by CELParser#Bytes.
-func (p *parser) VisitBytes(ctx *gen.BytesContext) interface{} {
+func (p *parser) VisitBytes(ctx *gen.BytesContext) any {
b := []byte(p.unquote(ctx, ctx.GetTok().GetText()[1:], true))
return p.helper.newLiteralBytes(ctx, b)
}
// Visit a parse tree produced by CELParser#BoolTrue.
-func (p *parser) VisitBoolTrue(ctx *gen.BoolTrueContext) interface{} {
+func (p *parser) VisitBoolTrue(ctx *gen.BoolTrueContext) any {
return p.helper.newLiteralBool(ctx, true)
}
// Visit a parse tree produced by CELParser#BoolFalse.
-func (p *parser) VisitBoolFalse(ctx *gen.BoolFalseContext) interface{} {
+func (p *parser) VisitBoolFalse(ctx *gen.BoolFalseContext) any {
return p.helper.newLiteralBool(ctx, false)
}
// Visit a parse tree produced by CELParser#Null.
-func (p *parser) VisitNull(ctx *gen.NullContext) interface{} {
+func (p *parser) VisitNull(ctx *gen.NullContext) any {
return p.helper.newLiteral(ctx,
&exprpb.Constant{
ConstantKind: &exprpb.Constant_NullValue{
NullValue: structpb.NullValue_NULL_VALUE}})
}
-func (p *parser) visitList(ctx gen.IExprListContext) []*exprpb.Expr {
+func (p *parser) visitExprList(ctx gen.IExprListContext) []*exprpb.Expr {
if ctx == nil {
return []*exprpb.Expr{}
}
return p.visitSlice(ctx.GetE())
}
+func (p *parser) visitListInit(ctx gen.IListInitContext) ([]*exprpb.Expr, []int32) {
+ if ctx == nil {
+ return []*exprpb.Expr{}, []int32{}
+ }
+ elements := ctx.GetElems()
+ result := make([]*exprpb.Expr, len(elements))
+ optionals := []int32{}
+ for i, e := range elements {
+ ex := p.Visit(e.GetE()).(*exprpb.Expr)
+ if ex == nil {
+ return []*exprpb.Expr{}, []int32{}
+ }
+ result[i] = ex
+ if e.GetOpt() != nil {
+ if !p.enableOptionalSyntax {
+ p.reportError(e.GetOpt(), "unsupported syntax '?'")
+ continue
+ }
+ optionals = append(optionals, int32(i))
+ }
+ }
+ return result, optionals
+}
+
func (p *parser) visitSlice(expressions []gen.IExprContext) []*exprpb.Expr {
if expressions == nil {
return []*exprpb.Expr{}
@@ -803,26 +858,7 @@ func (p *parser) visitSlice(expressions []gen.IExprContext) []*exprpb.Expr {
return result
}
-func (p *parser) extractQualifiedName(e *exprpb.Expr) (string, bool) {
- if e == nil {
- return "", false
- }
- switch e.GetExprKind().(type) {
- case *exprpb.Expr_IdentExpr:
- return e.GetIdentExpr().GetName(), true
- case *exprpb.Expr_SelectExpr:
- s := e.GetSelectExpr()
- if prefix, found := p.extractQualifiedName(s.GetOperand()); found {
- return prefix + "." + s.GetField(), true
- }
- }
- // TODO: Add a method to Source to get location from character offset.
- location := p.helper.getLocation(e.GetId())
- p.reportError(location, "expected a qualified name")
- return "", false
-}
-
-func (p *parser) unquote(ctx interface{}, value string, isBytes bool) string {
+func (p *parser) unquote(ctx any, value string, isBytes bool) string {
text, err := unescape(value, isBytes)
if err != nil {
p.reportError(ctx, "%s", err.Error())
@@ -831,7 +867,7 @@ func (p *parser) unquote(ctx interface{}, value string, isBytes bool) string {
return text
}
-func (p *parser) reportError(ctx interface{}, format string, args ...interface{}) *exprpb.Expr {
+func (p *parser) reportError(ctx any, format string, args ...any) *exprpb.Expr {
var location common.Location
switch ctx.(type) {
case common.Location:
@@ -847,10 +883,24 @@ func (p *parser) reportError(ctx interface{}, format string, args ...interface{}
}
// ANTLR Parse listener implementations
-func (p *parser) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) {
- // TODO: Snippet
+func (p *parser) SyntaxError(recognizer antlr.Recognizer, offendingSymbol any, line, column int, msg string, e antlr.RecognitionException) {
l := p.helper.source.NewLocation(line, column)
- p.errors.syntaxError(l, msg)
+ // Hack to keep existing error messages consistent with previous versions of CEL when a reserved word
+ // is used as an identifier. This behavior needs to be overhauled to provide consistent, normalized error
+ // messages out of ANTLR to prevent future breaking changes related to error message content.
+ if strings.Contains(msg, "no viable alternative") {
+ msg = reservedIdentifier.ReplaceAllString(msg, mismatchedReservedIdentifier)
+ }
+ // Ensure that no more than 100 syntax errors are reported as this will halt attempts to recover from a
+ // seriously broken expression.
+ if p.errorReports < p.errorReportingLimit {
+ p.errorReports++
+ p.errors.syntaxError(l, msg)
+ } else {
+ tme := &tooManyErrors{errorReportingLimit: p.errorReportingLimit}
+ p.errors.syntaxError(l, tme.Error())
+ panic(tme)
+ }
}
func (p *parser) ReportAmbiguity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, exact bool, ambigAlts *antlr.BitSet, configs antlr.ATNConfigSet) {
@@ -892,14 +942,95 @@ func (p *parser) expandMacro(exprID int64, function string, target *exprpb.Expr,
eh.parserHelper = p.helper
eh.id = exprID
expr, err := macro.Expander()(eh, target, args)
+ // An error indicates that the macro was matched, but the arguments were not well-formed.
if err != nil {
if err.Location != nil {
return p.reportError(err.Location, err.Message), true
}
return p.reportError(p.helper.getLocation(exprID), err.Message), true
}
+ // A nil value from the macro indicates that the macro implementation decided that
+ // an expansion should not be performed.
+ if expr == nil {
+ return nil, false
+ }
if p.populateMacroCalls {
p.helper.addMacroCall(expr.GetId(), function, target, args...)
}
return expr, true
}
+
+func (p *parser) checkAndIncrementRecursionDepth() {
+ p.recursionDepth++
+ if p.recursionDepth > p.maxRecursionDepth {
+ panic(&recursionError{message: "max recursion depth exceeded"})
+ }
+}
+
+func (p *parser) decrementRecursionDepth() {
+ p.recursionDepth--
+}
+
+// unnest traverses down the left-hand side of the parse graph until it encounters the first compound
+// parse node or the first leaf in the parse graph.
+func unnest(tree antlr.ParseTree) antlr.ParseTree {
+ for tree != nil {
+ switch t := tree.(type) {
+ case *gen.ExprContext:
+ // conditionalOr op='?' conditionalOr : expr
+ if t.GetOp() != nil {
+ return t
+ }
+ // conditionalOr
+ tree = t.GetE()
+ case *gen.ConditionalOrContext:
+ // conditionalAnd (ops=|| conditionalAnd)*
+ if t.GetOps() != nil && len(t.GetOps()) > 0 {
+ return t
+ }
+ // conditionalAnd
+ tree = t.GetE()
+ case *gen.ConditionalAndContext:
+ // relation (ops=&& relation)*
+ if t.GetOps() != nil && len(t.GetOps()) > 0 {
+ return t
+ }
+ // relation
+ tree = t.GetE()
+ case *gen.RelationContext:
+ // relation op relation
+ if t.GetOp() != nil {
+ return t
+ }
+ // calc
+ tree = t.Calc()
+ case *gen.CalcContext:
+ // calc op calc
+ if t.GetOp() != nil {
+ return t
+ }
+ // unary
+ tree = t.Unary()
+ case *gen.MemberExprContext:
+ // member expands to one of: primary, select, index, or create message
+ tree = t.Member()
+ case *gen.PrimaryExprContext:
+ // primary expands to one of identifier, nested, create list, create struct, literal
+ tree = t.Primary()
+ case *gen.NestedContext:
+ // contains a nested 'expr'
+ tree = t.GetE()
+ case *gen.ConstantLiteralContext:
+ // expands to a primitive literal
+ tree = t.Literal()
+ default:
+ return t
+ }
+ }
+ return tree
+}
+
+var (
+ reservedIdentifier = regexp.MustCompile("no viable alternative at input '.(true|false|null)'")
+ mismatchedReservedIdentifier = "mismatched input '$1' expecting IDENTIFIER"
+)
diff --git a/vendor/github.com/google/cel-go/parser/unparser.go b/vendor/github.com/google/cel-go/parser/unparser.go
index a459bb4a98..c3c40a0dd3 100644
--- a/vendor/github.com/google/cel-go/parser/unparser.go
+++ b/vendor/github.com/google/cel-go/parser/unparser.go
@@ -106,9 +106,15 @@ func (un *unparser) visitCall(expr *exprpb.Expr) error {
// ternary operator
case operators.Conditional:
return un.visitCallConditional(expr)
+ // optional select operator
+ case operators.OptSelect:
+ return un.visitOptSelect(expr)
// index operator
case operators.Index:
return un.visitCallIndex(expr)
+ // optional index operator
+ case operators.OptIndex:
+ return un.visitCallOptIndex(expr)
// unary operators
case operators.LogicalNot, operators.Negate:
return un.visitCallUnary(expr)
@@ -218,6 +224,14 @@ func (un *unparser) visitCallFunc(expr *exprpb.Expr) error {
}
func (un *unparser) visitCallIndex(expr *exprpb.Expr) error {
+ return un.visitCallIndexInternal(expr, "[")
+}
+
+func (un *unparser) visitCallOptIndex(expr *exprpb.Expr) error {
+ return un.visitCallIndexInternal(expr, "[?")
+}
+
+func (un *unparser) visitCallIndexInternal(expr *exprpb.Expr, op string) error {
c := expr.GetCallExpr()
args := c.GetArgs()
nested := isBinaryOrTernaryOperator(args[0])
@@ -225,7 +239,7 @@ func (un *unparser) visitCallIndex(expr *exprpb.Expr) error {
if err != nil {
return err
}
- un.str.WriteString("[")
+ un.str.WriteString(op)
err = un.visit(args[1])
if err != nil {
return err
@@ -262,6 +276,9 @@ func (un *unparser) visitConst(expr *exprpb.Expr) error {
// represent the float using the minimum required digits
d := strconv.FormatFloat(c.GetDoubleValue(), 'g', -1, 64)
un.str.WriteString(d)
+ if !strings.Contains(d, ".") {
+ un.str.WriteString(".0")
+ }
case *exprpb.Constant_Int64Value:
i := strconv.FormatInt(c.GetInt64Value(), 10)
un.str.WriteString(i)
@@ -289,8 +306,15 @@ func (un *unparser) visitIdent(expr *exprpb.Expr) error {
func (un *unparser) visitList(expr *exprpb.Expr) error {
l := expr.GetListExpr()
elems := l.GetElements()
+ optIndices := make(map[int]bool, len(elems))
+ for _, idx := range l.GetOptionalIndices() {
+ optIndices[int(idx)] = true
+ }
un.str.WriteString("[")
for i, elem := range elems {
+ if optIndices[i] {
+ un.str.WriteString("?")
+ }
err := un.visit(elem)
if err != nil {
return err
@@ -303,20 +327,32 @@ func (un *unparser) visitList(expr *exprpb.Expr) error {
return nil
}
+func (un *unparser) visitOptSelect(expr *exprpb.Expr) error {
+ c := expr.GetCallExpr()
+ args := c.GetArgs()
+ operand := args[0]
+ field := args[1].GetConstExpr().GetStringValue()
+ return un.visitSelectInternal(operand, false, ".?", field)
+}
+
func (un *unparser) visitSelect(expr *exprpb.Expr) error {
sel := expr.GetSelectExpr()
+ return un.visitSelectInternal(sel.GetOperand(), sel.GetTestOnly(), ".", sel.GetField())
+}
+
+func (un *unparser) visitSelectInternal(operand *exprpb.Expr, testOnly bool, op string, field string) error {
// handle the case when the select expression was generated by the has() macro.
- if sel.GetTestOnly() {
+ if testOnly {
un.str.WriteString("has(")
}
- nested := !sel.GetTestOnly() && isBinaryOrTernaryOperator(sel.GetOperand())
- err := un.visitMaybeNested(sel.GetOperand(), nested)
+ nested := !testOnly && isBinaryOrTernaryOperator(operand)
+ err := un.visitMaybeNested(operand, nested)
if err != nil {
return err
}
- un.str.WriteString(".")
- un.str.WriteString(sel.GetField())
- if sel.GetTestOnly() {
+ un.str.WriteString(op)
+ un.str.WriteString(field)
+ if testOnly {
un.str.WriteString(")")
}
return nil
@@ -339,6 +375,9 @@ func (un *unparser) visitStructMsg(expr *exprpb.Expr) error {
un.str.WriteString("{")
for i, entry := range entries {
f := entry.GetFieldKey()
+ if entry.GetOptionalEntry() {
+ un.str.WriteString("?")
+ }
un.str.WriteString(f)
un.str.WriteString(": ")
v := entry.GetValue()
@@ -360,6 +399,9 @@ func (un *unparser) visitStructMap(expr *exprpb.Expr) error {
un.str.WriteString("{")
for i, entry := range entries {
k := entry.GetMapKey()
+ if entry.GetOptionalEntry() {
+ un.str.WriteString("?")
+ }
err := un.visit(k)
if err != nil {
return err
@@ -492,11 +534,10 @@ func (un *unparser) writeOperatorWithWrapping(fun string, unmangled string) bool
un.str.WriteString(" ")
}
return true
- } else {
- un.str.WriteString(" ")
- un.str.WriteString(unmangled)
- un.str.WriteString(" ")
}
+ un.str.WriteString(" ")
+ un.str.WriteString(unmangled)
+ un.str.WriteString(" ")
return false
}
diff --git a/vendor/github.com/google/gnostic/LICENSE b/vendor/github.com/google/gnostic-models/LICENSE
similarity index 100%
rename from vendor/github.com/google/gnostic/LICENSE
rename to vendor/github.com/google/gnostic-models/LICENSE
diff --git a/vendor/github.com/google/gnostic/compiler/README.md b/vendor/github.com/google/gnostic-models/compiler/README.md
similarity index 100%
rename from vendor/github.com/google/gnostic/compiler/README.md
rename to vendor/github.com/google/gnostic-models/compiler/README.md
diff --git a/vendor/github.com/google/gnostic/compiler/context.go b/vendor/github.com/google/gnostic-models/compiler/context.go
similarity index 100%
rename from vendor/github.com/google/gnostic/compiler/context.go
rename to vendor/github.com/google/gnostic-models/compiler/context.go
diff --git a/vendor/github.com/google/gnostic/compiler/error.go b/vendor/github.com/google/gnostic-models/compiler/error.go
similarity index 100%
rename from vendor/github.com/google/gnostic/compiler/error.go
rename to vendor/github.com/google/gnostic-models/compiler/error.go
diff --git a/vendor/github.com/google/gnostic/compiler/extensions.go b/vendor/github.com/google/gnostic-models/compiler/extensions.go
similarity index 97%
rename from vendor/github.com/google/gnostic/compiler/extensions.go
rename to vendor/github.com/google/gnostic-models/compiler/extensions.go
index 5b5a916d2e..250c81e8c8 100644
--- a/vendor/github.com/google/gnostic/compiler/extensions.go
+++ b/vendor/github.com/google/gnostic-models/compiler/extensions.go
@@ -24,7 +24,7 @@ import (
"github.com/golang/protobuf/ptypes/any"
yaml "gopkg.in/yaml.v3"
- extensions "github.com/google/gnostic/extensions"
+ extensions "github.com/google/gnostic-models/extensions"
)
// ExtensionHandler describes a binary that is called by the compiler to handle specification extensions.
diff --git a/vendor/github.com/google/gnostic/compiler/helpers.go b/vendor/github.com/google/gnostic-models/compiler/helpers.go
similarity index 99%
rename from vendor/github.com/google/gnostic/compiler/helpers.go
rename to vendor/github.com/google/gnostic-models/compiler/helpers.go
index 97ffaa5131..975d65e8f8 100644
--- a/vendor/github.com/google/gnostic/compiler/helpers.go
+++ b/vendor/github.com/google/gnostic-models/compiler/helpers.go
@@ -22,7 +22,7 @@ import (
"gopkg.in/yaml.v3"
- "github.com/google/gnostic/jsonschema"
+ "github.com/google/gnostic-models/jsonschema"
)
// compiler helper functions, usually called from generated code
diff --git a/vendor/github.com/google/gnostic/compiler/main.go b/vendor/github.com/google/gnostic-models/compiler/main.go
similarity index 100%
rename from vendor/github.com/google/gnostic/compiler/main.go
rename to vendor/github.com/google/gnostic-models/compiler/main.go
diff --git a/vendor/github.com/google/gnostic/compiler/reader.go b/vendor/github.com/google/gnostic-models/compiler/reader.go
similarity index 100%
rename from vendor/github.com/google/gnostic/compiler/reader.go
rename to vendor/github.com/google/gnostic-models/compiler/reader.go
diff --git a/vendor/github.com/google/gnostic/extensions/README.md b/vendor/github.com/google/gnostic-models/extensions/README.md
similarity index 100%
rename from vendor/github.com/google/gnostic/extensions/README.md
rename to vendor/github.com/google/gnostic-models/extensions/README.md
diff --git a/vendor/github.com/google/gnostic/extensions/extension.pb.go b/vendor/github.com/google/gnostic-models/extensions/extension.pb.go
similarity index 99%
rename from vendor/github.com/google/gnostic/extensions/extension.pb.go
rename to vendor/github.com/google/gnostic-models/extensions/extension.pb.go
index a6a4ccca6c..a71df8abec 100644
--- a/vendor/github.com/google/gnostic/extensions/extension.pb.go
+++ b/vendor/github.com/google/gnostic-models/extensions/extension.pb.go
@@ -14,8 +14,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.26.0
-// protoc v3.18.1
+// protoc-gen-go v1.27.1
+// protoc v3.19.3
// source: extensions/extension.proto
package gnostic_extension_v1
diff --git a/vendor/github.com/google/gnostic/extensions/extension.proto b/vendor/github.com/google/gnostic-models/extensions/extension.proto
similarity index 100%
rename from vendor/github.com/google/gnostic/extensions/extension.proto
rename to vendor/github.com/google/gnostic-models/extensions/extension.proto
diff --git a/vendor/github.com/google/gnostic/extensions/extensions.go b/vendor/github.com/google/gnostic-models/extensions/extensions.go
similarity index 100%
rename from vendor/github.com/google/gnostic/extensions/extensions.go
rename to vendor/github.com/google/gnostic-models/extensions/extensions.go
diff --git a/vendor/github.com/google/gnostic/jsonschema/README.md b/vendor/github.com/google/gnostic-models/jsonschema/README.md
similarity index 100%
rename from vendor/github.com/google/gnostic/jsonschema/README.md
rename to vendor/github.com/google/gnostic-models/jsonschema/README.md
diff --git a/vendor/github.com/google/gnostic/jsonschema/base.go b/vendor/github.com/google/gnostic-models/jsonschema/base.go
similarity index 90%
rename from vendor/github.com/google/gnostic/jsonschema/base.go
rename to vendor/github.com/google/gnostic-models/jsonschema/base.go
index 0af8b148b9..5fcc4885a0 100644
--- a/vendor/github.com/google/gnostic/jsonschema/base.go
+++ b/vendor/github.com/google/gnostic-models/jsonschema/base.go
@@ -1,3 +1,16 @@
+// Copyright 2017 Google LLC. All Rights Reserved.
+//
+// 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.
// THIS FILE IS AUTOMATICALLY GENERATED.
@@ -81,4 +94,4 @@ YXkiIH0sCiAgICAgICAgImFueU9mIjogeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3NjaGVtYUFycmF5
IiB9LAogICAgICAgICJvbmVPZiI6IHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9zY2hlbWFBcnJheSIg
fSwKICAgICAgICAibm90IjogeyAiJHJlZiI6ICIjIiB9CiAgICB9LAogICAgImRlcGVuZGVuY2llcyI6
IHsKICAgICAgICAiZXhjbHVzaXZlTWF4aW11bSI6IFsgIm1heGltdW0iIF0sCiAgICAgICAgImV4Y2x1
-c2l2ZU1pbmltdW0iOiBbICJtaW5pbXVtIiBdCiAgICB9LAogICAgImRlZmF1bHQiOiB7fQp9Cg==`)}
\ No newline at end of file
+c2l2ZU1pbmltdW0iOiBbICJtaW5pbXVtIiBdCiAgICB9LAogICAgImRlZmF1bHQiOiB7fQp9Cg==`)}
diff --git a/vendor/github.com/google/gnostic/jsonschema/display.go b/vendor/github.com/google/gnostic-models/jsonschema/display.go
similarity index 100%
rename from vendor/github.com/google/gnostic/jsonschema/display.go
rename to vendor/github.com/google/gnostic-models/jsonschema/display.go
diff --git a/vendor/github.com/google/gnostic/jsonschema/models.go b/vendor/github.com/google/gnostic-models/jsonschema/models.go
similarity index 100%
rename from vendor/github.com/google/gnostic/jsonschema/models.go
rename to vendor/github.com/google/gnostic-models/jsonschema/models.go
diff --git a/vendor/github.com/google/gnostic/jsonschema/operations.go b/vendor/github.com/google/gnostic-models/jsonschema/operations.go
similarity index 100%
rename from vendor/github.com/google/gnostic/jsonschema/operations.go
rename to vendor/github.com/google/gnostic-models/jsonschema/operations.go
diff --git a/vendor/github.com/google/gnostic/jsonschema/reader.go b/vendor/github.com/google/gnostic-models/jsonschema/reader.go
similarity index 100%
rename from vendor/github.com/google/gnostic/jsonschema/reader.go
rename to vendor/github.com/google/gnostic-models/jsonschema/reader.go
diff --git a/vendor/github.com/google/gnostic/jsonschema/schema.json b/vendor/github.com/google/gnostic-models/jsonschema/schema.json
similarity index 100%
rename from vendor/github.com/google/gnostic/jsonschema/schema.json
rename to vendor/github.com/google/gnostic-models/jsonschema/schema.json
diff --git a/vendor/github.com/google/gnostic/jsonschema/writer.go b/vendor/github.com/google/gnostic-models/jsonschema/writer.go
similarity index 100%
rename from vendor/github.com/google/gnostic/jsonschema/writer.go
rename to vendor/github.com/google/gnostic-models/jsonschema/writer.go
diff --git a/vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.go b/vendor/github.com/google/gnostic-models/openapiv2/OpenAPIv2.go
similarity index 99%
rename from vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.go
rename to vendor/github.com/google/gnostic-models/openapiv2/OpenAPIv2.go
index 0f17907667..d71fe6d545 100644
--- a/vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.go
+++ b/vendor/github.com/google/gnostic-models/openapiv2/OpenAPIv2.go
@@ -23,7 +23,7 @@ import (
"gopkg.in/yaml.v3"
- "github.com/google/gnostic/compiler"
+ "github.com/google/gnostic-models/compiler"
)
// Version returns the package name (and OpenAPI version).
diff --git a/vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.pb.go b/vendor/github.com/google/gnostic-models/openapiv2/OpenAPIv2.pb.go
similarity index 99%
rename from vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.pb.go
rename to vendor/github.com/google/gnostic-models/openapiv2/OpenAPIv2.pb.go
index 06b60157c1..65c4c913ce 100644
--- a/vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.pb.go
+++ b/vendor/github.com/google/gnostic-models/openapiv2/OpenAPIv2.pb.go
@@ -16,8 +16,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.26.0
-// protoc v3.18.1
+// protoc-gen-go v1.27.1
+// protoc v3.19.3
// source: openapiv2/OpenAPIv2.proto
package openapi_v2
diff --git a/vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.proto b/vendor/github.com/google/gnostic-models/openapiv2/OpenAPIv2.proto
similarity index 100%
rename from vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.proto
rename to vendor/github.com/google/gnostic-models/openapiv2/OpenAPIv2.proto
diff --git a/vendor/github.com/google/gnostic/openapiv2/README.md b/vendor/github.com/google/gnostic-models/openapiv2/README.md
similarity index 100%
rename from vendor/github.com/google/gnostic/openapiv2/README.md
rename to vendor/github.com/google/gnostic-models/openapiv2/README.md
diff --git a/vendor/github.com/google/gnostic/openapiv2/document.go b/vendor/github.com/google/gnostic-models/openapiv2/document.go
similarity index 96%
rename from vendor/github.com/google/gnostic/openapiv2/document.go
rename to vendor/github.com/google/gnostic-models/openapiv2/document.go
index 0021ae871a..e96ac0d6da 100644
--- a/vendor/github.com/google/gnostic/openapiv2/document.go
+++ b/vendor/github.com/google/gnostic-models/openapiv2/document.go
@@ -17,7 +17,7 @@ package openapi_v2
import (
"gopkg.in/yaml.v3"
- "github.com/google/gnostic/compiler"
+ "github.com/google/gnostic-models/compiler"
)
// ParseDocument reads an OpenAPI v2 description from a YAML/JSON representation.
diff --git a/vendor/github.com/google/gnostic/openapiv2/openapi-2.0.json b/vendor/github.com/google/gnostic-models/openapiv2/openapi-2.0.json
similarity index 100%
rename from vendor/github.com/google/gnostic/openapiv2/openapi-2.0.json
rename to vendor/github.com/google/gnostic-models/openapiv2/openapi-2.0.json
diff --git a/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.go b/vendor/github.com/google/gnostic-models/openapiv3/OpenAPIv3.go
similarity index 99%
rename from vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.go
rename to vendor/github.com/google/gnostic-models/openapiv3/OpenAPIv3.go
index 5f4a7025ea..4b1131ce1c 100644
--- a/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.go
+++ b/vendor/github.com/google/gnostic-models/openapiv3/OpenAPIv3.go
@@ -23,7 +23,7 @@ import (
"gopkg.in/yaml.v3"
- "github.com/google/gnostic/compiler"
+ "github.com/google/gnostic-models/compiler"
)
// Version returns the package name (and OpenAPI version).
diff --git a/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.pb.go b/vendor/github.com/google/gnostic-models/openapiv3/OpenAPIv3.pb.go
similarity index 99%
rename from vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.pb.go
rename to vendor/github.com/google/gnostic-models/openapiv3/OpenAPIv3.pb.go
index 499e7f932d..945b8d11ff 100644
--- a/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.pb.go
+++ b/vendor/github.com/google/gnostic-models/openapiv3/OpenAPIv3.pb.go
@@ -16,8 +16,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.26.0
-// protoc v3.18.1
+// protoc-gen-go v1.27.1
+// protoc v3.19.3
// source: openapiv3/OpenAPIv3.proto
package openapi_v3
diff --git a/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.proto b/vendor/github.com/google/gnostic-models/openapiv3/OpenAPIv3.proto
similarity index 100%
rename from vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.proto
rename to vendor/github.com/google/gnostic-models/openapiv3/OpenAPIv3.proto
diff --git a/vendor/github.com/google/gnostic/openapiv3/README.md b/vendor/github.com/google/gnostic-models/openapiv3/README.md
similarity index 100%
rename from vendor/github.com/google/gnostic/openapiv3/README.md
rename to vendor/github.com/google/gnostic-models/openapiv3/README.md
diff --git a/vendor/github.com/google/gnostic/openapiv3/document.go b/vendor/github.com/google/gnostic-models/openapiv3/document.go
similarity index 96%
rename from vendor/github.com/google/gnostic/openapiv3/document.go
rename to vendor/github.com/google/gnostic-models/openapiv3/document.go
index ef10d1d909..1cee467735 100644
--- a/vendor/github.com/google/gnostic/openapiv3/document.go
+++ b/vendor/github.com/google/gnostic-models/openapiv3/document.go
@@ -17,7 +17,7 @@ package openapi_v3
import (
"gopkg.in/yaml.v3"
- "github.com/google/gnostic/compiler"
+ "github.com/google/gnostic-models/compiler"
)
// ParseDocument reads an OpenAPI v3 description from a YAML/JSON representation.
diff --git a/vendor/github.com/google/gnostic/openapiv3/openapi-3.0.json b/vendor/github.com/google/gnostic/openapiv3/openapi-3.0.json
deleted file mode 100644
index d5caed162d..0000000000
--- a/vendor/github.com/google/gnostic/openapiv3/openapi-3.0.json
+++ /dev/null
@@ -1,1251 +0,0 @@
-{
- "title": "A JSON Schema for OpenAPI 3.0.",
- "id": "http://openapis.org/v3/schema.json#",
- "$schema": "http://json-schema.org/draft-04/schema#",
- "type": "object",
- "description": "This is the root document object of the OpenAPI document.",
- "required": [
- "openapi",
- "info",
- "paths"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "openapi": {
- "type": "string"
- },
- "info": {
- "$ref": "#/definitions/info"
- },
- "servers": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/server"
- },
- "uniqueItems": true
- },
- "paths": {
- "$ref": "#/definitions/paths"
- },
- "components": {
- "$ref": "#/definitions/components"
- },
- "security": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/securityRequirement"
- },
- "uniqueItems": true
- },
- "tags": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/tag"
- },
- "uniqueItems": true
- },
- "externalDocs": {
- "$ref": "#/definitions/externalDocs"
- }
- },
- "definitions": {
- "info": {
- "type": "object",
- "description": "The object provides metadata about the API. The metadata MAY be used by the clients if needed, and MAY be presented in editing or documentation generation tools for convenience.",
- "required": [
- "title",
- "version"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "title": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "termsOfService": {
- "type": "string"
- },
- "contact": {
- "$ref": "#/definitions/contact"
- },
- "license": {
- "$ref": "#/definitions/license"
- },
- "version": {
- "type": "string"
- }
- }
- },
- "contact": {
- "type": "object",
- "description": "Contact information for the exposed API.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "name": {
- "type": "string"
- },
- "url": {
- "type": "string",
- "format": "uri"
- },
- "email": {
- "type": "string",
- "format": "email"
- }
- }
- },
- "license": {
- "type": "object",
- "description": "License information for the exposed API.",
- "required": [
- "name"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "name": {
- "type": "string"
- },
- "url": {
- "type": "string"
- }
- }
- },
- "server": {
- "type": "object",
- "description": "An object representing a Server.",
- "required": [
- "url"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "url": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "variables": {
- "$ref": "#/definitions/serverVariables"
- }
- }
- },
- "serverVariable": {
- "type": "object",
- "description": "An object representing a Server Variable for server URL template substitution.",
- "required": [
- "default"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "enum": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "uniqueItems": true
- },
- "default": {
- "type": "string"
- },
- "description": {
- "type": "string"
- }
- }
- },
- "components": {
- "type": "object",
- "description": "Holds a set of reusable objects for different aspects of the OAS. All objects defined within the components object will have no effect on the API unless they are explicitly referenced from properties outside the components object.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "schemas": {
- "$ref": "#/definitions/schemasOrReferences"
- },
- "responses": {
- "$ref": "#/definitions/responsesOrReferences"
- },
- "parameters": {
- "$ref": "#/definitions/parametersOrReferences"
- },
- "examples": {
- "$ref": "#/definitions/examplesOrReferences"
- },
- "requestBodies": {
- "$ref": "#/definitions/requestBodiesOrReferences"
- },
- "headers": {
- "$ref": "#/definitions/headersOrReferences"
- },
- "securitySchemes": {
- "$ref": "#/definitions/securitySchemesOrReferences"
- },
- "links": {
- "$ref": "#/definitions/linksOrReferences"
- },
- "callbacks": {
- "$ref": "#/definitions/callbacksOrReferences"
- }
- }
- },
- "paths": {
- "type": "object",
- "description": "Holds the relative paths to the individual endpoints and their operations. The path is appended to the URL from the `Server Object` in order to construct the full URL. The Paths MAY be empty, due to ACL constraints.",
- "additionalProperties": false,
- "patternProperties": {
- "^/": {
- "$ref": "#/definitions/pathItem"
- },
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- }
- },
- "pathItem": {
- "type": "object",
- "description": "Describes the operations available on a single path. A Path Item MAY be empty, due to ACL constraints. The path itself is still exposed to the documentation viewer but they will not know which operations and parameters are available.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "$ref": {
- "type": "string"
- },
- "summary": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "get": {
- "$ref": "#/definitions/operation"
- },
- "put": {
- "$ref": "#/definitions/operation"
- },
- "post": {
- "$ref": "#/definitions/operation"
- },
- "delete": {
- "$ref": "#/definitions/operation"
- },
- "options": {
- "$ref": "#/definitions/operation"
- },
- "head": {
- "$ref": "#/definitions/operation"
- },
- "patch": {
- "$ref": "#/definitions/operation"
- },
- "trace": {
- "$ref": "#/definitions/operation"
- },
- "servers": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/server"
- },
- "uniqueItems": true
- },
- "parameters": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/parameterOrReference"
- },
- "uniqueItems": true
- }
- }
- },
- "operation": {
- "type": "object",
- "description": "Describes a single API operation on a path.",
- "required": [
- "responses"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "tags": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "uniqueItems": true
- },
- "summary": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "externalDocs": {
- "$ref": "#/definitions/externalDocs"
- },
- "operationId": {
- "type": "string"
- },
- "parameters": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/parameterOrReference"
- },
- "uniqueItems": true
- },
- "requestBody": {
- "$ref": "#/definitions/requestBodyOrReference"
- },
- "responses": {
- "$ref": "#/definitions/responses"
- },
- "callbacks": {
- "$ref": "#/definitions/callbacksOrReferences"
- },
- "deprecated": {
- "type": "boolean"
- },
- "security": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/securityRequirement"
- },
- "uniqueItems": true
- },
- "servers": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/server"
- },
- "uniqueItems": true
- }
- }
- },
- "externalDocs": {
- "type": "object",
- "description": "Allows referencing an external resource for extended documentation.",
- "required": [
- "url"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "description": {
- "type": "string"
- },
- "url": {
- "type": "string"
- }
- }
- },
- "parameter": {
- "type": "object",
- "description": "Describes a single operation parameter. A unique parameter is defined by a combination of a name and location.",
- "required": [
- "name",
- "in"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "name": {
- "type": "string"
- },
- "in": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "required": {
- "type": "boolean"
- },
- "deprecated": {
- "type": "boolean"
- },
- "allowEmptyValue": {
- "type": "boolean"
- },
- "style": {
- "type": "string"
- },
- "explode": {
- "type": "boolean"
- },
- "allowReserved": {
- "type": "boolean"
- },
- "schema": {
- "$ref": "#/definitions/schemaOrReference"
- },
- "example": {
- "$ref": "#/definitions/any"
- },
- "examples": {
- "$ref": "#/definitions/examplesOrReferences"
- },
- "content": {
- "$ref": "#/definitions/mediaTypes"
- }
- }
- },
- "requestBody": {
- "type": "object",
- "description": "Describes a single request body.",
- "required": [
- "content"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "description": {
- "type": "string"
- },
- "content": {
- "$ref": "#/definitions/mediaTypes"
- },
- "required": {
- "type": "boolean"
- }
- }
- },
- "mediaType": {
- "type": "object",
- "description": "Each Media Type Object provides schema and examples for the media type identified by its key.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "schema": {
- "$ref": "#/definitions/schemaOrReference"
- },
- "example": {
- "$ref": "#/definitions/any"
- },
- "examples": {
- "$ref": "#/definitions/examplesOrReferences"
- },
- "encoding": {
- "$ref": "#/definitions/encodings"
- }
- }
- },
- "encoding": {
- "type": "object",
- "description": "A single encoding definition applied to a single schema property.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "contentType": {
- "type": "string"
- },
- "headers": {
- "$ref": "#/definitions/headersOrReferences"
- },
- "style": {
- "type": "string"
- },
- "explode": {
- "type": "boolean"
- },
- "allowReserved": {
- "type": "boolean"
- }
- }
- },
- "responses": {
- "type": "object",
- "description": "A container for the expected responses of an operation. The container maps a HTTP response code to the expected response. The documentation is not necessarily expected to cover all possible HTTP response codes because they may not be known in advance. However, documentation is expected to cover a successful operation response and any known errors. The `default` MAY be used as a default response object for all HTTP codes that are not covered individually by the specification. The `Responses Object` MUST contain at least one response code, and it SHOULD be the response for a successful operation call.",
- "additionalProperties": false,
- "patternProperties": {
- "^([0-9X]{3})$": {
- "$ref": "#/definitions/responseOrReference"
- },
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "default": {
- "$ref": "#/definitions/responseOrReference"
- }
- }
- },
- "response": {
- "type": "object",
- "description": "Describes a single response from an API Operation, including design-time, static `links` to operations based on the response.",
- "required": [
- "description"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "description": {
- "type": "string"
- },
- "headers": {
- "$ref": "#/definitions/headersOrReferences"
- },
- "content": {
- "$ref": "#/definitions/mediaTypes"
- },
- "links": {
- "$ref": "#/definitions/linksOrReferences"
- }
- }
- },
- "callback": {
- "type": "object",
- "description": "A map of possible out-of band callbacks related to the parent operation. Each value in the map is a Path Item Object that describes a set of requests that may be initiated by the API provider and the expected responses. The key value used to identify the callback object is an expression, evaluated at runtime, that identifies a URL to use for the callback operation.",
- "additionalProperties": false,
- "patternProperties": {
- "^": {
- "$ref": "#/definitions/pathItem"
- },
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- }
- },
- "example": {
- "type": "object",
- "description": "",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "summary": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "value": {
- "$ref": "#/definitions/any"
- },
- "externalValue": {
- "type": "string"
- }
- }
- },
- "link": {
- "type": "object",
- "description": "The `Link object` represents a possible design-time link for a response. The presence of a link does not guarantee the caller's ability to successfully invoke it, rather it provides a known relationship and traversal mechanism between responses and other operations. Unlike _dynamic_ links (i.e. links provided **in** the response payload), the OAS linking mechanism does not require link information in the runtime response. For computing links, and providing instructions to execute them, a runtime expression is used for accessing values in an operation and using them as parameters while invoking the linked operation.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "operationRef": {
- "type": "string"
- },
- "operationId": {
- "type": "string"
- },
- "parameters": {
- "$ref": "#/definitions/anysOrExpressions"
- },
- "requestBody": {
- "$ref": "#/definitions/anyOrExpression"
- },
- "description": {
- "type": "string"
- },
- "server": {
- "$ref": "#/definitions/server"
- }
- }
- },
- "header": {
- "type": "object",
- "description": "The Header Object follows the structure of the Parameter Object with the following changes: 1. `name` MUST NOT be specified, it is given in the corresponding `headers` map. 1. `in` MUST NOT be specified, it is implicitly in `header`. 1. All traits that are affected by the location MUST be applicable to a location of `header` (for example, `style`).",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "description": {
- "type": "string"
- },
- "required": {
- "type": "boolean"
- },
- "deprecated": {
- "type": "boolean"
- },
- "allowEmptyValue": {
- "type": "boolean"
- },
- "style": {
- "type": "string"
- },
- "explode": {
- "type": "boolean"
- },
- "allowReserved": {
- "type": "boolean"
- },
- "schema": {
- "$ref": "#/definitions/schemaOrReference"
- },
- "example": {
- "$ref": "#/definitions/any"
- },
- "examples": {
- "$ref": "#/definitions/examplesOrReferences"
- },
- "content": {
- "$ref": "#/definitions/mediaTypes"
- }
- }
- },
- "tag": {
- "type": "object",
- "description": "Adds metadata to a single tag that is used by the Operation Object. It is not mandatory to have a Tag Object per tag defined in the Operation Object instances.",
- "required": [
- "name"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "name": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "externalDocs": {
- "$ref": "#/definitions/externalDocs"
- }
- }
- },
- "reference": {
- "type": "object",
- "description": "A simple object to allow referencing other components in the specification, internally and externally. The Reference Object is defined by JSON Reference and follows the same structure, behavior and rules. For this specification, reference resolution is accomplished as defined by the JSON Reference specification and not by the JSON Schema specification.",
- "required": [
- "$ref"
- ],
- "additionalProperties": false,
- "properties": {
- "$ref": {
- "type": "string"
- },
- "summary": {
- "type": "string"
- },
- "description": {
- "type": "string"
- }
- }
- },
- "schema": {
- "type": "object",
- "description": "The Schema Object allows the definition of input and output data types. These types can be objects, but also primitives and arrays. This object is an extended subset of the JSON Schema Specification Wright Draft 00. For more information about the properties, see JSON Schema Core and JSON Schema Validation. Unless stated otherwise, the property definitions follow the JSON Schema.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "nullable": {
- "type": "boolean"
- },
- "discriminator": {
- "$ref": "#/definitions/discriminator"
- },
- "readOnly": {
- "type": "boolean"
- },
- "writeOnly": {
- "type": "boolean"
- },
- "xml": {
- "$ref": "#/definitions/xml"
- },
- "externalDocs": {
- "$ref": "#/definitions/externalDocs"
- },
- "example": {
- "$ref": "#/definitions/any"
- },
- "deprecated": {
- "type": "boolean"
- },
- "title": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/title"
- },
- "multipleOf": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/multipleOf"
- },
- "maximum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/maximum"
- },
- "exclusiveMaximum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/exclusiveMaximum"
- },
- "minimum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/minimum"
- },
- "exclusiveMinimum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/exclusiveMinimum"
- },
- "maxLength": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/maxLength"
- },
- "minLength": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/minLength"
- },
- "pattern": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/pattern"
- },
- "maxItems": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/maxItems"
- },
- "minItems": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/minItems"
- },
- "uniqueItems": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/uniqueItems"
- },
- "maxProperties": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/maxProperties"
- },
- "minProperties": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/minProperties"
- },
- "required": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/required"
- },
- "enum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/enum"
- },
- "type": {
- "type": "string"
- },
- "allOf": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/schemaOrReference"
- },
- "minItems": 1
- },
- "oneOf": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/schemaOrReference"
- },
- "minItems": 1
- },
- "anyOf": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/schemaOrReference"
- },
- "minItems": 1
- },
- "not": {
- "$ref": "#/definitions/schema"
- },
- "items": {
- "anyOf": [
- {
- "$ref": "#/definitions/schemaOrReference"
- },
- {
- "type": "array",
- "items": {
- "$ref": "#/definitions/schemaOrReference"
- },
- "minItems": 1
- }
- ]
- },
- "properties": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/schemaOrReference"
- }
- },
- "additionalProperties": {
- "oneOf": [
- {
- "$ref": "#/definitions/schemaOrReference"
- },
- {
- "type": "boolean"
- }
- ]
- },
- "default": {
- "$ref": "#/definitions/defaultType"
- },
- "description": {
- "type": "string"
- },
- "format": {
- "type": "string"
- }
- }
- },
- "discriminator": {
- "type": "object",
- "description": "When request bodies or response payloads may be one of a number of different schemas, a `discriminator` object can be used to aid in serialization, deserialization, and validation. The discriminator is a specific object in a schema which is used to inform the consumer of the specification of an alternative schema based on the value associated with it. When using the discriminator, _inline_ schemas will not be considered.",
- "required": [
- "propertyName"
- ],
- "additionalProperties": false,
- "properties": {
- "propertyName": {
- "type": "string"
- },
- "mapping": {
- "$ref": "#/definitions/strings"
- }
- }
- },
- "xml": {
- "type": "object",
- "description": "A metadata object that allows for more fine-tuned XML model definitions. When using arrays, XML element names are *not* inferred (for singular/plural forms) and the `name` property SHOULD be used to add that information. See examples for expected behavior.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "name": {
- "type": "string"
- },
- "namespace": {
- "type": "string"
- },
- "prefix": {
- "type": "string"
- },
- "attribute": {
- "type": "boolean"
- },
- "wrapped": {
- "type": "boolean"
- }
- }
- },
- "securityScheme": {
- "type": "object",
- "description": "Defines a security scheme that can be used by the operations. Supported schemes are HTTP authentication, an API key (either as a header or as a query parameter), OAuth2's common flows (implicit, password, application and access code) as defined in RFC6749, and OpenID Connect Discovery.",
- "required": [
- "type"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "type": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "name": {
- "type": "string"
- },
- "in": {
- "type": "string"
- },
- "scheme": {
- "type": "string"
- },
- "bearerFormat": {
- "type": "string"
- },
- "flows": {
- "$ref": "#/definitions/oauthFlows"
- },
- "openIdConnectUrl": {
- "type": "string"
- }
- }
- },
- "oauthFlows": {
- "type": "object",
- "description": "Allows configuration of the supported OAuth Flows.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "implicit": {
- "$ref": "#/definitions/oauthFlow"
- },
- "password": {
- "$ref": "#/definitions/oauthFlow"
- },
- "clientCredentials": {
- "$ref": "#/definitions/oauthFlow"
- },
- "authorizationCode": {
- "$ref": "#/definitions/oauthFlow"
- }
- }
- },
- "oauthFlow": {
- "type": "object",
- "description": "Configuration details for a supported OAuth Flow",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "authorizationUrl": {
- "type": "string"
- },
- "tokenUrl": {
- "type": "string"
- },
- "refreshUrl": {
- "type": "string"
- },
- "scopes": {
- "$ref": "#/definitions/strings"
- }
- }
- },
- "securityRequirement": {
- "type": "object",
- "description": "Lists the required security schemes to execute this operation. The name used for each property MUST correspond to a security scheme declared in the Security Schemes under the Components Object. Security Requirement Objects that contain multiple schemes require that all schemes MUST be satisfied for a request to be authorized. This enables support for scenarios where multiple query parameters or HTTP headers are required to convey security information. When a list of Security Requirement Objects is defined on the Open API object or Operation Object, only one of Security Requirement Objects in the list needs to be satisfied to authorize the request.",
- "additionalProperties": false,
- "patternProperties": {
- "^[a-zA-Z0-9\\.\\-_]+$": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "uniqueItems": true
- }
- }
- },
- "anyOrExpression": {
- "oneOf": [
- {
- "$ref": "#/definitions/any"
- },
- {
- "$ref": "#/definitions/expression"
- }
- ]
- },
- "callbackOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/callback"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "exampleOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/example"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "headerOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/header"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "linkOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/link"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "parameterOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/parameter"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "requestBodyOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/requestBody"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "responseOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/response"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "schemaOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/schema"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "securitySchemeOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/securityScheme"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "anysOrExpressions": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/anyOrExpression"
- }
- },
- "callbacksOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/callbackOrReference"
- }
- },
- "encodings": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/encoding"
- }
- },
- "examplesOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/exampleOrReference"
- }
- },
- "headersOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/headerOrReference"
- }
- },
- "linksOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/linkOrReference"
- }
- },
- "mediaTypes": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/mediaType"
- }
- },
- "parametersOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/parameterOrReference"
- }
- },
- "requestBodiesOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/requestBodyOrReference"
- }
- },
- "responsesOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/responseOrReference"
- }
- },
- "schemasOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/schemaOrReference"
- }
- },
- "securitySchemesOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/securitySchemeOrReference"
- }
- },
- "serverVariables": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/serverVariable"
- }
- },
- "strings": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
- },
- "object": {
- "type": "object",
- "additionalProperties": true
- },
- "any": {
- "additionalProperties": true
- },
- "expression": {
- "type": "object",
- "additionalProperties": true
- },
- "specificationExtension": {
- "description": "Any property starting with x- is valid.",
- "oneOf": [
- {
- "type": "null"
- },
- {
- "type": "number"
- },
- {
- "type": "boolean"
- },
- {
- "type": "string"
- },
- {
- "type": "object"
- },
- {
- "type": "array"
- }
- ]
- },
- "defaultType": {
- "oneOf": [
- {
- "type": "null"
- },
- {
- "type": "array"
- },
- {
- "type": "object"
- },
- {
- "type": "number"
- },
- {
- "type": "boolean"
- },
- {
- "type": "string"
- }
- ]
- }
- }
-}
diff --git a/vendor/github.com/google/gnostic/openapiv3/openapi-3.1.json b/vendor/github.com/google/gnostic/openapiv3/openapi-3.1.json
deleted file mode 100644
index ed0b83adf4..0000000000
--- a/vendor/github.com/google/gnostic/openapiv3/openapi-3.1.json
+++ /dev/null
@@ -1,1250 +0,0 @@
-{
- "title": "A JSON Schema for OpenAPI 3.0.",
- "id": "http://openapis.org/v3/schema.json#",
- "$schema": "http://json-schema.org/draft-04/schema#",
- "type": "object",
- "description": "This is the root document object of the OpenAPI document.",
- "required": [
- "openapi",
- "info",
- "paths"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "openapi": {
- "type": "string"
- },
- "info": {
- "$ref": "#/definitions/info"
- },
- "servers": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/server"
- },
- "uniqueItems": true
- },
- "paths": {
- "$ref": "#/definitions/paths"
- },
- "components": {
- "$ref": "#/definitions/components"
- },
- "security": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/securityRequirement"
- },
- "uniqueItems": true
- },
- "tags": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/tag"
- },
- "uniqueItems": true
- },
- "externalDocs": {
- "$ref": "#/definitions/externalDocs"
- }
- },
- "definitions": {
- "info": {
- "type": "object",
- "description": "The object provides metadata about the API. The metadata MAY be used by the clients if needed, and MAY be presented in editing or documentation generation tools for convenience.",
- "required": [
- "title",
- "version"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "title": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "termsOfService": {
- "type": "string"
- },
- "contact": {
- "$ref": "#/definitions/contact"
- },
- "license": {
- "$ref": "#/definitions/license"
- },
- "version": {
- "type": "string"
- },
- "summary": {
- "type": "string"
- }
- }
- },
- "contact": {
- "type": "object",
- "description": "Contact information for the exposed API.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "name": {
- "type": "string"
- },
- "url": {
- "type": "string",
- "format": "uri"
- },
- "email": {
- "type": "string",
- "format": "email"
- }
- }
- },
- "license": {
- "type": "object",
- "description": "License information for the exposed API.",
- "required": [
- "name"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "name": {
- "type": "string"
- },
- "url": {
- "type": "string"
- }
- }
- },
- "server": {
- "type": "object",
- "description": "An object representing a Server.",
- "required": [
- "url"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "url": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "variables": {
- "$ref": "#/definitions/serverVariables"
- }
- }
- },
- "serverVariable": {
- "type": "object",
- "description": "An object representing a Server Variable for server URL template substitution.",
- "required": [
- "default"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "enum": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "uniqueItems": true
- },
- "default": {
- "type": "string"
- },
- "description": {
- "type": "string"
- }
- }
- },
- "components": {
- "type": "object",
- "description": "Holds a set of reusable objects for different aspects of the OAS. All objects defined within the components object will have no effect on the API unless they are explicitly referenced from properties outside the components object.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "schemas": {
- "$ref": "#/definitions/schemasOrReferences"
- },
- "responses": {
- "$ref": "#/definitions/responsesOrReferences"
- },
- "parameters": {
- "$ref": "#/definitions/parametersOrReferences"
- },
- "examples": {
- "$ref": "#/definitions/examplesOrReferences"
- },
- "requestBodies": {
- "$ref": "#/definitions/requestBodiesOrReferences"
- },
- "headers": {
- "$ref": "#/definitions/headersOrReferences"
- },
- "securitySchemes": {
- "$ref": "#/definitions/securitySchemesOrReferences"
- },
- "links": {
- "$ref": "#/definitions/linksOrReferences"
- },
- "callbacks": {
- "$ref": "#/definitions/callbacksOrReferences"
- }
- }
- },
- "paths": {
- "type": "object",
- "description": "Holds the relative paths to the individual endpoints and their operations. The path is appended to the URL from the `Server Object` in order to construct the full URL. The Paths MAY be empty, due to ACL constraints.",
- "additionalProperties": false,
- "patternProperties": {
- "^/": {
- "$ref": "#/definitions/pathItem"
- },
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- }
- },
- "pathItem": {
- "type": "object",
- "description": "Describes the operations available on a single path. A Path Item MAY be empty, due to ACL constraints. The path itself is still exposed to the documentation viewer but they will not know which operations and parameters are available.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "$ref": {
- "type": "string"
- },
- "summary": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "get": {
- "$ref": "#/definitions/operation"
- },
- "put": {
- "$ref": "#/definitions/operation"
- },
- "post": {
- "$ref": "#/definitions/operation"
- },
- "delete": {
- "$ref": "#/definitions/operation"
- },
- "options": {
- "$ref": "#/definitions/operation"
- },
- "head": {
- "$ref": "#/definitions/operation"
- },
- "patch": {
- "$ref": "#/definitions/operation"
- },
- "trace": {
- "$ref": "#/definitions/operation"
- },
- "servers": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/server"
- },
- "uniqueItems": true
- },
- "parameters": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/parameterOrReference"
- },
- "uniqueItems": true
- }
- }
- },
- "operation": {
- "type": "object",
- "description": "Describes a single API operation on a path.",
- "required": [
- "responses"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "tags": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "uniqueItems": true
- },
- "summary": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "externalDocs": {
- "$ref": "#/definitions/externalDocs"
- },
- "operationId": {
- "type": "string"
- },
- "parameters": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/parameterOrReference"
- },
- "uniqueItems": true
- },
- "requestBody": {
- "$ref": "#/definitions/requestBodyOrReference"
- },
- "responses": {
- "$ref": "#/definitions/responses"
- },
- "callbacks": {
- "$ref": "#/definitions/callbacksOrReferences"
- },
- "deprecated": {
- "type": "boolean"
- },
- "security": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/securityRequirement"
- },
- "uniqueItems": true
- },
- "servers": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/server"
- },
- "uniqueItems": true
- }
- }
- },
- "externalDocs": {
- "type": "object",
- "description": "Allows referencing an external resource for extended documentation.",
- "required": [
- "url"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "description": {
- "type": "string"
- },
- "url": {
- "type": "string"
- }
- }
- },
- "parameter": {
- "type": "object",
- "description": "Describes a single operation parameter. A unique parameter is defined by a combination of a name and location.",
- "required": [
- "name",
- "in"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "name": {
- "type": "string"
- },
- "in": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "required": {
- "type": "boolean"
- },
- "deprecated": {
- "type": "boolean"
- },
- "allowEmptyValue": {
- "type": "boolean"
- },
- "style": {
- "type": "string"
- },
- "explode": {
- "type": "boolean"
- },
- "allowReserved": {
- "type": "boolean"
- },
- "schema": {
- "$ref": "#/definitions/schemaOrReference"
- },
- "example": {
- "$ref": "#/definitions/any"
- },
- "examples": {
- "$ref": "#/definitions/examplesOrReferences"
- },
- "content": {
- "$ref": "#/definitions/mediaTypes"
- }
- }
- },
- "requestBody": {
- "type": "object",
- "description": "Describes a single request body.",
- "required": [
- "content"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "description": {
- "type": "string"
- },
- "content": {
- "$ref": "#/definitions/mediaTypes"
- },
- "required": {
- "type": "boolean"
- }
- }
- },
- "mediaType": {
- "type": "object",
- "description": "Each Media Type Object provides schema and examples for the media type identified by its key.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "schema": {
- "$ref": "#/definitions/schemaOrReference"
- },
- "example": {
- "$ref": "#/definitions/any"
- },
- "examples": {
- "$ref": "#/definitions/examplesOrReferences"
- },
- "encoding": {
- "$ref": "#/definitions/encodings"
- }
- }
- },
- "encoding": {
- "type": "object",
- "description": "A single encoding definition applied to a single schema property.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "contentType": {
- "type": "string"
- },
- "headers": {
- "$ref": "#/definitions/headersOrReferences"
- },
- "style": {
- "type": "string"
- },
- "explode": {
- "type": "boolean"
- },
- "allowReserved": {
- "type": "boolean"
- }
- }
- },
- "responses": {
- "type": "object",
- "description": "A container for the expected responses of an operation. The container maps a HTTP response code to the expected response. The documentation is not necessarily expected to cover all possible HTTP response codes because they may not be known in advance. However, documentation is expected to cover a successful operation response and any known errors. The `default` MAY be used as a default response object for all HTTP codes that are not covered individually by the specification. The `Responses Object` MUST contain at least one response code, and it SHOULD be the response for a successful operation call.",
- "additionalProperties": false,
- "patternProperties": {
- "^([0-9X]{3})$": {
- "$ref": "#/definitions/responseOrReference"
- },
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "default": {
- "$ref": "#/definitions/responseOrReference"
- }
- }
- },
- "response": {
- "type": "object",
- "description": "Describes a single response from an API Operation, including design-time, static `links` to operations based on the response.",
- "required": [
- "description"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "description": {
- "type": "string"
- },
- "headers": {
- "$ref": "#/definitions/headersOrReferences"
- },
- "content": {
- "$ref": "#/definitions/mediaTypes"
- },
- "links": {
- "$ref": "#/definitions/linksOrReferences"
- }
- }
- },
- "callback": {
- "type": "object",
- "description": "A map of possible out-of band callbacks related to the parent operation. Each value in the map is a Path Item Object that describes a set of requests that may be initiated by the API provider and the expected responses. The key value used to identify the callback object is an expression, evaluated at runtime, that identifies a URL to use for the callback operation.",
- "additionalProperties": false,
- "patternProperties": {
- "^": {
- "$ref": "#/definitions/pathItem"
- },
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- }
- },
- "example": {
- "type": "object",
- "description": "",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "summary": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "value": {
- "$ref": "#/definitions/any"
- },
- "externalValue": {
- "type": "string"
- }
- }
- },
- "link": {
- "type": "object",
- "description": "The `Link object` represents a possible design-time link for a response. The presence of a link does not guarantee the caller's ability to successfully invoke it, rather it provides a known relationship and traversal mechanism between responses and other operations. Unlike _dynamic_ links (i.e. links provided **in** the response payload), the OAS linking mechanism does not require link information in the runtime response. For computing links, and providing instructions to execute them, a runtime expression is used for accessing values in an operation and using them as parameters while invoking the linked operation.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "operationRef": {
- "type": "string"
- },
- "operationId": {
- "type": "string"
- },
- "parameters": {
- "$ref": "#/definitions/anyOrExpression"
- },
- "requestBody": {
- "$ref": "#/definitions/anyOrExpression"
- },
- "description": {
- "type": "string"
- },
- "server": {
- "$ref": "#/definitions/server"
- }
- }
- },
- "header": {
- "type": "object",
- "description": "The Header Object follows the structure of the Parameter Object with the following changes: 1. `name` MUST NOT be specified, it is given in the corresponding `headers` map. 1. `in` MUST NOT be specified, it is implicitly in `header`. 1. All traits that are affected by the location MUST be applicable to a location of `header` (for example, `style`).",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "description": {
- "type": "string"
- },
- "required": {
- "type": "boolean"
- },
- "deprecated": {
- "type": "boolean"
- },
- "allowEmptyValue": {
- "type": "boolean"
- },
- "style": {
- "type": "string"
- },
- "explode": {
- "type": "boolean"
- },
- "allowReserved": {
- "type": "boolean"
- },
- "schema": {
- "$ref": "#/definitions/schemaOrReference"
- },
- "example": {
- "$ref": "#/definitions/any"
- },
- "examples": {
- "$ref": "#/definitions/examplesOrReferences"
- },
- "content": {
- "$ref": "#/definitions/mediaTypes"
- }
- }
- },
- "tag": {
- "type": "object",
- "description": "Adds metadata to a single tag that is used by the Operation Object. It is not mandatory to have a Tag Object per tag defined in the Operation Object instances.",
- "required": [
- "name"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "name": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "externalDocs": {
- "$ref": "#/definitions/externalDocs"
- }
- }
- },
- "reference": {
- "type": "object",
- "description": "A simple object to allow referencing other components in the specification, internally and externally. The Reference Object is defined by JSON Reference and follows the same structure, behavior and rules. For this specification, reference resolution is accomplished as defined by the JSON Reference specification and not by the JSON Schema specification.",
- "required": [
- "$ref"
- ],
- "additionalProperties": false,
- "properties": {
- "$ref": {
- "type": "string"
- },
- "summary": {
- "type": "string"
- },
- "description": {
- "type": "string"
- }
- }
- },
- "schema": {
- "type": "object",
- "description": "The Schema Object allows the definition of input and output data types. These types can be objects, but also primitives and arrays. This object is an extended subset of the JSON Schema Specification Wright Draft 00. For more information about the properties, see JSON Schema Core and JSON Schema Validation. Unless stated otherwise, the property definitions follow the JSON Schema.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "nullable": {
- "type": "boolean"
- },
- "discriminator": {
- "$ref": "#/definitions/discriminator"
- },
- "readOnly": {
- "type": "boolean"
- },
- "writeOnly": {
- "type": "boolean"
- },
- "xml": {
- "$ref": "#/definitions/xml"
- },
- "externalDocs": {
- "$ref": "#/definitions/externalDocs"
- },
- "example": {
- "$ref": "#/definitions/any"
- },
- "deprecated": {
- "type": "boolean"
- },
- "title": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/title"
- },
- "multipleOf": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/multipleOf"
- },
- "maximum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/maximum"
- },
- "exclusiveMaximum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/exclusiveMaximum"
- },
- "minimum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/minimum"
- },
- "exclusiveMinimum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/exclusiveMinimum"
- },
- "maxLength": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/maxLength"
- },
- "minLength": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/minLength"
- },
- "pattern": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/pattern"
- },
- "maxItems": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/maxItems"
- },
- "minItems": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/minItems"
- },
- "uniqueItems": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/uniqueItems"
- },
- "maxProperties": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/maxProperties"
- },
- "minProperties": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/minProperties"
- },
- "required": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/required"
- },
- "enum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/enum"
- },
- "type": {
- "type": "string"
- },
- "allOf": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/schemaOrReference"
- },
- "minItems": 1
- },
- "oneOf": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/schemaOrReference"
- },
- "minItems": 1
- },
- "anyOf": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/schemaOrReference"
- },
- "minItems": 1
- },
- "not": {
- "$ref": "#/definitions/schema"
- },
- "items": {
- "anyOf": [
- {
- "$ref": "#/definitions/schemaOrReference"
- },
- {
- "type": "array",
- "items": {
- "$ref": "#/definitions/schemaOrReference"
- },
- "minItems": 1
- }
- ]
- },
- "properties": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/schemaOrReference"
- }
- },
- "additionalProperties": {
- "oneOf": [
- {
- "$ref": "#/definitions/schemaOrReference"
- },
- {
- "type": "boolean"
- }
- ]
- },
- "default": {
- "$ref": "#/definitions/defaultType"
- },
- "description": {
- "type": "string"
- },
- "format": {
- "type": "string"
- }
- }
- },
- "discriminator": {
- "type": "object",
- "description": "When request bodies or response payloads may be one of a number of different schemas, a `discriminator` object can be used to aid in serialization, deserialization, and validation. The discriminator is a specific object in a schema which is used to inform the consumer of the specification of an alternative schema based on the value associated with it. When using the discriminator, _inline_ schemas will not be considered.",
- "required": [
- "propertyName"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "propertyName": {
- "type": "string"
- },
- "mapping": {
- "$ref": "#/definitions/strings"
- }
- }
- },
- "xml": {
- "type": "object",
- "description": "A metadata object that allows for more fine-tuned XML model definitions. When using arrays, XML element names are *not* inferred (for singular/plural forms) and the `name` property SHOULD be used to add that information. See examples for expected behavior.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "name": {
- "type": "string"
- },
- "namespace": {
- "type": "string"
- },
- "prefix": {
- "type": "string"
- },
- "attribute": {
- "type": "boolean"
- },
- "wrapped": {
- "type": "boolean"
- }
- }
- },
- "securityScheme": {
- "type": "object",
- "description": "Defines a security scheme that can be used by the operations. Supported schemes are HTTP authentication, an API key (either as a header, a cookie parameter or as a query parameter), mutual TLS (use of a client certificate), OAuth2's common flows (implicit, password, application and access code) as defined in RFC6749, and OpenID Connect. Please note that currently (2019) the implicit flow is about to be deprecated OAuth 2.0 Security Best Current Practice. Recommended for most use case is Authorization Code Grant flow with PKCE.",
- "required": [
- "type"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "type": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "name": {
- "type": "string"
- },
- "in": {
- "type": "string"
- },
- "scheme": {
- "type": "string"
- },
- "bearerFormat": {
- "type": "string"
- },
- "flows": {
- "$ref": "#/definitions/oauthFlows"
- },
- "openIdConnectUrl": {
- "type": "string"
- }
- }
- },
- "oauthFlows": {
- "type": "object",
- "description": "Allows configuration of the supported OAuth Flows.",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "implicit": {
- "$ref": "#/definitions/oauthFlow"
- },
- "password": {
- "$ref": "#/definitions/oauthFlow"
- },
- "clientCredentials": {
- "$ref": "#/definitions/oauthFlow"
- },
- "authorizationCode": {
- "$ref": "#/definitions/oauthFlow"
- }
- }
- },
- "oauthFlow": {
- "type": "object",
- "description": "Configuration details for a supported OAuth Flow",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/specificationExtension"
- }
- },
- "properties": {
- "authorizationUrl": {
- "type": "string"
- },
- "tokenUrl": {
- "type": "string"
- },
- "refreshUrl": {
- "type": "string"
- },
- "scopes": {
- "$ref": "#/definitions/strings"
- }
- }
- },
- "securityRequirement": {
- "type": "object",
- "description": "Lists the required security schemes to execute this operation. The name used for each property MUST correspond to a security scheme declared in the Security Schemes under the Components Object. Security Requirement Objects that contain multiple schemes require that all schemes MUST be satisfied for a request to be authorized. This enables support for scenarios where multiple query parameters or HTTP headers are required to convey security information. When a list of Security Requirement Objects is defined on the OpenAPI Object or Operation Object, only one of the Security Requirement Objects in the list needs to be satisfied to authorize the request.",
- "additionalProperties": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "uniqueItems": true
- }
- },
- "anyOrExpression": {
- "oneOf": [
- {
- "$ref": "#/definitions/any"
- },
- {
- "$ref": "#/definitions/expression"
- }
- ]
- },
- "callbackOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/callback"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "exampleOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/example"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "headerOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/header"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "linkOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/link"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "parameterOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/parameter"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "requestBodyOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/requestBody"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "responseOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/response"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "schemaOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/schema"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "securitySchemeOrReference": {
- "oneOf": [
- {
- "$ref": "#/definitions/securityScheme"
- },
- {
- "$ref": "#/definitions/reference"
- }
- ]
- },
- "callbacksOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/callbackOrReference"
- }
- },
- "encodings": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/encoding"
- }
- },
- "examplesOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/exampleOrReference"
- }
- },
- "headersOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/headerOrReference"
- }
- },
- "linksOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/linkOrReference"
- }
- },
- "mediaTypes": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/mediaType"
- }
- },
- "parametersOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/parameterOrReference"
- }
- },
- "requestBodiesOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/requestBodyOrReference"
- }
- },
- "responsesOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/responseOrReference"
- }
- },
- "schemasOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/schemaOrReference"
- }
- },
- "securitySchemesOrReferences": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/securitySchemeOrReference"
- }
- },
- "serverVariables": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/serverVariable"
- }
- },
- "strings": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
- },
- "object": {
- "type": "object",
- "additionalProperties": true
- },
- "any": {
- "additionalProperties": true
- },
- "expression": {
- "type": "object",
- "additionalProperties": true
- },
- "specificationExtension": {
- "description": "Any property starting with x- is valid.",
- "oneOf": [
- {
- "type": "null"
- },
- {
- "type": "number"
- },
- {
- "type": "boolean"
- },
- {
- "type": "string"
- },
- {
- "type": "object"
- },
- {
- "type": "array"
- }
- ]
- },
- "defaultType": {
- "oneOf": [
- {
- "type": "null"
- },
- {
- "type": "array"
- },
- {
- "type": "object"
- },
- {
- "type": "number"
- },
- {
- "type": "boolean"
- },
- {
- "type": "string"
- }
- ]
- }
- }
-}
diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_others.go b/vendor/github.com/inconshreveable/mousetrap/trap_others.go
index 9d2d8a4bab..06a91f0868 100644
--- a/vendor/github.com/inconshreveable/mousetrap/trap_others.go
+++ b/vendor/github.com/inconshreveable/mousetrap/trap_others.go
@@ -1,3 +1,4 @@
+//go:build !windows
// +build !windows
package mousetrap
diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_windows.go b/vendor/github.com/inconshreveable/mousetrap/trap_windows.go
index 336142a5e3..0c56880216 100644
--- a/vendor/github.com/inconshreveable/mousetrap/trap_windows.go
+++ b/vendor/github.com/inconshreveable/mousetrap/trap_windows.go
@@ -1,81 +1,32 @@
-// +build windows
-// +build !go1.4
-
package mousetrap
import (
- "fmt"
- "os"
"syscall"
"unsafe"
)
-const (
- // defined by the Win32 API
- th32cs_snapprocess uintptr = 0x2
-)
-
-var (
- kernel = syscall.MustLoadDLL("kernel32.dll")
- CreateToolhelp32Snapshot = kernel.MustFindProc("CreateToolhelp32Snapshot")
- Process32First = kernel.MustFindProc("Process32FirstW")
- Process32Next = kernel.MustFindProc("Process32NextW")
-)
-
-// ProcessEntry32 structure defined by the Win32 API
-type processEntry32 struct {
- dwSize uint32
- cntUsage uint32
- th32ProcessID uint32
- th32DefaultHeapID int
- th32ModuleID uint32
- cntThreads uint32
- th32ParentProcessID uint32
- pcPriClassBase int32
- dwFlags uint32
- szExeFile [syscall.MAX_PATH]uint16
-}
-
-func getProcessEntry(pid int) (pe *processEntry32, err error) {
- snapshot, _, e1 := CreateToolhelp32Snapshot.Call(th32cs_snapprocess, uintptr(0))
- if snapshot == uintptr(syscall.InvalidHandle) {
- err = fmt.Errorf("CreateToolhelp32Snapshot: %v", e1)
- return
+func getProcessEntry(pid int) (*syscall.ProcessEntry32, error) {
+ snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)
+ if err != nil {
+ return nil, err
}
- defer syscall.CloseHandle(syscall.Handle(snapshot))
-
- var processEntry processEntry32
- processEntry.dwSize = uint32(unsafe.Sizeof(processEntry))
- ok, _, e1 := Process32First.Call(snapshot, uintptr(unsafe.Pointer(&processEntry)))
- if ok == 0 {
- err = fmt.Errorf("Process32First: %v", e1)
- return
+ defer syscall.CloseHandle(snapshot)
+ var procEntry syscall.ProcessEntry32
+ procEntry.Size = uint32(unsafe.Sizeof(procEntry))
+ if err = syscall.Process32First(snapshot, &procEntry); err != nil {
+ return nil, err
}
-
for {
- if processEntry.th32ProcessID == uint32(pid) {
- pe = &processEntry
- return
+ if procEntry.ProcessID == uint32(pid) {
+ return &procEntry, nil
}
-
- ok, _, e1 = Process32Next.Call(snapshot, uintptr(unsafe.Pointer(&processEntry)))
- if ok == 0 {
- err = fmt.Errorf("Process32Next: %v", e1)
- return
+ err = syscall.Process32Next(snapshot, &procEntry)
+ if err != nil {
+ return nil, err
}
}
}
-func getppid() (pid int, err error) {
- pe, err := getProcessEntry(os.Getpid())
- if err != nil {
- return
- }
-
- pid = int(pe.th32ParentProcessID)
- return
-}
-
// StartedByExplorer returns true if the program was invoked by the user double-clicking
// on the executable from explorer.exe
//
@@ -83,16 +34,9 @@ func getppid() (pid int, err error) {
// It does not guarantee that the program was run from a terminal. It only can tell you
// whether it was launched from explorer.exe
func StartedByExplorer() bool {
- ppid, err := getppid()
+ pe, err := getProcessEntry(syscall.Getppid())
if err != nil {
return false
}
-
- pe, err := getProcessEntry(ppid)
- if err != nil {
- return false
- }
-
- name := syscall.UTF16ToString(pe.szExeFile[:])
- return name == "explorer.exe"
+ return "explorer.exe" == syscall.UTF16ToString(pe.ExeFile[:])
}
diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go b/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go
deleted file mode 100644
index 9a28e57c3c..0000000000
--- a/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// +build windows
-// +build go1.4
-
-package mousetrap
-
-import (
- "os"
- "syscall"
- "unsafe"
-)
-
-func getProcessEntry(pid int) (*syscall.ProcessEntry32, error) {
- snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)
- if err != nil {
- return nil, err
- }
- defer syscall.CloseHandle(snapshot)
- var procEntry syscall.ProcessEntry32
- procEntry.Size = uint32(unsafe.Sizeof(procEntry))
- if err = syscall.Process32First(snapshot, &procEntry); err != nil {
- return nil, err
- }
- for {
- if procEntry.ProcessID == uint32(pid) {
- return &procEntry, nil
- }
- err = syscall.Process32Next(snapshot, &procEntry)
- if err != nil {
- return nil, err
- }
- }
-}
-
-// StartedByExplorer returns true if the program was invoked by the user double-clicking
-// on the executable from explorer.exe
-//
-// It is conservative and returns false if any of the internal calls fail.
-// It does not guarantee that the program was run from a terminal. It only can tell you
-// whether it was launched from explorer.exe
-func StartedByExplorer() bool {
- pe, err := getProcessEntry(os.Getppid())
- if err != nil {
- return false
- }
- return "explorer.exe" == syscall.UTF16ToString(pe.ExeFile[:])
-}
diff --git a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md b/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
deleted file mode 100644
index 1955f2878c..0000000000
--- a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
+++ /dev/null
@@ -1,73 +0,0 @@
-## unreleased
-
-* Fix regression where `*time.Time` value would be set to empty and not be sent
- to decode hooks properly [GH-232]
-
-## 1.4.0
-
-* A new decode hook type `DecodeHookFuncValue` has been added that has
- access to the full values. [GH-183]
-* Squash is now supported with embedded fields that are struct pointers [GH-205]
-* Empty strings will convert to 0 for all numeric types when weakly decoding [GH-206]
-
-## 1.3.3
-
-* Decoding maps from maps creates a settable value for decode hooks [GH-203]
-
-## 1.3.2
-
-* Decode into interface type with a struct value is supported [GH-187]
-
-## 1.3.1
-
-* Squash should only squash embedded structs. [GH-194]
-
-## 1.3.0
-
-* Added `",omitempty"` support. This will ignore zero values in the source
- structure when encoding. [GH-145]
-
-## 1.2.3
-
-* Fix duplicate entries in Keys list with pointer values. [GH-185]
-
-## 1.2.2
-
-* Do not add unsettable (unexported) values to the unused metadata key
- or "remain" value. [GH-150]
-
-## 1.2.1
-
-* Go modules checksum mismatch fix
-
-## 1.2.0
-
-* Added support to capture unused values in a field using the `",remain"` value
- in the mapstructure tag. There is an example to showcase usage.
-* Added `DecoderConfig` option to always squash embedded structs
-* `json.Number` can decode into `uint` types
-* Empty slices are preserved and not replaced with nil slices
-* Fix panic that can occur in when decoding a map into a nil slice of structs
-* Improved package documentation for godoc
-
-## 1.1.2
-
-* Fix error when decode hook decodes interface implementation into interface
- type. [GH-140]
-
-## 1.1.1
-
-* Fix panic that can happen in `decodePtr`
-
-## 1.1.0
-
-* Added `StringToIPHookFunc` to convert `string` to `net.IP` and `net.IPNet` [GH-133]
-* Support struct to struct decoding [GH-137]
-* If source map value is nil, then destination map value is nil (instead of empty)
-* If source slice value is nil, then destination slice value is nil (instead of empty)
-* If source pointer is nil, then destination pointer is set to nil (instead of
- allocated zero value of type)
-
-## 1.0.0
-
-* Initial tagged stable release.
diff --git a/vendor/github.com/mitchellh/mapstructure/LICENSE b/vendor/github.com/mitchellh/mapstructure/LICENSE
deleted file mode 100644
index f9c841a51e..0000000000
--- a/vendor/github.com/mitchellh/mapstructure/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013 Mitchell Hashimoto
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/vendor/github.com/mitchellh/mapstructure/README.md b/vendor/github.com/mitchellh/mapstructure/README.md
deleted file mode 100644
index 0018dc7d9f..0000000000
--- a/vendor/github.com/mitchellh/mapstructure/README.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# mapstructure [![Godoc](https://godoc.org/github.com/mitchellh/mapstructure?status.svg)](https://godoc.org/github.com/mitchellh/mapstructure)
-
-mapstructure is a Go library for decoding generic map values to structures
-and vice versa, while providing helpful error handling.
-
-This library is most useful when decoding values from some data stream (JSON,
-Gob, etc.) where you don't _quite_ know the structure of the underlying data
-until you read a part of it. You can therefore read a `map[string]interface{}`
-and use this library to decode it into the proper underlying native Go
-structure.
-
-## Installation
-
-Standard `go get`:
-
-```
-$ go get github.com/mitchellh/mapstructure
-```
-
-## Usage & Example
-
-For usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/mapstructure).
-
-The `Decode` function has examples associated with it there.
-
-## But Why?!
-
-Go offers fantastic standard libraries for decoding formats such as JSON.
-The standard method is to have a struct pre-created, and populate that struct
-from the bytes of the encoded format. This is great, but the problem is if
-you have configuration or an encoding that changes slightly depending on
-specific fields. For example, consider this JSON:
-
-```json
-{
- "type": "person",
- "name": "Mitchell"
-}
-```
-
-Perhaps we can't populate a specific structure without first reading
-the "type" field from the JSON. We could always do two passes over the
-decoding of the JSON (reading the "type" first, and the rest later).
-However, it is much simpler to just decode this into a `map[string]interface{}`
-structure, read the "type" key, then use something like this library
-to decode it into the proper structure.
diff --git a/vendor/github.com/mitchellh/mapstructure/decode_hooks.go b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go
deleted file mode 100644
index 92e6f76fff..0000000000
--- a/vendor/github.com/mitchellh/mapstructure/decode_hooks.go
+++ /dev/null
@@ -1,256 +0,0 @@
-package mapstructure
-
-import (
- "encoding"
- "errors"
- "fmt"
- "net"
- "reflect"
- "strconv"
- "strings"
- "time"
-)
-
-// typedDecodeHook takes a raw DecodeHookFunc (an interface{}) and turns
-// it into the proper DecodeHookFunc type, such as DecodeHookFuncType.
-func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc {
- // Create variables here so we can reference them with the reflect pkg
- var f1 DecodeHookFuncType
- var f2 DecodeHookFuncKind
- var f3 DecodeHookFuncValue
-
- // Fill in the variables into this interface and the rest is done
- // automatically using the reflect package.
- potential := []interface{}{f1, f2, f3}
-
- v := reflect.ValueOf(h)
- vt := v.Type()
- for _, raw := range potential {
- pt := reflect.ValueOf(raw).Type()
- if vt.ConvertibleTo(pt) {
- return v.Convert(pt).Interface()
- }
- }
-
- return nil
-}
-
-// DecodeHookExec executes the given decode hook. This should be used
-// since it'll naturally degrade to the older backwards compatible DecodeHookFunc
-// that took reflect.Kind instead of reflect.Type.
-func DecodeHookExec(
- raw DecodeHookFunc,
- from reflect.Value, to reflect.Value) (interface{}, error) {
-
- switch f := typedDecodeHook(raw).(type) {
- case DecodeHookFuncType:
- return f(from.Type(), to.Type(), from.Interface())
- case DecodeHookFuncKind:
- return f(from.Kind(), to.Kind(), from.Interface())
- case DecodeHookFuncValue:
- return f(from, to)
- default:
- return nil, errors.New("invalid decode hook signature")
- }
-}
-
-// ComposeDecodeHookFunc creates a single DecodeHookFunc that
-// automatically composes multiple DecodeHookFuncs.
-//
-// The composed funcs are called in order, with the result of the
-// previous transformation.
-func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc {
- return func(f reflect.Value, t reflect.Value) (interface{}, error) {
- var err error
- var data interface{}
- newFrom := f
- for _, f1 := range fs {
- data, err = DecodeHookExec(f1, newFrom, t)
- if err != nil {
- return nil, err
- }
- newFrom = reflect.ValueOf(data)
- }
-
- return data, nil
- }
-}
-
-// StringToSliceHookFunc returns a DecodeHookFunc that converts
-// string to []string by splitting on the given sep.
-func StringToSliceHookFunc(sep string) DecodeHookFunc {
- return func(
- f reflect.Kind,
- t reflect.Kind,
- data interface{}) (interface{}, error) {
- if f != reflect.String || t != reflect.Slice {
- return data, nil
- }
-
- raw := data.(string)
- if raw == "" {
- return []string{}, nil
- }
-
- return strings.Split(raw, sep), nil
- }
-}
-
-// StringToTimeDurationHookFunc returns a DecodeHookFunc that converts
-// strings to time.Duration.
-func StringToTimeDurationHookFunc() DecodeHookFunc {
- return func(
- f reflect.Type,
- t reflect.Type,
- data interface{}) (interface{}, error) {
- if f.Kind() != reflect.String {
- return data, nil
- }
- if t != reflect.TypeOf(time.Duration(5)) {
- return data, nil
- }
-
- // Convert it by parsing
- return time.ParseDuration(data.(string))
- }
-}
-
-// StringToIPHookFunc returns a DecodeHookFunc that converts
-// strings to net.IP
-func StringToIPHookFunc() DecodeHookFunc {
- return func(
- f reflect.Type,
- t reflect.Type,
- data interface{}) (interface{}, error) {
- if f.Kind() != reflect.String {
- return data, nil
- }
- if t != reflect.TypeOf(net.IP{}) {
- return data, nil
- }
-
- // Convert it by parsing
- ip := net.ParseIP(data.(string))
- if ip == nil {
- return net.IP{}, fmt.Errorf("failed parsing ip %v", data)
- }
-
- return ip, nil
- }
-}
-
-// StringToIPNetHookFunc returns a DecodeHookFunc that converts
-// strings to net.IPNet
-func StringToIPNetHookFunc() DecodeHookFunc {
- return func(
- f reflect.Type,
- t reflect.Type,
- data interface{}) (interface{}, error) {
- if f.Kind() != reflect.String {
- return data, nil
- }
- if t != reflect.TypeOf(net.IPNet{}) {
- return data, nil
- }
-
- // Convert it by parsing
- _, net, err := net.ParseCIDR(data.(string))
- return net, err
- }
-}
-
-// StringToTimeHookFunc returns a DecodeHookFunc that converts
-// strings to time.Time.
-func StringToTimeHookFunc(layout string) DecodeHookFunc {
- return func(
- f reflect.Type,
- t reflect.Type,
- data interface{}) (interface{}, error) {
- if f.Kind() != reflect.String {
- return data, nil
- }
- if t != reflect.TypeOf(time.Time{}) {
- return data, nil
- }
-
- // Convert it by parsing
- return time.Parse(layout, data.(string))
- }
-}
-
-// WeaklyTypedHook is a DecodeHookFunc which adds support for weak typing to
-// the decoder.
-//
-// Note that this is significantly different from the WeaklyTypedInput option
-// of the DecoderConfig.
-func WeaklyTypedHook(
- f reflect.Kind,
- t reflect.Kind,
- data interface{}) (interface{}, error) {
- dataVal := reflect.ValueOf(data)
- switch t {
- case reflect.String:
- switch f {
- case reflect.Bool:
- if dataVal.Bool() {
- return "1", nil
- }
- return "0", nil
- case reflect.Float32:
- return strconv.FormatFloat(dataVal.Float(), 'f', -1, 64), nil
- case reflect.Int:
- return strconv.FormatInt(dataVal.Int(), 10), nil
- case reflect.Slice:
- dataType := dataVal.Type()
- elemKind := dataType.Elem().Kind()
- if elemKind == reflect.Uint8 {
- return string(dataVal.Interface().([]uint8)), nil
- }
- case reflect.Uint:
- return strconv.FormatUint(dataVal.Uint(), 10), nil
- }
- }
-
- return data, nil
-}
-
-func RecursiveStructToMapHookFunc() DecodeHookFunc {
- return func(f reflect.Value, t reflect.Value) (interface{}, error) {
- if f.Kind() != reflect.Struct {
- return f.Interface(), nil
- }
-
- var i interface{} = struct{}{}
- if t.Type() != reflect.TypeOf(&i).Elem() {
- return f.Interface(), nil
- }
-
- m := make(map[string]interface{})
- t.Set(reflect.ValueOf(m))
-
- return f.Interface(), nil
- }
-}
-
-// TextUnmarshallerHookFunc returns a DecodeHookFunc that applies
-// strings to the UnmarshalText function, when the target type
-// implements the encoding.TextUnmarshaler interface
-func TextUnmarshallerHookFunc() DecodeHookFuncType {
- return func(
- f reflect.Type,
- t reflect.Type,
- data interface{}) (interface{}, error) {
- if f.Kind() != reflect.String {
- return data, nil
- }
- result := reflect.New(t).Interface()
- unmarshaller, ok := result.(encoding.TextUnmarshaler)
- if !ok {
- return data, nil
- }
- if err := unmarshaller.UnmarshalText([]byte(data.(string))); err != nil {
- return nil, err
- }
- return result, nil
- }
-}
diff --git a/vendor/github.com/mitchellh/mapstructure/error.go b/vendor/github.com/mitchellh/mapstructure/error.go
deleted file mode 100644
index 47a99e5af3..0000000000
--- a/vendor/github.com/mitchellh/mapstructure/error.go
+++ /dev/null
@@ -1,50 +0,0 @@
-package mapstructure
-
-import (
- "errors"
- "fmt"
- "sort"
- "strings"
-)
-
-// Error implements the error interface and can represents multiple
-// errors that occur in the course of a single decode.
-type Error struct {
- Errors []string
-}
-
-func (e *Error) Error() string {
- points := make([]string, len(e.Errors))
- for i, err := range e.Errors {
- points[i] = fmt.Sprintf("* %s", err)
- }
-
- sort.Strings(points)
- return fmt.Sprintf(
- "%d error(s) decoding:\n\n%s",
- len(e.Errors), strings.Join(points, "\n"))
-}
-
-// WrappedErrors implements the errwrap.Wrapper interface to make this
-// return value more useful with the errwrap and go-multierror libraries.
-func (e *Error) WrappedErrors() []error {
- if e == nil {
- return nil
- }
-
- result := make([]error, len(e.Errors))
- for i, e := range e.Errors {
- result[i] = errors.New(e)
- }
-
- return result
-}
-
-func appendErrors(errors []string, err error) []string {
- switch e := err.(type) {
- case *Error:
- return append(errors, e.Errors...)
- default:
- return append(errors, e.Error())
- }
-}
diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure.go b/vendor/github.com/mitchellh/mapstructure/mapstructure.go
deleted file mode 100644
index 3643901f55..0000000000
--- a/vendor/github.com/mitchellh/mapstructure/mapstructure.go
+++ /dev/null
@@ -1,1462 +0,0 @@
-// Package mapstructure exposes functionality to convert one arbitrary
-// Go type into another, typically to convert a map[string]interface{}
-// into a native Go structure.
-//
-// The Go structure can be arbitrarily complex, containing slices,
-// other structs, etc. and the decoder will properly decode nested
-// maps and so on into the proper structures in the native Go struct.
-// See the examples to see what the decoder is capable of.
-//
-// The simplest function to start with is Decode.
-//
-// Field Tags
-//
-// When decoding to a struct, mapstructure will use the field name by
-// default to perform the mapping. For example, if a struct has a field
-// "Username" then mapstructure will look for a key in the source value
-// of "username" (case insensitive).
-//
-// type User struct {
-// Username string
-// }
-//
-// You can change the behavior of mapstructure by using struct tags.
-// The default struct tag that mapstructure looks for is "mapstructure"
-// but you can customize it using DecoderConfig.
-//
-// Renaming Fields
-//
-// To rename the key that mapstructure looks for, use the "mapstructure"
-// tag and set a value directly. For example, to change the "username" example
-// above to "user":
-//
-// type User struct {
-// Username string `mapstructure:"user"`
-// }
-//
-// Embedded Structs and Squashing
-//
-// Embedded structs are treated as if they're another field with that name.
-// By default, the two structs below are equivalent when decoding with
-// mapstructure:
-//
-// type Person struct {
-// Name string
-// }
-//
-// type Friend struct {
-// Person
-// }
-//
-// type Friend struct {
-// Person Person
-// }
-//
-// This would require an input that looks like below:
-//
-// map[string]interface{}{
-// "person": map[string]interface{}{"name": "alice"},
-// }
-//
-// If your "person" value is NOT nested, then you can append ",squash" to
-// your tag value and mapstructure will treat it as if the embedded struct
-// were part of the struct directly. Example:
-//
-// type Friend struct {
-// Person `mapstructure:",squash"`
-// }
-//
-// Now the following input would be accepted:
-//
-// map[string]interface{}{
-// "name": "alice",
-// }
-//
-// When decoding from a struct to a map, the squash tag squashes the struct
-// fields into a single map. Using the example structs from above:
-//
-// Friend{Person: Person{Name: "alice"}}
-//
-// Will be decoded into a map:
-//
-// map[string]interface{}{
-// "name": "alice",
-// }
-//
-// DecoderConfig has a field that changes the behavior of mapstructure
-// to always squash embedded structs.
-//
-// Remainder Values
-//
-// If there are any unmapped keys in the source value, mapstructure by
-// default will silently ignore them. You can error by setting ErrorUnused
-// in DecoderConfig. If you're using Metadata you can also maintain a slice
-// of the unused keys.
-//
-// You can also use the ",remain" suffix on your tag to collect all unused
-// values in a map. The field with this tag MUST be a map type and should
-// probably be a "map[string]interface{}" or "map[interface{}]interface{}".
-// See example below:
-//
-// type Friend struct {
-// Name string
-// Other map[string]interface{} `mapstructure:",remain"`
-// }
-//
-// Given the input below, Other would be populated with the other
-// values that weren't used (everything but "name"):
-//
-// map[string]interface{}{
-// "name": "bob",
-// "address": "123 Maple St.",
-// }
-//
-// Omit Empty Values
-//
-// When decoding from a struct to any other value, you may use the
-// ",omitempty" suffix on your tag to omit that value if it equates to
-// the zero value. The zero value of all types is specified in the Go
-// specification.
-//
-// For example, the zero type of a numeric type is zero ("0"). If the struct
-// field value is zero and a numeric type, the field is empty, and it won't
-// be encoded into the destination type.
-//
-// type Source {
-// Age int `mapstructure:",omitempty"`
-// }
-//
-// Unexported fields
-//
-// Since unexported (private) struct fields cannot be set outside the package
-// where they are defined, the decoder will simply skip them.
-//
-// For this output type definition:
-//
-// type Exported struct {
-// private string // this unexported field will be skipped
-// Public string
-// }
-//
-// Using this map as input:
-//
-// map[string]interface{}{
-// "private": "I will be ignored",
-// "Public": "I made it through!",
-// }
-//
-// The following struct will be decoded:
-//
-// type Exported struct {
-// private: "" // field is left with an empty string (zero value)
-// Public: "I made it through!"
-// }
-//
-// Other Configuration
-//
-// mapstructure is highly configurable. See the DecoderConfig struct
-// for other features and options that are supported.
-package mapstructure
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "reflect"
- "sort"
- "strconv"
- "strings"
-)
-
-// DecodeHookFunc is the callback function that can be used for
-// data transformations. See "DecodeHook" in the DecoderConfig
-// struct.
-//
-// The type must be one of DecodeHookFuncType, DecodeHookFuncKind, or
-// DecodeHookFuncValue.
-// Values are a superset of Types (Values can return types), and Types are a
-// superset of Kinds (Types can return Kinds) and are generally a richer thing
-// to use, but Kinds are simpler if you only need those.
-//
-// The reason DecodeHookFunc is multi-typed is for backwards compatibility:
-// we started with Kinds and then realized Types were the better solution,
-// but have a promise to not break backwards compat so we now support
-// both.
-type DecodeHookFunc interface{}
-
-// DecodeHookFuncType is a DecodeHookFunc which has complete information about
-// the source and target types.
-type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface{}, error)
-
-// DecodeHookFuncKind is a DecodeHookFunc which knows only the Kinds of the
-// source and target types.
-type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error)
-
-// DecodeHookFuncRaw is a DecodeHookFunc which has complete access to both the source and target
-// values.
-type DecodeHookFuncValue func(from reflect.Value, to reflect.Value) (interface{}, error)
-
-// DecoderConfig is the configuration that is used to create a new decoder
-// and allows customization of various aspects of decoding.
-type DecoderConfig struct {
- // DecodeHook, if set, will be called before any decoding and any
- // type conversion (if WeaklyTypedInput is on). This lets you modify
- // the values before they're set down onto the resulting struct. The
- // DecodeHook is called for every map and value in the input. This means
- // that if a struct has embedded fields with squash tags the decode hook
- // is called only once with all of the input data, not once for each
- // embedded struct.
- //
- // If an error is returned, the entire decode will fail with that error.
- DecodeHook DecodeHookFunc
-
- // If ErrorUnused is true, then it is an error for there to exist
- // keys in the original map that were unused in the decoding process
- // (extra keys).
- ErrorUnused bool
-
- // ZeroFields, if set to true, will zero fields before writing them.
- // For example, a map will be emptied before decoded values are put in
- // it. If this is false, a map will be merged.
- ZeroFields bool
-
- // If WeaklyTypedInput is true, the decoder will make the following
- // "weak" conversions:
- //
- // - bools to string (true = "1", false = "0")
- // - numbers to string (base 10)
- // - bools to int/uint (true = 1, false = 0)
- // - strings to int/uint (base implied by prefix)
- // - int to bool (true if value != 0)
- // - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F,
- // FALSE, false, False. Anything else is an error)
- // - empty array = empty map and vice versa
- // - negative numbers to overflowed uint values (base 10)
- // - slice of maps to a merged map
- // - single values are converted to slices if required. Each
- // element is weakly decoded. For example: "4" can become []int{4}
- // if the target type is an int slice.
- //
- WeaklyTypedInput bool
-
- // Squash will squash embedded structs. A squash tag may also be
- // added to an individual struct field using a tag. For example:
- //
- // type Parent struct {
- // Child `mapstructure:",squash"`
- // }
- Squash bool
-
- // Metadata is the struct that will contain extra metadata about
- // the decoding. If this is nil, then no metadata will be tracked.
- Metadata *Metadata
-
- // Result is a pointer to the struct that will contain the decoded
- // value.
- Result interface{}
-
- // The tag name that mapstructure reads for field names. This
- // defaults to "mapstructure"
- TagName string
-}
-
-// A Decoder takes a raw interface value and turns it into structured
-// data, keeping track of rich error information along the way in case
-// anything goes wrong. Unlike the basic top-level Decode method, you can
-// more finely control how the Decoder behaves using the DecoderConfig
-// structure. The top-level Decode method is just a convenience that sets
-// up the most basic Decoder.
-type Decoder struct {
- config *DecoderConfig
-}
-
-// Metadata contains information about decoding a structure that
-// is tedious or difficult to get otherwise.
-type Metadata struct {
- // Keys are the keys of the structure which were successfully decoded
- Keys []string
-
- // Unused is a slice of keys that were found in the raw value but
- // weren't decoded since there was no matching field in the result interface
- Unused []string
-}
-
-// Decode takes an input structure and uses reflection to translate it to
-// the output structure. output must be a pointer to a map or struct.
-func Decode(input interface{}, output interface{}) error {
- config := &DecoderConfig{
- Metadata: nil,
- Result: output,
- }
-
- decoder, err := NewDecoder(config)
- if err != nil {
- return err
- }
-
- return decoder.Decode(input)
-}
-
-// WeakDecode is the same as Decode but is shorthand to enable
-// WeaklyTypedInput. See DecoderConfig for more info.
-func WeakDecode(input, output interface{}) error {
- config := &DecoderConfig{
- Metadata: nil,
- Result: output,
- WeaklyTypedInput: true,
- }
-
- decoder, err := NewDecoder(config)
- if err != nil {
- return err
- }
-
- return decoder.Decode(input)
-}
-
-// DecodeMetadata is the same as Decode, but is shorthand to
-// enable metadata collection. See DecoderConfig for more info.
-func DecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error {
- config := &DecoderConfig{
- Metadata: metadata,
- Result: output,
- }
-
- decoder, err := NewDecoder(config)
- if err != nil {
- return err
- }
-
- return decoder.Decode(input)
-}
-
-// WeakDecodeMetadata is the same as Decode, but is shorthand to
-// enable both WeaklyTypedInput and metadata collection. See
-// DecoderConfig for more info.
-func WeakDecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error {
- config := &DecoderConfig{
- Metadata: metadata,
- Result: output,
- WeaklyTypedInput: true,
- }
-
- decoder, err := NewDecoder(config)
- if err != nil {
- return err
- }
-
- return decoder.Decode(input)
-}
-
-// NewDecoder returns a new decoder for the given configuration. Once
-// a decoder has been returned, the same configuration must not be used
-// again.
-func NewDecoder(config *DecoderConfig) (*Decoder, error) {
- val := reflect.ValueOf(config.Result)
- if val.Kind() != reflect.Ptr {
- return nil, errors.New("result must be a pointer")
- }
-
- val = val.Elem()
- if !val.CanAddr() {
- return nil, errors.New("result must be addressable (a pointer)")
- }
-
- if config.Metadata != nil {
- if config.Metadata.Keys == nil {
- config.Metadata.Keys = make([]string, 0)
- }
-
- if config.Metadata.Unused == nil {
- config.Metadata.Unused = make([]string, 0)
- }
- }
-
- if config.TagName == "" {
- config.TagName = "mapstructure"
- }
-
- result := &Decoder{
- config: config,
- }
-
- return result, nil
-}
-
-// Decode decodes the given raw interface to the target pointer specified
-// by the configuration.
-func (d *Decoder) Decode(input interface{}) error {
- return d.decode("", input, reflect.ValueOf(d.config.Result).Elem())
-}
-
-// Decodes an unknown data type into a specific reflection value.
-func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) error {
- var inputVal reflect.Value
- if input != nil {
- inputVal = reflect.ValueOf(input)
-
- // We need to check here if input is a typed nil. Typed nils won't
- // match the "input == nil" below so we check that here.
- if inputVal.Kind() == reflect.Ptr && inputVal.IsNil() {
- input = nil
- }
- }
-
- if input == nil {
- // If the data is nil, then we don't set anything, unless ZeroFields is set
- // to true.
- if d.config.ZeroFields {
- outVal.Set(reflect.Zero(outVal.Type()))
-
- if d.config.Metadata != nil && name != "" {
- d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
- }
- }
- return nil
- }
-
- if !inputVal.IsValid() {
- // If the input value is invalid, then we just set the value
- // to be the zero value.
- outVal.Set(reflect.Zero(outVal.Type()))
- if d.config.Metadata != nil && name != "" {
- d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
- }
- return nil
- }
-
- if d.config.DecodeHook != nil {
- // We have a DecodeHook, so let's pre-process the input.
- var err error
- input, err = DecodeHookExec(d.config.DecodeHook, inputVal, outVal)
- if err != nil {
- return fmt.Errorf("error decoding '%s': %s", name, err)
- }
- }
-
- var err error
- outputKind := getKind(outVal)
- addMetaKey := true
- switch outputKind {
- case reflect.Bool:
- err = d.decodeBool(name, input, outVal)
- case reflect.Interface:
- err = d.decodeBasic(name, input, outVal)
- case reflect.String:
- err = d.decodeString(name, input, outVal)
- case reflect.Int:
- err = d.decodeInt(name, input, outVal)
- case reflect.Uint:
- err = d.decodeUint(name, input, outVal)
- case reflect.Float32:
- err = d.decodeFloat(name, input, outVal)
- case reflect.Struct:
- err = d.decodeStruct(name, input, outVal)
- case reflect.Map:
- err = d.decodeMap(name, input, outVal)
- case reflect.Ptr:
- addMetaKey, err = d.decodePtr(name, input, outVal)
- case reflect.Slice:
- err = d.decodeSlice(name, input, outVal)
- case reflect.Array:
- err = d.decodeArray(name, input, outVal)
- case reflect.Func:
- err = d.decodeFunc(name, input, outVal)
- default:
- // If we reached this point then we weren't able to decode it
- return fmt.Errorf("%s: unsupported type: %s", name, outputKind)
- }
-
- // If we reached here, then we successfully decoded SOMETHING, so
- // mark the key as used if we're tracking metainput.
- if addMetaKey && d.config.Metadata != nil && name != "" {
- d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
- }
-
- return err
-}
-
-// This decodes a basic type (bool, int, string, etc.) and sets the
-// value to "data" of that type.
-func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error {
- if val.IsValid() && val.Elem().IsValid() {
- elem := val.Elem()
-
- // If we can't address this element, then its not writable. Instead,
- // we make a copy of the value (which is a pointer and therefore
- // writable), decode into that, and replace the whole value.
- copied := false
- if !elem.CanAddr() {
- copied = true
-
- // Make *T
- copy := reflect.New(elem.Type())
-
- // *T = elem
- copy.Elem().Set(elem)
-
- // Set elem so we decode into it
- elem = copy
- }
-
- // Decode. If we have an error then return. We also return right
- // away if we're not a copy because that means we decoded directly.
- if err := d.decode(name, data, elem); err != nil || !copied {
- return err
- }
-
- // If we're a copy, we need to set te final result
- val.Set(elem.Elem())
- return nil
- }
-
- dataVal := reflect.ValueOf(data)
-
- // If the input data is a pointer, and the assigned type is the dereference
- // of that exact pointer, then indirect it so that we can assign it.
- // Example: *string to string
- if dataVal.Kind() == reflect.Ptr && dataVal.Type().Elem() == val.Type() {
- dataVal = reflect.Indirect(dataVal)
- }
-
- if !dataVal.IsValid() {
- dataVal = reflect.Zero(val.Type())
- }
-
- dataValType := dataVal.Type()
- if !dataValType.AssignableTo(val.Type()) {
- return fmt.Errorf(
- "'%s' expected type '%s', got '%s'",
- name, val.Type(), dataValType)
- }
-
- val.Set(dataVal)
- return nil
-}
-
-func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) error {
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- dataKind := getKind(dataVal)
-
- converted := true
- switch {
- case dataKind == reflect.String:
- val.SetString(dataVal.String())
- case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
- if dataVal.Bool() {
- val.SetString("1")
- } else {
- val.SetString("0")
- }
- case dataKind == reflect.Int && d.config.WeaklyTypedInput:
- val.SetString(strconv.FormatInt(dataVal.Int(), 10))
- case dataKind == reflect.Uint && d.config.WeaklyTypedInput:
- val.SetString(strconv.FormatUint(dataVal.Uint(), 10))
- case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
- val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64))
- case dataKind == reflect.Slice && d.config.WeaklyTypedInput,
- dataKind == reflect.Array && d.config.WeaklyTypedInput:
- dataType := dataVal.Type()
- elemKind := dataType.Elem().Kind()
- switch elemKind {
- case reflect.Uint8:
- var uints []uint8
- if dataKind == reflect.Array {
- uints = make([]uint8, dataVal.Len(), dataVal.Len())
- for i := range uints {
- uints[i] = dataVal.Index(i).Interface().(uint8)
- }
- } else {
- uints = dataVal.Interface().([]uint8)
- }
- val.SetString(string(uints))
- default:
- converted = false
- }
- default:
- converted = false
- }
-
- if !converted {
- return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
- name, val.Type(), dataVal.Type(), data)
- }
-
- return nil
-}
-
-func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error {
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- dataKind := getKind(dataVal)
- dataType := dataVal.Type()
-
- switch {
- case dataKind == reflect.Int:
- val.SetInt(dataVal.Int())
- case dataKind == reflect.Uint:
- val.SetInt(int64(dataVal.Uint()))
- case dataKind == reflect.Float32:
- val.SetInt(int64(dataVal.Float()))
- case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
- if dataVal.Bool() {
- val.SetInt(1)
- } else {
- val.SetInt(0)
- }
- case dataKind == reflect.String && d.config.WeaklyTypedInput:
- str := dataVal.String()
- if str == "" {
- str = "0"
- }
-
- i, err := strconv.ParseInt(str, 0, val.Type().Bits())
- if err == nil {
- val.SetInt(i)
- } else {
- return fmt.Errorf("cannot parse '%s' as int: %s", name, err)
- }
- case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
- jn := data.(json.Number)
- i, err := jn.Int64()
- if err != nil {
- return fmt.Errorf(
- "error decoding json.Number into %s: %s", name, err)
- }
- val.SetInt(i)
- default:
- return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
- name, val.Type(), dataVal.Type(), data)
- }
-
- return nil
-}
-
-func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error {
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- dataKind := getKind(dataVal)
- dataType := dataVal.Type()
-
- switch {
- case dataKind == reflect.Int:
- i := dataVal.Int()
- if i < 0 && !d.config.WeaklyTypedInput {
- return fmt.Errorf("cannot parse '%s', %d overflows uint",
- name, i)
- }
- val.SetUint(uint64(i))
- case dataKind == reflect.Uint:
- val.SetUint(dataVal.Uint())
- case dataKind == reflect.Float32:
- f := dataVal.Float()
- if f < 0 && !d.config.WeaklyTypedInput {
- return fmt.Errorf("cannot parse '%s', %f overflows uint",
- name, f)
- }
- val.SetUint(uint64(f))
- case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
- if dataVal.Bool() {
- val.SetUint(1)
- } else {
- val.SetUint(0)
- }
- case dataKind == reflect.String && d.config.WeaklyTypedInput:
- str := dataVal.String()
- if str == "" {
- str = "0"
- }
-
- i, err := strconv.ParseUint(str, 0, val.Type().Bits())
- if err == nil {
- val.SetUint(i)
- } else {
- return fmt.Errorf("cannot parse '%s' as uint: %s", name, err)
- }
- case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
- jn := data.(json.Number)
- i, err := jn.Int64()
- if err != nil {
- return fmt.Errorf(
- "error decoding json.Number into %s: %s", name, err)
- }
- if i < 0 && !d.config.WeaklyTypedInput {
- return fmt.Errorf("cannot parse '%s', %d overflows uint",
- name, i)
- }
- val.SetUint(uint64(i))
- default:
- return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
- name, val.Type(), dataVal.Type(), data)
- }
-
- return nil
-}
-
-func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) error {
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- dataKind := getKind(dataVal)
-
- switch {
- case dataKind == reflect.Bool:
- val.SetBool(dataVal.Bool())
- case dataKind == reflect.Int && d.config.WeaklyTypedInput:
- val.SetBool(dataVal.Int() != 0)
- case dataKind == reflect.Uint && d.config.WeaklyTypedInput:
- val.SetBool(dataVal.Uint() != 0)
- case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
- val.SetBool(dataVal.Float() != 0)
- case dataKind == reflect.String && d.config.WeaklyTypedInput:
- b, err := strconv.ParseBool(dataVal.String())
- if err == nil {
- val.SetBool(b)
- } else if dataVal.String() == "" {
- val.SetBool(false)
- } else {
- return fmt.Errorf("cannot parse '%s' as bool: %s", name, err)
- }
- default:
- return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
- name, val.Type(), dataVal.Type(), data)
- }
-
- return nil
-}
-
-func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error {
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- dataKind := getKind(dataVal)
- dataType := dataVal.Type()
-
- switch {
- case dataKind == reflect.Int:
- val.SetFloat(float64(dataVal.Int()))
- case dataKind == reflect.Uint:
- val.SetFloat(float64(dataVal.Uint()))
- case dataKind == reflect.Float32:
- val.SetFloat(dataVal.Float())
- case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
- if dataVal.Bool() {
- val.SetFloat(1)
- } else {
- val.SetFloat(0)
- }
- case dataKind == reflect.String && d.config.WeaklyTypedInput:
- str := dataVal.String()
- if str == "" {
- str = "0"
- }
-
- f, err := strconv.ParseFloat(str, val.Type().Bits())
- if err == nil {
- val.SetFloat(f)
- } else {
- return fmt.Errorf("cannot parse '%s' as float: %s", name, err)
- }
- case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
- jn := data.(json.Number)
- i, err := jn.Float64()
- if err != nil {
- return fmt.Errorf(
- "error decoding json.Number into %s: %s", name, err)
- }
- val.SetFloat(i)
- default:
- return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
- name, val.Type(), dataVal.Type(), data)
- }
-
- return nil
-}
-
-func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error {
- valType := val.Type()
- valKeyType := valType.Key()
- valElemType := valType.Elem()
-
- // By default we overwrite keys in the current map
- valMap := val
-
- // If the map is nil or we're purposely zeroing fields, make a new map
- if valMap.IsNil() || d.config.ZeroFields {
- // Make a new map to hold our result
- mapType := reflect.MapOf(valKeyType, valElemType)
- valMap = reflect.MakeMap(mapType)
- }
-
- // Check input type and based on the input type jump to the proper func
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- switch dataVal.Kind() {
- case reflect.Map:
- return d.decodeMapFromMap(name, dataVal, val, valMap)
-
- case reflect.Struct:
- return d.decodeMapFromStruct(name, dataVal, val, valMap)
-
- case reflect.Array, reflect.Slice:
- if d.config.WeaklyTypedInput {
- return d.decodeMapFromSlice(name, dataVal, val, valMap)
- }
-
- fallthrough
-
- default:
- return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
- }
-}
-
-func (d *Decoder) decodeMapFromSlice(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
- // Special case for BC reasons (covered by tests)
- if dataVal.Len() == 0 {
- val.Set(valMap)
- return nil
- }
-
- for i := 0; i < dataVal.Len(); i++ {
- err := d.decode(
- name+"["+strconv.Itoa(i)+"]",
- dataVal.Index(i).Interface(), val)
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
- valType := val.Type()
- valKeyType := valType.Key()
- valElemType := valType.Elem()
-
- // Accumulate errors
- errors := make([]string, 0)
-
- // If the input data is empty, then we just match what the input data is.
- if dataVal.Len() == 0 {
- if dataVal.IsNil() {
- if !val.IsNil() {
- val.Set(dataVal)
- }
- } else {
- // Set to empty allocated value
- val.Set(valMap)
- }
-
- return nil
- }
-
- for _, k := range dataVal.MapKeys() {
- fieldName := name + "[" + k.String() + "]"
-
- // First decode the key into the proper type
- currentKey := reflect.Indirect(reflect.New(valKeyType))
- if err := d.decode(fieldName, k.Interface(), currentKey); err != nil {
- errors = appendErrors(errors, err)
- continue
- }
-
- // Next decode the data into the proper type
- v := dataVal.MapIndex(k).Interface()
- currentVal := reflect.Indirect(reflect.New(valElemType))
- if err := d.decode(fieldName, v, currentVal); err != nil {
- errors = appendErrors(errors, err)
- continue
- }
-
- valMap.SetMapIndex(currentKey, currentVal)
- }
-
- // Set the built up map to the value
- val.Set(valMap)
-
- // If we had errors, return those
- if len(errors) > 0 {
- return &Error{errors}
- }
-
- return nil
-}
-
-func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
- typ := dataVal.Type()
- for i := 0; i < typ.NumField(); i++ {
- // Get the StructField first since this is a cheap operation. If the
- // field is unexported, then ignore it.
- f := typ.Field(i)
- if f.PkgPath != "" {
- continue
- }
-
- // Next get the actual value of this field and verify it is assignable
- // to the map value.
- v := dataVal.Field(i)
- if !v.Type().AssignableTo(valMap.Type().Elem()) {
- return fmt.Errorf("cannot assign type '%s' to map value field of type '%s'", v.Type(), valMap.Type().Elem())
- }
-
- tagValue := f.Tag.Get(d.config.TagName)
- keyName := f.Name
-
- // If Squash is set in the config, we squash the field down.
- squash := d.config.Squash && v.Kind() == reflect.Struct && f.Anonymous
-
- // Determine the name of the key in the map
- if index := strings.Index(tagValue, ","); index != -1 {
- if tagValue[:index] == "-" {
- continue
- }
- // If "omitempty" is specified in the tag, it ignores empty values.
- if strings.Index(tagValue[index+1:], "omitempty") != -1 && isEmptyValue(v) {
- continue
- }
-
- // If "squash" is specified in the tag, we squash the field down.
- squash = !squash && strings.Index(tagValue[index+1:], "squash") != -1
- if squash {
- // When squashing, the embedded type can be a pointer to a struct.
- if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct {
- v = v.Elem()
- }
-
- // The final type must be a struct
- if v.Kind() != reflect.Struct {
- return fmt.Errorf("cannot squash non-struct type '%s'", v.Type())
- }
- }
- keyName = tagValue[:index]
- } else if len(tagValue) > 0 {
- if tagValue == "-" {
- continue
- }
- keyName = tagValue
- }
-
- switch v.Kind() {
- // this is an embedded struct, so handle it differently
- case reflect.Struct:
- x := reflect.New(v.Type())
- x.Elem().Set(v)
-
- vType := valMap.Type()
- vKeyType := vType.Key()
- vElemType := vType.Elem()
- mType := reflect.MapOf(vKeyType, vElemType)
- vMap := reflect.MakeMap(mType)
-
- // Creating a pointer to a map so that other methods can completely
- // overwrite the map if need be (looking at you decodeMapFromMap). The
- // indirection allows the underlying map to be settable (CanSet() == true)
- // where as reflect.MakeMap returns an unsettable map.
- addrVal := reflect.New(vMap.Type())
- reflect.Indirect(addrVal).Set(vMap)
-
- err := d.decode(keyName, x.Interface(), reflect.Indirect(addrVal))
- if err != nil {
- return err
- }
-
- // the underlying map may have been completely overwritten so pull
- // it indirectly out of the enclosing value.
- vMap = reflect.Indirect(addrVal)
-
- if squash {
- for _, k := range vMap.MapKeys() {
- valMap.SetMapIndex(k, vMap.MapIndex(k))
- }
- } else {
- valMap.SetMapIndex(reflect.ValueOf(keyName), vMap)
- }
-
- default:
- valMap.SetMapIndex(reflect.ValueOf(keyName), v)
- }
- }
-
- if val.CanAddr() {
- val.Set(valMap)
- }
-
- return nil
-}
-
-func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) (bool, error) {
- // If the input data is nil, then we want to just set the output
- // pointer to be nil as well.
- isNil := data == nil
- if !isNil {
- switch v := reflect.Indirect(reflect.ValueOf(data)); v.Kind() {
- case reflect.Chan,
- reflect.Func,
- reflect.Interface,
- reflect.Map,
- reflect.Ptr,
- reflect.Slice:
- isNil = v.IsNil()
- }
- }
- if isNil {
- if !val.IsNil() && val.CanSet() {
- nilValue := reflect.New(val.Type()).Elem()
- val.Set(nilValue)
- }
-
- return true, nil
- }
-
- // Create an element of the concrete (non pointer) type and decode
- // into that. Then set the value of the pointer to this type.
- valType := val.Type()
- valElemType := valType.Elem()
- if val.CanSet() {
- realVal := val
- if realVal.IsNil() || d.config.ZeroFields {
- realVal = reflect.New(valElemType)
- }
-
- if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {
- return false, err
- }
-
- val.Set(realVal)
- } else {
- if err := d.decode(name, data, reflect.Indirect(val)); err != nil {
- return false, err
- }
- }
- return false, nil
-}
-
-func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error {
- // Create an element of the concrete (non pointer) type and decode
- // into that. Then set the value of the pointer to this type.
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- if val.Type() != dataVal.Type() {
- return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
- name, val.Type(), dataVal.Type(), data)
- }
- val.Set(dataVal)
- return nil
-}
-
-func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error {
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- dataValKind := dataVal.Kind()
- valType := val.Type()
- valElemType := valType.Elem()
- sliceType := reflect.SliceOf(valElemType)
-
- // If we have a non array/slice type then we first attempt to convert.
- if dataValKind != reflect.Array && dataValKind != reflect.Slice {
- if d.config.WeaklyTypedInput {
- switch {
- // Slice and array we use the normal logic
- case dataValKind == reflect.Slice, dataValKind == reflect.Array:
- break
-
- // Empty maps turn into empty slices
- case dataValKind == reflect.Map:
- if dataVal.Len() == 0 {
- val.Set(reflect.MakeSlice(sliceType, 0, 0))
- return nil
- }
- // Create slice of maps of other sizes
- return d.decodeSlice(name, []interface{}{data}, val)
-
- case dataValKind == reflect.String && valElemType.Kind() == reflect.Uint8:
- return d.decodeSlice(name, []byte(dataVal.String()), val)
-
- // All other types we try to convert to the slice type
- // and "lift" it into it. i.e. a string becomes a string slice.
- default:
- // Just re-try this function with data as a slice.
- return d.decodeSlice(name, []interface{}{data}, val)
- }
- }
-
- return fmt.Errorf(
- "'%s': source data must be an array or slice, got %s", name, dataValKind)
- }
-
- // If the input value is nil, then don't allocate since empty != nil
- if dataVal.IsNil() {
- return nil
- }
-
- valSlice := val
- if valSlice.IsNil() || d.config.ZeroFields {
- // Make a new slice to hold our result, same size as the original data.
- valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len())
- }
-
- // Accumulate any errors
- errors := make([]string, 0)
-
- for i := 0; i < dataVal.Len(); i++ {
- currentData := dataVal.Index(i).Interface()
- for valSlice.Len() <= i {
- valSlice = reflect.Append(valSlice, reflect.Zero(valElemType))
- }
- currentField := valSlice.Index(i)
-
- fieldName := name + "[" + strconv.Itoa(i) + "]"
- if err := d.decode(fieldName, currentData, currentField); err != nil {
- errors = appendErrors(errors, err)
- }
- }
-
- // Finally, set the value to the slice we built up
- val.Set(valSlice)
-
- // If there were errors, we return those
- if len(errors) > 0 {
- return &Error{errors}
- }
-
- return nil
-}
-
-func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value) error {
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- dataValKind := dataVal.Kind()
- valType := val.Type()
- valElemType := valType.Elem()
- arrayType := reflect.ArrayOf(valType.Len(), valElemType)
-
- valArray := val
-
- if valArray.Interface() == reflect.Zero(valArray.Type()).Interface() || d.config.ZeroFields {
- // Check input type
- if dataValKind != reflect.Array && dataValKind != reflect.Slice {
- if d.config.WeaklyTypedInput {
- switch {
- // Empty maps turn into empty arrays
- case dataValKind == reflect.Map:
- if dataVal.Len() == 0 {
- val.Set(reflect.Zero(arrayType))
- return nil
- }
-
- // All other types we try to convert to the array type
- // and "lift" it into it. i.e. a string becomes a string array.
- default:
- // Just re-try this function with data as a slice.
- return d.decodeArray(name, []interface{}{data}, val)
- }
- }
-
- return fmt.Errorf(
- "'%s': source data must be an array or slice, got %s", name, dataValKind)
-
- }
- if dataVal.Len() > arrayType.Len() {
- return fmt.Errorf(
- "'%s': expected source data to have length less or equal to %d, got %d", name, arrayType.Len(), dataVal.Len())
-
- }
-
- // Make a new array to hold our result, same size as the original data.
- valArray = reflect.New(arrayType).Elem()
- }
-
- // Accumulate any errors
- errors := make([]string, 0)
-
- for i := 0; i < dataVal.Len(); i++ {
- currentData := dataVal.Index(i).Interface()
- currentField := valArray.Index(i)
-
- fieldName := name + "[" + strconv.Itoa(i) + "]"
- if err := d.decode(fieldName, currentData, currentField); err != nil {
- errors = appendErrors(errors, err)
- }
- }
-
- // Finally, set the value to the array we built up
- val.Set(valArray)
-
- // If there were errors, we return those
- if len(errors) > 0 {
- return &Error{errors}
- }
-
- return nil
-}
-
-func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error {
- dataVal := reflect.Indirect(reflect.ValueOf(data))
-
- // If the type of the value to write to and the data match directly,
- // then we just set it directly instead of recursing into the structure.
- if dataVal.Type() == val.Type() {
- val.Set(dataVal)
- return nil
- }
-
- dataValKind := dataVal.Kind()
- switch dataValKind {
- case reflect.Map:
- return d.decodeStructFromMap(name, dataVal, val)
-
- case reflect.Struct:
- // Not the most efficient way to do this but we can optimize later if
- // we want to. To convert from struct to struct we go to map first
- // as an intermediary.
-
- // Make a new map to hold our result
- mapType := reflect.TypeOf((map[string]interface{})(nil))
- mval := reflect.MakeMap(mapType)
-
- // Creating a pointer to a map so that other methods can completely
- // overwrite the map if need be (looking at you decodeMapFromMap). The
- // indirection allows the underlying map to be settable (CanSet() == true)
- // where as reflect.MakeMap returns an unsettable map.
- addrVal := reflect.New(mval.Type())
-
- reflect.Indirect(addrVal).Set(mval)
- if err := d.decodeMapFromStruct(name, dataVal, reflect.Indirect(addrVal), mval); err != nil {
- return err
- }
-
- result := d.decodeStructFromMap(name, reflect.Indirect(addrVal), val)
- return result
-
- default:
- return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
- }
-}
-
-func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) error {
- dataValType := dataVal.Type()
- if kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface {
- return fmt.Errorf(
- "'%s' needs a map with string keys, has '%s' keys",
- name, dataValType.Key().Kind())
- }
-
- dataValKeys := make(map[reflect.Value]struct{})
- dataValKeysUnused := make(map[interface{}]struct{})
- for _, dataValKey := range dataVal.MapKeys() {
- dataValKeys[dataValKey] = struct{}{}
- dataValKeysUnused[dataValKey.Interface()] = struct{}{}
- }
-
- errors := make([]string, 0)
-
- // This slice will keep track of all the structs we'll be decoding.
- // There can be more than one struct if there are embedded structs
- // that are squashed.
- structs := make([]reflect.Value, 1, 5)
- structs[0] = val
-
- // Compile the list of all the fields that we're going to be decoding
- // from all the structs.
- type field struct {
- field reflect.StructField
- val reflect.Value
- }
-
- // remainField is set to a valid field set with the "remain" tag if
- // we are keeping track of remaining values.
- var remainField *field
-
- fields := []field{}
- for len(structs) > 0 {
- structVal := structs[0]
- structs = structs[1:]
-
- structType := structVal.Type()
-
- for i := 0; i < structType.NumField(); i++ {
- fieldType := structType.Field(i)
- fieldVal := structVal.Field(i)
- if fieldVal.Kind() == reflect.Ptr && fieldVal.Elem().Kind() == reflect.Struct {
- // Handle embedded struct pointers as embedded structs.
- fieldVal = fieldVal.Elem()
- }
-
- // If "squash" is specified in the tag, we squash the field down.
- squash := d.config.Squash && fieldVal.Kind() == reflect.Struct && fieldType.Anonymous
- remain := false
-
- // We always parse the tags cause we're looking for other tags too
- tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",")
- for _, tag := range tagParts[1:] {
- if tag == "squash" {
- squash = true
- break
- }
-
- if tag == "remain" {
- remain = true
- break
- }
- }
-
- if squash {
- if fieldVal.Kind() != reflect.Struct {
- errors = appendErrors(errors,
- fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldVal.Kind()))
- } else {
- structs = append(structs, fieldVal)
- }
- continue
- }
-
- // Build our field
- if remain {
- remainField = &field{fieldType, fieldVal}
- } else {
- // Normal struct field, store it away
- fields = append(fields, field{fieldType, fieldVal})
- }
- }
- }
-
- // for fieldType, field := range fields {
- for _, f := range fields {
- field, fieldValue := f.field, f.val
- fieldName := field.Name
-
- tagValue := field.Tag.Get(d.config.TagName)
- tagValue = strings.SplitN(tagValue, ",", 2)[0]
- if tagValue != "" {
- fieldName = tagValue
- }
-
- rawMapKey := reflect.ValueOf(fieldName)
- rawMapVal := dataVal.MapIndex(rawMapKey)
- if !rawMapVal.IsValid() {
- // Do a slower search by iterating over each key and
- // doing case-insensitive search.
- for dataValKey := range dataValKeys {
- mK, ok := dataValKey.Interface().(string)
- if !ok {
- // Not a string key
- continue
- }
-
- if strings.EqualFold(mK, fieldName) {
- rawMapKey = dataValKey
- rawMapVal = dataVal.MapIndex(dataValKey)
- break
- }
- }
-
- if !rawMapVal.IsValid() {
- // There was no matching key in the map for the value in
- // the struct. Just ignore.
- continue
- }
- }
-
- if !fieldValue.IsValid() {
- // This should never happen
- panic("field is not valid")
- }
-
- // If we can't set the field, then it is unexported or something,
- // and we just continue onwards.
- if !fieldValue.CanSet() {
- continue
- }
-
- // Delete the key we're using from the unused map so we stop tracking
- delete(dataValKeysUnused, rawMapKey.Interface())
-
- // If the name is empty string, then we're at the root, and we
- // don't dot-join the fields.
- if name != "" {
- fieldName = name + "." + fieldName
- }
-
- if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil {
- errors = appendErrors(errors, err)
- }
- }
-
- // If we have a "remain"-tagged field and we have unused keys then
- // we put the unused keys directly into the remain field.
- if remainField != nil && len(dataValKeysUnused) > 0 {
- // Build a map of only the unused values
- remain := map[interface{}]interface{}{}
- for key := range dataValKeysUnused {
- remain[key] = dataVal.MapIndex(reflect.ValueOf(key)).Interface()
- }
-
- // Decode it as-if we were just decoding this map onto our map.
- if err := d.decodeMap(name, remain, remainField.val); err != nil {
- errors = appendErrors(errors, err)
- }
-
- // Set the map to nil so we have none so that the next check will
- // not error (ErrorUnused)
- dataValKeysUnused = nil
- }
-
- if d.config.ErrorUnused && len(dataValKeysUnused) > 0 {
- keys := make([]string, 0, len(dataValKeysUnused))
- for rawKey := range dataValKeysUnused {
- keys = append(keys, rawKey.(string))
- }
- sort.Strings(keys)
-
- err := fmt.Errorf("'%s' has invalid keys: %s", name, strings.Join(keys, ", "))
- errors = appendErrors(errors, err)
- }
-
- if len(errors) > 0 {
- return &Error{errors}
- }
-
- // Add the unused keys to the list of unused keys if we're tracking metadata
- if d.config.Metadata != nil {
- for rawKey := range dataValKeysUnused {
- key := rawKey.(string)
- if name != "" {
- key = name + "." + key
- }
-
- d.config.Metadata.Unused = append(d.config.Metadata.Unused, key)
- }
- }
-
- return nil
-}
-
-func isEmptyValue(v reflect.Value) bool {
- switch getKind(v) {
- case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
- return v.Len() == 0
- case reflect.Bool:
- return !v.Bool()
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return v.Int() == 0
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return v.Uint() == 0
- case reflect.Float32, reflect.Float64:
- return v.Float() == 0
- case reflect.Interface, reflect.Ptr:
- return v.IsNil()
- }
- return false
-}
-
-func getKind(val reflect.Value) reflect.Kind {
- kind := val.Kind()
-
- switch {
- case kind >= reflect.Int && kind <= reflect.Int64:
- return reflect.Int
- case kind >= reflect.Uint && kind <= reflect.Uint64:
- return reflect.Uint
- case kind >= reflect.Float32 && kind <= reflect.Float64:
- return reflect.Float32
- default:
- return kind
- }
-}
diff --git a/vendor/github.com/openshift/api/.gitignore b/vendor/github.com/openshift/api/.gitignore
index 760e2df449..1c3e4625d3 100644
--- a/vendor/github.com/openshift/api/.gitignore
+++ b/vendor/github.com/openshift/api/.gitignore
@@ -17,3 +17,5 @@ _output/
tests/bin/
models-schema
+/render
+/write-available-featuresets
diff --git a/vendor/github.com/openshift/api/Dockerfile.rhel8 b/vendor/github.com/openshift/api/Dockerfile.rhel8
new file mode 100644
index 0000000000..62fa30b2c0
--- /dev/null
+++ b/vendor/github.com/openshift/api/Dockerfile.rhel8
@@ -0,0 +1,35 @@
+FROM registry.ci.openshift.org/ocp/builder:rhel-8-golang-1.20-openshift-4.15 AS builder
+WORKDIR /go/src/github.com/openshift/api
+COPY . .
+ENV GO_PACKAGE github.com/openshift/api
+RUN make build --warn-undefined-variables
+
+FROM registry.ci.openshift.org/ocp/4.14:base
+
+# copy the built binaries to /usr/bin
+COPY --from=builder /go/src/github.com/openshift/api/render /usr/bin/
+COPY --from=builder /go/src/github.com/openshift/api/write-available-featuresets /usr/bin/
+
+# this directory is used to produce rendered manifests that the installer applies (but does not maintain) in bootkube
+RUN mkdir -p /usr/share/bootkube/manifests/manifests
+COPY config/v1/*_config-operator_*.yaml /usr/share/bootkube/manifests/manifests
+COPY quota/v1/*.crd.yaml /usr/share/bootkube/manifests/manifests
+COPY security/v1/*.crd.yaml /usr/share/bootkube/manifests/manifests
+COPY securityinternal/v1/*.crd.yaml /usr/share/bootkube/manifests/manifests
+COPY authorization/v1/*.crd.yaml /usr/share/bootkube/manifests/manifests
+COPY operator/v1alpha1/0000_10_config-operator_01_imagecontentsourcepolicy.crd.yaml /usr/share/bootkube/manifests/manifests
+
+# these are applied by the CVO
+COPY manifests /manifests
+# TODO copy these back when we're ready to make the switch from cluster-config-operator to here
+#COPY config/v1/*_config-operator_*.yaml /manifests
+#COPY quota/v1/*.crd.yaml /manifests
+#COPY security/v1/*.crd.yaml /manifests
+#COPY securityinternal/v1/*.crd.yaml /manifests
+#COPY authorization/v1/*.crd.yaml /manifests
+#COPY operator/v1alpha1/0000_10_config-operator_01_imagecontentsourcepolicy.crd.yaml /manifests
+#COPY operator/v1/0000_10_config-operator_*.yaml /manifests
+#COPY payload-command/empty-resources /manifests
+
+# TODO uncomment after all the other "add a new image" steps are complete.
+#LABEL io.openshift.release.operator true
diff --git a/vendor/github.com/openshift/api/Makefile b/vendor/github.com/openshift/api/Makefile
index 9310a72128..69eee4376a 100644
--- a/vendor/github.com/openshift/api/Makefile
+++ b/vendor/github.com/openshift/api/Makefile
@@ -51,12 +51,16 @@ verify-scripts:
bash -x hack/verify-prerelease-lifecycle-gen.sh
.PHONY: verify
-verify: verify-scripts verify-codegen-crds
+verify: verify-scripts verify-crd-schema verify-codegen-crds
.PHONY: verify-codegen-crds
verify-codegen-crds:
bash -x hack/verify-codegen-crds.sh
+.PHONY: verify-crd-schema
+verify-crd-schema:
+ bash -x hack/verify-crd-schema-checker.sh
+
.PHONY: verify-%
verify-%:
make $*
@@ -121,3 +125,47 @@ integration:
tests-vendor:
make -C tests vendor
+
+##################################
+#
+# BEGIN: Build binaries and images
+#
+##################################
+
+.PHONY: build
+build: render write-available-featuresets
+
+render:
+ go build --mod=vendor -trimpath github.com/openshift/api/payload-command/cmd/render
+
+write-available-featuresets:
+ go build --mod=vendor -trimpath github.com/openshift/api/payload-command/cmd/write-available-featuresets
+
+.PHONY: clean
+clean:
+ rm render write-available-featuresets
+
+VERSION ?= $(shell git describe --always --abbrev=7)
+MUTABLE_TAG ?= latest
+IMAGE ?= registry.ci.openshift.org/openshift/api
+
+ifeq ($(shell command -v podman > /dev/null 2>&1 ; echo $$? ), 0)
+ ENGINE=podman
+else ifeq ($(shell command -v docker > /dev/null 2>&1 ; echo $$? ), 0)
+ ENGINE=docker
+endif
+
+USE_DOCKER ?= 0
+ifeq ($(USE_DOCKER), 1)
+ ENGINE=docker
+endif
+
+.PHONY: images
+images:
+ $(ENGINE) build -f Dockerfile.rhel8 -t "$(IMAGE):$(VERSION)" -t "$(IMAGE):$(MUTABLE_TAG)" ./
+
+################################
+#
+# END: Build binaries and images
+#
+################################
diff --git a/vendor/github.com/openshift/api/config/.codegen.yaml b/vendor/github.com/openshift/api/config/.codegen.yaml
index 4523a71eb4..e799336feb 100644
--- a/vendor/github.com/openshift/api/config/.codegen.yaml
+++ b/vendor/github.com/openshift/api/config/.codegen.yaml
@@ -3,5 +3,6 @@ schemapatch:
- ""
- "Default"
- "TechPreviewNoUpgrade"
+ - "CustomNoUpgrade"
swaggerdocs:
commentPolicy: Warn
diff --git a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion.crd.yaml
index 0028eaa7b3..7cf29c2a84 100644
--- a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion.crd.yaml
+++ b/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion.crd.yaml
@@ -72,6 +72,10 @@ spec:
- CSISnapshot
- NodeTuning
- MachineAPI
+ - Build
+ - DeploymentConfig
+ - ImageRegistry
+ - OperatorLifecycleManager
x-kubernetes-list-type: atomic
baselineCapabilitySet:
description: baselineCapabilitySet selects an initial set of optional capabilities to enable, which can be extended via additionalEnabledCapabilities. If unset, the cluster will choose a default, and the default may change over time. The current default is vCurrent.
@@ -195,6 +199,10 @@ spec:
- CSISnapshot
- NodeTuning
- MachineAPI
+ - Build
+ - DeploymentConfig
+ - ImageRegistry
+ - OperatorLifecycleManager
x-kubernetes-list-type: atomic
knownCapabilities:
description: knownCapabilities lists all the capabilities known to the current cluster.
@@ -212,6 +220,10 @@ spec:
- CSISnapshot
- NodeTuning
- MachineAPI
+ - Build
+ - DeploymentConfig
+ - ImageRegistry
+ - OperatorLifecycleManager
x-kubernetes-list-type: atomic
conditionalUpdates:
description: conditionalUpdates contains the list of updates that may be recommended for this cluster if it meets specific required conditions. Consumers interested in the set of updates that are actually recommended for this cluster should use availableUpdates. This list may be empty if no updates are recommended, if the update service is unavailable, or if an empty or invalid channel has been specified.
@@ -433,6 +445,11 @@ spec:
versionHash:
description: versionHash is a fingerprint of the content that the cluster will be updated with. It is used by the operator to avoid unnecessary work and is for internal use only.
type: string
+ x-kubernetes-validations:
+ - rule: 'has(self.spec.capabilities) && has(self.spec.capabilities.additionalEnabledCapabilities) && self.spec.capabilities.baselineCapabilitySet == ''None'' && ''baremetal'' in self.spec.capabilities.additionalEnabledCapabilities ? ''MachineAPI'' in self.spec.capabilities.additionalEnabledCapabilities || (has(self.status) && has(self.status.capabilities) && has(self.status.capabilities.enabledCapabilities) && ''MachineAPI'' in self.status.capabilities.enabledCapabilities) : true'
+ message: the `baremetal` capability requires the `MachineAPI` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `MachineAPI` capability
+ - rule: 'has(self.spec.capabilities) && has(self.spec.capabilities.additionalEnabledCapabilities) && self.spec.capabilities.baselineCapabilitySet == ''None'' && ''marketplace'' in self.spec.capabilities.additionalEnabledCapabilities ? ''OperatorLifecycleManager'' in self.spec.capabilities.additionalEnabledCapabilities || (has(self.status) && has(self.status.capabilities) && has(self.status.capabilities.enabledCapabilities) && ''OperatorLifecycleManager'' in self.status.capabilities.enabledCapabilities) : true'
+ message: the `marketplace` capability requires the `OperatorLifecycleManager` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `OperatorLifecycleManager` capability
served: true
storage: true
subresources:
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_apiserver-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_apiserver-CustomNoUpgrade.crd.yaml
new file mode 100644
index 0000000000..1895f9d33e
--- /dev/null
+++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_apiserver-CustomNoUpgrade.crd.yaml
@@ -0,0 +1,179 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ api-approved.openshift.io: https://github.com/openshift/api/pull/470
+ include.release.openshift.io/ibm-cloud-managed: "true"
+ include.release.openshift.io/self-managed-high-availability: "true"
+ include.release.openshift.io/single-node-developer: "true"
+ release.openshift.io/feature-set: CustomNoUpgrade
+ name: apiservers.config.openshift.io
+spec:
+ group: config.openshift.io
+ names:
+ kind: APIServer
+ listKind: APIServerList
+ plural: apiservers
+ singular: apiserver
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ description: "APIServer holds configuration (like serving certificates, client CA and CORS domains) shared by all API servers in the system, among them especially kube-apiserver and openshift-apiserver. The canonical name of an instance is 'cluster'. \n Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer)."
+ type: object
+ required:
+ - spec
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: spec holds user settable values for configuration
+ type: object
+ properties:
+ additionalCORSAllowedOrigins:
+ description: additionalCORSAllowedOrigins lists additional, user-defined regular expressions describing hosts for which the API server allows access using the CORS headers. This may be needed to access the API and the integrated OAuth server from JavaScript applications. The values are regular expressions that correspond to the Golang regular expression language.
+ type: array
+ items:
+ type: string
+ audit:
+ description: audit specifies the settings for audit configuration to be applied to all OpenShift-provided API servers in the cluster.
+ type: object
+ default:
+ profile: Default
+ properties:
+ customRules:
+ description: customRules specify profiles per group. These profile take precedence over the top-level profile field if they apply. They are evaluation from top to bottom and the first one that matches, applies.
+ type: array
+ items:
+ description: AuditCustomRule describes a custom rule for an audit profile that takes precedence over the top-level profile.
+ type: object
+ required:
+ - group
+ - profile
+ properties:
+ group:
+ description: group is a name of group a request user must be member of in order to this profile to apply.
+ type: string
+ minLength: 1
+ profile:
+ description: "profile specifies the name of the desired audit policy configuration to be deployed to all OpenShift-provided API servers in the cluster. \n The following profiles are provided: - Default: the existing default policy. - WriteRequestBodies: like 'Default', but logs request and response HTTP payloads for write requests (create, update, patch). - AllRequestBodies: like 'WriteRequestBodies', but also logs request and response HTTP payloads for read requests (get, list). - None: no requests are logged at all, not even oauthaccesstokens and oauthauthorizetokens. \n If unset, the 'Default' profile is used as the default."
+ type: string
+ enum:
+ - Default
+ - WriteRequestBodies
+ - AllRequestBodies
+ - None
+ x-kubernetes-list-map-keys:
+ - group
+ x-kubernetes-list-type: map
+ profile:
+ description: "profile specifies the name of the desired top-level audit profile to be applied to all requests sent to any of the OpenShift-provided API servers in the cluster (kube-apiserver, openshift-apiserver and oauth-apiserver), with the exception of those requests that match one or more of the customRules. \n The following profiles are provided: - Default: default policy which means MetaData level logging with the exception of events (not logged at all), oauthaccesstokens and oauthauthorizetokens (both logged at RequestBody level). - WriteRequestBodies: like 'Default', but logs request and response HTTP payloads for write requests (create, update, patch). - AllRequestBodies: like 'WriteRequestBodies', but also logs request and response HTTP payloads for read requests (get, list). - None: no requests are logged at all, not even oauthaccesstokens and oauthauthorizetokens. \n Warning: It is not recommended to disable audit logging by using the `None` profile unless you are fully aware of the risks of not logging data that can be beneficial when troubleshooting issues. If you disable audit logging and a support situation arises, you might need to enable audit logging and reproduce the issue in order to troubleshoot properly. \n If unset, the 'Default' profile is used as the default."
+ type: string
+ default: Default
+ enum:
+ - Default
+ - WriteRequestBodies
+ - AllRequestBodies
+ - None
+ clientCA:
+ description: 'clientCA references a ConfigMap containing a certificate bundle for the signers that will be recognized for incoming client certificates in addition to the operator managed signers. If this is empty, then only operator managed signers are valid. You usually only have to set this if you have your own PKI you wish to honor client certificates from. The ConfigMap must exist in the openshift-config namespace and contain the following required fields: - ConfigMap.Data["ca-bundle.crt"] - CA bundle.'
+ type: object
+ required:
+ - name
+ properties:
+ name:
+ description: name is the metadata.name of the referenced config map
+ type: string
+ encryption:
+ description: encryption allows the configuration of encryption of resources at the datastore layer.
+ type: object
+ properties:
+ type:
+ description: "type defines what encryption type should be used to encrypt resources at the datastore layer. When this field is unset (i.e. when it is set to the empty string), identity is implied. The behavior of unset can and will change over time. Even if encryption is enabled by default, the meaning of unset may change to a different encryption type based on changes in best practices. \n When encryption is enabled, all sensitive resources shipped with the platform are encrypted. This list of sensitive resources can and will change over time. The current authoritative list is: \n 1. secrets 2. configmaps 3. routes.route.openshift.io 4. oauthaccesstokens.oauth.openshift.io 5. oauthauthorizetokens.oauth.openshift.io"
+ type: string
+ enum:
+ - ""
+ - identity
+ - aescbc
+ - aesgcm
+ servingCerts:
+ description: servingCert is the TLS cert info for serving secure traffic. If not specified, operator managed certificates will be used for serving secure traffic.
+ type: object
+ properties:
+ namedCertificates:
+ description: namedCertificates references secrets containing the TLS cert info for serving secure traffic to specific hostnames. If no named certificates are provided, or no named certificates match the server name as understood by a client, the defaultServingCertificate will be used.
+ type: array
+ items:
+ description: APIServerNamedServingCert maps a server DNS name, as understood by a client, to a certificate.
+ type: object
+ properties:
+ names:
+ description: names is a optional list of explicit DNS names (leading wildcards allowed) that should use this certificate to serve secure traffic. If no names are provided, the implicit names will be extracted from the certificates. Exact names trump over wildcard names. Explicit names defined here trump over extracted implicit names.
+ type: array
+ items:
+ type: string
+ servingCertificate:
+ description: 'servingCertificate references a kubernetes.io/tls type secret containing the TLS cert info for serving secure traffic. The secret must exist in the openshift-config namespace and contain the following required fields: - Secret.Data["tls.key"] - TLS private key. - Secret.Data["tls.crt"] - TLS certificate.'
+ type: object
+ required:
+ - name
+ properties:
+ name:
+ description: name is the metadata.name of the referenced secret
+ type: string
+ tlsSecurityProfile:
+ description: "tlsSecurityProfile specifies settings for TLS connections for externally exposed servers. \n If unset, a default (which may change between releases) is chosen. Note that only Old, Intermediate and Custom profiles are currently supported, and the maximum available MinTLSVersions is VersionTLS12."
+ type: object
+ properties:
+ custom:
+ description: "custom is a user-defined TLS security profile. Be extremely careful using a custom profile as invalid configurations can be catastrophic. An example custom profile looks like this: \n ciphers: - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305 - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256 minTLSVersion: TLSv1.1"
+ type: object
+ properties:
+ ciphers:
+ description: "ciphers is used to specify the cipher algorithms that are negotiated during the TLS handshake. Operators may remove entries their operands do not support. For example, to use DES-CBC3-SHA (yaml): \n ciphers: - DES-CBC3-SHA"
+ type: array
+ items:
+ type: string
+ minTLSVersion:
+ description: "minTLSVersion is used to specify the minimal version of the TLS protocol that is negotiated during the TLS handshake. For example, to use TLS versions 1.1, 1.2 and 1.3 (yaml): \n minTLSVersion: TLSv1.1 \n NOTE: currently the highest minTLSVersion allowed is VersionTLS12"
+ type: string
+ enum:
+ - VersionTLS10
+ - VersionTLS11
+ - VersionTLS12
+ - VersionTLS13
+ nullable: true
+ intermediate:
+ description: "intermediate is a TLS security profile based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29 \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256 - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305 - DHE-RSA-AES128-GCM-SHA256 - DHE-RSA-AES256-GCM-SHA384 minTLSVersion: TLSv1.2"
+ type: object
+ nullable: true
+ modern:
+ description: "modern is a TLS security profile based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256 - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 minTLSVersion: TLSv1.3 \n NOTE: Currently unsupported."
+ type: object
+ nullable: true
+ old:
+ description: "old is a TLS security profile based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256 - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305 - DHE-RSA-AES128-GCM-SHA256 - DHE-RSA-AES256-GCM-SHA384 - DHE-RSA-CHACHA20-POLY1305 - ECDHE-ECDSA-AES128-SHA256 - ECDHE-RSA-AES128-SHA256 - ECDHE-ECDSA-AES128-SHA - ECDHE-RSA-AES128-SHA - ECDHE-ECDSA-AES256-SHA384 - ECDHE-RSA-AES256-SHA384 - ECDHE-ECDSA-AES256-SHA - ECDHE-RSA-AES256-SHA - DHE-RSA-AES128-SHA256 - DHE-RSA-AES256-SHA256 - AES128-GCM-SHA256 - AES256-GCM-SHA384 - AES128-SHA256 - AES256-SHA256 - AES128-SHA - AES256-SHA - DES-CBC3-SHA minTLSVersion: TLSv1.0"
+ type: object
+ nullable: true
+ type:
+ description: "type is one of Old, Intermediate, Modern or Custom. Custom provides the ability to specify individual TLS security profile parameters. Old, Intermediate and Modern are TLS security profiles based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations \n The profiles are intent based, so they may change over time as new ciphers are developed and existing ciphers are found to be insecure. Depending on precisely which ciphers are available to a process, the list may be reduced. \n Note that the Modern profile is currently not supported because it is not yet well adopted by common software libraries."
+ type: string
+ enum:
+ - Old
+ - Intermediate
+ - Modern
+ - Custom
+ status:
+ description: status holds observed values from the cluster. They may not be overridden.
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns-CustomNoUpgrade.crd.yaml
new file mode 100644
index 0000000000..9da62cbfe1
--- /dev/null
+++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns-CustomNoUpgrade.crd.yaml
@@ -0,0 +1,114 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ api-approved.openshift.io: https://github.com/openshift/api/pull/470
+ include.release.openshift.io/ibm-cloud-managed: "true"
+ include.release.openshift.io/self-managed-high-availability: "true"
+ include.release.openshift.io/single-node-developer: "true"
+ release.openshift.io/feature-set: CustomNoUpgrade
+ name: dnses.config.openshift.io
+spec:
+ group: config.openshift.io
+ names:
+ kind: DNS
+ listKind: DNSList
+ plural: dnses
+ singular: dns
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ description: "DNS holds cluster-wide information about DNS. The canonical name is `cluster` \n Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer)."
+ type: object
+ required:
+ - spec
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: spec holds user settable values for configuration
+ type: object
+ properties:
+ baseDomain:
+ description: "baseDomain is the base domain of the cluster. All managed DNS records will be sub-domains of this base. \n For example, given the base domain `openshift.example.com`, an API server DNS record may be created for `cluster-api.openshift.example.com`. \n Once set, this field cannot be changed."
+ type: string
+ platform:
+ description: platform holds configuration specific to the underlying infrastructure provider for DNS. When omitted, this means the user has no opinion and the platform is left to choose reasonable defaults. These defaults are subject to change over time.
+ type: object
+ required:
+ - type
+ properties:
+ aws:
+ description: aws contains DNS configuration specific to the Amazon Web Services cloud provider.
+ type: object
+ properties:
+ privateZoneIAMRole:
+ description: privateZoneIAMRole contains the ARN of an IAM role that should be assumed when performing operations on the cluster's private hosted zone specified in the cluster DNS config. When left empty, no role should be assumed.
+ type: string
+ pattern: ^arn:(aws|aws-cn|aws-us-gov):iam::[0-9]{12}:role\/.*$
+ type:
+ description: "type is the underlying infrastructure provider for the cluster. Allowed values: \"\", \"AWS\". \n Individual components may not support all platforms, and must handle unrecognized platforms with best-effort defaults."
+ type: string
+ enum:
+ - ""
+ - AWS
+ - Azure
+ - BareMetal
+ - GCP
+ - Libvirt
+ - OpenStack
+ - None
+ - VSphere
+ - oVirt
+ - IBMCloud
+ - KubeVirt
+ - EquinixMetal
+ - PowerVS
+ - AlibabaCloud
+ - Nutanix
+ - External
+ x-kubernetes-validations:
+ - rule: self in ['','AWS']
+ message: allowed values are '' and 'AWS'
+ x-kubernetes-validations:
+ - rule: 'has(self.type) && self.type == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ message: aws configuration is required when platform is AWS, and forbidden otherwise
+ privateZone:
+ description: "privateZone is the location where all the DNS records that are only available internally to the cluster exist. \n If this field is nil, no private records should be created. \n Once set, this field cannot be changed."
+ type: object
+ properties:
+ id:
+ description: "id is the identifier that can be used to find the DNS hosted zone. \n on AWS zone can be fetched using `ID` as id in [1] on Azure zone can be fetched using `ID` as a pre-determined name in [2], on GCP zone can be fetched using `ID` as a pre-determined name in [3]. \n [1]: https://docs.aws.amazon.com/cli/latest/reference/route53/get-hosted-zone.html#options [2]: https://docs.microsoft.com/en-us/cli/azure/network/dns/zone?view=azure-cli-latest#az-network-dns-zone-show [3]: https://cloud.google.com/dns/docs/reference/v1/managedZones/get"
+ type: string
+ tags:
+ description: "tags can be used to query the DNS hosted zone. \n on AWS, resourcegroupstaggingapi [1] can be used to fetch a zone using `Tags` as tag-filters, \n [1]: https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html#options"
+ type: object
+ additionalProperties:
+ type: string
+ publicZone:
+ description: "publicZone is the location where all the DNS records that are publicly accessible to the internet exist. \n If this field is nil, no public records should be created. \n Once set, this field cannot be changed."
+ type: object
+ properties:
+ id:
+ description: "id is the identifier that can be used to find the DNS hosted zone. \n on AWS zone can be fetched using `ID` as id in [1] on Azure zone can be fetched using `ID` as a pre-determined name in [2], on GCP zone can be fetched using `ID` as a pre-determined name in [3]. \n [1]: https://docs.aws.amazon.com/cli/latest/reference/route53/get-hosted-zone.html#options [2]: https://docs.microsoft.com/en-us/cli/azure/network/dns/zone?view=azure-cli-latest#az-network-dns-zone-show [3]: https://cloud.google.com/dns/docs/reference/v1/managedZones/get"
+ type: string
+ tags:
+ description: "tags can be used to query the DNS hosted zone. \n on AWS, resourcegroupstaggingapi [1] can be used to fetch a zone using `Tags` as tag-filters, \n [1]: https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html#options"
+ type: object
+ additionalProperties:
+ type: string
+ status:
+ description: status holds observed values from the cluster. They may not be overridden.
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns-Default.crd.yaml
similarity index 68%
rename from vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns.crd.yaml
rename to vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns-Default.crd.yaml
index bbf40f65e1..62080e10e1 100644
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns.crd.yaml
+++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns-Default.crd.yaml
@@ -40,6 +40,47 @@ spec:
baseDomain:
description: "baseDomain is the base domain of the cluster. All managed DNS records will be sub-domains of this base. \n For example, given the base domain `openshift.example.com`, an API server DNS record may be created for `cluster-api.openshift.example.com`. \n Once set, this field cannot be changed."
type: string
+ platform:
+ description: platform holds configuration specific to the underlying infrastructure provider for DNS. When omitted, this means the user has no opinion and the platform is left to choose reasonable defaults. These defaults are subject to change over time.
+ type: object
+ required:
+ - type
+ properties:
+ aws:
+ description: aws contains DNS configuration specific to the Amazon Web Services cloud provider.
+ type: object
+ properties:
+ privateZoneIAMRole:
+ description: privateZoneIAMRole contains the ARN of an IAM role that should be assumed when performing operations on the cluster's private hosted zone specified in the cluster DNS config. When left empty, no role should be assumed.
+ type: string
+ pattern: ^arn:(aws|aws-cn|aws-us-gov):iam::[0-9]{12}:role\/.*$
+ type:
+ description: "type is the underlying infrastructure provider for the cluster. Allowed values: \"\", \"AWS\". \n Individual components may not support all platforms, and must handle unrecognized platforms with best-effort defaults."
+ type: string
+ enum:
+ - ""
+ - AWS
+ - Azure
+ - BareMetal
+ - GCP
+ - Libvirt
+ - OpenStack
+ - None
+ - VSphere
+ - oVirt
+ - IBMCloud
+ - KubeVirt
+ - EquinixMetal
+ - PowerVS
+ - AlibabaCloud
+ - Nutanix
+ - External
+ x-kubernetes-validations:
+ - rule: self in ['','AWS']
+ message: allowed values are '' and 'AWS'
+ x-kubernetes-validations:
+ - rule: 'has(self.type) && self.type == ''AWS'' ? has(self.aws) : !has(self.aws)'
+ message: aws configuration is required when platform is AWS, and forbidden otherwise
privateZone:
description: "privateZone is the location where all the DNS records that are only available internally to the cluster exist. \n If this field is nil, no private records should be created. \n Once set, this field cannot be changed."
type: object
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_image.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_image.crd.yaml
index a160fef40f..bc320544ec 100644
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_image.crd.yaml
+++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_image.crd.yaml
@@ -100,7 +100,7 @@ spec:
items:
type: string
internalRegistryHostname:
- description: internalRegistryHostname sets the hostname for the default internal image registry. The value must be in "hostname[:port]" format. This value is set by the image registry operator which controls the internal registry hostname. For backward compatibility, users can still use OPENSHIFT_DEFAULT_REGISTRY environment variable but this setting overrides the environment variable.
+ description: internalRegistryHostname sets the hostname for the default internal image registry. The value must be in "hostname[:port]" format. This value is set by the image registry operator which controls the internal registry hostname.
type: string
served: true
storage: true
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml
new file mode 100644
index 0000000000..1b96b19c7e
--- /dev/null
+++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml
@@ -0,0 +1,1023 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ api-approved.openshift.io: https://github.com/openshift/api/pull/470
+ include.release.openshift.io/ibm-cloud-managed: "true"
+ include.release.openshift.io/self-managed-high-availability: "true"
+ include.release.openshift.io/single-node-developer: "true"
+ release.openshift.io/feature-set: CustomNoUpgrade
+ name: infrastructures.config.openshift.io
+spec:
+ group: config.openshift.io
+ names:
+ kind: Infrastructure
+ listKind: InfrastructureList
+ plural: infrastructures
+ singular: infrastructure
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ description: "Infrastructure holds cluster-wide information about Infrastructure. The canonical name is `cluster` \n Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer)."
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: spec holds user settable values for configuration
+ properties:
+ cloudConfig:
+ description: "cloudConfig is a reference to a ConfigMap containing the cloud provider configuration file. This configuration file is used to configure the Kubernetes cloud provider integration when using the built-in cloud provider integration or the external cloud controller manager. The namespace for this config map is openshift-config. \n cloudConfig should only be consumed by the kube_cloud_config controller. The controller is responsible for using the user configuration in the spec for various platforms and combining that with the user provided ConfigMap in this field to create a stitched kube cloud config. The controller generates a ConfigMap `kube-cloud-config` in `openshift-config-managed` namespace with the kube cloud config is stored in `cloud.conf` key. All the clients are expected to use the generated ConfigMap only."
+ properties:
+ key:
+ description: Key allows pointing to a specific key/value inside of the configmap. This is useful for logical file references.
+ type: string
+ name:
+ type: string
+ type: object
+ platformSpec:
+ description: platformSpec holds desired information specific to the underlying infrastructure provider.
+ properties:
+ alibabaCloud:
+ description: AlibabaCloud contains settings specific to the Alibaba Cloud infrastructure provider.
+ type: object
+ aws:
+ description: AWS contains settings specific to the Amazon Web Services infrastructure provider.
+ properties:
+ serviceEndpoints:
+ description: serviceEndpoints list contains custom endpoints which will override default service endpoint of AWS Services. There must be only one ServiceEndpoint for a service.
+ items:
+ description: AWSServiceEndpoint store the configuration of a custom url to override existing defaults of AWS Services.
+ properties:
+ name:
+ description: name is the name of the AWS service. The list of all the service names can be found at https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html This must be provided and cannot be empty.
+ pattern: ^[a-z0-9-]+$
+ type: string
+ url:
+ description: url is fully qualified URI with scheme https, that overrides the default generated endpoint for a client. This must be provided and cannot be empty.
+ pattern: ^https://
+ type: string
+ type: object
+ type: array
+ type: object
+ azure:
+ description: Azure contains settings specific to the Azure infrastructure provider.
+ type: object
+ baremetal:
+ description: BareMetal contains settings specific to the BareMetal platform.
+ type: object
+ equinixMetal:
+ description: EquinixMetal contains settings specific to the Equinix Metal infrastructure provider.
+ type: object
+ external:
+ description: ExternalPlatformType represents generic infrastructure provider. Platform-specific components should be supplemented separately.
+ properties:
+ platformName:
+ default: Unknown
+ description: PlatformName holds the arbitrary string representing the infrastructure provider name, expected to be set at the installation time. This field is solely for informational and reporting purposes and is not expected to be used for decision-making.
+ type: string
+ x-kubernetes-validations:
+ - message: platform name cannot be changed once set
+ rule: oldSelf == 'Unknown' || self == oldSelf
+ type: object
+ gcp:
+ description: GCP contains settings specific to the Google Cloud Platform infrastructure provider.
+ type: object
+ ibmcloud:
+ description: IBMCloud contains settings specific to the IBMCloud infrastructure provider.
+ type: object
+ kubevirt:
+ description: Kubevirt contains settings specific to the kubevirt infrastructure provider.
+ type: object
+ nutanix:
+ description: Nutanix contains settings specific to the Nutanix infrastructure provider.
+ properties:
+ prismCentral:
+ description: prismCentral holds the endpoint address and port to access the Nutanix Prism Central. When a cluster-wide proxy is installed, by default, this endpoint will be accessed via the proxy. Should you wish for communication with this endpoint not to be proxied, please add the endpoint to the proxy spec.noProxy list.
+ properties:
+ address:
+ description: address is the endpoint address (DNS name or IP address) of the Nutanix Prism Central or Element (cluster)
+ maxLength: 256
+ type: string
+ port:
+ description: port is the port number to access the Nutanix Prism Central or Element (cluster)
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - address
+ - port
+ type: object
+ prismElements:
+ description: prismElements holds one or more endpoint address and port data to access the Nutanix Prism Elements (clusters) of the Nutanix Prism Central. Currently we only support one Prism Element (cluster) for an OpenShift cluster, where all the Nutanix resources (VMs, subnets, volumes, etc.) used in the OpenShift cluster are located. In the future, we may support Nutanix resources (VMs, etc.) spread over multiple Prism Elements (clusters) of the Prism Central.
+ items:
+ description: NutanixPrismElementEndpoint holds the name and endpoint data for a Prism Element (cluster)
+ properties:
+ endpoint:
+ description: endpoint holds the endpoint address and port data of the Prism Element (cluster). When a cluster-wide proxy is installed, by default, this endpoint will be accessed via the proxy. Should you wish for communication with this endpoint not to be proxied, please add the endpoint to the proxy spec.noProxy list.
+ properties:
+ address:
+ description: address is the endpoint address (DNS name or IP address) of the Nutanix Prism Central or Element (cluster)
+ maxLength: 256
+ type: string
+ port:
+ description: port is the port number to access the Nutanix Prism Central or Element (cluster)
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - address
+ - port
+ type: object
+ name:
+ description: name is the name of the Prism Element (cluster). This value will correspond with the cluster field configured on other resources (eg Machines, PVCs, etc).
+ maxLength: 256
+ type: string
+ required:
+ - endpoint
+ - name
+ type: object
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
+ required:
+ - prismCentral
+ - prismElements
+ type: object
+ openstack:
+ description: OpenStack contains settings specific to the OpenStack infrastructure provider.
+ type: object
+ ovirt:
+ description: Ovirt contains settings specific to the oVirt infrastructure provider.
+ type: object
+ powervs:
+ description: PowerVS contains settings specific to the IBM Power Systems Virtual Servers infrastructure provider.
+ properties:
+ serviceEndpoints:
+ description: serviceEndpoints is a list of custom endpoints which will override the default service endpoints of a Power VS service.
+ items:
+ description: PowervsServiceEndpoint stores the configuration of a custom url to override existing defaults of PowerVS Services.
+ properties:
+ name:
+ description: name is the name of the Power VS service. Few of the services are IAM - https://cloud.ibm.com/apidocs/iam-identity-token-api ResourceController - https://cloud.ibm.com/apidocs/resource-controller/resource-controller Power Cloud - https://cloud.ibm.com/apidocs/power-cloud
+ pattern: ^[a-z0-9-]+$
+ type: string
+ url:
+ description: url is fully qualified URI with scheme https, that overrides the default generated endpoint for a client. This must be provided and cannot be empty.
+ format: uri
+ pattern: ^https://
+ type: string
+ required:
+ - name
+ - url
+ type: object
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
+ type: object
+ type:
+ description: type is the underlying infrastructure provider for the cluster. This value controls whether infrastructure automation such as service load balancers, dynamic volume provisioning, machine creation and deletion, and other integrations are enabled. If None, no infrastructure automation is enabled. Allowed values are "AWS", "Azure", "BareMetal", "GCP", "Libvirt", "OpenStack", "VSphere", "oVirt", "KubeVirt", "EquinixMetal", "PowerVS", "AlibabaCloud", "Nutanix" and "None". Individual components may not support all platforms, and must handle unrecognized platforms as None if they do not support that platform.
+ enum:
+ - ""
+ - AWS
+ - Azure
+ - BareMetal
+ - GCP
+ - Libvirt
+ - OpenStack
+ - None
+ - VSphere
+ - oVirt
+ - IBMCloud
+ - KubeVirt
+ - EquinixMetal
+ - PowerVS
+ - AlibabaCloud
+ - Nutanix
+ - External
+ type: string
+ vsphere:
+ description: VSphere contains settings specific to the VSphere infrastructure provider.
+ properties:
+ failureDomains:
+ description: failureDomains contains the definition of region, zone and the vCenter topology. If this is omitted failure domains (regions and zones) will not be used.
+ items:
+ description: VSpherePlatformFailureDomainSpec holds the region and zone failure domain and the vCenter topology of that failure domain.
+ properties:
+ name:
+ description: name defines the arbitrary but unique name of a failure domain.
+ maxLength: 256
+ minLength: 1
+ type: string
+ region:
+ description: region defines the name of a region tag that will be attached to a vCenter datacenter. The tag category in vCenter must be named openshift-region.
+ maxLength: 80
+ minLength: 1
+ type: string
+ server:
+ anyOf:
+ - format: ipv4
+ - format: ipv6
+ - format: hostname
+ description: server is the fully-qualified domain name or the IP address of the vCenter server. ---
+ maxLength: 255
+ minLength: 1
+ type: string
+ topology:
+ description: Topology describes a given failure domain using vSphere constructs
+ properties:
+ computeCluster:
+ description: computeCluster the absolute path of the vCenter cluster in which virtual machine will be located. The absolute path is of the form //host/. The maximum length of the path is 2048 characters.
+ maxLength: 2048
+ pattern: ^/.*?/host/.*?
+ type: string
+ datacenter:
+ description: datacenter is the name of vCenter datacenter in which virtual machines will be located. The maximum length of the datacenter name is 80 characters.
+ maxLength: 80
+ type: string
+ datastore:
+ description: datastore is the absolute path of the datastore in which the virtual machine is located. The absolute path is of the form //datastore/ The maximum length of the path is 2048 characters.
+ maxLength: 2048
+ pattern: ^/.*?/datastore/.*?
+ type: string
+ folder:
+ description: folder is the absolute path of the folder where virtual machines are located. The absolute path is of the form //vm/. The maximum length of the path is 2048 characters.
+ maxLength: 2048
+ pattern: ^/.*?/vm/.*?
+ type: string
+ networks:
+ description: networks is the list of port group network names within this failure domain. Currently, we only support a single interface per RHCOS virtual machine. The available networks (port groups) can be listed using `govc ls 'network/*'` The single interface should be the absolute path of the form //network/.
+ items:
+ type: string
+ maxItems: 1
+ minItems: 1
+ type: array
+ resourcePool:
+ description: resourcePool is the absolute path of the resource pool where virtual machines will be created. The absolute path is of the form //host//Resources/. The maximum length of the path is 2048 characters.
+ maxLength: 2048
+ pattern: ^/.*?/host/.*?/Resources.*
+ type: string
+ required:
+ - computeCluster
+ - datacenter
+ - datastore
+ - networks
+ type: object
+ zone:
+ description: zone defines the name of a zone tag that will be attached to a vCenter cluster. The tag category in vCenter must be named openshift-zone.
+ maxLength: 80
+ minLength: 1
+ type: string
+ required:
+ - name
+ - region
+ - server
+ - topology
+ - zone
+ type: object
+ type: array
+ nodeNetworking:
+ description: nodeNetworking contains the definition of internal and external network constraints for assigning the node's networking. If this field is omitted, networking defaults to the legacy address selection behavior which is to only support a single address and return the first one found.
+ properties:
+ external:
+ description: external represents the network configuration of the node that is externally routable.
+ properties:
+ excludeNetworkSubnetCidr:
+ description: excludeNetworkSubnetCidr IP addresses in subnet ranges will be excluded when selecting the IP address from the VirtualMachine's VM for use in the status.addresses fields. ---
+ items:
+ format: cidr
+ type: string
+ type: array
+ network:
+ description: network VirtualMachine's VM Network names that will be used to when searching for status.addresses fields. Note that if internal.networkSubnetCIDR and external.networkSubnetCIDR are not set, then the vNIC associated to this network must only have a single IP address assigned to it. The available networks (port groups) can be listed using `govc ls 'network/*'`
+ type: string
+ networkSubnetCidr:
+ description: networkSubnetCidr IP address on VirtualMachine's network interfaces included in the fields' CIDRs that will be used in respective status.addresses fields. ---
+ items:
+ format: cidr
+ type: string
+ type: array
+ type: object
+ internal:
+ description: internal represents the network configuration of the node that is routable only within the cluster.
+ properties:
+ excludeNetworkSubnetCidr:
+ description: excludeNetworkSubnetCidr IP addresses in subnet ranges will be excluded when selecting the IP address from the VirtualMachine's VM for use in the status.addresses fields. ---
+ items:
+ format: cidr
+ type: string
+ type: array
+ network:
+ description: network VirtualMachine's VM Network names that will be used to when searching for status.addresses fields. Note that if internal.networkSubnetCIDR and external.networkSubnetCIDR are not set, then the vNIC associated to this network must only have a single IP address assigned to it. The available networks (port groups) can be listed using `govc ls 'network/*'`
+ type: string
+ networkSubnetCidr:
+ description: networkSubnetCidr IP address on VirtualMachine's network interfaces included in the fields' CIDRs that will be used in respective status.addresses fields. ---
+ items:
+ format: cidr
+ type: string
+ type: array
+ type: object
+ type: object
+ vcenters:
+ description: vcenters holds the connection details for services to communicate with vCenter. Currently, only a single vCenter is supported. ---
+ items:
+ description: VSpherePlatformVCenterSpec stores the vCenter connection fields. This is used by the vSphere CCM.
+ properties:
+ datacenters:
+ description: The vCenter Datacenters in which the RHCOS vm guests are located. This field will be used by the Cloud Controller Manager. Each datacenter listed here should be used within a topology.
+ items:
+ type: string
+ minItems: 1
+ type: array
+ port:
+ description: port is the TCP port that will be used to communicate to the vCenter endpoint. When omitted, this means the user has no opinion and it is up to the platform to choose a sensible default, which is subject to change over time.
+ format: int32
+ maximum: 32767
+ minimum: 1
+ type: integer
+ server:
+ anyOf:
+ - format: ipv4
+ - format: ipv6
+ - format: hostname
+ description: server is the fully-qualified domain name or the IP address of the vCenter server. ---
+ maxLength: 255
+ type: string
+ required:
+ - datacenters
+ - server
+ type: object
+ maxItems: 1
+ minItems: 0
+ type: array
+ type: object
+ type: object
+ type: object
+ status:
+ description: status holds observed values from the cluster. They may not be overridden.
+ properties:
+ apiServerInternalURI:
+ description: apiServerInternalURL is a valid URI with scheme 'https', address and optionally a port (defaulting to 443). apiServerInternalURL can be used by components like kubelets, to contact the Kubernetes API server using the infrastructure provider rather than Kubernetes networking.
+ type: string
+ apiServerURL:
+ description: apiServerURL is a valid URI with scheme 'https', address and optionally a port (defaulting to 443). apiServerURL can be used by components like the web console to tell users where to find the Kubernetes API.
+ type: string
+ controlPlaneTopology:
+ default: HighlyAvailable
+ description: controlPlaneTopology expresses the expectations for operands that normally run on control nodes. The default is 'HighlyAvailable', which represents the behavior operators have in a "normal" cluster. The 'SingleReplica' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation The 'External' mode indicates that the control plane is hosted externally to the cluster and that its components are not visible within the cluster.
+ enum:
+ - HighlyAvailable
+ - SingleReplica
+ - External
+ type: string
+ cpuPartitioning:
+ default: None
+ description: cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. Valid values are "None" and "AllNodes". When omitted, the default value is "None". The default value of "None" indicates that no nodes will be setup with CPU partitioning. The "AllNodes" value indicates that all nodes have been setup with CPU partitioning, and can then be further configured via the PerformanceProfile API.
+ enum:
+ - None
+ - AllNodes
+ type: string
+ etcdDiscoveryDomain:
+ description: 'etcdDiscoveryDomain is the domain used to fetch the SRV records for discovering etcd servers and clients. For more info: https://github.com/etcd-io/etcd/blob/329be66e8b3f9e2e6af83c123ff89297e49ebd15/Documentation/op-guide/clustering.md#dns-discovery deprecated: as of 4.7, this field is no longer set or honored. It will be removed in a future release.'
+ type: string
+ infrastructureName:
+ description: infrastructureName uniquely identifies a cluster with a human friendly name. Once set it should not be changed. Must be of max length 27 and must have only alphanumeric or hyphen characters.
+ type: string
+ infrastructureTopology:
+ default: HighlyAvailable
+ description: 'infrastructureTopology expresses the expectations for infrastructure services that do not run on control plane nodes, usually indicated by a node selector for a `role` value other than `master`. The default is ''HighlyAvailable'', which represents the behavior operators have in a "normal" cluster. The ''SingleReplica'' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation NOTE: External topology mode is not applicable for this field.'
+ enum:
+ - HighlyAvailable
+ - SingleReplica
+ type: string
+ platform:
+ description: "platform is the underlying infrastructure provider for the cluster. \n Deprecated: Use platformStatus.type instead."
+ enum:
+ - ""
+ - AWS
+ - Azure
+ - BareMetal
+ - GCP
+ - Libvirt
+ - OpenStack
+ - None
+ - VSphere
+ - oVirt
+ - IBMCloud
+ - KubeVirt
+ - EquinixMetal
+ - PowerVS
+ - AlibabaCloud
+ - Nutanix
+ - External
+ type: string
+ platformStatus:
+ description: platformStatus holds status information specific to the underlying infrastructure provider.
+ properties:
+ alibabaCloud:
+ description: AlibabaCloud contains settings specific to the Alibaba Cloud infrastructure provider.
+ properties:
+ region:
+ description: region specifies the region for Alibaba Cloud resources created for the cluster.
+ pattern: ^[0-9A-Za-z-]+$
+ type: string
+ resourceGroupID:
+ description: resourceGroupID is the ID of the resource group for the cluster.
+ pattern: ^(rg-[0-9A-Za-z]+)?$
+ type: string
+ resourceTags:
+ description: resourceTags is a list of additional tags to apply to Alibaba Cloud resources created for the cluster.
+ items:
+ description: AlibabaCloudResourceTag is the set of tags to add to apply to resources.
+ properties:
+ key:
+ description: key is the key of the tag.
+ maxLength: 128
+ minLength: 1
+ type: string
+ value:
+ description: value is the value of the tag.
+ maxLength: 128
+ minLength: 1
+ type: string
+ required:
+ - key
+ - value
+ type: object
+ maxItems: 20
+ type: array
+ x-kubernetes-list-map-keys:
+ - key
+ x-kubernetes-list-type: map
+ required:
+ - region
+ type: object
+ aws:
+ description: AWS contains settings specific to the Amazon Web Services infrastructure provider.
+ properties:
+ region:
+ description: region holds the default AWS region for new AWS resources created by the cluster.
+ type: string
+ resourceTags:
+ description: resourceTags is a list of additional tags to apply to AWS resources created for the cluster. See https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html for information on tagging AWS resources. AWS supports a maximum of 50 tags per resource. OpenShift reserves 25 tags for its use, leaving 25 tags available for the user.
+ items:
+ description: AWSResourceTag is a tag to apply to AWS resources created for the cluster.
+ properties:
+ key:
+ description: key is the key of the tag
+ maxLength: 128
+ minLength: 1
+ pattern: ^[0-9A-Za-z_.:/=+-@]+$
+ type: string
+ value:
+ description: value is the value of the tag. Some AWS service do not support empty values. Since tags are added to resources in many services, the length of the tag value must meet the requirements of all services.
+ maxLength: 256
+ minLength: 1
+ pattern: ^[0-9A-Za-z_.:/=+-@]+$
+ type: string
+ required:
+ - key
+ - value
+ type: object
+ maxItems: 25
+ type: array
+ serviceEndpoints:
+ description: ServiceEndpoints list contains custom endpoints which will override default service endpoint of AWS Services. There must be only one ServiceEndpoint for a service.
+ items:
+ description: AWSServiceEndpoint store the configuration of a custom url to override existing defaults of AWS Services.
+ properties:
+ name:
+ description: name is the name of the AWS service. The list of all the service names can be found at https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html This must be provided and cannot be empty.
+ pattern: ^[a-z0-9-]+$
+ type: string
+ url:
+ description: url is fully qualified URI with scheme https, that overrides the default generated endpoint for a client. This must be provided and cannot be empty.
+ pattern: ^https://
+ type: string
+ type: object
+ type: array
+ type: object
+ azure:
+ description: Azure contains settings specific to the Azure infrastructure provider.
+ properties:
+ armEndpoint:
+ description: armEndpoint specifies a URL to use for resource management in non-soverign clouds such as Azure Stack.
+ type: string
+ cloudName:
+ description: cloudName is the name of the Azure cloud environment which can be used to configure the Azure SDK with the appropriate Azure API endpoints. If empty, the value is equal to `AzurePublicCloud`.
+ enum:
+ - ""
+ - AzurePublicCloud
+ - AzureUSGovernmentCloud
+ - AzureChinaCloud
+ - AzureGermanCloud
+ - AzureStackCloud
+ type: string
+ networkResourceGroupName:
+ description: networkResourceGroupName is the Resource Group for network resources like the Virtual Network and Subnets used by the cluster. If empty, the value is same as ResourceGroupName.
+ type: string
+ resourceGroupName:
+ description: resourceGroupName is the Resource Group for new Azure resources created for the cluster.
+ type: string
+ resourceTags:
+ description: resourceTags is a list of additional tags to apply to Azure resources created for the cluster. See https://docs.microsoft.com/en-us/rest/api/resources/tags for information on tagging Azure resources. Due to limitations on Automation, Content Delivery Network, DNS Azure resources, a maximum of 15 tags may be applied. OpenShift reserves 5 tags for internal use, allowing 10 tags for user configuration.
+ items:
+ description: AzureResourceTag is a tag to apply to Azure resources created for the cluster.
+ properties:
+ key:
+ description: key is the key part of the tag. A tag key can have a maximum of 128 characters and cannot be empty. Key must begin with a letter, end with a letter, number or underscore, and must contain only alphanumeric characters and the following special characters `_ . -`.
+ maxLength: 128
+ minLength: 1
+ pattern: ^[a-zA-Z]([0-9A-Za-z_.-]*[0-9A-Za-z_])?$
+ type: string
+ value:
+ description: 'value is the value part of the tag. A tag value can have a maximum of 256 characters and cannot be empty. Value must contain only alphanumeric characters and the following special characters `_ + , - . / : ; < = > ? @`.'
+ maxLength: 256
+ minLength: 1
+ pattern: ^[0-9A-Za-z_.=+-@]+$
+ type: string
+ required:
+ - key
+ - value
+ type: object
+ maxItems: 10
+ type: array
+ x-kubernetes-validations:
+ - message: resourceTags are immutable and may only be configured during installation
+ rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
+ type: object
+ x-kubernetes-validations:
+ - message: resourceTags may only be configured during installation
+ rule: '!has(oldSelf.resourceTags) && !has(self.resourceTags) || has(oldSelf.resourceTags) && has(self.resourceTags)'
+ baremetal:
+ description: BareMetal contains settings specific to the BareMetal platform.
+ properties:
+ apiServerInternalIP:
+ description: "apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used by components inside the cluster, like kubelets using the infrastructure rather than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI points to. It is the IP for a self-hosted load balancer in front of the API servers. \n Deprecated: Use APIServerInternalIPs instead."
+ type: string
+ apiServerInternalIPs:
+ description: apiServerInternalIPs are the IP addresses to contact the Kubernetes API server that can be used by components inside the cluster, like kubelets using the infrastructure rather than Kubernetes networking. These are the IPs for a self-hosted load balancer in front of the API servers. In dual stack clusters this list contains two IPs otherwise only one.
+ format: ip
+ items:
+ type: string
+ maxItems: 2
+ type: array
+ ingressIP:
+ description: "ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names. \n Deprecated: Use IngressIPs instead."
+ type: string
+ ingressIPs:
+ description: ingressIPs are the external IPs which route to the default ingress controller. The IPs are suitable targets of a wildcard DNS record used to resolve default route host names. In dual stack clusters this list contains two IPs otherwise only one.
+ format: ip
+ items:
+ type: string
+ maxItems: 2
+ type: array
+ loadBalancer:
+ default:
+ type: OpenShiftManagedDefault
+ description: loadBalancer defines how the load balancer used by the cluster is configured.
+ properties:
+ type:
+ default: OpenShiftManagedDefault
+ description: type defines the type of load balancer used by the cluster on BareMetal platform which can be a user-managed or openshift-managed load balancer that is to be used for the OpenShift API and Ingress endpoints. When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing defined in the machine config operator will be deployed. When set to UserManaged these static pods will not be deployed and it is expected that the load balancer is configured out of band by the deployer. When omitted, this means no opinion and the platform is left to choose a reasonable default. The default value is OpenShiftManagedDefault.
+ enum:
+ - OpenShiftManagedDefault
+ - UserManaged
+ type: string
+ x-kubernetes-validations:
+ - message: type is immutable once set
+ rule: oldSelf == '' || self == oldSelf
+ type: object
+ nodeDNSIP:
+ description: nodeDNSIP is the IP address for the internal DNS used by the nodes. Unlike the one managed by the DNS operator, `NodeDNSIP` provides name resolution for the nodes themselves. There is no DNS-as-a-service for BareMetal deployments. In order to minimize necessary changes to the datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames to the nodes in the cluster.
+ type: string
+ type: object
+ equinixMetal:
+ description: EquinixMetal contains settings specific to the Equinix Metal infrastructure provider.
+ properties:
+ apiServerInternalIP:
+ description: apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used by components inside the cluster, like kubelets using the infrastructure rather than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI points to. It is the IP for a self-hosted load balancer in front of the API servers.
+ type: string
+ ingressIP:
+ description: ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names.
+ type: string
+ type: object
+ external:
+ description: External contains settings specific to the generic External infrastructure provider.
+ properties:
+ cloudControllerManager:
+ description: cloudControllerManager contains settings specific to the external Cloud Controller Manager (a.k.a. CCM or CPI). When omitted, new nodes will be not tainted and no extra initialization from the cloud controller manager is expected.
+ properties:
+ state:
+ description: "state determines whether or not an external Cloud Controller Manager is expected to be installed within the cluster. https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/#running-cloud-controller-manager \n Valid values are \"External\", \"None\" and omitted. When set to \"External\", new nodes will be tainted as uninitialized when created, preventing them from running workloads until they are initialized by the cloud controller manager. When omitted or set to \"None\", new nodes will be not tainted and no extra initialization from the cloud controller manager is expected."
+ enum:
+ - ""
+ - External
+ - None
+ type: string
+ x-kubernetes-validations:
+ - message: state is immutable once set
+ rule: self == oldSelf
+ type: object
+ x-kubernetes-validations:
+ - message: state may not be added or removed once set
+ rule: (has(self.state) == has(oldSelf.state)) || (!has(oldSelf.state) && self.state != "External")
+ type: object
+ x-kubernetes-validations:
+ - message: cloudControllerManager may not be added or removed once set
+ rule: has(self.cloudControllerManager) == has(oldSelf.cloudControllerManager)
+ gcp:
+ description: GCP contains settings specific to the Google Cloud Platform infrastructure provider.
+ properties:
+ projectID:
+ description: resourceGroupName is the Project ID for new GCP resources created for the cluster.
+ type: string
+ region:
+ description: region holds the region for new GCP resources created for the cluster.
+ type: string
+ resourceLabels:
+ description: resourceLabels is a list of additional labels to apply to GCP resources created for the cluster. See https://cloud.google.com/compute/docs/labeling-resources for information on labeling GCP resources. GCP supports a maximum of 64 labels per resource. OpenShift reserves 32 labels for internal use, allowing 32 labels for user configuration.
+ items:
+ description: GCPResourceLabel is a label to apply to GCP resources created for the cluster.
+ properties:
+ key:
+ description: key is the key part of the label. A label key can have a maximum of 63 characters and cannot be empty. Label key must begin with a lowercase letter, and must contain only lowercase letters, numeric characters, and the following special characters `_-`. Label key must not have the reserved prefixes `kubernetes-io` and `openshift-io`.
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-z][0-9a-z_-]+$
+ type: string
+ x-kubernetes-validations:
+ - message: label keys must not start with either `openshift-io` or `kubernetes-io`
+ rule: '!self.startsWith(''openshift-io'') && !self.startsWith(''kubernetes-io'')'
+ value:
+ description: value is the value part of the label. A label value can have a maximum of 63 characters and cannot be empty. Value must contain only lowercase letters, numeric characters, and the following special characters `_-`.
+ maxLength: 63
+ minLength: 1
+ pattern: ^[0-9a-z_-]+$
+ type: string
+ required:
+ - key
+ - value
+ type: object
+ maxItems: 32
+ type: array
+ x-kubernetes-list-map-keys:
+ - key
+ x-kubernetes-list-type: map
+ x-kubernetes-validations:
+ - message: resourceLabels are immutable and may only be configured during installation
+ rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
+ resourceTags:
+ description: resourceTags is a list of additional tags to apply to GCP resources created for the cluster. See https://cloud.google.com/resource-manager/docs/tags/tags-overview for information on tagging GCP resources. GCP supports a maximum of 50 tags per resource.
+ items:
+ description: GCPResourceTag is a tag to apply to GCP resources created for the cluster.
+ properties:
+ key:
+ description: key is the key part of the tag. A tag key can have a maximum of 63 characters and cannot be empty. Tag key must begin and end with an alphanumeric character, and must contain only uppercase, lowercase alphanumeric characters, and the following special characters `._-`.
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z0-9]([0-9A-Za-z_.-]{0,61}[a-zA-Z0-9])?$
+ type: string
+ parentID:
+ description: 'parentID is the ID of the hierarchical resource where the tags are defined, e.g. at the Organization or the Project level. To find the Organization or Project ID refer to the following pages: https://cloud.google.com/resource-manager/docs/creating-managing-organization#retrieving_your_organization_id, https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects. An OrganizationID must consist of decimal numbers, and cannot have leading zeroes. A ProjectID must be 6 to 30 characters in length, can only contain lowercase letters, numbers, and hyphens, and must start with a letter, and cannot end with a hyphen.'
+ maxLength: 32
+ minLength: 1
+ pattern: (^[1-9][0-9]{0,31}$)|(^[a-z][a-z0-9-]{4,28}[a-z0-9]$)
+ type: string
+ value:
+ description: value is the value part of the tag. A tag value can have a maximum of 63 characters and cannot be empty. Tag value must begin and end with an alphanumeric character, and must contain only uppercase, lowercase alphanumeric characters, and the following special characters `_-.@%=+:,*#&(){}[]` and spaces.
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z0-9]([0-9A-Za-z_.@%=+:,*#&()\[\]{}\-\s]{0,61}[a-zA-Z0-9])?$
+ type: string
+ required:
+ - key
+ - parentID
+ - value
+ type: object
+ maxItems: 50
+ type: array
+ x-kubernetes-list-map-keys:
+ - key
+ x-kubernetes-list-type: map
+ x-kubernetes-validations:
+ - message: resourceTags are immutable and may only be configured during installation
+ rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
+ type: object
+ x-kubernetes-validations:
+ - message: resourceLabels may only be configured during installation
+ rule: '!has(oldSelf.resourceLabels) && !has(self.resourceLabels) || has(oldSelf.resourceLabels) && has(self.resourceLabels)'
+ - message: resourceTags may only be configured during installation
+ rule: '!has(oldSelf.resourceTags) && !has(self.resourceTags) || has(oldSelf.resourceTags) && has(self.resourceTags)'
+ ibmcloud:
+ description: IBMCloud contains settings specific to the IBMCloud infrastructure provider.
+ properties:
+ cisInstanceCRN:
+ description: CISInstanceCRN is the CRN of the Cloud Internet Services instance managing the DNS zone for the cluster's base domain
+ type: string
+ dnsInstanceCRN:
+ description: DNSInstanceCRN is the CRN of the DNS Services instance managing the DNS zone for the cluster's base domain
+ type: string
+ location:
+ description: Location is where the cluster has been deployed
+ type: string
+ providerType:
+ description: ProviderType indicates the type of cluster that was created
+ type: string
+ resourceGroupName:
+ description: ResourceGroupName is the Resource Group for new IBMCloud resources created for the cluster.
+ type: string
+ serviceEndpoints:
+ description: serviceEndpoints is a list of custom endpoints which will override the default service endpoints of an IBM Cloud service. These endpoints are consumed by components within the cluster to reach the respective IBM Cloud Services.
+ items:
+ description: IBMCloudServiceEndpoint stores the configuration of a custom url to override existing defaults of IBM Cloud Services.
+ properties:
+ name:
+ description: name is the name of the IBM Cloud service. For example, the IBM Cloud Private IAM service could be configured with the service `name` of `IAM` and `url` of `https://private.iam.cloud.ibm.com` Whereas the IBM Cloud Private VPC service for US South (Dallas) could be configured with the service `name` of `VPC` and `url` of `https://us.south.private.iaas.cloud.ibm.com`
+ maxLength: 32
+ pattern: ^[a-zA-Z0-9-]+$
+ type: string
+ url:
+ description: url is fully qualified URI with scheme https, that overrides the default generated endpoint for a client. This must be provided and cannot be empty.
+ type: string
+ x-kubernetes-validations:
+ - message: url must be a valid absolute URL
+ rule: isURL(self)
+ required:
+ - name
+ - url
+ type: object
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
+ type: object
+ kubevirt:
+ description: Kubevirt contains settings specific to the kubevirt infrastructure provider.
+ properties:
+ apiServerInternalIP:
+ description: apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used by components inside the cluster, like kubelets using the infrastructure rather than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI points to. It is the IP for a self-hosted load balancer in front of the API servers.
+ type: string
+ ingressIP:
+ description: ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names.
+ type: string
+ type: object
+ nutanix:
+ description: Nutanix contains settings specific to the Nutanix infrastructure provider.
+ properties:
+ apiServerInternalIP:
+ description: "apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used by components inside the cluster, like kubelets using the infrastructure rather than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI points to. It is the IP for a self-hosted load balancer in front of the API servers. \n Deprecated: Use APIServerInternalIPs instead."
+ type: string
+ apiServerInternalIPs:
+ description: apiServerInternalIPs are the IP addresses to contact the Kubernetes API server that can be used by components inside the cluster, like kubelets using the infrastructure rather than Kubernetes networking. These are the IPs for a self-hosted load balancer in front of the API servers. In dual stack clusters this list contains two IPs otherwise only one.
+ format: ip
+ items:
+ type: string
+ maxItems: 2
+ type: array
+ ingressIP:
+ description: "ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names. \n Deprecated: Use IngressIPs instead."
+ type: string
+ ingressIPs:
+ description: ingressIPs are the external IPs which route to the default ingress controller. The IPs are suitable targets of a wildcard DNS record used to resolve default route host names. In dual stack clusters this list contains two IPs otherwise only one.
+ format: ip
+ items:
+ type: string
+ maxItems: 2
+ type: array
+ loadBalancer:
+ default:
+ type: OpenShiftManagedDefault
+ description: loadBalancer defines how the load balancer used by the cluster is configured.
+ properties:
+ type:
+ default: OpenShiftManagedDefault
+ description: type defines the type of load balancer used by the cluster on Nutanix platform which can be a user-managed or openshift-managed load balancer that is to be used for the OpenShift API and Ingress endpoints. When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing defined in the machine config operator will be deployed. When set to UserManaged these static pods will not be deployed and it is expected that the load balancer is configured out of band by the deployer. When omitted, this means no opinion and the platform is left to choose a reasonable default. The default value is OpenShiftManagedDefault.
+ enum:
+ - OpenShiftManagedDefault
+ - UserManaged
+ type: string
+ x-kubernetes-validations:
+ - message: type is immutable once set
+ rule: oldSelf == '' || self == oldSelf
+ type: object
+ type: object
+ openstack:
+ description: OpenStack contains settings specific to the OpenStack infrastructure provider.
+ properties:
+ apiServerInternalIP:
+ description: "apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used by components inside the cluster, like kubelets using the infrastructure rather than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI points to. It is the IP for a self-hosted load balancer in front of the API servers. \n Deprecated: Use APIServerInternalIPs instead."
+ type: string
+ apiServerInternalIPs:
+ description: apiServerInternalIPs are the IP addresses to contact the Kubernetes API server that can be used by components inside the cluster, like kubelets using the infrastructure rather than Kubernetes networking. These are the IPs for a self-hosted load balancer in front of the API servers. In dual stack clusters this list contains two IPs otherwise only one.
+ format: ip
+ items:
+ type: string
+ maxItems: 2
+ type: array
+ cloudName:
+ description: cloudName is the name of the desired OpenStack cloud in the client configuration file (`clouds.yaml`).
+ type: string
+ ingressIP:
+ description: "ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names. \n Deprecated: Use IngressIPs instead."
+ type: string
+ ingressIPs:
+ description: ingressIPs are the external IPs which route to the default ingress controller. The IPs are suitable targets of a wildcard DNS record used to resolve default route host names. In dual stack clusters this list contains two IPs otherwise only one.
+ format: ip
+ items:
+ type: string
+ maxItems: 2
+ type: array
+ loadBalancer:
+ default:
+ type: OpenShiftManagedDefault
+ description: loadBalancer defines how the load balancer used by the cluster is configured.
+ properties:
+ type:
+ default: OpenShiftManagedDefault
+ description: type defines the type of load balancer used by the cluster on OpenStack platform which can be a user-managed or openshift-managed load balancer that is to be used for the OpenShift API and Ingress endpoints. When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing defined in the machine config operator will be deployed. When set to UserManaged these static pods will not be deployed and it is expected that the load balancer is configured out of band by the deployer. When omitted, this means no opinion and the platform is left to choose a reasonable default. The default value is OpenShiftManagedDefault.
+ enum:
+ - OpenShiftManagedDefault
+ - UserManaged
+ type: string
+ x-kubernetes-validations:
+ - message: type is immutable once set
+ rule: oldSelf == '' || self == oldSelf
+ type: object
+ nodeDNSIP:
+ description: nodeDNSIP is the IP address for the internal DNS used by the nodes. Unlike the one managed by the DNS operator, `NodeDNSIP` provides name resolution for the nodes themselves. There is no DNS-as-a-service for OpenStack deployments. In order to minimize necessary changes to the datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames to the nodes in the cluster.
+ type: string
+ type: object
+ ovirt:
+ description: Ovirt contains settings specific to the oVirt infrastructure provider.
+ properties:
+ apiServerInternalIP:
+ description: "apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used by components inside the cluster, like kubelets using the infrastructure rather than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI points to. It is the IP for a self-hosted load balancer in front of the API servers. \n Deprecated: Use APIServerInternalIPs instead."
+ type: string
+ apiServerInternalIPs:
+ description: apiServerInternalIPs are the IP addresses to contact the Kubernetes API server that can be used by components inside the cluster, like kubelets using the infrastructure rather than Kubernetes networking. These are the IPs for a self-hosted load balancer in front of the API servers. In dual stack clusters this list contains two IPs otherwise only one.
+ format: ip
+ items:
+ type: string
+ maxItems: 2
+ type: array
+ ingressIP:
+ description: "ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names. \n Deprecated: Use IngressIPs instead."
+ type: string
+ ingressIPs:
+ description: ingressIPs are the external IPs which route to the default ingress controller. The IPs are suitable targets of a wildcard DNS record used to resolve default route host names. In dual stack clusters this list contains two IPs otherwise only one.
+ format: ip
+ items:
+ type: string
+ maxItems: 2
+ type: array
+ loadBalancer:
+ default:
+ type: OpenShiftManagedDefault
+ description: loadBalancer defines how the load balancer used by the cluster is configured.
+ properties:
+ type:
+ default: OpenShiftManagedDefault
+ description: type defines the type of load balancer used by the cluster on Ovirt platform which can be a user-managed or openshift-managed load balancer that is to be used for the OpenShift API and Ingress endpoints. When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing defined in the machine config operator will be deployed. When set to UserManaged these static pods will not be deployed and it is expected that the load balancer is configured out of band by the deployer. When omitted, this means no opinion and the platform is left to choose a reasonable default. The default value is OpenShiftManagedDefault.
+ enum:
+ - OpenShiftManagedDefault
+ - UserManaged
+ type: string
+ x-kubernetes-validations:
+ - message: type is immutable once set
+ rule: oldSelf == '' || self == oldSelf
+ type: object
+ nodeDNSIP:
+ description: 'deprecated: as of 4.6, this field is no longer set or honored. It will be removed in a future release.'
+ type: string
+ type: object
+ powervs:
+ description: PowerVS contains settings specific to the Power Systems Virtual Servers infrastructure provider.
+ properties:
+ cisInstanceCRN:
+ description: CISInstanceCRN is the CRN of the Cloud Internet Services instance managing the DNS zone for the cluster's base domain
+ type: string
+ dnsInstanceCRN:
+ description: DNSInstanceCRN is the CRN of the DNS Services instance managing the DNS zone for the cluster's base domain
+ type: string
+ region:
+ description: region holds the default Power VS region for new Power VS resources created by the cluster.
+ type: string
+ resourceGroup:
+ description: 'resourceGroup is the resource group name for new IBMCloud resources created for a cluster. The resource group specified here will be used by cluster-image-registry-operator to set up a COS Instance in IBMCloud for the cluster registry. More about resource groups can be found here: https://cloud.ibm.com/docs/account?topic=account-rgs. When omitted, the image registry operator won''t be able to configure storage, which results in the image registry cluster operator not being in an available state.'
+ maxLength: 40
+ pattern: ^[a-zA-Z0-9-_ ]+$
+ type: string
+ x-kubernetes-validations:
+ - message: resourceGroup is immutable once set
+ rule: oldSelf == '' || self == oldSelf
+ serviceEndpoints:
+ description: serviceEndpoints is a list of custom endpoints which will override the default service endpoints of a Power VS service.
+ items:
+ description: PowervsServiceEndpoint stores the configuration of a custom url to override existing defaults of PowerVS Services.
+ properties:
+ name:
+ description: name is the name of the Power VS service. Few of the services are IAM - https://cloud.ibm.com/apidocs/iam-identity-token-api ResourceController - https://cloud.ibm.com/apidocs/resource-controller/resource-controller Power Cloud - https://cloud.ibm.com/apidocs/power-cloud
+ pattern: ^[a-z0-9-]+$
+ type: string
+ url:
+ description: url is fully qualified URI with scheme https, that overrides the default generated endpoint for a client. This must be provided and cannot be empty.
+ format: uri
+ pattern: ^https://
+ type: string
+ required:
+ - name
+ - url
+ type: object
+ type: array
+ zone:
+ description: 'zone holds the default zone for the new Power VS resources created by the cluster. Note: Currently only single-zone OCP clusters are supported'
+ type: string
+ type: object
+ x-kubernetes-validations:
+ - message: cannot unset resourceGroup once set
+ rule: '!has(oldSelf.resourceGroup) || has(self.resourceGroup)'
+ type:
+ description: "type is the underlying infrastructure provider for the cluster. This value controls whether infrastructure automation such as service load balancers, dynamic volume provisioning, machine creation and deletion, and other integrations are enabled. If None, no infrastructure automation is enabled. Allowed values are \"AWS\", \"Azure\", \"BareMetal\", \"GCP\", \"Libvirt\", \"OpenStack\", \"VSphere\", \"oVirt\", \"EquinixMetal\", \"PowerVS\", \"AlibabaCloud\", \"Nutanix\" and \"None\". Individual components may not support all platforms, and must handle unrecognized platforms as None if they do not support that platform. \n This value will be synced with to the `status.platform` and `status.platformStatus.type`. Currently this value cannot be changed once set."
+ enum:
+ - ""
+ - AWS
+ - Azure
+ - BareMetal
+ - GCP
+ - Libvirt
+ - OpenStack
+ - None
+ - VSphere
+ - oVirt
+ - IBMCloud
+ - KubeVirt
+ - EquinixMetal
+ - PowerVS
+ - AlibabaCloud
+ - Nutanix
+ - External
+ type: string
+ vsphere:
+ description: VSphere contains settings specific to the VSphere infrastructure provider.
+ properties:
+ apiServerInternalIP:
+ description: "apiServerInternalIP is an IP address to contact the Kubernetes API server that can be used by components inside the cluster, like kubelets using the infrastructure rather than Kubernetes networking. It is the IP that the Infrastructure.status.apiServerInternalURI points to. It is the IP for a self-hosted load balancer in front of the API servers. \n Deprecated: Use APIServerInternalIPs instead."
+ type: string
+ apiServerInternalIPs:
+ description: apiServerInternalIPs are the IP addresses to contact the Kubernetes API server that can be used by components inside the cluster, like kubelets using the infrastructure rather than Kubernetes networking. These are the IPs for a self-hosted load balancer in front of the API servers. In dual stack clusters this list contains two IPs otherwise only one.
+ format: ip
+ items:
+ type: string
+ maxItems: 2
+ type: array
+ ingressIP:
+ description: "ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names. \n Deprecated: Use IngressIPs instead."
+ type: string
+ ingressIPs:
+ description: ingressIPs are the external IPs which route to the default ingress controller. The IPs are suitable targets of a wildcard DNS record used to resolve default route host names. In dual stack clusters this list contains two IPs otherwise only one.
+ format: ip
+ items:
+ type: string
+ maxItems: 2
+ type: array
+ loadBalancer:
+ default:
+ type: OpenShiftManagedDefault
+ description: loadBalancer defines how the load balancer used by the cluster is configured.
+ properties:
+ type:
+ default: OpenShiftManagedDefault
+ description: type defines the type of load balancer used by the cluster on VSphere platform which can be a user-managed or openshift-managed load balancer that is to be used for the OpenShift API and Ingress endpoints. When set to OpenShiftManagedDefault the static pods in charge of API and Ingress traffic load-balancing defined in the machine config operator will be deployed. When set to UserManaged these static pods will not be deployed and it is expected that the load balancer is configured out of band by the deployer. When omitted, this means no opinion and the platform is left to choose a reasonable default. The default value is OpenShiftManagedDefault.
+ enum:
+ - OpenShiftManagedDefault
+ - UserManaged
+ type: string
+ x-kubernetes-validations:
+ - message: type is immutable once set
+ rule: oldSelf == '' || self == oldSelf
+ type: object
+ nodeDNSIP:
+ description: nodeDNSIP is the IP address for the internal DNS used by the nodes. Unlike the one managed by the DNS operator, `NodeDNSIP` provides name resolution for the nodes themselves. There is no DNS-as-a-service for vSphere deployments. In order to minimize necessary changes to the datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames to the nodes in the cluster.
+ type: string
+ type: object
+ type: object
+ type: object
+ required:
+ - spec
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml-patch b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml-patch
new file mode 100644
index 0000000000..d127130add
--- /dev/null
+++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml-patch
@@ -0,0 +1,24 @@
+- op: add
+ path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/vcenters/items/properties/server/anyOf
+ value:
+ - format: ipv4
+ - format: ipv6
+ - format: hostname
+- op: add
+ path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/failureDomains/items/properties/server/anyOf
+ value:
+ - format: ipv4
+ - format: ipv6
+ - format: hostname
+- op: add
+ path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/nodeNetworking/properties/external/properties/excludeNetworkSubnetCidr/items/format
+ value: cidr
+- op: add
+ path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/nodeNetworking/properties/external/properties/networkSubnetCidr/items/format
+ value: cidr
+- op: add
+ path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/nodeNetworking/properties/internal/properties/excludeNetworkSubnetCidr/items/format
+ value: cidr
+- op: add
+ path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/nodeNetworking/properties/internal/properties/networkSubnetCidr/items/format
+ value: cidr
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-Default.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-Default.crd.yaml
index bb8817110f..8e58063098 100644
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-Default.crd.yaml
+++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-Default.crd.yaml
@@ -381,6 +381,13 @@ spec:
- SingleReplica
- External
type: string
+ cpuPartitioning:
+ default: None
+ description: cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. Valid values are "None" and "AllNodes". When omitted, the default value is "None". The default value of "None" indicates that no nodes will be setup with CPU partitioning. The "AllNodes" value indicates that all nodes have been setup with CPU partitioning, and can then be further configured via the PerformanceProfile API.
+ enum:
+ - None
+ - AllNodes
+ type: string
etcdDiscoveryDomain:
description: 'etcdDiscoveryDomain is the domain used to fetch the SRV records for discovering etcd servers and clients. For more info: https://github.com/etcd-io/etcd/blob/329be66e8b3f9e2e6af83c123ff89297e49ebd15/Documentation/op-guide/clustering.md#dns-discovery deprecated: as of 4.7, this field is no longer set or honored. It will be removed in a future release.'
type: string
@@ -592,7 +599,28 @@ spec:
type: object
external:
description: External contains settings specific to the generic External infrastructure provider.
+ properties:
+ cloudControllerManager:
+ description: cloudControllerManager contains settings specific to the external Cloud Controller Manager (a.k.a. CCM or CPI). When omitted, new nodes will be not tainted and no extra initialization from the cloud controller manager is expected.
+ properties:
+ state:
+ description: "state determines whether or not an external Cloud Controller Manager is expected to be installed within the cluster. https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/#running-cloud-controller-manager \n Valid values are \"External\", \"None\" and omitted. When set to \"External\", new nodes will be tainted as uninitialized when created, preventing them from running workloads until they are initialized by the cloud controller manager. When omitted or set to \"None\", new nodes will be not tainted and no extra initialization from the cloud controller manager is expected."
+ enum:
+ - ""
+ - External
+ - None
+ type: string
+ x-kubernetes-validations:
+ - message: state is immutable once set
+ rule: self == oldSelf
+ type: object
+ x-kubernetes-validations:
+ - message: state may not be added or removed once set
+ rule: (has(self.state) == has(oldSelf.state)) || (!has(oldSelf.state) && self.state != "External")
type: object
+ x-kubernetes-validations:
+ - message: cloudControllerManager may not be added or removed once set
+ rule: has(self.cloudControllerManager) == has(oldSelf.cloudControllerManager)
gcp:
description: GCP contains settings specific to the Google Cloud Platform infrastructure provider.
properties:
@@ -621,6 +649,30 @@ spec:
resourceGroupName:
description: ResourceGroupName is the Resource Group for new IBMCloud resources created for the cluster.
type: string
+ serviceEndpoints:
+ description: serviceEndpoints is a list of custom endpoints which will override the default service endpoints of an IBM Cloud service. These endpoints are consumed by components within the cluster to reach the respective IBM Cloud Services.
+ items:
+ description: IBMCloudServiceEndpoint stores the configuration of a custom url to override existing defaults of IBM Cloud Services.
+ properties:
+ name:
+ description: name is the name of the IBM Cloud service. For example, the IBM Cloud Private IAM service could be configured with the service `name` of `IAM` and `url` of `https://private.iam.cloud.ibm.com` Whereas the IBM Cloud Private VPC service for US South (Dallas) could be configured with the service `name` of `VPC` and `url` of `https://us.south.private.iaas.cloud.ibm.com`
+ maxLength: 32
+ pattern: ^[a-zA-Z0-9-]+$
+ type: string
+ url:
+ description: url is fully qualified URI with scheme https, that overrides the default generated endpoint for a client. This must be provided and cannot be empty.
+ type: string
+ x-kubernetes-validations:
+ - message: url must be a valid absolute URL
+ rule: isURL(self)
+ required:
+ - name
+ - url
+ type: object
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
type: object
kubevirt:
description: Kubevirt contains settings specific to the kubevirt infrastructure provider.
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml
index e8fce28aa8..1b84d0ae6f 100644
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml
+++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml
@@ -634,6 +634,9 @@ spec:
- message: state may not be added or removed once set
rule: (has(self.state) == has(oldSelf.state)) || (!has(oldSelf.state) && self.state != "External")
type: object
+ x-kubernetes-validations:
+ - message: cloudControllerManager may not be added or removed once set
+ rule: has(self.cloudControllerManager) == has(oldSelf.cloudControllerManager)
gcp:
description: GCP contains settings specific to the Google Cloud Platform infrastructure provider.
properties:
@@ -643,7 +646,80 @@ spec:
region:
description: region holds the region for new GCP resources created for the cluster.
type: string
+ resourceLabels:
+ description: resourceLabels is a list of additional labels to apply to GCP resources created for the cluster. See https://cloud.google.com/compute/docs/labeling-resources for information on labeling GCP resources. GCP supports a maximum of 64 labels per resource. OpenShift reserves 32 labels for internal use, allowing 32 labels for user configuration.
+ items:
+ description: GCPResourceLabel is a label to apply to GCP resources created for the cluster.
+ properties:
+ key:
+ description: key is the key part of the label. A label key can have a maximum of 63 characters and cannot be empty. Label key must begin with a lowercase letter, and must contain only lowercase letters, numeric characters, and the following special characters `_-`. Label key must not have the reserved prefixes `kubernetes-io` and `openshift-io`.
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-z][0-9a-z_-]+$
+ type: string
+ x-kubernetes-validations:
+ - message: label keys must not start with either `openshift-io` or `kubernetes-io`
+ rule: '!self.startsWith(''openshift-io'') && !self.startsWith(''kubernetes-io'')'
+ value:
+ description: value is the value part of the label. A label value can have a maximum of 63 characters and cannot be empty. Value must contain only lowercase letters, numeric characters, and the following special characters `_-`.
+ maxLength: 63
+ minLength: 1
+ pattern: ^[0-9a-z_-]+$
+ type: string
+ required:
+ - key
+ - value
+ type: object
+ maxItems: 32
+ type: array
+ x-kubernetes-list-map-keys:
+ - key
+ x-kubernetes-list-type: map
+ x-kubernetes-validations:
+ - message: resourceLabels are immutable and may only be configured during installation
+ rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
+ resourceTags:
+ description: resourceTags is a list of additional tags to apply to GCP resources created for the cluster. See https://cloud.google.com/resource-manager/docs/tags/tags-overview for information on tagging GCP resources. GCP supports a maximum of 50 tags per resource.
+ items:
+ description: GCPResourceTag is a tag to apply to GCP resources created for the cluster.
+ properties:
+ key:
+ description: key is the key part of the tag. A tag key can have a maximum of 63 characters and cannot be empty. Tag key must begin and end with an alphanumeric character, and must contain only uppercase, lowercase alphanumeric characters, and the following special characters `._-`.
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z0-9]([0-9A-Za-z_.-]{0,61}[a-zA-Z0-9])?$
+ type: string
+ parentID:
+ description: 'parentID is the ID of the hierarchical resource where the tags are defined, e.g. at the Organization or the Project level. To find the Organization or Project ID refer to the following pages: https://cloud.google.com/resource-manager/docs/creating-managing-organization#retrieving_your_organization_id, https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects. An OrganizationID must consist of decimal numbers, and cannot have leading zeroes. A ProjectID must be 6 to 30 characters in length, can only contain lowercase letters, numbers, and hyphens, and must start with a letter, and cannot end with a hyphen.'
+ maxLength: 32
+ minLength: 1
+ pattern: (^[1-9][0-9]{0,31}$)|(^[a-z][a-z0-9-]{4,28}[a-z0-9]$)
+ type: string
+ value:
+ description: value is the value part of the tag. A tag value can have a maximum of 63 characters and cannot be empty. Tag value must begin and end with an alphanumeric character, and must contain only uppercase, lowercase alphanumeric characters, and the following special characters `_-.@%=+:,*#&(){}[]` and spaces.
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z0-9]([0-9A-Za-z_.@%=+:,*#&()\[\]{}\-\s]{0,61}[a-zA-Z0-9])?$
+ type: string
+ required:
+ - key
+ - parentID
+ - value
+ type: object
+ maxItems: 50
+ type: array
+ x-kubernetes-list-map-keys:
+ - key
+ x-kubernetes-list-type: map
+ x-kubernetes-validations:
+ - message: resourceTags are immutable and may only be configured during installation
+ rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
type: object
+ x-kubernetes-validations:
+ - message: resourceLabels may only be configured during installation
+ rule: '!has(oldSelf.resourceLabels) && !has(self.resourceLabels) || has(oldSelf.resourceLabels) && has(self.resourceLabels)'
+ - message: resourceTags may only be configured during installation
+ rule: '!has(oldSelf.resourceTags) && !has(self.resourceTags) || has(oldSelf.resourceTags) && has(self.resourceTags)'
ibmcloud:
description: IBMCloud contains settings specific to the IBMCloud infrastructure provider.
properties:
@@ -662,6 +738,30 @@ spec:
resourceGroupName:
description: ResourceGroupName is the Resource Group for new IBMCloud resources created for the cluster.
type: string
+ serviceEndpoints:
+ description: serviceEndpoints is a list of custom endpoints which will override the default service endpoints of an IBM Cloud service. These endpoints are consumed by components within the cluster to reach the respective IBM Cloud Services.
+ items:
+ description: IBMCloudServiceEndpoint stores the configuration of a custom url to override existing defaults of IBM Cloud Services.
+ properties:
+ name:
+ description: name is the name of the IBM Cloud service. For example, the IBM Cloud Private IAM service could be configured with the service `name` of `IAM` and `url` of `https://private.iam.cloud.ibm.com` Whereas the IBM Cloud Private VPC service for US South (Dallas) could be configured with the service `name` of `VPC` and `url` of `https://us.south.private.iaas.cloud.ibm.com`
+ maxLength: 32
+ pattern: ^[a-zA-Z0-9-]+$
+ type: string
+ url:
+ description: url is fully qualified URI with scheme https, that overrides the default generated endpoint for a client. This must be provided and cannot be empty.
+ type: string
+ x-kubernetes-validations:
+ - message: url must be a valid absolute URL
+ rule: isURL(self)
+ required:
+ - name
+ - url
+ type: object
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
type: object
kubevirt:
description: Kubevirt contains settings specific to the kubevirt infrastructure provider.
diff --git a/vendor/github.com/openshift/api/config/v1/custom.apiserver.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/custom.apiserver.testsuite.yaml
new file mode 100644
index 0000000000..5e2dea3ea9
--- /dev/null
+++ b/vendor/github.com/openshift/api/config/v1/custom.apiserver.testsuite.yaml
@@ -0,0 +1,35 @@
+apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
+name: "[CustomNoUpgrade] APIServer"
+crd: 0000_10_config-operator_01_apiserver-CustomNoUpgrade.crd.yaml
+tests:
+ onCreate:
+ - name: Should be able to create encrypt with aescbc
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: APIServer
+ spec:
+ encryption:
+ type: aescbc
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: APIServer
+ spec:
+ audit:
+ profile: Default
+ encryption:
+ type: aescbc
+ - name: Should be able to create encrypt with aesgcm
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: APIServer
+ spec:
+ encryption:
+ type: aesgcm
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: APIServer
+ spec:
+ audit:
+ profile: Default
+ encryption:
+ type: aesgcm
diff --git a/vendor/github.com/openshift/api/config/v1/custom.dns.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/custom.dns.testsuite.yaml
new file mode 100644
index 0000000000..ab1a123b60
--- /dev/null
+++ b/vendor/github.com/openshift/api/config/v1/custom.dns.testsuite.yaml
@@ -0,0 +1,104 @@
+apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
+name: "[Custom] DNS"
+crd: 0000_10_config-operator_01_dns-CustomNoUpgrade.crd.yaml
+tests:
+ onCreate:
+ - name: Should be able to create a minimal DNS
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec: {} # No spec is required for a DNS
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec: {}
+ - name: Should be able to specify an AWS role ARN for a private hosted zone
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: AWS
+ aws:
+ privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: AWS
+ aws:
+ privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
+ - name: Should not be able to specify unsupported platform
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: Azure
+ azure:
+ privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
+ expectedError: "Invalid value: \"string\": allowed values are '' and 'AWS'"
+ - name: Should not be able to specify invalid AWS role ARN
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ metadata:
+ name: cluster
+ spec:
+ platform:
+ type: AWS
+ aws:
+ privateZoneIAMRole: arn:aws:iam:bad:123456789012:role/foo
+ expectedError: "DNS.config.openshift.io \"cluster\" is invalid: spec.platform.aws.privateZoneIAMRole: Invalid value: \"arn:aws:iam:bad:123456789012:role/foo\": spec.platform.aws.privateZoneIAMRole in body should match '^arn:(aws|aws-cn|aws-us-gov):iam::[0-9]{12}:role\\/.*$'"
+ - name: Should not be able to specify different type and platform
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: ""
+ aws:
+ privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
+ expectedError: "Invalid value: \"object\": aws configuration is required when platform is AWS, and forbidden otherwise"
+ onUpdate:
+ - name: Can switch from empty (default), to AWS
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: ""
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: AWS
+ aws:
+ privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: AWS
+ aws:
+ privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
+ - name: Upgrade case is valid
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec: {} # No spec is required for a DNS
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: ""
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: ""
diff --git a/vendor/github.com/openshift/api/config/v1/custom.infrastructure.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/custom.infrastructure.testsuite.yaml
new file mode 100644
index 0000000000..24433f4f75
--- /dev/null
+++ b/vendor/github.com/openshift/api/config/v1/custom.infrastructure.testsuite.yaml
@@ -0,0 +1,321 @@
+apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
+name: "[Custom] Infrastructure"
+crd: 0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml
+tests:
+ onCreate:
+ - name: Should be able to create a minimal Infrastructure
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {} # No spec is required for a Infrastructure
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ onUpdate:
+ - name: Should not be able to modify an existing GCP ResourceLabels Label
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ controlPlaneTopology: "HighlyAvailable"
+ infrastructureTopology: "HighlyAvailable"
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "changed"}
+ expectedStatusError: "status.platformStatus.gcp.resourceLabels: Invalid value: \"array\": resourceLabels are immutable and may only be configured during installation"
+ - name: Should not be able to add a Label to an existing GCP ResourceLabels
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ controlPlaneTopology: "HighlyAvailable"
+ infrastructureTopology: "HighlyAvailable"
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
+ - {key: "new", value: "entry"}
+ expectedStatusError: "status.platformStatus.gcp.resourceLabels: Invalid value: \"array\": resourceLabels are immutable and may only be configured during installation"
+ - name: Should not be able to remove a Label from an existing GCP ResourceLabels
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
+ - {key: "new", value: "entry"}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
+ expectedStatusError: "status.platformStatus.gcp.resourceLabels: Invalid value: \"array\": resourceLabels are immutable and may only be configured during installation"
+ - name: Should not be able to add GCP ResourceLabels to an empty platformStatus.gcp
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp: {}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
+ expectedStatusError: "status.platformStatus.gcp: Invalid value: \"object\": resourceLabels may only be configured during installation"
+ - name: Should not be able to remove GCP ResourceLabels from platformStatus.gcp
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp: {}
+ expectedStatusError: "status.platformStatus.gcp: Invalid value: \"object\": resourceLabels may only be configured during installation"
+ - name: Should not have label key start with openshift-io for GCP ResourceLabels in platformStatus.gcp
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status: {}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
+ - {key: "openshift-io-created-cluster", value: "true"}
+ expectedStatusError: "status.platformStatus.gcp.resourceLabels[1].key: Invalid value: \"string\": label keys must not start with either `openshift-io` or `kubernetes-io`"
+ - name: Should not have label key start with kubernetes-io for GCP ResourceLabels in platformStatus.gcp
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status: {}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
+ - {key: "kubernetes-io-created-cluster", value: "true"}
+ expectedStatusError: "status.platformStatus.gcp.resourceLabels[1].key: Invalid value: \"string\": label keys must not start with either `openshift-io` or `kubernetes-io`"
+ - name: Should not be able to modify an existing GCP ResourceTags Tag
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ controlPlaneTopology: "HighlyAvailable"
+ infrastructureTopology: "HighlyAvailable"
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key", value: "value"}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key", value: "changed"}
+ expectedStatusError: "status.platformStatus.gcp.resourceTags: Invalid value: \"array\": resourceTags are immutable and may only be configured during installation"
+ - name: Should not be able to add a Tag to an existing GCP ResourceTags
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ controlPlaneTopology: "HighlyAvailable"
+ infrastructureTopology: "HighlyAvailable"
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key", value: "value"}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key", value: "value"}
+ - {parentID: "test-project-123", key: "new", value: "tag"}
+ expectedStatusError: "status.platformStatus.gcp.resourceTags: Invalid value: \"array\": resourceTags are immutable and may only be configured during installation"
+ - name: Should not be able to remove a Tag from an existing GCP ResourceTags
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key1", value: "value1"}
+ - {parentID: "test-project-123", key: "key2", value: "value2"}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key1", value: "value1"}
+ expectedStatusError: "status.platformStatus.gcp.resourceTags: Invalid value: \"array\": resourceTags are immutable and may only be configured during installation"
+ - name: Should not be able to add GCP ResourceTags to an empty platformStatus.gcp
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp: {}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key", value: "value"}
+ expectedStatusError: "status.platformStatus.gcp: Invalid value: \"object\": resourceTags may only be configured during installation"
+ - name: Should not be able to remove GCP ResourceTags from platformStatus.gcp
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key", value: "value"}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp: {}
+ expectedStatusError: "status.platformStatus.gcp: Invalid value: \"object\": resourceTags may only be configured during installation"
+ - name: Should not be able to modify ParentID of a Tag in the GCP ResourceTags
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ controlPlaneTopology: "HighlyAvailable"
+ infrastructureTopology: "HighlyAvailable"
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key", value: "value"}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: GCP
+ platformStatus:
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "test-project-123", key: "key", value: "value"}
+ expectedStatusError: "status.platformStatus.gcp.resourceTags: Invalid value: \"array\": resourceTags are immutable and may only be configured during installation"
diff --git a/vendor/github.com/openshift/api/config/v1/feature_gates.go b/vendor/github.com/openshift/api/config/v1/feature_gates.go
index 8c022170c3..158487b5a8 100644
--- a/vendor/github.com/openshift/api/config/v1/feature_gates.go
+++ b/vendor/github.com/openshift/api/config/v1/feature_gates.go
@@ -23,6 +23,16 @@ var (
)
var (
+ FeatureGateValidatingAdmissionPolicy = FeatureGateName("ValidatingAdmissionPolicy")
+ validatingAdmissionPolicy = FeatureGateDescription{
+ FeatureGateAttributes: FeatureGateAttributes{
+ Name: FeatureGateValidatingAdmissionPolicy,
+ },
+ OwningJiraComponent: "kube-apiserver",
+ ResponsiblePerson: "benluddy",
+ OwningProduct: kubernetes,
+ }
+
FeatureGateGatewayAPI = FeatureGateName("GatewayAPI")
gateGatewayAPI = FeatureGateDescription{
FeatureGateAttributes: FeatureGateAttributes{
@@ -143,26 +153,6 @@ var (
OwningProduct: ocpSpecific,
}
- FeatureGateMatchLabelKeysInPodTopologySpread = FeatureGateName("MatchLabelKeysInPodTopologySpread")
- matchLabelKeysInPodTopologySpread = FeatureGateDescription{
- FeatureGateAttributes: FeatureGateAttributes{
- Name: FeatureGateMatchLabelKeysInPodTopologySpread,
- },
- OwningJiraComponent: "scheduling",
- ResponsiblePerson: "ingvagabund",
- OwningProduct: kubernetes,
- }
-
- FeatureGatePDBUnhealthyPodEvictionPolicy = FeatureGateName("PDBUnhealthyPodEvictionPolicy")
- pdbUnhealthyPodEvictionPolicy = FeatureGateDescription{
- FeatureGateAttributes: FeatureGateAttributes{
- Name: FeatureGatePDBUnhealthyPodEvictionPolicy,
- },
- OwningJiraComponent: "apps",
- ResponsiblePerson: "atiratree",
- OwningProduct: kubernetes,
- }
-
FeatureGateDynamicResourceAllocation = FeatureGateName("DynamicResourceAllocation")
dynamicResourceAllocation = FeatureGateDescription{
FeatureGateAttributes: FeatureGateAttributes{
@@ -173,16 +163,6 @@ var (
OwningProduct: kubernetes,
}
- FeatureGateAdmissionWebhookMatchConditions = FeatureGateName("AdmissionWebhookMatchConditions")
- admissionWebhookMatchConditions = FeatureGateDescription{
- FeatureGateAttributes: FeatureGateAttributes{
- Name: FeatureGateAdmissionWebhookMatchConditions,
- },
- OwningJiraComponent: "kube-apiserver",
- ResponsiblePerson: "benluddy",
- OwningProduct: kubernetes,
- }
-
FeatureGateAzureWorkloadIdentity = FeatureGateName("AzureWorkloadIdentity")
azureWorkloadIdentity = FeatureGateDescription{
FeatureGateAttributes: FeatureGateAttributes{
@@ -262,4 +242,53 @@ var (
ResponsiblePerson: "mkowalsk",
OwningProduct: kubernetes,
}
+ FeatureGateVSphereStaticIPs = FeatureGateName("VSphereStaticIPs")
+ vSphereStaticIPs = FeatureGateDescription{
+ FeatureGateAttributes: FeatureGateAttributes{
+ Name: FeatureGateVSphereStaticIPs,
+ },
+ OwningJiraComponent: "splat",
+ ResponsiblePerson: "rvanderp3",
+ OwningProduct: ocpSpecific,
+ }
+
+ FeatureGateRouteExternalCertificate = FeatureGateName("RouteExternalCertificate")
+ routeExternalCertificate = FeatureGateDescription{
+ FeatureGateAttributes: FeatureGateAttributes{
+ Name: FeatureGateRouteExternalCertificate,
+ },
+ OwningJiraComponent: "router",
+ ResponsiblePerson: "thejasn",
+ OwningProduct: ocpSpecific,
+ }
+
+ FeatureGateAdminNetworkPolicy = FeatureGateName("AdminNetworkPolicy")
+ adminNetworkPolicy = FeatureGateDescription{
+ FeatureGateAttributes: FeatureGateAttributes{
+ Name: FeatureGateAdminNetworkPolicy,
+ },
+ OwningJiraComponent: "Networking/ovn-kubernetes",
+ ResponsiblePerson: "tssurya",
+ OwningProduct: ocpSpecific,
+ }
+
+ FeatureGateAutomatedEtcdBackup = FeatureGateName("AutomatedEtcdBackup")
+ automatedEtcdBackup = FeatureGateDescription{
+ FeatureGateAttributes: FeatureGateAttributes{
+ Name: FeatureGateAutomatedEtcdBackup,
+ },
+ OwningJiraComponent: "etcd",
+ ResponsiblePerson: "hasbro17",
+ OwningProduct: ocpSpecific,
+ }
+
+ FeatureGateMachineAPIOperatorDisableMachineHealthCheckController = FeatureGateName("MachineAPIOperatorDisableMachineHealthCheckController")
+ machineAPIOperatorDisableMachineHealthCheckController = FeatureGateDescription{
+ FeatureGateAttributes: FeatureGateAttributes{
+ Name: FeatureGateMachineAPIOperatorDisableMachineHealthCheckController,
+ },
+ OwningJiraComponent: "ecoproject",
+ ResponsiblePerson: "msluiter",
+ OwningProduct: ocpSpecific,
+ }
)
diff --git a/vendor/github.com/openshift/api/config/v1/stable.clusterversion.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.clusterversion.testsuite.yaml
index b966b29a88..50bb3e0274 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.clusterversion.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.clusterversion.testsuite.yaml
@@ -98,6 +98,70 @@ tests:
version: 4.11.1
image: bar
expectedError: "cannot set both Architecture and Image"
+ - name: Should be able to create a ClusterVersion with base capability None, and additional capabilities baremetal and MachineAPI
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ additionalEnabledCapabilities:
+ - baremetal
+ - MachineAPI
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ additionalEnabledCapabilities:
+ - baremetal
+ - MachineAPI
+ - name: Should not be able to create a ClusterVersion with base capability None, and additional capabilities baremetal without MachineAPI
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ additionalEnabledCapabilities:
+ - baremetal
+ expectedError: the `baremetal` capability requires the `MachineAPI` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `MachineAPI` capability
+ - name: Should be able to create a ClusterVersion with base capability None, and additional capabilities marketplace and OperatorLifecycleManager
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ additionalEnabledCapabilities:
+ - marketplace
+ - OperatorLifecycleManager
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ additionalEnabledCapabilities:
+ - marketplace
+ - OperatorLifecycleManager
+ - name: Should not be able to create a ClusterVersion with base capability None, and additional capabilities marketplace without OperatorLifecycleManager
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ additionalEnabledCapabilities:
+ - marketplace
+ expectedError: the `marketplace` capability requires the `OperatorLifecycleManager` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `OperatorLifecycleManager` capability
onUpdate:
- name: Should not allow image to be set if architecture set
initial: |
@@ -136,3 +200,219 @@ tests:
version: 4.11.1
image: bar
expectedError: "cannot set both Architecture and Image"
+ - name: Should be able to add the baremetal capability with a ClusterVersion with base capability None, and implicitly enabled MachineAPI
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ status:
+ desired:
+ version: foo
+ image: foo
+ observedGeneration: 1
+ versionHash: foo
+ availableUpdates:
+ - version: foo
+ image: foo
+ capabilities:
+ enabledCapabilities:
+ - MachineAPI
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ additionalEnabledCapabilities:
+ - baremetal
+ status:
+ desired:
+ version: foo
+ image: foo
+ observedGeneration: 1
+ versionHash: foo
+ availableUpdates:
+ - version: foo
+ image: foo
+ capabilities:
+ enabledCapabilities:
+ - MachineAPI
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ additionalEnabledCapabilities:
+ - baremetal
+ status:
+ desired:
+ version: foo
+ image: foo
+ observedGeneration: 1
+ versionHash: foo
+ availableUpdates:
+ - version: foo
+ image: foo
+ capabilities:
+ enabledCapabilities:
+ - MachineAPI
+ - name: Should be able to add the baremetal capability with a ClusterVersion with base capability None, with the Machine API capability
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ additionalEnabledCapabilities:
+ - baremetal
+ - MachineAPI
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ additionalEnabledCapabilities:
+ - baremetal
+ - MachineAPI
+ - name: Should not be able to add the baremetal capability with a ClusterVersion with base capability None, and without MachineAPI
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ additionalEnabledCapabilities:
+ - baremetal
+ expectedError: the `baremetal` capability requires the `MachineAPI` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `MachineAPI` capability
+ - name: Should be able to add the marketplace capability with a ClusterVersion with base capability None, and implicitly enabled OperatorLifecycleManager
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ status:
+ desired:
+ version: foo
+ image: foo
+ observedGeneration: 1
+ versionHash: foo
+ availableUpdates:
+ - version: foo
+ image: foo
+ capabilities:
+ enabledCapabilities:
+ - OperatorLifecycleManager
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ additionalEnabledCapabilities:
+ - marketplace
+ status:
+ desired:
+ version: foo
+ image: foo
+ observedGeneration: 1
+ versionHash: foo
+ availableUpdates:
+ - version: foo
+ image: foo
+ capabilities:
+ enabledCapabilities:
+ - OperatorLifecycleManager
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ additionalEnabledCapabilities:
+ - marketplace
+ status:
+ desired:
+ version: foo
+ image: foo
+ observedGeneration: 1
+ versionHash: foo
+ availableUpdates:
+ - version: foo
+ image: foo
+ capabilities:
+ enabledCapabilities:
+ - OperatorLifecycleManager
+ - name: Should be able to add the marketplace capability with a ClusterVersion with base capability None, with the OperatorLifecycleManager capability
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ additionalEnabledCapabilities:
+ - marketplace
+ - OperatorLifecycleManager
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ additionalEnabledCapabilities:
+ - marketplace
+ - OperatorLifecycleManager
+ - name: Should not be able to add the marketplace capability with a ClusterVersion with base capability None, and without OperatorLifecycleManager
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: ClusterVersion
+ spec:
+ clusterID: foo
+ capabilities:
+ baselineCapabilitySet: None
+ additionalEnabledCapabilities:
+ - marketplace
+ expectedError: the `marketplace` capability requires the `OperatorLifecycleManager` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `OperatorLifecycleManager` capability
diff --git a/vendor/github.com/openshift/api/config/v1/stable.dns.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.dns.testsuite.yaml
index c69f50050a..3054d200e6 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.dns.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.dns.testsuite.yaml
@@ -1,6 +1,6 @@
apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
name: "[Stable] DNS"
-crd: 0000_10_config-operator_01_dns.crd.yaml
+crd: 0000_10_config-operator_01_dns-Default.crd.yaml
tests:
onCreate:
- name: Should be able to create a minimal DNS
@@ -12,3 +12,94 @@ tests:
apiVersion: config.openshift.io/v1
kind: DNS
spec: {}
+ - name: Should be able to specify an AWS role ARN for a private hosted zone
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: AWS
+ aws:
+ privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: AWS
+ aws:
+ privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
+ - name: Should not be able to specify unsupported platform
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: Azure
+ azure:
+ privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
+ expectedError: "Invalid value: \"string\": allowed values are '' and 'AWS'"
+ - name: Should not be able to specify invalid AWS role ARN
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ metadata:
+ name: cluster
+ spec:
+ platform:
+ type: AWS
+ aws:
+ privateZoneIAMRole: arn:aws:iam:bad:123456789012:role/foo
+ expectedError: "DNS.config.openshift.io \"cluster\" is invalid: spec.platform.aws.privateZoneIAMRole: Invalid value: \"arn:aws:iam:bad:123456789012:role/foo\": spec.platform.aws.privateZoneIAMRole in body should match '^arn:(aws|aws-cn|aws-us-gov):iam::[0-9]{12}:role\\/.*$'"
+ - name: Should not be able to specify different type and platform
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: ""
+ aws:
+ privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
+ expectedError: "Invalid value: \"object\": aws configuration is required when platform is AWS, and forbidden otherwise"
+ onUpdate:
+ - name: Can switch from empty (default), to AWS
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: ""
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: AWS
+ aws:
+ privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: AWS
+ aws:
+ privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
+ - name: Upgrade case is valid
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec: {} # No spec is required for a DNS
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: ""
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: DNS
+ spec:
+ platform:
+ type: ""
+
diff --git a/vendor/github.com/openshift/api/config/v1/stable.infrastructure.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.infrastructure.testsuite.yaml
index 4266122b04..99b11b0894 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.infrastructure.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.infrastructure.testsuite.yaml
@@ -208,6 +208,7 @@ tests:
status:
controlPlaneTopology: "HighlyAvailable"
infrastructureTopology: "HighlyAvailable"
+ cpuPartitioning: None
platform: Azure
platformStatus:
azure:
@@ -340,6 +341,7 @@ tests:
type: OpenStack
status:
controlPlaneTopology: HighlyAvailable
+ cpuPartitioning: None
infrastructureTopology: HighlyAvailable
platform: OpenStack
platformStatus:
@@ -378,6 +380,7 @@ tests:
type: OpenStack
status:
controlPlaneTopology: HighlyAvailable
+ cpuPartitioning: None
infrastructureTopology: HighlyAvailable
platform: OpenStack
platformStatus:
@@ -474,3 +477,590 @@ tests:
type: FooBar
type: OpenStack
expectedStatusError: "status.platformStatus.openstack.loadBalancer.type: Unsupported value: \"FooBar\": supported values: \"OpenShiftManagedDefault\", \"UserManaged\""
+ - name: Should not be able to update cloudControllerManager state to empty string when state is already set to None
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: None
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platformStatus:
+ external:
+ cloudControllerManager:
+ state: ""
+ expectedStatusError: " status.platformStatus.external.cloudControllerManager.state: Invalid value: \"string\": state is immutable once set"
+ - name: Should not be able to update cloudControllerManager state to External when state is already set to None
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: None
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: External
+ expectedStatusError: " status.platformStatus.external.cloudControllerManager.state: Invalid value: \"string\": state is immutable once set"
+ - name: Should be able to update cloudControllerManager state to None when state is already set to None
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: None
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: None
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ controlPlaneTopology: HighlyAvailable
+ infrastructureTopology: HighlyAvailable
+ cpuPartitioning: None
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: None
+ - name: Should not be able to unset cloudControllerManager state when state is already set to None
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: None
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager: {}
+ expectedStatusError: " status.platformStatus.external.cloudControllerManager: Invalid value: \"object\": state may not be added or removed once set"
+ - name: Should not be able to update cloudControllerManager state to empty string when state is already set to External
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: External
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: ""
+ expectedStatusError: " status.platformStatus.external.cloudControllerManager.state: Invalid value: \"string\": state is immutable once set"
+ - name: Should not be able to update cloudControllerManager state to None when state is already set to External
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: External
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: None
+ expectedStatusError: " status.platformStatus.external.cloudControllerManager.state: Invalid value: \"string\": state is immutable once set"
+ - name: Should be able to update cloudControllerManager state to External when state is already set to External
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: External
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: External
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ controlPlaneTopology: HighlyAvailable
+ infrastructureTopology: HighlyAvailable
+ cpuPartitioning: None
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: External
+ - name: Should not be able to unset cloudControllerManager state when state is already set to External
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: External
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager: {}
+ expectedStatusError: " status.platformStatus.external.cloudControllerManager: Invalid value: \"object\": state may not be added or removed once set"
+ - name: Should not be able to update cloudControllerManager state to None when state is already set to empty string
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: ""
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: None
+ expectedStatusError: " status.platformStatus.external.cloudControllerManager.state: Invalid value: \"string\": state is immutable once set"
+ - name: Should not be able to update cloudControllerManager state to External when state is already set to empty string
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: ""
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: External
+ expectedStatusError: " status.platformStatus.external.cloudControllerManager.state: Invalid value: \"string\": state is immutable once set"
+ - name: Should be able to update cloudControllerManager state to empty string when state is already set to empty string
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: ""
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: ""
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ controlPlaneTopology: HighlyAvailable
+ infrastructureTopology: HighlyAvailable
+ cpuPartitioning: None
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: ""
+ - name: Should not be able to unset cloudControllerManager state when state is already set to empty string
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: ""
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager: {}
+ expectedStatusError: " status.platformStatus.external.cloudControllerManager: Invalid value: \"object\": state may not be added or removed once set"
+ - name: Should be able to update cloudControllerManager state to None when cloudControllerManager state is unset
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager: {}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: None
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ controlPlaneTopology: HighlyAvailable
+ infrastructureTopology: HighlyAvailable
+ cpuPartitioning: None
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: None
+ - name: Should be able to update cloudControllerManager state to empty string when cloudControllerManager state is unset
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager: {}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: ""
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ controlPlaneTopology: HighlyAvailable
+ infrastructureTopology: HighlyAvailable
+ cpuPartitioning: None
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: ""
+ - name: Should not be able to update cloudControllerManager state to External when cloudControllerManager state is unset
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager: {}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: External
+ expectedStatusError: " status.platformStatus.external.cloudControllerManager: Invalid value: \"object\": state may not be added or removed once set"
+ - name: Should be able to unset cloudControllerManager state when cloudControllerManager state is unset
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager: {}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager: {}
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ controlPlaneTopology: HighlyAvailable
+ infrastructureTopology: HighlyAvailable
+ cpuPartitioning: None
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager: {}
+ - name: Should not be able to add cloudControllerManager when cloudControllerManager is unset
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external: {}
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: External
+ expectedStatusError: " status.platformStatus.external: Invalid value: \"object\": cloudControllerManager may not be added or removed once set"
+ - name: Should not be able to remove cloudControllerManager when cloudControllerManager is set
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external:
+ cloudControllerManager:
+ state: External
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: External
+ platformStatus:
+ type: External
+ external: {}
+ expectedStatusError: " status.platformStatus.external: Invalid value: \"object\": cloudControllerManager may not be added or removed once set"
+ - name: Should be able to add valid (URL) ServiceEndpoints to IBMCloud PlatformStatus
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: IBMCloud
+ platformStatus:
+ type: IBMCloud
+ ibmcloud:
+ serviceEndpoints: []
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: IBMCloud
+ platformStatus:
+ type: IBMCloud
+ ibmcloud:
+ serviceEndpoints:
+ - name: DummyVPC
+ url: https://dummy.vpc.com
+ - name: DummyCOS
+ url: https://dummy.cos.com
+ expected: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ controlPlaneTopology: HighlyAvailable
+ cpuPartitioning: None
+ infrastructureTopology: HighlyAvailable
+ platform: IBMCloud
+ platformStatus:
+ type: IBMCloud
+ ibmcloud:
+ serviceEndpoints:
+ - name: DummyVPC
+ url: https://dummy.vpc.com
+ - name: DummyCOS
+ url: https://dummy.cos.com
+ - name: Should not be able to add empty (URL) ServiceEndpoints to IBMCloud PlatformStatus
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: IBMCloud
+ platformStatus:
+ type: IBMCloud
+ ibmcloud:
+ serviceEndpoints: []
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: IBMCloud
+ platformStatus:
+ type: IBMCloud
+ ibmcloud:
+ serviceEndpoints:
+ - name: EmptyCOS
+ url: " "
+ expectedStatusError: " status.platformStatus.ibmcloud.serviceEndpoints[0].url: Invalid value: \"string\": url must be a valid absolute URL"
+ - name: Should not be able to add invalid (URL) ServiceEndpoints to IBMCloud PlatformStatus
+ initial: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: IBMCloud
+ platformStatus:
+ type: IBMCloud
+ ibmcloud:
+ serviceEndpoints: []
+ updated: |
+ apiVersion: config.openshift.io/v1
+ kind: Infrastructure
+ spec: {}
+ status:
+ platform: IBMCloud
+ platformStatus:
+ type: IBMCloud
+ ibmcloud:
+ serviceEndpoints:
+ - name: DummyVPC
+ url: https://dummy.vpc.com
+ - name: BadCOS
+ url: dummy-cos-com
+ expectedStatusError: " status.platformStatus.ibmcloud.serviceEndpoints[1].url: Invalid value: \"string\": url must be a valid absolute URL"
diff --git a/vendor/github.com/openshift/api/config/v1/techpreview.dns.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/techpreview.dns.testsuite.yaml
index a63ff885d1..ec64352e35 100644
--- a/vendor/github.com/openshift/api/config/v1/techpreview.dns.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/techpreview.dns.testsuite.yaml
@@ -12,93 +12,3 @@ tests:
apiVersion: config.openshift.io/v1
kind: DNS
spec: {}
- - name: Should be able to specify an AWS role ARN for a private hosted zone
- initial: |
- apiVersion: config.openshift.io/v1
- kind: DNS
- spec:
- platform:
- type: AWS
- aws:
- privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
- expected: |
- apiVersion: config.openshift.io/v1
- kind: DNS
- spec:
- platform:
- type: AWS
- aws:
- privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
- - name: Should not be able to specify unsupported platform
- initial: |
- apiVersion: config.openshift.io/v1
- kind: DNS
- spec:
- platform:
- type: Azure
- azure:
- privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
- expectedError: "Invalid value: \"string\": allowed values are '' and 'AWS'"
- - name: Should not be able to specify invalid AWS role ARN
- initial: |
- apiVersion: config.openshift.io/v1
- kind: DNS
- metadata:
- name: cluster
- spec:
- platform:
- type: AWS
- aws:
- privateZoneIAMRole: arn:aws:iam:bad:123456789012:role/foo
- expectedError: "DNS.config.openshift.io \"cluster\" is invalid: spec.platform.aws.privateZoneIAMRole: Invalid value: \"arn:aws:iam:bad:123456789012:role/foo\": spec.platform.aws.privateZoneIAMRole in body should match '^arn:(aws|aws-cn|aws-us-gov):iam::[0-9]{12}:role\\/.*$'"
- - name: Should not be able to specify different type and platform
- initial: |
- apiVersion: config.openshift.io/v1
- kind: DNS
- spec:
- platform:
- type: ""
- aws:
- privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
- expectedError: "Invalid value: \"object\": aws configuration is required when platform is AWS, and forbidden otherwise"
- onUpdate:
- - name: Can switch from empty (default), to AWS
- initial: |
- apiVersion: config.openshift.io/v1
- kind: DNS
- spec:
- platform:
- type: ""
- updated: |
- apiVersion: config.openshift.io/v1
- kind: DNS
- spec:
- platform:
- type: AWS
- aws:
- privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
- expected: |
- apiVersion: config.openshift.io/v1
- kind: DNS
- spec:
- platform:
- type: AWS
- aws:
- privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
- - name: Upgrade case is valid
- initial: |
- apiVersion: config.openshift.io/v1
- kind: DNS
- spec: {} # No spec is required for a DNS
- updated: |
- apiVersion: config.openshift.io/v1
- kind: DNS
- spec:
- platform:
- type: ""
- expected: |
- apiVersion: config.openshift.io/v1
- kind: DNS
- spec:
- platform:
- type: ""
diff --git a/vendor/github.com/openshift/api/config/v1/techpreview.infrastructure.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/techpreview.infrastructure.testsuite.yaml
index 546f392f76..7834e1f841 100644
--- a/vendor/github.com/openshift/api/config/v1/techpreview.infrastructure.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/techpreview.infrastructure.testsuite.yaml
@@ -211,454 +211,309 @@ tests:
type: FooBar
type: BareMetal
expectedStatusError: "status.platformStatus.baremetal.loadBalancer.type: Unsupported value: \"FooBar\": supported values: \"OpenShiftManagedDefault\", \"UserManaged\""
- - name: Should not be able to update cloudControllerManager state to empty string when state is already set to None
+ - name: Should not be able to modify an existing GCP ResourceLabels Label
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ controlPlaneTopology: "HighlyAvailable"
+ infrastructureTopology: "HighlyAvailable"
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: None
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
+ platform: GCP
platformStatus:
- external:
- cloudControllerManager:
- state: ""
- expectedStatusError: " status.platformStatus.external.cloudControllerManager.state: Invalid value: \"string\": state is immutable once set"
- - name: Should not be able to update cloudControllerManager state to External when state is already set to None
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "changed"}
+ expectedStatusError: "status.platformStatus.gcp.resourceLabels: Invalid value: \"array\": resourceLabels are immutable and may only be configured during installation"
+ - name: Should not be able to add a Label to an existing GCP ResourceLabels
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ controlPlaneTopology: "HighlyAvailable"
+ infrastructureTopology: "HighlyAvailable"
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: None
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: External
- expectedStatusError: " status.platformStatus.external.cloudControllerManager.state: Invalid value: \"string\": state is immutable once set"
- - name: Should be able to update cloudControllerManager state to None when state is already set to None
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
+ - {key: "new", value: "entry"}
+ expectedStatusError: "status.platformStatus.gcp.resourceLabels: Invalid value: \"array\": resourceLabels are immutable and may only be configured during installation"
+ - name: Should not be able to remove a Label from an existing GCP ResourceLabels
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: None
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
+ - {key: "new", value: "entry"}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: None
- expected: |
- apiVersion: config.openshift.io/v1
- kind: Infrastructure
- spec: {}
- status:
- controlPlaneTopology: HighlyAvailable
- cpuPartitioning: None
- infrastructureTopology: HighlyAvailable
- platform: External
- platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: None
- - name: Should not be able to unset cloudControllerManager state when state is already set to None
- initial: |
- apiVersion: config.openshift.io/v1
- kind: Infrastructure
- spec: {}
- status:
- platform: External
- platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: None
- updated: |
- apiVersion: config.openshift.io/v1
- kind: Infrastructure
- spec: {}
- status:
- platform: External
- platformStatus:
- type: External
- external:
- cloudControllerManager: {}
- expectedStatusError: " status.platformStatus.external.cloudControllerManager: Invalid value: \"object\": state may not be added or removed once set"
- - name: Should not be able to update cloudControllerManager state to empty string when state is already set to External
- initial: |
- apiVersion: config.openshift.io/v1
- kind: Infrastructure
- spec: {}
- status:
- platform: External
- platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: External
- updated: |
- apiVersion: config.openshift.io/v1
- kind: Infrastructure
- spec: {}
- status:
- platform: External
- platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: ""
- expectedStatusError: " status.platformStatus.external.cloudControllerManager.state: Invalid value: \"string\": state is immutable once set"
- - name: Should not be able to update cloudControllerManager state to None when state is already set to External
- initial: |
- apiVersion: config.openshift.io/v1
- kind: Infrastructure
- spec: {}
- status:
- platform: External
- platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: External
- updated: |
- apiVersion: config.openshift.io/v1
- kind: Infrastructure
- spec: {}
- status:
- platform: External
- platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: None
- expectedStatusError: " status.platformStatus.external.cloudControllerManager.state: Invalid value: \"string\": state is immutable once set"
- - name: Should be able to update cloudControllerManager state to External when state is already set to External
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
+ expectedStatusError: "status.platformStatus.gcp.resourceLabels: Invalid value: \"array\": resourceLabels are immutable and may only be configured during installation"
+ - name: Should not be able to add GCP ResourceLabels to an empty platformStatus.gcp
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: External
+ type: GCP
+ gcp: {}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
- platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: External
- expected: |
- apiVersion: config.openshift.io/v1
- kind: Infrastructure
- spec: {}
- status:
- controlPlaneTopology: HighlyAvailable
- cpuPartitioning: None
- infrastructureTopology: HighlyAvailable
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: External
- - name: Should not be able to unset cloudControllerManager state when state is already set to External
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
+ expectedStatusError: "status.platformStatus.gcp: Invalid value: \"object\": resourceLabels may only be configured during installation"
+ - name: Should not be able to remove GCP ResourceLabels from platformStatus.gcp
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: External
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager: {}
- expectedStatusError: " status.platformStatus.external.cloudControllerManager: Invalid value: \"object\": state may not be added or removed once set"
- - name: Should not be able to update cloudControllerManager state to None when state is already set to empty string
+ type: GCP
+ gcp: {}
+ expectedStatusError: "status.platformStatus.gcp: Invalid value: \"object\": resourceLabels may only be configured during installation"
+ - name: Should not have label key start with openshift-io for GCP ResourceLabels in platformStatus.gcp
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
- status:
- platform: External
- platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: ""
+ status: {}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: None
- expectedStatusError: " status.platformStatus.external.cloudControllerManager.state: Invalid value: \"string\": state is immutable once set"
- - name: Should not be able to update cloudControllerManager state to External when state is already set to empty string
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
+ - {key: "openshift-io-created-cluster", value: "true"}
+ expectedStatusError: "status.platformStatus.gcp.resourceLabels[1].key: Invalid value: \"string\": label keys must not start with either `openshift-io` or `kubernetes-io`"
+ - name: Should not have label key start with kubernetes-io for GCP ResourceLabels in platformStatus.gcp
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
- status:
- platform: External
- platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: ""
+ status: {}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: External
- expectedStatusError: " status.platformStatus.external.cloudControllerManager.state: Invalid value: \"string\": state is immutable once set"
- - name: Should be able to update cloudControllerManager state to empty string when state is already set to empty string
+ type: GCP
+ gcp:
+ resourceLabels:
+ - {key: "key", value: "value"}
+ - {key: "kubernetes-io-created-cluster", value: "true"}
+ expectedStatusError: "status.platformStatus.gcp.resourceLabels[1].key: Invalid value: \"string\": label keys must not start with either `openshift-io` or `kubernetes-io`"
+ - name: Should not be able to modify an existing GCP ResourceTags Tag
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ controlPlaneTopology: "HighlyAvailable"
+ infrastructureTopology: "HighlyAvailable"
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: ""
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key", value: "value"}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: ""
- expected: |
- apiVersion: config.openshift.io/v1
- kind: Infrastructure
- spec: {}
- status:
- controlPlaneTopology: HighlyAvailable
- cpuPartitioning: None
- infrastructureTopology: HighlyAvailable
- platform: External
- platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: ""
- - name: Should not be able to unset cloudControllerManager state when state is already set to empty string
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key", value: "changed"}
+ expectedStatusError: "status.platformStatus.gcp.resourceTags: Invalid value: \"array\": resourceTags are immutable and may only be configured during installation"
+ - name: Should not be able to add a Tag to an existing GCP ResourceTags
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ controlPlaneTopology: "HighlyAvailable"
+ infrastructureTopology: "HighlyAvailable"
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: ""
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key", value: "value"}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager: {}
- expectedStatusError: " status.platformStatus.external.cloudControllerManager: Invalid value: \"object\": state may not be added or removed once set"
- - name: Should be able to update cloudControllerManager state to None when cloudControllerManager state is unset
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key", value: "value"}
+ - {parentID: "test-project-123", key: "new", value: "tag"}
+ expectedStatusError: "status.platformStatus.gcp.resourceTags: Invalid value: \"array\": resourceTags are immutable and may only be configured during installation"
+ - name: Should not be able to remove a Tag from an existing GCP ResourceTags
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager: {}
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key1", value: "value1"}
+ - {parentID: "test-project-123", key: "key2", value: "value2"}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
- platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: None
- expected: |
- apiVersion: config.openshift.io/v1
- kind: Infrastructure
- spec: {}
- status:
- controlPlaneTopology: HighlyAvailable
- cpuPartitioning: None
- infrastructureTopology: HighlyAvailable
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: None
- - name: Should be able to update cloudControllerManager state to empty string when cloudControllerManager state is unset
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key1", value: "value1"}
+ expectedStatusError: "status.platformStatus.gcp.resourceTags: Invalid value: \"array\": resourceTags are immutable and may only be configured during installation"
+ - name: Should not be able to add GCP ResourceTags to an empty platformStatus.gcp
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager: {}
+ type: GCP
+ gcp: {}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
- platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: ""
- expected: |
- apiVersion: config.openshift.io/v1
- kind: Infrastructure
- spec: {}
- status:
- controlPlaneTopology: HighlyAvailable
- cpuPartitioning: None
- infrastructureTopology: HighlyAvailable
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: ""
- - name: Should not be able to update cloudControllerManager state to External when cloudControllerManager state is unset
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key", value: "value"}
+ expectedStatusError: "status.platformStatus.gcp: Invalid value: \"object\": resourceTags may only be configured during installation"
+ - name: Should not be able to remove GCP ResourceTags from platformStatus.gcp
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager: {}
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key", value: "value"}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager:
- state: External
- expectedStatusError: " status.platformStatus.external.cloudControllerManager: Invalid value: \"object\": state may not be added or removed once set"
- - name: Should be able to unset cloudControllerManager state when cloudControllerManager state is unset
+ type: GCP
+ gcp: {}
+ expectedStatusError: "status.platformStatus.gcp: Invalid value: \"object\": resourceTags may only be configured during installation"
+ - name: Should not be able to modify ParentID of a Tag in the GCP ResourceTags
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
+ controlPlaneTopology: "HighlyAvailable"
+ infrastructureTopology: "HighlyAvailable"
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager: {}
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "1234567890", key: "key", value: "value"}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
- platform: External
- platformStatus:
- type: External
- external:
- cloudControllerManager: {}
- expected: |
- apiVersion: config.openshift.io/v1
- kind: Infrastructure
- spec: {}
- status:
- controlPlaneTopology: HighlyAvailable
- cpuPartitioning: None
- infrastructureTopology: HighlyAvailable
- platform: External
+ platform: GCP
platformStatus:
- type: External
- external:
- cloudControllerManager: {}
+ type: GCP
+ gcp:
+ resourceTags:
+ - {parentID: "test-project-123", key: "key", value: "value"}
+ expectedStatusError: "status.platformStatus.gcp.resourceTags: Invalid value: \"array\": resourceTags are immutable and may only be configured during installation"
diff --git a/vendor/github.com/openshift/api/config/v1/types_cluster_version.go b/vendor/github.com/openshift/api/config/v1/types_cluster_version.go
index 234720477b..a9bade6fe7 100644
--- a/vendor/github.com/openshift/api/config/v1/types_cluster_version.go
+++ b/vendor/github.com/openshift/api/config/v1/types_cluster_version.go
@@ -13,6 +13,8 @@ import (
//
// Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
// +openshift:compatibility-gen:level=1
+// +kubebuilder:validation:XValidation:rule="has(self.spec.capabilities) && has(self.spec.capabilities.additionalEnabledCapabilities) && self.spec.capabilities.baselineCapabilitySet == 'None' && 'baremetal' in self.spec.capabilities.additionalEnabledCapabilities ? 'MachineAPI' in self.spec.capabilities.additionalEnabledCapabilities || (has(self.status) && has(self.status.capabilities) && has(self.status.capabilities.enabledCapabilities) && 'MachineAPI' in self.status.capabilities.enabledCapabilities) : true",message="the `baremetal` capability requires the `MachineAPI` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `MachineAPI` capability"
+// +kubebuilder:validation:XValidation:rule="has(self.spec.capabilities) && has(self.spec.capabilities.additionalEnabledCapabilities) && self.spec.capabilities.baselineCapabilitySet == 'None' && 'marketplace' in self.spec.capabilities.additionalEnabledCapabilities ? 'OperatorLifecycleManager' in self.spec.capabilities.additionalEnabledCapabilities || (has(self.status) && has(self.status.capabilities) && has(self.status.capabilities.enabledCapabilities) && 'OperatorLifecycleManager' in self.status.capabilities.enabledCapabilities) : true",message="the `marketplace` capability requires the `OperatorLifecycleManager` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `OperatorLifecycleManager` capability"
type ClusterVersion struct {
metav1.TypeMeta `json:",inline"`
@@ -247,7 +249,7 @@ const (
)
// ClusterVersionCapability enumerates optional, core cluster components.
-// +kubebuilder:validation:Enum=openshift-samples;baremetal;marketplace;Console;Insights;Storage;CSISnapshot;NodeTuning;MachineAPI
+// +kubebuilder:validation:Enum=openshift-samples;baremetal;marketplace;Console;Insights;Storage;CSISnapshot;NodeTuning;MachineAPI;Build;DeploymentConfig;ImageRegistry;OperatorLifecycleManager
type ClusterVersionCapability string
const (
@@ -266,6 +268,9 @@ const (
// ClusterVersionCapabilityMarketplace manages the Marketplace operator which
// supplies Operator Lifecycle Manager (OLM) users with default catalogs of
// "optional" operators.
+ //
+ // Note that Marketplace has a hard requirement on OLM. OLM can not be disabled
+ // while Marketplace is enabled.
ClusterVersionCapabilityMarketplace ClusterVersionCapability = "marketplace"
// ClusterVersionCapabilityConsole manages the Console operator which
@@ -313,6 +318,31 @@ const (
// documentation. This is important part of openshift system
// and may cause cluster damage
ClusterVersionCapabilityMachineAPI ClusterVersionCapability = "MachineAPI"
+
+ // ClusterVersionCapabilityBuild manages the Build API which is responsible
+ // for watching the Build API objects and managing their lifecycle.
+ // The functionality is located under openshift-apiserver and openshift-controller-manager.
+ //
+ // The following resources are taken into account:
+ // - builds
+ // - buildconfigs
+ ClusterVersionCapabilityBuild ClusterVersionCapability = "Build"
+
+ // ClusterVersionCapabilityDeploymentConfig manages the DeploymentConfig API
+ // which is responsible for watching the DeploymentConfig API and managing their lifecycle.
+ // The functionality is located under openshift-apiserver and openshift-controller-manager.
+ //
+ // The following resources are taken into account:
+ // - deploymentconfigs
+ ClusterVersionCapabilityDeploymentConfig ClusterVersionCapability = "DeploymentConfig"
+
+ // ClusterVersionCapabilityImageRegistry manages the image registry which
+ // allows to distribute Docker images
+ ClusterVersionCapabilityImageRegistry ClusterVersionCapability = "ImageRegistry"
+
+ // ClusterVersionCapabilityOperatorLifecycleManager manages the Operator Lifecycle Manager
+ // which itself manages the lifecycle of operators
+ ClusterVersionCapabilityOperatorLifecycleManager ClusterVersionCapability = "OperatorLifecycleManager"
)
// KnownClusterVersionCapabilities includes all known optional, core cluster components.
@@ -326,6 +356,10 @@ var KnownClusterVersionCapabilities = []ClusterVersionCapability{
ClusterVersionCapabilityCSISnapshot,
ClusterVersionCapabilityNodeTuning,
ClusterVersionCapabilityMachineAPI,
+ ClusterVersionCapabilityBuild,
+ ClusterVersionCapabilityDeploymentConfig,
+ ClusterVersionCapabilityImageRegistry,
+ ClusterVersionCapabilityOperatorLifecycleManager,
}
// ClusterVersionCapabilitySet defines sets of cluster version capabilities.
@@ -374,6 +408,7 @@ var ClusterVersionCapabilitySets = map[ClusterVersionCapabilitySet][]ClusterVers
ClusterVersionCapabilityBaremetal,
ClusterVersionCapabilityMarketplace,
ClusterVersionCapabilityOpenShiftSamples,
+ ClusterVersionCapabilityMachineAPI,
},
ClusterVersionCapabilitySet4_12: {
ClusterVersionCapabilityBaremetal,
@@ -383,6 +418,7 @@ var ClusterVersionCapabilitySets = map[ClusterVersionCapabilitySet][]ClusterVers
ClusterVersionCapabilityStorage,
ClusterVersionCapabilityOpenShiftSamples,
ClusterVersionCapabilityCSISnapshot,
+ ClusterVersionCapabilityMachineAPI,
},
ClusterVersionCapabilitySet4_13: {
ClusterVersionCapabilityBaremetal,
@@ -393,6 +429,7 @@ var ClusterVersionCapabilitySets = map[ClusterVersionCapabilitySet][]ClusterVers
ClusterVersionCapabilityOpenShiftSamples,
ClusterVersionCapabilityCSISnapshot,
ClusterVersionCapabilityNodeTuning,
+ ClusterVersionCapabilityMachineAPI,
},
ClusterVersionCapabilitySet4_14: {
ClusterVersionCapabilityBaremetal,
@@ -404,6 +441,9 @@ var ClusterVersionCapabilitySets = map[ClusterVersionCapabilitySet][]ClusterVers
ClusterVersionCapabilityCSISnapshot,
ClusterVersionCapabilityNodeTuning,
ClusterVersionCapabilityMachineAPI,
+ ClusterVersionCapabilityBuild,
+ ClusterVersionCapabilityDeploymentConfig,
+ ClusterVersionCapabilityImageRegistry,
},
ClusterVersionCapabilitySetCurrent: {
ClusterVersionCapabilityBaremetal,
@@ -415,6 +455,10 @@ var ClusterVersionCapabilitySets = map[ClusterVersionCapabilitySet][]ClusterVers
ClusterVersionCapabilityCSISnapshot,
ClusterVersionCapabilityNodeTuning,
ClusterVersionCapabilityMachineAPI,
+ ClusterVersionCapabilityBuild,
+ ClusterVersionCapabilityDeploymentConfig,
+ ClusterVersionCapabilityImageRegistry,
+ ClusterVersionCapabilityOperatorLifecycleManager,
},
}
diff --git a/vendor/github.com/openshift/api/config/v1/types_dns.go b/vendor/github.com/openshift/api/config/v1/types_dns.go
index afd241f9fd..5f8697673f 100644
--- a/vendor/github.com/openshift/api/config/v1/types_dns.go
+++ b/vendor/github.com/openshift/api/config/v1/types_dns.go
@@ -57,7 +57,6 @@ type DNSSpec struct {
// infrastructure provider for DNS.
// When omitted, this means the user has no opinion and the platform is left
// to choose reasonable defaults. These defaults are subject to change over time.
- // +openshift:enable:FeatureSets=TechPreviewNoUpgrade
// +optional
Platform DNSPlatformSpec `json:"platform,omitempty"`
}
diff --git a/vendor/github.com/openshift/api/config/v1/types_feature.go b/vendor/github.com/openshift/api/config/v1/types_feature.go
index 510ed11328..4bae91db88 100644
--- a/vendor/github.com/openshift/api/config/v1/types_feature.go
+++ b/vendor/github.com/openshift/api/config/v1/types_feature.go
@@ -163,27 +163,23 @@ var FeatureSets = map[FeatureSet]*FeatureGateEnabledDisabled{
Disabled: []FeatureGateDescription{},
},
TechPreviewNoUpgrade: newDefaultFeatures().
- with(externalCloudProvider).
- with(externalCloudProviderAzure).
- with(externalCloudProviderGCP).
- with(externalCloudProviderExternal).
+ without(validatingAdmissionPolicy).
with(csiDriverSharedResource).
- with(buildCSIVolumes).
with(nodeSwap).
with(machineAPIProviderOpenStack).
with(insightsConfigAPI).
- with(matchLabelKeysInPodTopologySpread).
with(retroactiveDefaultStorageClass).
- with(pdbUnhealthyPodEvictionPolicy).
with(dynamicResourceAllocation).
- with(admissionWebhookMatchConditions).
- with(azureWorkloadIdentity).
with(gateGatewayAPI).
with(maxUnavailableStatefulSet).
without(eventedPleg).
- with(privateHostedZoneAWS).
with(sigstoreImageVerification).
with(gcpLabelsTags).
+ with(vSphereStaticIPs).
+ with(routeExternalCertificate).
+ with(automatedEtcdBackup).
+ without(machineAPIOperatorDisableMachineHealthCheckController).
+ with(adminNetworkPolicy).
toFeatures(defaultFeatures),
LatencySensitive: newDefaultFeatures().
toFeatures(defaultFeatures),
@@ -193,7 +189,14 @@ var defaultFeatures = &FeatureGateEnabledDisabled{
Enabled: []FeatureGateDescription{
openShiftPodSecurityAdmission,
alibabaPlatform, // This is a bug, it should be TechPreviewNoUpgrade. This must be downgraded before 4.14 is shipped.
+ azureWorkloadIdentity,
cloudDualStackNodeIPs,
+ externalCloudProvider,
+ externalCloudProviderAzure,
+ externalCloudProviderGCP,
+ externalCloudProviderExternal,
+ privateHostedZoneAWS,
+ buildCSIVolumes,
},
Disabled: []FeatureGateDescription{
retroactiveDefaultStorageClass,
diff --git a/vendor/github.com/openshift/api/config/v1/types_image.go b/vendor/github.com/openshift/api/config/v1/types_image.go
index eb7643f2bc..928224c0d7 100644
--- a/vendor/github.com/openshift/api/config/v1/types_image.go
+++ b/vendor/github.com/openshift/api/config/v1/types_image.go
@@ -64,12 +64,10 @@ type ImageSpec struct {
}
type ImageStatus struct {
-
// internalRegistryHostname sets the hostname for the default internal image
// registry. The value must be in "hostname[:port]" format.
// This value is set by the image registry operator which controls the internal registry
- // hostname. For backward compatibility, users can still use OPENSHIFT_DEFAULT_REGISTRY
- // environment variable but this setting overrides the environment variable.
+ // hostname.
// +optional
InternalRegistryHostname string `json:"internalRegistryHostname,omitempty"`
diff --git a/vendor/github.com/openshift/api/config/v1/types_infrastructure.go b/vendor/github.com/openshift/api/config/v1/types_infrastructure.go
index c274d9cdee..18d36519d1 100644
--- a/vendor/github.com/openshift/api/config/v1/types_infrastructure.go
+++ b/vendor/github.com/openshift/api/config/v1/types_infrastructure.go
@@ -114,7 +114,6 @@ type InfrastructureStatus struct {
// +kubebuilder:default=None
// +default="None"
// +kubebuilder:validation:Enum=None;AllNodes
- // +openshift:enable:FeatureSets=TechPreviewNoUpgrade
// +optional
CPUPartitioning CPUPartitioningMode `json:"cpuPartitioning,omitempty"`
}
@@ -349,11 +348,11 @@ type CloudControllerManagerStatus struct {
}
// ExternalPlatformStatus holds the current status of the generic External infrastructure provider.
+// +kubebuilder:validation:XValidation:rule="has(self.cloudControllerManager) == has(oldSelf.cloudControllerManager)",message="cloudControllerManager may not be added or removed once set"
type ExternalPlatformStatus struct {
// cloudControllerManager contains settings specific to the external Cloud Controller Manager (a.k.a. CCM or CPI).
// When omitted, new nodes will be not tainted
// and no extra initialization from the cloud controller manager is expected.
- // +openshift:enable:FeatureSets=TechPreviewNoUpgrade
// +optional
CloudControllerManager CloudControllerManagerStatus `json:"cloudControllerManager"`
}
@@ -580,12 +579,93 @@ const (
type GCPPlatformSpec struct{}
// GCPPlatformStatus holds the current status of the Google Cloud Platform infrastructure provider.
+// +openshift:validation:FeatureSetAwareXValidation:featureSet=CustomNoUpgrade;TechPreviewNoUpgrade,rule="!has(oldSelf.resourceLabels) && !has(self.resourceLabels) || has(oldSelf.resourceLabels) && has(self.resourceLabels)",message="resourceLabels may only be configured during installation"
+// +openshift:validation:FeatureSetAwareXValidation:featureSet=CustomNoUpgrade;TechPreviewNoUpgrade,rule="!has(oldSelf.resourceTags) && !has(self.resourceTags) || has(oldSelf.resourceTags) && has(self.resourceTags)",message="resourceTags may only be configured during installation"
type GCPPlatformStatus struct {
// resourceGroupName is the Project ID for new GCP resources created for the cluster.
ProjectID string `json:"projectID"`
// region holds the region for new GCP resources created for the cluster.
Region string `json:"region"`
+
+ // resourceLabels is a list of additional labels to apply to GCP resources created for the cluster.
+ // See https://cloud.google.com/compute/docs/labeling-resources for information on labeling GCP resources.
+ // GCP supports a maximum of 64 labels per resource. OpenShift reserves 32 labels for internal use,
+ // allowing 32 labels for user configuration.
+ // +kubebuilder:validation:MaxItems=32
+ // +kubebuilder:validation:XValidation:rule="self.all(x, x in oldSelf) && oldSelf.all(x, x in self)",message="resourceLabels are immutable and may only be configured during installation"
+ // +listType=map
+ // +listMapKey=key
+ // +optional
+ // +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade
+ ResourceLabels []GCPResourceLabel `json:"resourceLabels,omitempty"`
+
+ // resourceTags is a list of additional tags to apply to GCP resources created for the cluster.
+ // See https://cloud.google.com/resource-manager/docs/tags/tags-overview for information on
+ // tagging GCP resources. GCP supports a maximum of 50 tags per resource.
+ // +kubebuilder:validation:MaxItems=50
+ // +kubebuilder:validation:XValidation:rule="self.all(x, x in oldSelf) && oldSelf.all(x, x in self)",message="resourceTags are immutable and may only be configured during installation"
+ // +listType=map
+ // +listMapKey=key
+ // +optional
+ // +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade
+ ResourceTags []GCPResourceTag `json:"resourceTags,omitempty"`
+}
+
+// GCPResourceLabel is a label to apply to GCP resources created for the cluster.
+type GCPResourceLabel struct {
+ // key is the key part of the label. A label key can have a maximum of 63 characters and cannot be empty.
+ // Label key must begin with a lowercase letter, and must contain only lowercase letters, numeric characters,
+ // and the following special characters `_-`. Label key must not have the reserved prefixes `kubernetes-io`
+ // and `openshift-io`.
+ // +kubebuilder:validation:XValidation:rule="!self.startsWith('openshift-io') && !self.startsWith('kubernetes-io')",message="label keys must not start with either `openshift-io` or `kubernetes-io`"
+ // +kubebuilder:validation:Required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=63
+ // +kubebuilder:validation:Pattern=`^[a-z][0-9a-z_-]+$`
+ Key string `json:"key"`
+
+ // value is the value part of the label. A label value can have a maximum of 63 characters and cannot be empty.
+ // Value must contain only lowercase letters, numeric characters, and the following special characters `_-`.
+ // +kubebuilder:validation:Required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=63
+ // +kubebuilder:validation:Pattern=`^[0-9a-z_-]+$`
+ Value string `json:"value"`
+}
+
+// GCPResourceTag is a tag to apply to GCP resources created for the cluster.
+type GCPResourceTag struct {
+ // parentID is the ID of the hierarchical resource where the tags are defined,
+ // e.g. at the Organization or the Project level. To find the Organization or Project ID refer to the following pages:
+ // https://cloud.google.com/resource-manager/docs/creating-managing-organization#retrieving_your_organization_id,
+ // https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects.
+ // An OrganizationID must consist of decimal numbers, and cannot have leading zeroes.
+ // A ProjectID must be 6 to 30 characters in length, can only contain lowercase letters, numbers,
+ // and hyphens, and must start with a letter, and cannot end with a hyphen.
+ // +kubebuilder:validation:Required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=32
+ // +kubebuilder:validation:Pattern=`(^[1-9][0-9]{0,31}$)|(^[a-z][a-z0-9-]{4,28}[a-z0-9]$)`
+ ParentID string `json:"parentID"`
+
+ // key is the key part of the tag. A tag key can have a maximum of 63 characters and cannot be empty.
+ // Tag key must begin and end with an alphanumeric character, and must contain only uppercase, lowercase
+ // alphanumeric characters, and the following special characters `._-`.
+ // +kubebuilder:validation:Required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=63
+ // +kubebuilder:validation:Pattern=`^[a-zA-Z0-9]([0-9A-Za-z_.-]{0,61}[a-zA-Z0-9])?$`
+ Key string `json:"key"`
+
+ // value is the value part of the tag. A tag value can have a maximum of 63 characters and cannot be empty.
+ // Tag value must begin and end with an alphanumeric character, and must contain only uppercase, lowercase
+ // alphanumeric characters, and the following special characters `_-.@%=+:,*#&(){}[]` and spaces.
+ // +kubebuilder:validation:Required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=63
+ // +kubebuilder:validation:Pattern=`^[a-zA-Z0-9]([0-9A-Za-z_.@%=+:,*#&()\[\]{}\-\s]{0,61}[a-zA-Z0-9])?$`
+ Value string `json:"value"`
}
// BareMetalPlatformLoadBalancer defines the load balancer used by the cluster on BareMetal platform.
@@ -661,7 +741,7 @@ type BareMetalPlatformStatus struct {
// loadBalancer defines how the load balancer used by the cluster is configured.
// +default={"type": "OpenShiftManagedDefault"}
// +kubebuilder:default={"type": "OpenShiftManagedDefault"}
- // +openshift:enable:FeatureSets=TechPreviewNoUpgrade
+ // +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade
// +optional
LoadBalancer *BareMetalPlatformLoadBalancer `json:"loadBalancer,omitempty"`
}
@@ -811,7 +891,7 @@ type OvirtPlatformStatus struct {
// loadBalancer defines how the load balancer used by the cluster is configured.
// +default={"type": "OpenShiftManagedDefault"}
// +kubebuilder:default={"type": "OpenShiftManagedDefault"}
- // +openshift:enable:FeatureSets=TechPreviewNoUpgrade
+ // +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade
// +optional
LoadBalancer *OvirtPlatformLoadBalancer `json:"loadBalancer,omitempty"`
}
@@ -1077,11 +1157,35 @@ type VSpherePlatformStatus struct {
// loadBalancer defines how the load balancer used by the cluster is configured.
// +default={"type": "OpenShiftManagedDefault"}
// +kubebuilder:default={"type": "OpenShiftManagedDefault"}
- // +openshift:enable:FeatureSets=TechPreviewNoUpgrade
+ // +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade
// +optional
LoadBalancer *VSpherePlatformLoadBalancer `json:"loadBalancer,omitempty"`
}
+// IBMCloudServiceEndpoint stores the configuration of a custom url to
+// override existing defaults of IBM Cloud Services.
+type IBMCloudServiceEndpoint struct {
+ // name is the name of the IBM Cloud service.
+ // For example, the IBM Cloud Private IAM service could be configured with the
+ // service `name` of `IAM` and `url` of `https://private.iam.cloud.ibm.com`
+ // Whereas the IBM Cloud Private VPC service for US South (Dallas) could be configured
+ // with the service `name` of `VPC` and `url` of `https://us.south.private.iaas.cloud.ibm.com`
+ //
+ // +kubebuilder:validation:Required
+ // +kubebuilder:validation:Pattern=`^[a-zA-Z0-9-]+$`
+ // +kubebuilder:validation:MaxLength=32
+ Name string `json:"name"`
+
+ // url is fully qualified URI with scheme https, that overrides the default generated
+ // endpoint for a client.
+ // This must be provided and cannot be empty.
+ //
+ // +kubebuilder:validation:Required
+ // +kubebuilder:validation:Type=string
+ // +kubebuilder:validation:XValidation:rule="isURL(self)",message="url must be a valid absolute URL"
+ URL string `json:"url"`
+}
+
// IBMCloudPlatformSpec holds the desired state of the IBMCloud infrastructure provider.
// This only includes fields that can be modified in the cluster.
type IBMCloudPlatformSpec struct{}
@@ -1104,6 +1208,14 @@ type IBMCloudPlatformStatus struct {
// DNSInstanceCRN is the CRN of the DNS Services instance managing the DNS zone
// for the cluster's base domain
DNSInstanceCRN string `json:"dnsInstanceCRN,omitempty"`
+
+ // serviceEndpoints is a list of custom endpoints which will override the default
+ // service endpoints of an IBM Cloud service. These endpoints are consumed by
+ // components within the cluster to reach the respective IBM Cloud Services.
+ // +listType=map
+ // +listMapKey=name
+ // +optional
+ ServiceEndpoints []IBMCloudServiceEndpoint `json:"serviceEndpoints,omitempty"`
}
// KubevirtPlatformSpec holds the desired state of the kubevirt infrastructure provider.
@@ -1360,7 +1472,7 @@ type NutanixPlatformStatus struct {
// loadBalancer defines how the load balancer used by the cluster is configured.
// +default={"type": "OpenShiftManagedDefault"}
// +kubebuilder:default={"type": "OpenShiftManagedDefault"}
- // +openshift:enable:FeatureSets=TechPreviewNoUpgrade
+ // +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade
// +optional
LoadBalancer *NutanixPlatformLoadBalancer `json:"loadBalancer,omitempty"`
}
diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go
index 5738354605..63b9f050d0 100644
--- a/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go
+++ b/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go
@@ -2137,6 +2137,16 @@ func (in *GCPPlatformSpec) DeepCopy() *GCPPlatformSpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GCPPlatformStatus) DeepCopyInto(out *GCPPlatformStatus) {
*out = *in
+ if in.ResourceLabels != nil {
+ in, out := &in.ResourceLabels, &out.ResourceLabels
+ *out = make([]GCPResourceLabel, len(*in))
+ copy(*out, *in)
+ }
+ if in.ResourceTags != nil {
+ in, out := &in.ResourceTags, &out.ResourceTags
+ *out = make([]GCPResourceTag, len(*in))
+ copy(*out, *in)
+ }
return
}
@@ -2150,6 +2160,38 @@ func (in *GCPPlatformStatus) DeepCopy() *GCPPlatformStatus {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GCPResourceLabel) DeepCopyInto(out *GCPResourceLabel) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GCPResourceLabel.
+func (in *GCPResourceLabel) DeepCopy() *GCPResourceLabel {
+ if in == nil {
+ return nil
+ }
+ out := new(GCPResourceLabel)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GCPResourceTag) DeepCopyInto(out *GCPResourceTag) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GCPResourceTag.
+func (in *GCPResourceTag) DeepCopy() *GCPResourceTag {
+ if in == nil {
+ return nil
+ }
+ out := new(GCPResourceTag)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GenericAPIServerConfig) DeepCopyInto(out *GenericAPIServerConfig) {
*out = *in
@@ -2345,6 +2387,11 @@ func (in *IBMCloudPlatformSpec) DeepCopy() *IBMCloudPlatformSpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IBMCloudPlatformStatus) DeepCopyInto(out *IBMCloudPlatformStatus) {
*out = *in
+ if in.ServiceEndpoints != nil {
+ in, out := &in.ServiceEndpoints, &out.ServiceEndpoints
+ *out = make([]IBMCloudServiceEndpoint, len(*in))
+ copy(*out, *in)
+ }
return
}
@@ -2358,6 +2405,22 @@ func (in *IBMCloudPlatformStatus) DeepCopy() *IBMCloudPlatformStatus {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IBMCloudServiceEndpoint) DeepCopyInto(out *IBMCloudServiceEndpoint) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IBMCloudServiceEndpoint.
+func (in *IBMCloudServiceEndpoint) DeepCopy() *IBMCloudServiceEndpoint {
+ if in == nil {
+ return nil
+ }
+ out := new(IBMCloudServiceEndpoint)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IdentityProvider) DeepCopyInto(out *IdentityProvider) {
*out = *in
@@ -4335,7 +4398,7 @@ func (in *PlatformStatus) DeepCopyInto(out *PlatformStatus) {
if in.GCP != nil {
in, out := &in.GCP, &out.GCP
*out = new(GCPPlatformStatus)
- **out = **in
+ (*in).DeepCopyInto(*out)
}
if in.BareMetal != nil {
in, out := &in.BareMetal, &out.BareMetal
@@ -4360,7 +4423,7 @@ func (in *PlatformStatus) DeepCopyInto(out *PlatformStatus) {
if in.IBMCloud != nil {
in, out := &in.IBMCloud, &out.IBMCloud
*out = new(IBMCloudPlatformStatus)
- **out = **in
+ (*in).DeepCopyInto(*out)
}
if in.Kubevirt != nil {
in, out := &in.Kubevirt, &out.Kubevirt
diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go
index f84e44573b..048c37b16f 100644
--- a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go
+++ b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go
@@ -903,7 +903,7 @@ func (ImageSpec) SwaggerDoc() map[string]string {
}
var map_ImageStatus = map[string]string{
- "internalRegistryHostname": "internalRegistryHostname sets the hostname for the default internal image registry. The value must be in \"hostname[:port]\" format. This value is set by the image registry operator which controls the internal registry hostname. For backward compatibility, users can still use OPENSHIFT_DEFAULT_REGISTRY environment variable but this setting overrides the environment variable.",
+ "internalRegistryHostname": "internalRegistryHostname sets the hostname for the default internal image registry. The value must be in \"hostname[:port]\" format. This value is set by the image registry operator which controls the internal registry hostname.",
"externalRegistryHostnames": "externalRegistryHostnames provides the hostnames for the default external image registry. The external hostname should be set only when the image registry is exposed externally. The first value is used in 'publicDockerImageRepository' field in ImageStreams. The value must be in \"hostname[:port]\" format.",
}
@@ -1237,15 +1237,38 @@ func (GCPPlatformSpec) SwaggerDoc() map[string]string {
}
var map_GCPPlatformStatus = map[string]string{
- "": "GCPPlatformStatus holds the current status of the Google Cloud Platform infrastructure provider.",
- "projectID": "resourceGroupName is the Project ID for new GCP resources created for the cluster.",
- "region": "region holds the region for new GCP resources created for the cluster.",
+ "": "GCPPlatformStatus holds the current status of the Google Cloud Platform infrastructure provider.",
+ "projectID": "resourceGroupName is the Project ID for new GCP resources created for the cluster.",
+ "region": "region holds the region for new GCP resources created for the cluster.",
+ "resourceLabels": "resourceLabels is a list of additional labels to apply to GCP resources created for the cluster. See https://cloud.google.com/compute/docs/labeling-resources for information on labeling GCP resources. GCP supports a maximum of 64 labels per resource. OpenShift reserves 32 labels for internal use, allowing 32 labels for user configuration.",
+ "resourceTags": "resourceTags is a list of additional tags to apply to GCP resources created for the cluster. See https://cloud.google.com/resource-manager/docs/tags/tags-overview for information on tagging GCP resources. GCP supports a maximum of 50 tags per resource.",
}
func (GCPPlatformStatus) SwaggerDoc() map[string]string {
return map_GCPPlatformStatus
}
+var map_GCPResourceLabel = map[string]string{
+ "": "GCPResourceLabel is a label to apply to GCP resources created for the cluster.",
+ "key": "key is the key part of the label. A label key can have a maximum of 63 characters and cannot be empty. Label key must begin with a lowercase letter, and must contain only lowercase letters, numeric characters, and the following special characters `_-`. Label key must not have the reserved prefixes `kubernetes-io` and `openshift-io`.",
+ "value": "value is the value part of the label. A label value can have a maximum of 63 characters and cannot be empty. Value must contain only lowercase letters, numeric characters, and the following special characters `_-`.",
+}
+
+func (GCPResourceLabel) SwaggerDoc() map[string]string {
+ return map_GCPResourceLabel
+}
+
+var map_GCPResourceTag = map[string]string{
+ "": "GCPResourceTag is a tag to apply to GCP resources created for the cluster.",
+ "parentID": "parentID is the ID of the hierarchical resource where the tags are defined, e.g. at the Organization or the Project level. To find the Organization or Project ID refer to the following pages: https://cloud.google.com/resource-manager/docs/creating-managing-organization#retrieving_your_organization_id, https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects. An OrganizationID must consist of decimal numbers, and cannot have leading zeroes. A ProjectID must be 6 to 30 characters in length, can only contain lowercase letters, numbers, and hyphens, and must start with a letter, and cannot end with a hyphen.",
+ "key": "key is the key part of the tag. A tag key can have a maximum of 63 characters and cannot be empty. Tag key must begin and end with an alphanumeric character, and must contain only uppercase, lowercase alphanumeric characters, and the following special characters `._-`.",
+ "value": "value is the value part of the tag. A tag value can have a maximum of 63 characters and cannot be empty. Tag value must begin and end with an alphanumeric character, and must contain only uppercase, lowercase alphanumeric characters, and the following special characters `_-.@%=+:,*#&(){}[]` and spaces.",
+}
+
+func (GCPResourceTag) SwaggerDoc() map[string]string {
+ return map_GCPResourceTag
+}
+
var map_IBMCloudPlatformSpec = map[string]string{
"": "IBMCloudPlatformSpec holds the desired state of the IBMCloud infrastructure provider. This only includes fields that can be modified in the cluster.",
}
@@ -1261,12 +1284,23 @@ var map_IBMCloudPlatformStatus = map[string]string{
"providerType": "ProviderType indicates the type of cluster that was created",
"cisInstanceCRN": "CISInstanceCRN is the CRN of the Cloud Internet Services instance managing the DNS zone for the cluster's base domain",
"dnsInstanceCRN": "DNSInstanceCRN is the CRN of the DNS Services instance managing the DNS zone for the cluster's base domain",
+ "serviceEndpoints": "serviceEndpoints is a list of custom endpoints which will override the default service endpoints of an IBM Cloud service. These endpoints are consumed by components within the cluster to reach the respective IBM Cloud Services.",
}
func (IBMCloudPlatformStatus) SwaggerDoc() map[string]string {
return map_IBMCloudPlatformStatus
}
+var map_IBMCloudServiceEndpoint = map[string]string{
+ "": "IBMCloudServiceEndpoint stores the configuration of a custom url to override existing defaults of IBM Cloud Services.",
+ "name": "name is the name of the IBM Cloud service. For example, the IBM Cloud Private IAM service could be configured with the service `name` of `IAM` and `url` of `https://private.iam.cloud.ibm.com` Whereas the IBM Cloud Private VPC service for US South (Dallas) could be configured with the service `name` of `VPC` and `url` of `https://us.south.private.iaas.cloud.ibm.com`",
+ "url": "url is fully qualified URI with scheme https, that overrides the default generated endpoint for a client. This must be provided and cannot be empty.",
+}
+
+func (IBMCloudServiceEndpoint) SwaggerDoc() map[string]string {
+ return map_IBMCloudServiceEndpoint
+}
+
var map_Infrastructure = map[string]string{
"": "Infrastructure holds cluster-wide information about Infrastructure. The canonical name is `cluster`\n\nCompatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).",
"metadata": "metadata is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
diff --git a/vendor/github.com/openshift/api/config/v1alpha1/0000_10_config-operator_01_backup-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1alpha1/0000_10_config-operator_01_backup-TechPreviewNoUpgrade.crd.yaml
new file mode 100644
index 0000000000..0ee3bdea49
--- /dev/null
+++ b/vendor/github.com/openshift/api/config/v1alpha1/0000_10_config-operator_01_backup-TechPreviewNoUpgrade.crd.yaml
@@ -0,0 +1,100 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ api-approved.openshift.io: https://github.com/openshift/api/pull/1482
+ include.release.openshift.io/ibm-cloud-managed: "true"
+ include.release.openshift.io/self-managed-high-availability: "true"
+ include.release.openshift.io/single-node-developer: "true"
+ release.openshift.io/feature-set: TechPreviewNoUpgrade
+ name: backups.config.openshift.io
+spec:
+ group: config.openshift.io
+ names:
+ kind: Backup
+ listKind: BackupList
+ plural: backups
+ singular: backup
+ scope: Cluster
+ versions:
+ - name: v1alpha1
+ served: true
+ storage: true
+ subresources:
+ status: {}
+ schema:
+ openAPIV3Schema:
+ description: "Backup provides configuration for performing backups of the openshift cluster. \n Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support."
+ type: object
+ required:
+ - spec
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: spec holds user settable values for configuration
+ type: object
+ required:
+ - etcd
+ properties:
+ etcd:
+ description: etcd specifies the configuration for periodic backups of the etcd cluster
+ type: object
+ properties:
+ pvcName:
+ description: PVCName specifies the name of the PersistentVolumeClaim (PVC) which binds a PersistentVolume where the etcd backup files would be saved The PVC itself must always be created in the "openshift-etcd" namespace If the PVC is left unspecified "" then the platform will choose a reasonable default location to save the backup. In the future this would be backups saved across the control-plane master nodes.
+ type: string
+ retentionPolicy:
+ description: RetentionPolicy defines the retention policy for retaining and deleting existing backups.
+ type: object
+ required:
+ - retentionType
+ properties:
+ retentionNumber:
+ description: RetentionNumber configures the retention policy based on the number of backups
+ type: object
+ required:
+ - maxNumberOfBackups
+ properties:
+ maxNumberOfBackups:
+ description: MaxNumberOfBackups defines the maximum number of backups to retain. If the existing number of backups saved is equal to MaxNumberOfBackups then the oldest backup will be removed before a new backup is initiated.
+ type: integer
+ minimum: 1
+ retentionSize:
+ description: RetentionSize configures the retention policy based on the size of backups
+ type: object
+ required:
+ - maxSizeOfBackupsGb
+ properties:
+ maxSizeOfBackupsGb:
+ description: MaxSizeOfBackupsGb defines the total size in GB of backups to retain. If the current total size backups exceeds MaxSizeOfBackupsGb then the oldest backup will be removed before a new backup is initiated.
+ type: integer
+ minimum: 1
+ retentionType:
+ description: RetentionType sets the type of retention policy. Currently, the only valid policies are retention by number of backups (RetentionNumber), by the size of backups (RetentionSize). More policies or types may be added in the future. Empty string means no opinion and the platform is left to choose a reasonable default which is subject to change without notice. The current default is RetentionNumber with 15 backups kept.
+ type: string
+ allOf:
+ - enum:
+ - RetentionNumber
+ - RetentionSize
+ - enum:
+ - ""
+ - RetentionNumber
+ - RetentionSize
+ schedule:
+ description: 'Schedule defines the recurring backup schedule in Cron format every 2 hours: 0 */2 * * * every day at 3am: 0 3 * * * Empty string means no opinion and the platform is left to choose a reasonable default which is subject to change without notice. The current default is "no backups", but will change in the future.'
+ type: string
+ pattern: ^(@(annually|yearly|monthly|weekly|daily|hourly))|(\*|(?:\*|(?:[0-9]|(?:[1-5][0-9])))\/(?:[0-9]|(?:[1-5][0-9]))|(?:[0-9]|(?:[1-5][0-9]))(?:(?:\-[0-9]|\-(?:[1-5][0-9]))?|(?:\,(?:[0-9]|(?:[1-5][0-9])))*)) (\*|(?:\*|(?:\*|(?:[0-9]|1[0-9]|2[0-3])))\/(?:[0-9]|1[0-9]|2[0-3])|(?:[0-9]|1[0-9]|2[0-3])(?:(?:\-(?:[0-9]|1[0-9]|2[0-3]))?|(?:\,(?:[0-9]|1[0-9]|2[0-3]))*)) (\*|(?:[1-9]|(?:[12][0-9])|3[01])(?:(?:\-(?:[1-9]|(?:[12][0-9])|3[01]))?|(?:\,(?:[1-9]|(?:[12][0-9])|3[01]))*)) (\*|(?:[1-9]|1[012]|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(?:(?:\-(?:[1-9]|1[012]|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?|(?:\,(?:[1-9]|1[012]|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))*)) (\*|(?:[0-6]|SUN|MON|TUE|WED|THU|FRI|SAT)(?:(?:\-(?:[0-6]|SUN|MON|TUE|WED|THU|FRI|SAT))?|(?:\,(?:[0-6]|SUN|MON|TUE|WED|THU|FRI|SAT))*))$
+ timeZone:
+ description: The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. If not specified, this will default to the time zone of the kube-controller-manager process. See https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones
+ type: string
+ pattern: ^([A-Za-z_]+([+-]*0)*|[A-Za-z_]+(\/[A-Za-z_]+){1,2})(\/GMT[+-]\d{1,2})?$
+ status:
+ description: status holds observed values from the cluster. They may not be overridden.
+ type: object
diff --git a/vendor/github.com/openshift/api/config/v1alpha1/register.go b/vendor/github.com/openshift/api/config/v1alpha1/register.go
index 73ddb749f9..7ec30d7aaf 100644
--- a/vendor/github.com/openshift/api/config/v1alpha1/register.go
+++ b/vendor/github.com/openshift/api/config/v1alpha1/register.go
@@ -32,6 +32,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(GroupVersion,
&InsightsDataGather{},
&InsightsDataGatherList{},
+ &Backup{},
+ &BackupList{},
)
metav1.AddToGroupVersion(scheme, GroupVersion)
return nil
diff --git a/vendor/github.com/openshift/api/config/v1alpha1/techpreview.backup.testsuite.yaml b/vendor/github.com/openshift/api/config/v1alpha1/techpreview.backup.testsuite.yaml
new file mode 100644
index 0000000000..91836dd93e
--- /dev/null
+++ b/vendor/github.com/openshift/api/config/v1alpha1/techpreview.backup.testsuite.yaml
@@ -0,0 +1,202 @@
+apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
+name: "[TechPreview] Backup"
+crd: 0000_10_config-operator_01_backup-TechPreviewNoUpgrade.crd.yaml
+tests:
+ onCreate:
+ - name: Should be able to create a Backup with a valid spec
+ initial: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ schedule: "* 2 * * *"
+ pvcName: etcdbackup-pvc
+ expected: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ schedule: "* 2 * * *"
+ pvcName: etcdbackup-pvc
+ - name: Should be able to create an EtcdBackup without the pvcName specified
+ initial: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ schedule: "* 2 * * *"
+ expected: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ schedule: "* 2 * * *"
+ - name: Should be able to create a Backup with a valid schedule - At 22:00 on every day-of-week from Monday through Friday
+ initial: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ schedule: "0 22 * * 1-5"
+ pvcName: etcdbackup-pvc
+ expected: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ schedule: "0 22 * * 1-5"
+ pvcName: etcdbackup-pvc
+ - name: Should be able to create a Backup with a valid schedule - At 04:05 on Sunday.
+ initial: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ schedule: "5 4 * * SUN"
+ pvcName: etcdbackup-pvc
+ expected: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ schedule: "5 4 * * SUN"
+ pvcName: etcdbackup-pvc
+ - name: Should be able to create a Backup with a valid schedule - Predefined hourly
+ initial: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ schedule: "@hourly"
+ pvcName: etcdbackup-pvc
+ expected: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ schedule: "@hourly"
+ pvcName: etcdbackup-pvc
+ - name: Should fail to create an EtcdBackup with an invalid schedule - At 04:05 on invalid day FOO.
+ initial: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ schedule: "5 4 * * FOO"
+ pvcName: etcdbackup-pvc
+ expectedError: "spec.etcd.schedule in body should match"
+ - name: Should fail to create an EtcdBackup with an invalid schedule - Predefined typo @hourli instead of @hourly.
+ initial: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ schedule: "@hourli"
+ pvcName: etcdbackup-pvc
+ expectedError: "spec.etcd.schedule in body should match"
+ - name: Should fail to create an EtcdBackup with an invalid schedule - Non standard L last Friday in month
+ initial: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ schedule: "* * * * 5L"
+ pvcName: etcdbackup-pvc
+ expectedError: "spec.etcd.schedule in body should match"
+ - name: Should fail to create an EtcdBackup with an invalid schedule - Non standard L 5th day before last day of month
+ initial: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ schedule: "* * L-5 * *"
+ pvcName: etcdbackup-pvc
+ expectedError: "spec.etcd.schedule in body should match"
+ - name: Should fail to create an EtcdBackup with an invalid schedule - Non standard W closest weekday to 15th of month
+ initial: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ schedule: "* * 15W * *"
+ pvcName: etcdbackup-pvc
+ expectedError: "spec.etcd.schedule in body should match"
+ - name: Should be able to create a Backup with a valid time zone - Africa/Banjul
+ initial: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ timeZone: Africa/Banjul
+ pvcName: etcdbackup-pvc
+ expected: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ timeZone: Africa/Banjul
+ pvcName: etcdbackup-pvc
+ - name: Should be able to create a Backup with a valid time zone - Etc/GMT-8
+ initial: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ timeZone: Etc/GMT-8
+ pvcName: etcdbackup-pvc
+ expected: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ timeZone: Etc/GMT-8
+ pvcName: etcdbackup-pvc
+ - name: Should be able to create a Backup with a valid time zone - Etc/UTC
+ initial: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ timeZone: Etc/UTC
+ pvcName: etcdbackup-pvc
+ expected: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ timeZone: Etc/UTC
+ pvcName: etcdbackup-pvc
+ - name: Should be able to create a Backup with a valid time zone - America/Argentina/Catamarca
+ initial: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ timeZone: America/Argentina/Catamarca
+ pvcName: etcdbackup-pvc
+ expected: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ timeZone: America/Argentina/Catamarca
+ pvcName: etcdbackup-pvc
+ - name: Should fail to create an EtcdBackup with an invalid time zone - GMT2
+ initial: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ timeZone: GMT2
+ pvcName: etcdbackup-pvc
+ expectedError: "spec.etcd.timeZone in body should match"
+ - name: Should fail to create an EtcdBackup with an invalid time zone - GMT+3
+ initial: |
+ apiVersion: config.openshift.io/v1alpha1
+ kind: Backup
+ spec:
+ etcd:
+ timeZone: GMT+3
+ pvcName: etcdbackup-pvc
+ expectedError: "spec.etcd.timeZone in body should match"
+
diff --git a/vendor/github.com/openshift/api/config/v1alpha1/types_backup.go b/vendor/github.com/openshift/api/config/v1alpha1/types_backup.go
new file mode 100644
index 0000000000..9af55b540e
--- /dev/null
+++ b/vendor/github.com/openshift/api/config/v1alpha1/types_backup.go
@@ -0,0 +1,168 @@
+package v1alpha1
+
+import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+// +genclient
+// +genclient:nonNamespaced
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+//
+// Backup provides configuration for performing backups of the openshift cluster.
+//
+// Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.
+// +openshift:compatibility-gen:level=4
+type Backup struct {
+ metav1.TypeMeta `json:",inline"`
+
+ // metadata is the standard object's metadata.
+ // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ // spec holds user settable values for configuration
+ // +kubebuilder:validation:Required
+ // +required
+ Spec BackupSpec `json:"spec"`
+ // status holds observed values from the cluster. They may not be overridden.
+ // +kubebuilder:validation:Optional
+ // +optional
+ Status BackupStatus `json:"status"`
+}
+
+type BackupSpec struct {
+ // etcd specifies the configuration for periodic backups of the etcd cluster
+ // +kubebuilder:validation:Required
+ EtcdBackupSpec EtcdBackupSpec `json:"etcd"`
+}
+
+type BackupStatus struct {
+}
+
+// EtcdBackupSpec provides configuration for automated etcd backups to the cluster-etcd-operator
+type EtcdBackupSpec struct {
+
+ // Schedule defines the recurring backup schedule in Cron format
+ // every 2 hours: 0 */2 * * *
+ // every day at 3am: 0 3 * * *
+ // Empty string means no opinion and the platform is left to choose a reasonable default which is subject to change without notice.
+ // The current default is "no backups", but will change in the future.
+ // +kubebuilder:validation:Optional
+ // +optional
+ // +kubebuilder:validation:Pattern:=`^(@(annually|yearly|monthly|weekly|daily|hourly))|(\*|(?:\*|(?:[0-9]|(?:[1-5][0-9])))\/(?:[0-9]|(?:[1-5][0-9]))|(?:[0-9]|(?:[1-5][0-9]))(?:(?:\-[0-9]|\-(?:[1-5][0-9]))?|(?:\,(?:[0-9]|(?:[1-5][0-9])))*)) (\*|(?:\*|(?:\*|(?:[0-9]|1[0-9]|2[0-3])))\/(?:[0-9]|1[0-9]|2[0-3])|(?:[0-9]|1[0-9]|2[0-3])(?:(?:\-(?:[0-9]|1[0-9]|2[0-3]))?|(?:\,(?:[0-9]|1[0-9]|2[0-3]))*)) (\*|(?:[1-9]|(?:[12][0-9])|3[01])(?:(?:\-(?:[1-9]|(?:[12][0-9])|3[01]))?|(?:\,(?:[1-9]|(?:[12][0-9])|3[01]))*)) (\*|(?:[1-9]|1[012]|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(?:(?:\-(?:[1-9]|1[012]|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?|(?:\,(?:[1-9]|1[012]|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))*)) (\*|(?:[0-6]|SUN|MON|TUE|WED|THU|FRI|SAT)(?:(?:\-(?:[0-6]|SUN|MON|TUE|WED|THU|FRI|SAT))?|(?:\,(?:[0-6]|SUN|MON|TUE|WED|THU|FRI|SAT))*))$`
+ Schedule string `json:"schedule"`
+
+ // Cron Regex breakdown:
+ // Allow macros: (@(annually|yearly|monthly|weekly|daily|hourly))
+ // OR
+ // Minute:
+ // (\*|(?:\*|(?:[0-9]|(?:[1-5][0-9])))\/(?:[0-9]|(?:[1-5][0-9]))|(?:[0-9]|(?:[1-5][0-9]))(?:(?:\-[0-9]|\-(?:[1-5][0-9]))?|(?:\,(?:[0-9]|(?:[1-5][0-9])))*))
+ // Hour:
+ // (\*|(?:\*|(?:\*|(?:[0-9]|1[0-9]|2[0-3])))\/(?:[0-9]|1[0-9]|2[0-3])|(?:[0-9]|1[0-9]|2[0-3])(?:(?:\-(?:[0-9]|1[0-9]|2[0-3]))?|(?:\,(?:[0-9]|1[0-9]|2[0-3]))*))
+ // Day of the Month:
+ // (\*|(?:[1-9]|(?:[12][0-9])|3[01])(?:(?:\-(?:[1-9]|(?:[12][0-9])|3[01]))?|(?:\,(?:[1-9]|(?:[12][0-9])|3[01]))*))
+ // Month:
+ // (\*|(?:[1-9]|1[012]|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(?:(?:\-(?:[1-9]|1[012]|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?|(?:\,(?:[1-9]|1[012]|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))*))
+ // Day of Week:
+ // (\*|(?:[0-6]|SUN|MON|TUE|WED|THU|FRI|SAT)(?:(?:\-(?:[0-6]|SUN|MON|TUE|WED|THU|FRI|SAT))?|(?:\,(?:[0-6]|SUN|MON|TUE|WED|THU|FRI|SAT))*))
+ //
+
+ // The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones.
+ // If not specified, this will default to the time zone of the kube-controller-manager process.
+ // See https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones
+ // +kubebuilder:validation:Optional
+ // +optional
+ // +kubebuilder:validation:Pattern:=`^([A-Za-z_]+([+-]*0)*|[A-Za-z_]+(\/[A-Za-z_]+){1,2})(\/GMT[+-]\d{1,2})?$`
+ TimeZone string `json:"timeZone"`
+
+ // Timezone regex breakdown:
+ // ([A-Za-z_]+([+-]*0)*|[A-Za-z_]+(/[A-Za-z_]+){1,2}) - Matches either:
+ // [A-Za-z_]+([+-]*0)* - One or more alphabetical characters (uppercase or lowercase) or underscores, followed by a +0 or -0 to account for GMT+0 or GMT-0 (for the first part of the timezone identifier).
+ // [A-Za-z_]+(/[A-Za-z_]+){1,2} - One or more alphabetical characters (uppercase or lowercase) or underscores, followed by one or two occurrences of a forward slash followed by one or more alphabetical characters or underscores. This allows for matching timezone identifiers with 2 or 3 parts, e.g America/Argentina/Buenos_Aires
+ // (/GMT[+-]\d{1,2})? - Makes the GMT offset suffix optional. It matches "/GMT" followed by either a plus ("+") or minus ("-") sign and one or two digits (the GMT offset)
+
+ // RetentionPolicy defines the retention policy for retaining and deleting existing backups.
+ // +kubebuilder:validation:Optional
+ // +optional
+ RetentionPolicy RetentionPolicy `json:"retentionPolicy"`
+
+ // PVCName specifies the name of the PersistentVolumeClaim (PVC) which binds a PersistentVolume where the
+ // etcd backup files would be saved
+ // The PVC itself must always be created in the "openshift-etcd" namespace
+ // If the PVC is left unspecified "" then the platform will choose a reasonable default location to save the backup.
+ // In the future this would be backups saved across the control-plane master nodes.
+ // +kubebuilder:validation:Optional
+ // +optional
+ PVCName string `json:"pvcName"`
+}
+
+// RetentionType is the enumeration of valid retention policy types
+// +enum
+// +kubebuilder:validation:Enum:="RetentionNumber";"RetentionSize"
+type RetentionType string
+
+const (
+ // RetentionTypeNumber sets the retention policy based on the number of backup files saved
+ RetentionTypeNumber RetentionType = "RetentionNumber"
+ // RetentionTypeSize sets the retention policy based on the total size of the backup files saved
+ RetentionTypeSize RetentionType = "RetentionSize"
+)
+
+// RetentionPolicy defines the retention policy for retaining and deleting existing backups.
+// This struct is a discriminated union that allows users to select the type of retention policy from the supported types.
+// +union
+type RetentionPolicy struct {
+ // RetentionType sets the type of retention policy.
+ // Currently, the only valid policies are retention by number of backups (RetentionNumber), by the size of backups (RetentionSize). More policies or types may be added in the future.
+ // Empty string means no opinion and the platform is left to choose a reasonable default which is subject to change without notice.
+ // The current default is RetentionNumber with 15 backups kept.
+ // +unionDiscriminator
+ // +required
+ // +kubebuilder:validation:Required
+ // +kubebuilder:validation:Enum:="";"RetentionNumber";"RetentionSize"
+ RetentionType RetentionType `json:"retentionType"`
+
+ // RetentionNumber configures the retention policy based on the number of backups
+ // +kubebuilder:validation:Optional
+ // +optional
+ RetentionNumber *RetentionNumberConfig `json:"retentionNumber,omitempty"`
+
+ // RetentionSize configures the retention policy based on the size of backups
+ // +kubebuilder:validation:Optional
+ // +optional
+ RetentionSize *RetentionSizeConfig `json:"retentionSize,omitempty"`
+}
+
+// RetentionNumberConfig specifies the configuration of the retention policy on the number of backups
+type RetentionNumberConfig struct {
+ // MaxNumberOfBackups defines the maximum number of backups to retain.
+ // If the existing number of backups saved is equal to MaxNumberOfBackups then
+ // the oldest backup will be removed before a new backup is initiated.
+ // +kubebuilder:validation:Minimum=1
+ // +kubebuilder:validation:Required
+ // +required
+ MaxNumberOfBackups int `json:"maxNumberOfBackups,omitempty"`
+}
+
+// RetentionSizeConfig specifies the configuration of the retention policy on the total size of backups
+type RetentionSizeConfig struct {
+ // MaxSizeOfBackupsGb defines the total size in GB of backups to retain.
+ // If the current total size backups exceeds MaxSizeOfBackupsGb then
+ // the oldest backup will be removed before a new backup is initiated.
+ // +kubebuilder:validation:Minimum=1
+ // +kubebuilder:validation:Required
+ // +required
+ MaxSizeOfBackupsGb int `json:"maxSizeOfBackupsGb,omitempty"`
+}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+// BackupList is a collection of items
+//
+// Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.
+// +openshift:compatibility-gen:level=4
+type BackupList struct {
+ metav1.TypeMeta `json:",inline"`
+
+ // metadata is the standard list's metadata.
+ // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
+ metav1.ListMeta `json:"metadata"`
+ Items []Backup `json:"items"`
+}
diff --git a/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go
index 440cfd2e0b..8cd8536f32 100644
--- a/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go
+++ b/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go
@@ -9,6 +9,117 @@ import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Backup) DeepCopyInto(out *Backup) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ in.Spec.DeepCopyInto(&out.Spec)
+ out.Status = in.Status
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Backup.
+func (in *Backup) DeepCopy() *Backup {
+ if in == nil {
+ return nil
+ }
+ out := new(Backup)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *Backup) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BackupList) DeepCopyInto(out *BackupList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]Backup, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupList.
+func (in *BackupList) DeepCopy() *BackupList {
+ if in == nil {
+ return nil
+ }
+ out := new(BackupList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *BackupList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BackupSpec) DeepCopyInto(out *BackupSpec) {
+ *out = *in
+ in.EtcdBackupSpec.DeepCopyInto(&out.EtcdBackupSpec)
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupSpec.
+func (in *BackupSpec) DeepCopy() *BackupSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(BackupSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BackupStatus) DeepCopyInto(out *BackupStatus) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupStatus.
+func (in *BackupStatus) DeepCopy() *BackupStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(BackupStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EtcdBackupSpec) DeepCopyInto(out *EtcdBackupSpec) {
+ *out = *in
+ in.RetentionPolicy.DeepCopyInto(&out.RetentionPolicy)
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EtcdBackupSpec.
+func (in *EtcdBackupSpec) DeepCopy() *EtcdBackupSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(EtcdBackupSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GatherConfig) DeepCopyInto(out *GatherConfig) {
*out = *in
@@ -123,3 +234,61 @@ func (in *InsightsDataGatherStatus) DeepCopy() *InsightsDataGatherStatus {
in.DeepCopyInto(out)
return out
}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *RetentionNumberConfig) DeepCopyInto(out *RetentionNumberConfig) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RetentionNumberConfig.
+func (in *RetentionNumberConfig) DeepCopy() *RetentionNumberConfig {
+ if in == nil {
+ return nil
+ }
+ out := new(RetentionNumberConfig)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *RetentionPolicy) DeepCopyInto(out *RetentionPolicy) {
+ *out = *in
+ if in.RetentionNumber != nil {
+ in, out := &in.RetentionNumber, &out.RetentionNumber
+ *out = new(RetentionNumberConfig)
+ **out = **in
+ }
+ if in.RetentionSize != nil {
+ in, out := &in.RetentionSize, &out.RetentionSize
+ *out = new(RetentionSizeConfig)
+ **out = **in
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RetentionPolicy.
+func (in *RetentionPolicy) DeepCopy() *RetentionPolicy {
+ if in == nil {
+ return nil
+ }
+ out := new(RetentionPolicy)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *RetentionSizeConfig) DeepCopyInto(out *RetentionSizeConfig) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RetentionSizeConfig.
+func (in *RetentionSizeConfig) DeepCopy() *RetentionSizeConfig {
+ if in == nil {
+ return nil
+ }
+ out := new(RetentionSizeConfig)
+ in.DeepCopyInto(out)
+ return out
+}
diff --git a/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go
index 6bc6e2522c..425c1ec511 100644
--- a/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go
+++ b/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go
@@ -11,6 +11,75 @@ package v1alpha1
// Those methods can be generated by using hack/update-swagger-docs.sh
// AUTO-GENERATED FUNCTIONS START HERE
+var map_Backup = map[string]string{
+ "": "\n\nBackup provides configuration for performing backups of the openshift cluster.\n\nCompatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.",
+ "metadata": "metadata is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
+ "spec": "spec holds user settable values for configuration",
+ "status": "status holds observed values from the cluster. They may not be overridden.",
+}
+
+func (Backup) SwaggerDoc() map[string]string {
+ return map_Backup
+}
+
+var map_BackupList = map[string]string{
+ "": "BackupList is a collection of items\n\nCompatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.",
+ "metadata": "metadata is the standard list's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
+}
+
+func (BackupList) SwaggerDoc() map[string]string {
+ return map_BackupList
+}
+
+var map_BackupSpec = map[string]string{
+ "etcd": "etcd specifies the configuration for periodic backups of the etcd cluster",
+}
+
+func (BackupSpec) SwaggerDoc() map[string]string {
+ return map_BackupSpec
+}
+
+var map_EtcdBackupSpec = map[string]string{
+ "": "EtcdBackupSpec provides configuration for automated etcd backups to the cluster-etcd-operator",
+ "schedule": "Schedule defines the recurring backup schedule in Cron format every 2 hours: 0 */2 * * * every day at 3am: 0 3 * * * Empty string means no opinion and the platform is left to choose a reasonable default which is subject to change without notice. The current default is \"no backups\", but will change in the future.",
+ "timeZone": "The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. If not specified, this will default to the time zone of the kube-controller-manager process. See https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones",
+ "retentionPolicy": "RetentionPolicy defines the retention policy for retaining and deleting existing backups.",
+ "pvcName": "PVCName specifies the name of the PersistentVolumeClaim (PVC) which binds a PersistentVolume where the etcd backup files would be saved The PVC itself must always be created in the \"openshift-etcd\" namespace If the PVC is left unspecified \"\" then the platform will choose a reasonable default location to save the backup. In the future this would be backups saved across the control-plane master nodes.",
+}
+
+func (EtcdBackupSpec) SwaggerDoc() map[string]string {
+ return map_EtcdBackupSpec
+}
+
+var map_RetentionNumberConfig = map[string]string{
+ "": "RetentionNumberConfig specifies the configuration of the retention policy on the number of backups",
+ "maxNumberOfBackups": "MaxNumberOfBackups defines the maximum number of backups to retain. If the existing number of backups saved is equal to MaxNumberOfBackups then the oldest backup will be removed before a new backup is initiated.",
+}
+
+func (RetentionNumberConfig) SwaggerDoc() map[string]string {
+ return map_RetentionNumberConfig
+}
+
+var map_RetentionPolicy = map[string]string{
+ "": "RetentionPolicy defines the retention policy for retaining and deleting existing backups. This struct is a discriminated union that allows users to select the type of retention policy from the supported types.",
+ "retentionType": "RetentionType sets the type of retention policy. Currently, the only valid policies are retention by number of backups (RetentionNumber), by the size of backups (RetentionSize). More policies or types may be added in the future. Empty string means no opinion and the platform is left to choose a reasonable default which is subject to change without notice. The current default is RetentionNumber with 15 backups kept.",
+ "retentionNumber": "RetentionNumber configures the retention policy based on the number of backups",
+ "retentionSize": "RetentionSize configures the retention policy based on the size of backups",
+}
+
+func (RetentionPolicy) SwaggerDoc() map[string]string {
+ return map_RetentionPolicy
+}
+
+var map_RetentionSizeConfig = map[string]string{
+ "": "RetentionSizeConfig specifies the configuration of the retention policy on the total size of backups",
+ "maxSizeOfBackupsGb": "MaxSizeOfBackupsGb defines the total size in GB of backups to retain. If the current total size backups exceeds MaxSizeOfBackupsGb then the oldest backup will be removed before a new backup is initiated.",
+}
+
+func (RetentionSizeConfig) SwaggerDoc() map[string]string {
+ return map_RetentionSizeConfig
+}
+
var map_GatherConfig = map[string]string{
"": "gatherConfig provides data gathering configuration options.",
"dataPolicy": "dataPolicy allows user to enable additional global obfuscation of the IP addresses and base domain in the Insights archive data. Valid values are \"None\" and \"ObfuscateNetworking\". When set to None the data is not obfuscated. When set to ObfuscateNetworking the IP addresses and the cluster domain name are obfuscated. When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. The current default is None.",
diff --git a/vendor/github.com/openshift/api/console/v1/0000_10_consoleclidownload.crd.yaml b/vendor/github.com/openshift/api/console/v1/00_consoleclidownload.crd.yaml
similarity index 100%
rename from vendor/github.com/openshift/api/console/v1/0000_10_consoleclidownload.crd.yaml
rename to vendor/github.com/openshift/api/console/v1/00_consoleclidownload.crd.yaml
diff --git a/vendor/github.com/openshift/api/console/v1/0000_10_consoleexternalloglink.crd.yaml b/vendor/github.com/openshift/api/console/v1/00_consoleexternalloglink.crd.yaml
similarity index 100%
rename from vendor/github.com/openshift/api/console/v1/0000_10_consoleexternalloglink.crd.yaml
rename to vendor/github.com/openshift/api/console/v1/00_consoleexternalloglink.crd.yaml
diff --git a/vendor/github.com/openshift/api/console/v1/0000_10_consolelink.crd.yaml b/vendor/github.com/openshift/api/console/v1/00_consolelink.crd.yaml
similarity index 100%
rename from vendor/github.com/openshift/api/console/v1/0000_10_consolelink.crd.yaml
rename to vendor/github.com/openshift/api/console/v1/00_consolelink.crd.yaml
diff --git a/vendor/github.com/openshift/api/console/v1/0000_10_consolenotification.crd.yaml b/vendor/github.com/openshift/api/console/v1/00_consolenotification.crd.yaml
similarity index 100%
rename from vendor/github.com/openshift/api/console/v1/0000_10_consolenotification.crd.yaml
rename to vendor/github.com/openshift/api/console/v1/00_consolenotification.crd.yaml
diff --git a/vendor/github.com/openshift/api/console/v1/0000_10_consolequickstart.crd.yaml b/vendor/github.com/openshift/api/console/v1/00_consolequickstart.crd.yaml
similarity index 100%
rename from vendor/github.com/openshift/api/console/v1/0000_10_consolequickstart.crd.yaml
rename to vendor/github.com/openshift/api/console/v1/00_consolequickstart.crd.yaml
diff --git a/vendor/github.com/openshift/api/console/v1/00_consolesample.crd.yaml b/vendor/github.com/openshift/api/console/v1/00_consolesample.crd.yaml
new file mode 100644
index 0000000000..a7234f5566
--- /dev/null
+++ b/vendor/github.com/openshift/api/console/v1/00_consolesample.crd.yaml
@@ -0,0 +1,167 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ api-approved.openshift.io: https://github.com/openshift/api/pull/481
+ capability.openshift.io/name: Console
+ description: ConsoleSample is an extension to customizing OpenShift web console by adding samples.
+ displayName: ConsoleSample
+ include.release.openshift.io/ibm-cloud-managed: "true"
+ include.release.openshift.io/self-managed-high-availability: "true"
+ include.release.openshift.io/single-node-developer: "true"
+ name: consolesamples.console.openshift.io
+spec:
+ group: console.openshift.io
+ names:
+ kind: ConsoleSample
+ listKind: ConsoleSampleList
+ plural: consolesamples
+ singular: consolesample
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ description: "ConsoleSample is an extension to customizing OpenShift web console by adding samples. \n Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer)."
+ type: object
+ required:
+ - metadata
+ - spec
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: spec contains configuration for a console sample.
+ type: object
+ required:
+ - abstract
+ - description
+ - source
+ - title
+ properties:
+ abstract:
+ description: "abstract is a short introduction to the sample. \n It is required and must be no more than 100 characters in length. \n The abstract is shown on the sample card tile below the title and provider and is limited to three lines of content."
+ type: string
+ maxLength: 100
+ description:
+ description: "description is a long form explanation of the sample. \n It is required and can have a maximum length of **4096** characters. \n It is a README.md-like content for additional information, links, pre-conditions, and other instructions. It will be rendered as Markdown so that it can contain line breaks, links, and other simple formatting."
+ type: string
+ maxLength: 4096
+ icon:
+ description: "icon is an optional base64 encoded image and shown beside the sample title. \n The format must follow the data: URL format and can have a maximum size of **10 KB**. \n data:[][;base64], \n For example: \n data:image;base64, plus the base64 encoded image. \n Vector images can also be used. SVG icons must start with: \n data:image/svg+xml;base64, plus the base64 encoded SVG image. \n All sample catalog icons will be shown on a white background (also when the dark theme is used). The web console ensures that different aspect ratios work correctly. Currently, the surface of the icon is at most 40x100px. \n For more information on the data URL format, please visit https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs."
+ type: string
+ maxLength: 14000
+ pattern: ^data:([a-z/\.+0-9]*;(([-a-zA-Z0-9=])*;)?)?base64,
+ provider:
+ description: "provider is an optional label to honor who provides the sample. \n It is optional and must be no more than 50 characters in length. \n A provider can be a company like \"Red Hat\" or an organization like \"CNCF\" or \"Knative\". \n Currently, the provider is only shown on the sample card tile below the title with the prefix \"Provided by \""
+ type: string
+ maxLength: 50
+ source:
+ description: source defines where to deploy the sample service from. The sample may be sourced from an external git repository or container image.
+ type: object
+ required:
+ - type
+ properties:
+ containerImport:
+ description: containerImport allows the user import a container image.
+ type: object
+ required:
+ - image
+ properties:
+ image:
+ description: "reference to a container image that provides a HTTP service. The service must be exposed on the default port (8080) unless otherwise configured with the port field. \n Supported formats: - / - docker.io// - quay.io// - quay.io//@sha256: - quay.io//:"
+ type: string
+ maxLength: 256
+ minLength: 1
+ service:
+ description: service contains configuration for the Service resource created for this sample.
+ type: object
+ default:
+ targetPort: 8080
+ properties:
+ targetPort:
+ description: targetPort is the port that the service listens on for HTTP requests. This port will be used for Service and Route created for this sample. Port must be in the range 1 to 65535. Default port is 8080.
+ type: integer
+ format: int32
+ default: 8080
+ maximum: 65535
+ minimum: 1
+ gitImport:
+ description: gitImport allows the user to import code from a git repository.
+ type: object
+ required:
+ - repository
+ properties:
+ repository:
+ description: repository contains the reference to the actual Git repository.
+ type: object
+ required:
+ - url
+ properties:
+ contextDir:
+ description: contextDir is used to specify a directory within the repository to build the component. Must start with `/` and have a maximum length of 256 characters. When omitted, the default value is to build from the root of the repository.
+ type: string
+ maxLength: 256
+ pattern: ^/
+ revision:
+ description: revision is the git revision at which to clone the git repository Can be used to clone a specific branch, tag or commit SHA. Must be at most 256 characters in length. When omitted the repository's default branch is used.
+ type: string
+ maxLength: 256
+ url:
+ description: "url of the Git repository that contains a HTTP service. The HTTP service must be exposed on the default port (8080) unless otherwise configured with the port field. \n Only public repositories on GitHub, GitLab and Bitbucket are currently supported: \n - https://github.com// - https://gitlab.com// - https://bitbucket.org// \n The url must have a maximum length of 256 characters."
+ type: string
+ maxLength: 256
+ minLength: 1
+ pattern: ^https:\/\/(github.com|gitlab.com|bitbucket.org)\/[a-zA-Z0-9-]+\/[a-zA-Z0-9-]+(.git)?$
+ service:
+ description: service contains configuration for the Service resource created for this sample.
+ type: object
+ default:
+ targetPort: 8080
+ properties:
+ targetPort:
+ description: targetPort is the port that the service listens on for HTTP requests. This port will be used for Service created for this sample. Port must be in the range 1 to 65535. Default port is 8080.
+ type: integer
+ format: int32
+ default: 8080
+ maximum: 65535
+ minimum: 1
+ type:
+ description: 'type of the sample, currently supported: "GitImport";"ContainerImport"'
+ type: string
+ allOf:
+ - enum:
+ - GitImport
+ - ContainerImport
+ - enum:
+ - GitImport
+ - ContainerImport
+ x-kubernetes-validations:
+ - rule: 'self.type == ''GitImport'' ? has(self.gitImport) : !has(self.gitImport)'
+ message: source.gitImport is required when source.type is GitImport, and forbidden otherwise
+ - rule: 'self.type == ''ContainerImport'' ? has(self.containerImport) : !has(self.containerImport)'
+ message: source.containerImport is required when source.type is ContainerImport, and forbidden otherwise
+ tags:
+ description: "tags are optional string values that can be used to find samples in the samples catalog. \n Examples of common tags may be \"Java\", \"Quarkus\", etc. \n They will be displayed on the samples details page."
+ type: array
+ maxItems: 10
+ items:
+ type: string
+ x-kubernetes-list-type: set
+ title:
+ description: "title is the display name of the sample. \n It is required and must be no more than 50 characters in length."
+ type: string
+ maxLength: 50
+ minLength: 1
+ type:
+ description: "type is an optional label to group multiple samples. \n It is optional and must be no more than 20 characters in length. \n Recommendation is a singular term like \"Builder Image\", \"Devfile\" or \"Serverless Function\". \n Currently, the type is shown a badge on the sample card tile in the top right corner."
+ type: string
+ maxLength: 20
+ served: true
+ storage: true
diff --git a/vendor/github.com/openshift/api/console/v1/0000_10_consoleyamlsample.crd.yaml b/vendor/github.com/openshift/api/console/v1/00_consoleyamlsample.crd.yaml
similarity index 100%
rename from vendor/github.com/openshift/api/console/v1/0000_10_consoleyamlsample.crd.yaml
rename to vendor/github.com/openshift/api/console/v1/00_consoleyamlsample.crd.yaml
diff --git a/vendor/github.com/openshift/api/console/v1/0000_10_consoleplugin.crd.yaml b/vendor/github.com/openshift/api/console/v1/90_consoleplugin.crd.yaml
similarity index 100%
rename from vendor/github.com/openshift/api/console/v1/0000_10_consoleplugin.crd.yaml
rename to vendor/github.com/openshift/api/console/v1/90_consoleplugin.crd.yaml
diff --git a/vendor/github.com/openshift/api/console/v1/register.go b/vendor/github.com/openshift/api/console/v1/register.go
index bed83f7395..22319469f4 100644
--- a/vendor/github.com/openshift/api/console/v1/register.go
+++ b/vendor/github.com/openshift/api/console/v1/register.go
@@ -31,20 +31,22 @@ func Resource(resource string) schema.GroupResource {
// addKnownTypes adds types to API group
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(GroupVersion,
- &ConsoleLink{},
- &ConsoleLinkList{},
&ConsoleCLIDownload{},
&ConsoleCLIDownloadList{},
- &ConsoleNotification{},
- &ConsoleNotificationList{},
&ConsoleExternalLogLink{},
&ConsoleExternalLogLinkList{},
- &ConsoleYAMLSample{},
- &ConsoleYAMLSampleList{},
- &ConsoleQuickStart{},
- &ConsoleQuickStartList{},
+ &ConsoleLink{},
+ &ConsoleLinkList{},
+ &ConsoleNotification{},
+ &ConsoleNotificationList{},
&ConsolePlugin{},
&ConsolePluginList{},
+ &ConsoleQuickStart{},
+ &ConsoleQuickStartList{},
+ &ConsoleSample{},
+ &ConsoleSampleList{},
+ &ConsoleYAMLSample{},
+ &ConsoleYAMLSampleList{},
)
metav1.AddToGroupVersion(scheme, GroupVersion)
return nil
diff --git a/vendor/github.com/openshift/api/console/v1/stable.consoleclidownload.testsuite.yaml b/vendor/github.com/openshift/api/console/v1/stable.consoleclidownload.testsuite.yaml
index 0f1b27db92..8faef369b3 100644
--- a/vendor/github.com/openshift/api/console/v1/stable.consoleclidownload.testsuite.yaml
+++ b/vendor/github.com/openshift/api/console/v1/stable.consoleclidownload.testsuite.yaml
@@ -1,6 +1,6 @@
apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
name: "[Stable] ConsoleCLIDownload"
-crd: 0000_10_consoleclidownload.crd.yaml
+crd: 00_consoleclidownload.crd.yaml
tests:
onCreate:
- name: Should be able to create a minimal ConsoleCLIDownload
diff --git a/vendor/github.com/openshift/api/console/v1/stable.consoleexternalloglink.testsuite.yaml b/vendor/github.com/openshift/api/console/v1/stable.consoleexternalloglink.testsuite.yaml
index 76846597f9..8602d88b8e 100644
--- a/vendor/github.com/openshift/api/console/v1/stable.consoleexternalloglink.testsuite.yaml
+++ b/vendor/github.com/openshift/api/console/v1/stable.consoleexternalloglink.testsuite.yaml
@@ -1,6 +1,6 @@
apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
name: "[Stable] ConsoleExternalLogLink"
-crd: 0000_10_consoleexternalloglink.crd.yaml
+crd: 00_consoleexternalloglink.crd.yaml
tests:
onCreate:
- name: Should be able to create a minimal ConsoleExternalLogLink
diff --git a/vendor/github.com/openshift/api/console/v1/stable.consolelink.testsuite.yaml b/vendor/github.com/openshift/api/console/v1/stable.consolelink.testsuite.yaml
index 9ab5596427..87415ec163 100644
--- a/vendor/github.com/openshift/api/console/v1/stable.consolelink.testsuite.yaml
+++ b/vendor/github.com/openshift/api/console/v1/stable.consolelink.testsuite.yaml
@@ -1,6 +1,6 @@
apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
name: "[Stable] ConsoleLink"
-crd: 0000_10_consolelink.crd.yaml
+crd: 00_consolelink.crd.yaml
tests:
onCreate:
- name: Should be able to create a minimal ConsoleLink
diff --git a/vendor/github.com/openshift/api/console/v1/stable.consolenotification.testsuite.yaml b/vendor/github.com/openshift/api/console/v1/stable.consolenotification.testsuite.yaml
index ade1c6ac69..c60dd0a64e 100644
--- a/vendor/github.com/openshift/api/console/v1/stable.consolenotification.testsuite.yaml
+++ b/vendor/github.com/openshift/api/console/v1/stable.consolenotification.testsuite.yaml
@@ -1,6 +1,6 @@
apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
name: "[Stable] ConsoleNotification"
-crd: 0000_10_consolenotification.crd.yaml
+crd: 00_consolenotification.crd.yaml
tests:
onCreate:
- name: Should be able to create a minimal ConsoleNotification
diff --git a/vendor/github.com/openshift/api/console/v1/stable.consoleplugin.testsuite.yaml b/vendor/github.com/openshift/api/console/v1/stable.consoleplugin.testsuite.yaml
index 627cea6f38..0abe23ba7a 100644
--- a/vendor/github.com/openshift/api/console/v1/stable.consoleplugin.testsuite.yaml
+++ b/vendor/github.com/openshift/api/console/v1/stable.consoleplugin.testsuite.yaml
@@ -1,6 +1,6 @@
apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
name: "[Stable] ConsolePlugin"
-crd: 0000_10_consoleplugin.crd.yaml
+crd: 90_consoleplugin.crd.yaml
tests:
onCreate:
- name: Should be able to create a minimal ConsolePlugin
diff --git a/vendor/github.com/openshift/api/console/v1/stable.consolequickstart.testsuite.yaml b/vendor/github.com/openshift/api/console/v1/stable.consolequickstart.testsuite.yaml
index b5a403be59..d9c3ec93f4 100644
--- a/vendor/github.com/openshift/api/console/v1/stable.consolequickstart.testsuite.yaml
+++ b/vendor/github.com/openshift/api/console/v1/stable.consolequickstart.testsuite.yaml
@@ -1,6 +1,6 @@
apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
name: "[Stable] ConsoleQuickStart"
-crd: 0000_10_consolequickstart.crd.yaml
+crd: 00_consolequickstart.crd.yaml
tests:
onCreate:
- name: Should be able to create a minimal ConsoleQuickStart
diff --git a/vendor/github.com/openshift/api/console/v1/stable.consolesample.testsuite.yaml b/vendor/github.com/openshift/api/console/v1/stable.consolesample.testsuite.yaml
new file mode 100644
index 0000000000..f5af743603
--- /dev/null
+++ b/vendor/github.com/openshift/api/console/v1/stable.consolesample.testsuite.yaml
@@ -0,0 +1,183 @@
+apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
+name: "[Stable] ConsoleSample"
+crd: 00_consolesample.crd.yaml
+tests:
+ onCreate:
+ - name: Should be able to create a minimal ConsoleSample with GitImport
+ initial: |
+ apiVersion: console.openshift.io/v1
+ kind: ConsoleSample
+ spec:
+ title: Java with Maven test
+ abstract: Build and run Java applications using Maven and OpenJDK.
+ description: Build and run Java applications using Maven and OpenJDK.
+ source:
+ type: GitImport
+ gitImport:
+ repository:
+ url: https://github.com/jboss-openshift/openshift-quickstarts
+ expected: |
+ apiVersion: console.openshift.io/v1
+ kind: ConsoleSample
+ spec:
+ title: Java with Maven test
+ abstract: Build and run Java applications using Maven and OpenJDK.
+ description: Build and run Java applications using Maven and OpenJDK.
+ source:
+ type: GitImport
+ gitImport:
+ repository:
+ url: https://github.com/jboss-openshift/openshift-quickstarts
+ service:
+ targetPort: 8080
+ - name: Should be able to create a minimal ConsoleSample with ContainerImport
+ initial: |
+ apiVersion: console.openshift.io/v1
+ kind: ConsoleSample
+ spec:
+ title: Base image test
+ abstract: Test the minimal Red Hat Universal Base Image (UBI).
+ description: Test the minimal Red Hat Universal Base Image (UBI).
+ source:
+ type: ContainerImport
+ containerImport:
+ image: registry.access.redhat.com/ubi8/ubi-minimal:8.8-860
+ expected: |
+ apiVersion: console.openshift.io/v1
+ kind: ConsoleSample
+ spec:
+ title: Base image test
+ abstract: Test the minimal Red Hat Universal Base Image (UBI).
+ description: Test the minimal Red Hat Universal Base Image (UBI).
+ source:
+ type: ContainerImport
+ containerImport:
+ image: registry.access.redhat.com/ubi8/ubi-minimal:8.8-860
+ service:
+ targetPort: 8080
+ - name: Should be able to create a full ConsoleSample with GitImport
+ initial: |
+ apiVersion: console.openshift.io/v1
+ kind: ConsoleSample
+ spec:
+ title: Java with Maven test
+ abstract: Build and run Java applications using Maven and OpenJDK.
+ description: Build and run Java applications using Maven and OpenJDK.
+ icon: data:image;base64,base64 encoded image
+ type: Serverless function
+ provider: Red Hat
+ tags:
+ - java
+ - jboss
+ - openjdk
+ source:
+ type: GitImport
+ gitImport:
+ repository:
+ url: https://github.com/openshift-dev-console/nodejs-sample
+ revision: main
+ contextDir: /backend
+ service:
+ targetPort: 3000
+ expected: |
+ apiVersion: console.openshift.io/v1
+ kind: ConsoleSample
+ spec:
+ title: Java with Maven test
+ abstract: Build and run Java applications using Maven and OpenJDK.
+ description: Build and run Java applications using Maven and OpenJDK.
+ icon: data:image;base64,base64 encoded image
+ type: Serverless function
+ provider: Red Hat
+ tags:
+ - java
+ - jboss
+ - openjdk
+ source:
+ type: GitImport
+ gitImport:
+ repository:
+ url: https://github.com/openshift-dev-console/nodejs-sample
+ revision: main
+ contextDir: /backend
+ service:
+ targetPort: 3000
+ - name: Should be able to create a full ConsoleSample with ContainerImport
+ initial: |
+ apiVersion: console.openshift.io/v1
+ kind: ConsoleSample
+ spec:
+ title: Base image test
+ abstract: Test the minimal Red Hat Universal Base Image (UBI).
+ description: Test the minimal Red Hat Universal Base Image (UBI).
+ icon: data:image;base64,base64 encoded image
+ type: Serverless function
+ provider: Red Hat
+ tags:
+ - java
+ - jboss
+ - openjdk
+ source:
+ type: ContainerImport
+ containerImport:
+ image: registry.access.redhat.com/ubi8/ubi-minimal:8.8-860
+ service:
+ targetPort: 3000
+ expected: |
+ apiVersion: console.openshift.io/v1
+ kind: ConsoleSample
+ spec:
+ title: Base image test
+ abstract: Test the minimal Red Hat Universal Base Image (UBI).
+ description: Test the minimal Red Hat Universal Base Image (UBI).
+ icon: data:image;base64,base64 encoded image
+ type: Serverless function
+ provider: Red Hat
+ tags:
+ - java
+ - jboss
+ - openjdk
+ source:
+ type: ContainerImport
+ containerImport:
+ image: registry.access.redhat.com/ubi8/ubi-minimal:8.8-860
+ service:
+ targetPort: 3000
+ - name: Should decline a ConsoleSample when reusing a tag
+ initial: |
+ apiVersion: console.openshift.io/v1
+ kind: ConsoleSample
+ spec:
+ title: Java with Maven test
+ abstract: Build and run Java applications using Maven and OpenJDK.
+ description: Build and run Java applications using Maven and OpenJDK.
+ icon: data:image;base64,base64 encoded image
+ type: Serverless function
+ provider: Red Hat
+ tags:
+ - same-tag-should-be-decline
+ - same-tag-should-be-decline
+ source:
+ type: GitImport
+ gitImport:
+ repository:
+ url: https://github.com/openshift-dev-console/nodejs-sample
+ expectedError: "spec.tags[1]: Duplicate value: \"same-tag-should-be-decline\""
+ - name: Should decline a ConsoleSample with more then 10 tags
+ initial: |
+ apiVersion: console.openshift.io/v1
+ kind: ConsoleSample
+ spec:
+ title: Java with Maven test
+ abstract: Build and run Java applications using Maven and OpenJDK.
+ description: Build and run Java applications using Maven and OpenJDK.
+ icon: data:image;base64,base64 encoded image
+ type: Serverless function
+ provider: Red Hat
+ tags: [tag1, tag2, tag3, tag4, tag5, tag6, tag7, tag8, tag9, tag10, tag11]
+ source:
+ type: GitImport
+ gitImport:
+ repository:
+ url: https://github.com/openshift-dev-console/nodejs-sample
+ expectedError: "spec.tags: Too many: 11: must have at most 10 items"
diff --git a/vendor/github.com/openshift/api/console/v1/stable.consoleyamlsample.testsuite.yaml b/vendor/github.com/openshift/api/console/v1/stable.consoleyamlsample.testsuite.yaml
index 661c48fe07..1e72d5ac71 100644
--- a/vendor/github.com/openshift/api/console/v1/stable.consoleyamlsample.testsuite.yaml
+++ b/vendor/github.com/openshift/api/console/v1/stable.consoleyamlsample.testsuite.yaml
@@ -1,6 +1,6 @@
apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
name: "[Stable] ConsoleYAMLSample"
-crd: 0000_10_consoleyamlsample.crd.yaml
+crd: 00_consoleyamlsample.crd.yaml
tests:
onCreate:
- name: Should be able to create a minimal ConsoleYAMLSample
diff --git a/vendor/github.com/openshift/api/console/v1/types_console_sample.go b/vendor/github.com/openshift/api/console/v1/types_console_sample.go
new file mode 100644
index 0000000000..7edb4ba9ea
--- /dev/null
+++ b/vendor/github.com/openshift/api/console/v1/types_console_sample.go
@@ -0,0 +1,266 @@
+package v1
+
+import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+// +genclient
+// +genclient:nonNamespaced
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+// ConsoleSample is an extension to customizing OpenShift web console by adding samples.
+//
+// Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
+// +openshift:compatibility-gen:level=1
+type ConsoleSample struct {
+ metav1.TypeMeta `json:",inline"`
+
+ // metadata is the standard object's metadata.
+ // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
+ metav1.ObjectMeta `json:"metadata"`
+
+ // spec contains configuration for a console sample.
+ // +kubebuilder:validation:Required
+ Spec ConsoleSampleSpec `json:"spec"`
+}
+
+// ConsoleSampleSpec is the desired sample for the web console.
+// Samples will appear with their title, descriptions and a badge in a samples catalog.
+type ConsoleSampleSpec struct {
+ // title is the display name of the sample.
+ //
+ // It is required and must be no more than 50 characters in length.
+ // +kubebuilder:validation:Required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=50
+ Title string `json:"title"`
+
+ // abstract is a short introduction to the sample.
+ //
+ // It is required and must be no more than 100 characters in length.
+ //
+ // The abstract is shown on the sample card tile below the title and provider
+ // and is limited to three lines of content.
+ // +kubebuilder:validation:Required
+ // +kubebuilder:validation:MaxLength=100
+ Abstract string `json:"abstract"`
+
+ // description is a long form explanation of the sample.
+ //
+ // It is required and can have a maximum length of **4096** characters.
+ //
+ // It is a README.md-like content for additional information, links, pre-conditions, and other instructions.
+ // It will be rendered as Markdown so that it can contain line breaks, links, and other simple formatting.
+ // +kubebuilder:validation:Required
+ // +kubebuilder:validation:MaxLength=4096
+ Description string `json:"description"`
+
+ // icon is an optional base64 encoded image and shown beside the sample title.
+ //
+ // The format must follow the data: URL format and can have a maximum size of **10 KB**.
+ //
+ // data:[][;base64],
+ //
+ // For example:
+ //
+ // data:image;base64, plus the base64 encoded image.
+ //
+ // Vector images can also be used. SVG icons must start with:
+ //
+ // data:image/svg+xml;base64, plus the base64 encoded SVG image.
+ //
+ // All sample catalog icons will be shown on a white background (also when the dark theme is used).
+ // The web console ensures that different aspect ratios work correctly.
+ // Currently, the surface of the icon is at most 40x100px.
+ //
+ // For more information on the data URL format, please visit
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs.
+ // +optional
+ // +kubebuilder:validation:Pattern=`^data:([a-z/\.+0-9]*;(([-a-zA-Z0-9=])*;)?)?base64,`
+ // +kubebuilder:validation:MaxLength=14000
+ Icon string `json:"icon"`
+
+ // type is an optional label to group multiple samples.
+ //
+ // It is optional and must be no more than 20 characters in length.
+ //
+ // Recommendation is a singular term like "Builder Image", "Devfile" or "Serverless Function".
+ //
+ // Currently, the type is shown a badge on the sample card tile in the top right corner.
+ // +optional
+ // +kubebuilder:validation:MaxLength=20
+ Type string `json:"type"`
+
+ // provider is an optional label to honor who provides the sample.
+ //
+ // It is optional and must be no more than 50 characters in length.
+ //
+ // A provider can be a company like "Red Hat" or an organization like "CNCF" or "Knative".
+ //
+ // Currently, the provider is only shown on the sample card tile below the title with the prefix "Provided by "
+ // +optional
+ // +kubebuilder:validation:MaxLength=50
+ Provider string `json:"provider"`
+
+ // tags are optional string values that can be used to find samples in the samples catalog.
+ //
+ // Examples of common tags may be "Java", "Quarkus", etc.
+ //
+ // They will be displayed on the samples details page.
+ // +optional
+ // +listType=set
+ // +kubebuilder:validation:MaxItems:=10
+ Tags []string `json:"tags"`
+
+ // source defines where to deploy the sample service from.
+ // The sample may be sourced from an external git repository or container image.
+ // +kubebuilder:validation:Required
+ Source ConsoleSampleSource `json:"source"`
+}
+
+// ConsoleSampleSourceType is an enumeration of the supported sample types.
+// Unsupported samples types will be ignored in the web console.
+// +kubebuilder:validation:Enum:=GitImport;ContainerImport
+type ConsoleSampleSourceType string
+
+const (
+ // A sample that let the user import code from a git repository.
+ GitImport ConsoleSampleSourceType = "GitImport"
+ // A sample that let the user import a container image.
+ ContainerImport ConsoleSampleSourceType = "ContainerImport"
+)
+
+// ConsoleSampleSource is the actual sample definition and can hold different sample types.
+// Unsupported sample types will be ignored in the web console.
+// +union
+// +kubebuilder:validation:XValidation:rule="self.type == 'GitImport' ? has(self.gitImport) : !has(self.gitImport)",message="source.gitImport is required when source.type is GitImport, and forbidden otherwise"
+// +kubebuilder:validation:XValidation:rule="self.type == 'ContainerImport' ? has(self.containerImport) : !has(self.containerImport)",message="source.containerImport is required when source.type is ContainerImport, and forbidden otherwise"
+type ConsoleSampleSource struct {
+ // type of the sample, currently supported: "GitImport";"ContainerImport"
+ // +unionDiscriminator
+ // +kubebuilder:validation:Required
+ // +kubebuilder:validation:Enum:="GitImport";"ContainerImport"
+ Type ConsoleSampleSourceType `json:"type"`
+
+ // gitImport allows the user to import code from a git repository.
+ // +unionMember
+ // +optional
+ GitImport *ConsoleSampleGitImportSource `json:"gitImport,omitempty"`
+
+ // containerImport allows the user import a container image.
+ // +unionMember
+ // +optional
+ ContainerImport *ConsoleSampleContainerImportSource `json:"containerImport,omitempty"`
+}
+
+// ConsoleSampleGitImportSource let the user import code from a public Git repository.
+type ConsoleSampleGitImportSource struct {
+ // repository contains the reference to the actual Git repository.
+ // +kubebuilder:validation:Required
+ Repository ConsoleSampleGitImportSourceRepository `json:"repository"`
+ // service contains configuration for the Service resource created for this sample.
+ // +optional
+ // +kubebuilder:default={"targetPort": 8080}
+ // +default:={"targetPort": 8080}
+ Service ConsoleSampleGitImportSourceService `json:"service"`
+}
+
+// ConsoleSampleGitImportSourceRepository let the user import code from a public git repository.
+type ConsoleSampleGitImportSourceRepository struct {
+ // url of the Git repository that contains a HTTP service.
+ // The HTTP service must be exposed on the default port (8080) unless
+ // otherwise configured with the port field.
+ //
+ // Only public repositories on GitHub, GitLab and Bitbucket are currently supported:
+ //
+ // - https://github.com//
+ // - https://gitlab.com//
+ // - https://bitbucket.org//
+ //
+ // The url must have a maximum length of 256 characters.
+ // +kubebuilder:validation:Required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=256
+ // +kubebuilder:validation:Pattern=`^https:\/\/(github.com|gitlab.com|bitbucket.org)\/[a-zA-Z0-9-]+\/[a-zA-Z0-9-]+(.git)?$`
+ URL string `json:"url"`
+ // revision is the git revision at which to clone the git repository
+ // Can be used to clone a specific branch, tag or commit SHA.
+ // Must be at most 256 characters in length.
+ // When omitted the repository's default branch is used.
+ // +optional
+ // +kubebuilder:validation:MaxLength=256
+ Revision string `json:"revision"`
+ // contextDir is used to specify a directory within the repository to build the
+ // component.
+ // Must start with `/` and have a maximum length of 256 characters.
+ // When omitted, the default value is to build from the root of the repository.
+ // +optional
+ // +kubebuilder:validation:MaxLength=256
+ // +kubebuilder:validation:Pattern=`^/`
+ ContextDir string `json:"contextDir"`
+}
+
+// ConsoleSampleGitImportSourceService let the samples author define defaults
+// for the Service created for this sample.
+type ConsoleSampleGitImportSourceService struct {
+ // targetPort is the port that the service listens on for HTTP requests.
+ // This port will be used for Service created for this sample.
+ // Port must be in the range 1 to 65535.
+ // Default port is 8080.
+ // +optional
+ // +kubebuilder:validation:Minimum=1
+ // +kubebuilder:validation:Maximum=65535
+ // +kubebuilder:default=8080
+ // +default:=8080
+ TargetPort int32 `json:"targetPort,omitempty"`
+}
+
+// ConsoleSampleContainerImportSource let the user import a container image.
+type ConsoleSampleContainerImportSource struct {
+ // reference to a container image that provides a HTTP service.
+ // The service must be exposed on the default port (8080) unless
+ // otherwise configured with the port field.
+ //
+ // Supported formats:
+ // - /
+ // - docker.io//
+ // - quay.io//
+ // - quay.io//@sha256:
+ // - quay.io//:
+ // +kubebuilder:validation:Required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=256
+ Image string `json:"image"`
+ // service contains configuration for the Service resource created for this sample.
+ // +optional
+ // +kubebuilder:default={"targetPort": 8080}
+ // +default:={"targetPort": 8080}
+ Service ConsoleSampleContainerImportSourceService `json:"service"`
+}
+
+// ConsoleSampleContainerImportSourceService let the samples author define defaults
+// for the Service created for this sample.
+type ConsoleSampleContainerImportSourceService struct {
+ // targetPort is the port that the service listens on for HTTP requests.
+ // This port will be used for Service and Route created for this sample.
+ // Port must be in the range 1 to 65535.
+ // Default port is 8080.
+ // +optional
+ // +kubebuilder:validation:Minimum=1
+ // +kubebuilder:validation:Maximum=65535
+ // +kubebuilder:default=8080
+ // +default:=8080
+ TargetPort int32 `json:"targetPort,omitempty"`
+}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+// Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
+// +openshift:compatibility-gen:level=1
+type ConsoleSampleList struct {
+ metav1.TypeMeta `json:",inline"`
+
+ // metadata is the standard list's metadata.
+ // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
+ metav1.ListMeta `json:"metadata"`
+
+ Items []ConsoleSample `json:"items"`
+}
diff --git a/vendor/github.com/openshift/api/console/v1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/console/v1/zz_generated.deepcopy.go
index 7266afa477..a268d697ac 100644
--- a/vendor/github.com/openshift/api/console/v1/zz_generated.deepcopy.go
+++ b/vendor/github.com/openshift/api/console/v1/zz_generated.deepcopy.go
@@ -721,6 +721,197 @@ func (in *ConsoleQuickStartTaskSummary) DeepCopy() *ConsoleQuickStartTaskSummary
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ConsoleSample) DeepCopyInto(out *ConsoleSample) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ in.Spec.DeepCopyInto(&out.Spec)
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsoleSample.
+func (in *ConsoleSample) DeepCopy() *ConsoleSample {
+ if in == nil {
+ return nil
+ }
+ out := new(ConsoleSample)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *ConsoleSample) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ConsoleSampleContainerImportSource) DeepCopyInto(out *ConsoleSampleContainerImportSource) {
+ *out = *in
+ out.Service = in.Service
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsoleSampleContainerImportSource.
+func (in *ConsoleSampleContainerImportSource) DeepCopy() *ConsoleSampleContainerImportSource {
+ if in == nil {
+ return nil
+ }
+ out := new(ConsoleSampleContainerImportSource)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ConsoleSampleContainerImportSourceService) DeepCopyInto(out *ConsoleSampleContainerImportSourceService) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsoleSampleContainerImportSourceService.
+func (in *ConsoleSampleContainerImportSourceService) DeepCopy() *ConsoleSampleContainerImportSourceService {
+ if in == nil {
+ return nil
+ }
+ out := new(ConsoleSampleContainerImportSourceService)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ConsoleSampleGitImportSource) DeepCopyInto(out *ConsoleSampleGitImportSource) {
+ *out = *in
+ out.Repository = in.Repository
+ out.Service = in.Service
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsoleSampleGitImportSource.
+func (in *ConsoleSampleGitImportSource) DeepCopy() *ConsoleSampleGitImportSource {
+ if in == nil {
+ return nil
+ }
+ out := new(ConsoleSampleGitImportSource)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ConsoleSampleGitImportSourceRepository) DeepCopyInto(out *ConsoleSampleGitImportSourceRepository) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsoleSampleGitImportSourceRepository.
+func (in *ConsoleSampleGitImportSourceRepository) DeepCopy() *ConsoleSampleGitImportSourceRepository {
+ if in == nil {
+ return nil
+ }
+ out := new(ConsoleSampleGitImportSourceRepository)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ConsoleSampleGitImportSourceService) DeepCopyInto(out *ConsoleSampleGitImportSourceService) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsoleSampleGitImportSourceService.
+func (in *ConsoleSampleGitImportSourceService) DeepCopy() *ConsoleSampleGitImportSourceService {
+ if in == nil {
+ return nil
+ }
+ out := new(ConsoleSampleGitImportSourceService)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ConsoleSampleList) DeepCopyInto(out *ConsoleSampleList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]ConsoleSample, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsoleSampleList.
+func (in *ConsoleSampleList) DeepCopy() *ConsoleSampleList {
+ if in == nil {
+ return nil
+ }
+ out := new(ConsoleSampleList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *ConsoleSampleList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ConsoleSampleSource) DeepCopyInto(out *ConsoleSampleSource) {
+ *out = *in
+ if in.GitImport != nil {
+ in, out := &in.GitImport, &out.GitImport
+ *out = new(ConsoleSampleGitImportSource)
+ **out = **in
+ }
+ if in.ContainerImport != nil {
+ in, out := &in.ContainerImport, &out.ContainerImport
+ *out = new(ConsoleSampleContainerImportSource)
+ **out = **in
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsoleSampleSource.
+func (in *ConsoleSampleSource) DeepCopy() *ConsoleSampleSource {
+ if in == nil {
+ return nil
+ }
+ out := new(ConsoleSampleSource)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ConsoleSampleSpec) DeepCopyInto(out *ConsoleSampleSpec) {
+ *out = *in
+ if in.Tags != nil {
+ in, out := &in.Tags, &out.Tags
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+ in.Source.DeepCopyInto(&out.Source)
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsoleSampleSpec.
+func (in *ConsoleSampleSpec) DeepCopy() *ConsoleSampleSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(ConsoleSampleSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ConsoleYAMLSample) DeepCopyInto(out *ConsoleYAMLSample) {
*out = *in
diff --git a/vendor/github.com/openshift/api/console/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/console/v1/zz_generated.swagger_doc_generated.go
index a843d922ab..c6f2070fa4 100644
--- a/vendor/github.com/openshift/api/console/v1/zz_generated.swagger_doc_generated.go
+++ b/vendor/github.com/openshift/api/console/v1/zz_generated.swagger_doc_generated.go
@@ -331,6 +331,101 @@ func (ConsoleQuickStartTaskSummary) SwaggerDoc() map[string]string {
return map_ConsoleQuickStartTaskSummary
}
+var map_ConsoleSample = map[string]string{
+ "": "ConsoleSample is an extension to customizing OpenShift web console by adding samples.\n\nCompatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).",
+ "metadata": "metadata is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
+ "spec": "spec contains configuration for a console sample.",
+}
+
+func (ConsoleSample) SwaggerDoc() map[string]string {
+ return map_ConsoleSample
+}
+
+var map_ConsoleSampleContainerImportSource = map[string]string{
+ "": "ConsoleSampleContainerImportSource let the user import a container image.",
+ "image": "reference to a container image that provides a HTTP service. The service must be exposed on the default port (8080) unless otherwise configured with the port field.\n\nSupported formats:\n - /\n - docker.io//\n - quay.io//\n - quay.io//@sha256:\n - quay.io//:",
+ "service": "service contains configuration for the Service resource created for this sample.",
+}
+
+func (ConsoleSampleContainerImportSource) SwaggerDoc() map[string]string {
+ return map_ConsoleSampleContainerImportSource
+}
+
+var map_ConsoleSampleContainerImportSourceService = map[string]string{
+ "": "ConsoleSampleContainerImportSourceService let the samples author define defaults for the Service created for this sample.",
+ "targetPort": "targetPort is the port that the service listens on for HTTP requests. This port will be used for Service and Route created for this sample. Port must be in the range 1 to 65535. Default port is 8080.",
+}
+
+func (ConsoleSampleContainerImportSourceService) SwaggerDoc() map[string]string {
+ return map_ConsoleSampleContainerImportSourceService
+}
+
+var map_ConsoleSampleGitImportSource = map[string]string{
+ "": "ConsoleSampleGitImportSource let the user import code from a public Git repository.",
+ "repository": "repository contains the reference to the actual Git repository.",
+ "service": "service contains configuration for the Service resource created for this sample.",
+}
+
+func (ConsoleSampleGitImportSource) SwaggerDoc() map[string]string {
+ return map_ConsoleSampleGitImportSource
+}
+
+var map_ConsoleSampleGitImportSourceRepository = map[string]string{
+ "": "ConsoleSampleGitImportSourceRepository let the user import code from a public git repository.",
+ "url": "url of the Git repository that contains a HTTP service. The HTTP service must be exposed on the default port (8080) unless otherwise configured with the port field.\n\nOnly public repositories on GitHub, GitLab and Bitbucket are currently supported:\n\n - https://github.com//\n - https://gitlab.com//\n - https://bitbucket.org//\n\nThe url must have a maximum length of 256 characters.",
+ "revision": "revision is the git revision at which to clone the git repository Can be used to clone a specific branch, tag or commit SHA. Must be at most 256 characters in length. When omitted the repository's default branch is used.",
+ "contextDir": "contextDir is used to specify a directory within the repository to build the component. Must start with `/` and have a maximum length of 256 characters. When omitted, the default value is to build from the root of the repository.",
+}
+
+func (ConsoleSampleGitImportSourceRepository) SwaggerDoc() map[string]string {
+ return map_ConsoleSampleGitImportSourceRepository
+}
+
+var map_ConsoleSampleGitImportSourceService = map[string]string{
+ "": "ConsoleSampleGitImportSourceService let the samples author define defaults for the Service created for this sample.",
+ "targetPort": "targetPort is the port that the service listens on for HTTP requests. This port will be used for Service created for this sample. Port must be in the range 1 to 65535. Default port is 8080.",
+}
+
+func (ConsoleSampleGitImportSourceService) SwaggerDoc() map[string]string {
+ return map_ConsoleSampleGitImportSourceService
+}
+
+var map_ConsoleSampleList = map[string]string{
+ "": "Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).",
+ "metadata": "metadata is the standard list's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
+}
+
+func (ConsoleSampleList) SwaggerDoc() map[string]string {
+ return map_ConsoleSampleList
+}
+
+var map_ConsoleSampleSource = map[string]string{
+ "": "ConsoleSampleSource is the actual sample definition and can hold different sample types. Unsupported sample types will be ignored in the web console.",
+ "type": "type of the sample, currently supported: \"GitImport\";\"ContainerImport\"",
+ "gitImport": "gitImport allows the user to import code from a git repository.",
+ "containerImport": "containerImport allows the user import a container image.",
+}
+
+func (ConsoleSampleSource) SwaggerDoc() map[string]string {
+ return map_ConsoleSampleSource
+}
+
+var map_ConsoleSampleSpec = map[string]string{
+ "": "ConsoleSampleSpec is the desired sample for the web console. Samples will appear with their title, descriptions and a badge in a samples catalog.",
+ "title": "title is the display name of the sample.\n\nIt is required and must be no more than 50 characters in length.",
+ "abstract": "abstract is a short introduction to the sample.\n\nIt is required and must be no more than 100 characters in length.\n\nThe abstract is shown on the sample card tile below the title and provider and is limited to three lines of content.",
+ "description": "description is a long form explanation of the sample.\n\nIt is required and can have a maximum length of **4096** characters.\n\nIt is a README.md-like content for additional information, links, pre-conditions, and other instructions. It will be rendered as Markdown so that it can contain line breaks, links, and other simple formatting.",
+ "icon": "icon is an optional base64 encoded image and shown beside the sample title.\n\nThe format must follow the data: URL format and can have a maximum size of **10 KB**.\n\n data:[][;base64],\n\nFor example:\n\n data:image;base64, plus the base64 encoded image.\n\nVector images can also be used. SVG icons must start with:\n\n data:image/svg+xml;base64, plus the base64 encoded SVG image.\n\nAll sample catalog icons will be shown on a white background (also when the dark theme is used). The web console ensures that different aspect ratios work correctly. Currently, the surface of the icon is at most 40x100px.\n\nFor more information on the data URL format, please visit https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs.",
+ "type": "type is an optional label to group multiple samples.\n\nIt is optional and must be no more than 20 characters in length.\n\nRecommendation is a singular term like \"Builder Image\", \"Devfile\" or \"Serverless Function\".\n\nCurrently, the type is shown a badge on the sample card tile in the top right corner.",
+ "provider": "provider is an optional label to honor who provides the sample.\n\nIt is optional and must be no more than 50 characters in length.\n\nA provider can be a company like \"Red Hat\" or an organization like \"CNCF\" or \"Knative\".\n\nCurrently, the provider is only shown on the sample card tile below the title with the prefix \"Provided by \"",
+ "tags": "tags are optional string values that can be used to find samples in the samples catalog.\n\nExamples of common tags may be \"Java\", \"Quarkus\", etc.\n\nThey will be displayed on the samples details page.",
+ "source": "source defines where to deploy the sample service from. The sample may be sourced from an external git repository or container image.",
+}
+
+func (ConsoleSampleSpec) SwaggerDoc() map[string]string {
+ return map_ConsoleSampleSpec
+}
+
var map_ConsoleYAMLSample = map[string]string{
"": "ConsoleYAMLSample is an extension for customizing OpenShift web console YAML samples.\n\nCompatibility level 2: Stable within a major release for a minimum of 9 months or 3 minor releases (whichever is longer).",
"metadata": "metadata is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
diff --git a/vendor/github.com/openshift/api/console/v1alpha1/0000_10_consoleplugin.crd.yaml b/vendor/github.com/openshift/api/console/v1alpha1/90_consoleplugin.crd.yaml
similarity index 100%
rename from vendor/github.com/openshift/api/console/v1alpha1/0000_10_consoleplugin.crd.yaml
rename to vendor/github.com/openshift/api/console/v1alpha1/90_consoleplugin.crd.yaml
diff --git a/vendor/github.com/openshift/api/console/v1alpha1/stable.consoleplugin.testsuite.yaml b/vendor/github.com/openshift/api/console/v1alpha1/stable.consoleplugin.testsuite.yaml
index 138e8f6fa5..d861a65434 100644
--- a/vendor/github.com/openshift/api/console/v1alpha1/stable.consoleplugin.testsuite.yaml
+++ b/vendor/github.com/openshift/api/console/v1alpha1/stable.consoleplugin.testsuite.yaml
@@ -1,6 +1,6 @@
apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
name: "[Stable] ConsolePlugin"
-crd: 0000_10_consoleplugin.crd.yaml
+crd: 90_consoleplugin.crd.yaml
tests:
onCreate:
- name: Should be able to create a minimal ConsolePlugin
diff --git a/vendor/github.com/openshift/api/helm/v1beta1/0000_10-helm-chart-repository.crd.yaml b/vendor/github.com/openshift/api/helm/v1beta1/00_helm-chart-repository.crd.yaml
similarity index 100%
rename from vendor/github.com/openshift/api/helm/v1beta1/0000_10-helm-chart-repository.crd.yaml
rename to vendor/github.com/openshift/api/helm/v1beta1/00_helm-chart-repository.crd.yaml
diff --git a/vendor/github.com/openshift/api/helm/v1beta1/0000_10-project-helm-chart-repository.crd.yaml b/vendor/github.com/openshift/api/helm/v1beta1/00_project-helm-chart-repository.crd.yaml
similarity index 100%
rename from vendor/github.com/openshift/api/helm/v1beta1/0000_10-project-helm-chart-repository.crd.yaml
rename to vendor/github.com/openshift/api/helm/v1beta1/00_project-helm-chart-repository.crd.yaml
diff --git a/vendor/github.com/openshift/api/helm/v1beta1/stable.helmchartrepository.testsuite.yaml b/vendor/github.com/openshift/api/helm/v1beta1/stable.helmchartrepository.testsuite.yaml
index bac1227e27..64f1447ccc 100644
--- a/vendor/github.com/openshift/api/helm/v1beta1/stable.helmchartrepository.testsuite.yaml
+++ b/vendor/github.com/openshift/api/helm/v1beta1/stable.helmchartrepository.testsuite.yaml
@@ -1,6 +1,6 @@
apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
name: "[Stable] HelmChartRepository"
-crd: 0000_10-helm-chart-repository.crd.yaml
+crd: 00_helm-chart-repository.crd.yaml
tests:
onCreate:
- name: Should be able to create a minimal HelmChartRepository
diff --git a/vendor/github.com/openshift/api/helm/v1beta1/stable.projecthelmchartrepository.testsuite.yaml b/vendor/github.com/openshift/api/helm/v1beta1/stable.projecthelmchartrepository.testsuite.yaml
index e11f9d349e..d7c402a534 100644
--- a/vendor/github.com/openshift/api/helm/v1beta1/stable.projecthelmchartrepository.testsuite.yaml
+++ b/vendor/github.com/openshift/api/helm/v1beta1/stable.projecthelmchartrepository.testsuite.yaml
@@ -1,6 +1,6 @@
apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
name: "[Stable] ProjectHelmChartRepository"
-crd: 0000_10-project-helm-chart-repository.crd.yaml
+crd: 00_project-helm-chart-repository.crd.yaml
tests:
onCreate:
- name: Should be able to create a minimal ProjectHelmChartRepository
diff --git a/vendor/github.com/openshift/api/kubecontrolplane/v1/types.go b/vendor/github.com/openshift/api/kubecontrolplane/v1/types.go
index aae8f464c2..b9cdcc213b 100644
--- a/vendor/github.com/openshift/api/kubecontrolplane/v1/types.go
+++ b/vendor/github.com/openshift/api/kubecontrolplane/v1/types.go
@@ -1,10 +1,10 @@
package v1
import (
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-
"fmt"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
configv1 "github.com/openshift/api/config/v1"
osinv1 "github.com/openshift/api/osin/v1"
)
@@ -76,8 +76,6 @@ func (t Arguments) String() string {
type KubeAPIServerImagePolicyConfig struct {
// internalRegistryHostname sets the hostname for the default internal image
// registry. The value must be in "hostname[:port]" format.
- // For backward compatibility, users can still use OPENSHIFT_DEFAULT_REGISTRY
- // environment variable but this setting overrides the environment variable.
InternalRegistryHostname string `json:"internalRegistryHostname"`
// externalRegistryHostnames provides the hostnames for the default external image
// registry. The external hostname should be set only when the image registry
diff --git a/vendor/github.com/openshift/api/kubecontrolplane/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/kubecontrolplane/v1/zz_generated.swagger_doc_generated.go
index 3ee8b23fd4..906bb271b0 100644
--- a/vendor/github.com/openshift/api/kubecontrolplane/v1/zz_generated.swagger_doc_generated.go
+++ b/vendor/github.com/openshift/api/kubecontrolplane/v1/zz_generated.swagger_doc_generated.go
@@ -40,7 +40,7 @@ func (KubeAPIServerConfig) SwaggerDoc() map[string]string {
}
var map_KubeAPIServerImagePolicyConfig = map[string]string{
- "internalRegistryHostname": "internalRegistryHostname sets the hostname for the default internal image registry. The value must be in \"hostname[:port]\" format. For backward compatibility, users can still use OPENSHIFT_DEFAULT_REGISTRY environment variable but this setting overrides the environment variable.",
+ "internalRegistryHostname": "internalRegistryHostname sets the hostname for the default internal image registry. The value must be in \"hostname[:port]\" format.",
"externalRegistryHostnames": "externalRegistryHostnames provides the hostnames for the default external image registry. The external hostname should be set only when the image registry is exposed externally. The first value is used in 'publicDockerImageRepository' field in ImageStreams. The value must be in \"hostname[:port]\" format.",
}
diff --git a/vendor/github.com/openshift/api/legacyconfig/v1/types.go b/vendor/github.com/openshift/api/legacyconfig/v1/types.go
index 871eadd8b7..eaf40b6ee4 100644
--- a/vendor/github.com/openshift/api/legacyconfig/v1/types.go
+++ b/vendor/github.com/openshift/api/legacyconfig/v1/types.go
@@ -414,8 +414,6 @@ type ImagePolicyConfig struct {
AllowedRegistriesForImport *AllowedRegistries `json:"allowedRegistriesForImport,omitempty"`
// InternalRegistryHostname sets the hostname for the default internal image
// registry. The value must be in "hostname[:port]" format.
- // For backward compatibility, users can still use OPENSHIFT_DEFAULT_REGISTRY
- // environment variable but this setting overrides the environment variable.
InternalRegistryHostname string `json:"internalRegistryHostname,omitempty"`
// ExternalRegistryHostname sets the hostname for the default external image
// registry. The external hostname should be set only when the image registry
@@ -442,7 +440,7 @@ type RegistryLocation struct {
Insecure bool `json:"insecure,omitempty"`
}
-// holds the necessary configuration options for
+// holds the necessary configuration options for
type ProjectConfig struct {
// DefaultNodeSelector holds default project node label selector
DefaultNodeSelector string `json:"defaultNodeSelector"`
@@ -482,7 +480,7 @@ type SecurityAllocator struct {
MCSLabelsPerProject int `json:"mcsLabelsPerProject"`
}
-// holds the necessary configuration options for
+// holds the necessary configuration options for
type PolicyConfig struct {
// UserAgentMatchingConfig controls how API calls from *voluntarily* identifying clients will be handled. THIS DOES NOT DEFEND AGAINST MALICIOUS CLIENTS!
UserAgentMatchingConfig UserAgentMatchingConfig `json:"userAgentMatchingConfig"`
@@ -737,7 +735,7 @@ type OAuthConfig struct {
// AlwaysShowProviderSelection will force the provider selection page to render even when there is only a single provider.
AlwaysShowProviderSelection bool `json:"alwaysShowProviderSelection"`
- //IdentityProviders is an ordered list of ways for a user to identify themselves
+ // IdentityProviders is an ordered list of ways for a user to identify themselves
IdentityProviders []IdentityProvider `json:"identityProviders"`
// GrantConfig describes how to handle grants
@@ -1563,7 +1561,6 @@ type BuildDefaultsConfig struct {
// SourceStrategyDefaultsConfig contains values that apply to builds using the
// source strategy.
type SourceStrategyDefaultsConfig struct {
-
// incremental indicates if s2i build strategies should perform an incremental
// build or not
Incremental *bool `json:"incremental,omitempty"`
diff --git a/vendor/github.com/openshift/api/legacyconfig/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/legacyconfig/v1/zz_generated.swagger_doc_generated.go
index 29269b1a30..daa0868b6b 100644
--- a/vendor/github.com/openshift/api/legacyconfig/v1/zz_generated.swagger_doc_generated.go
+++ b/vendor/github.com/openshift/api/legacyconfig/v1/zz_generated.swagger_doc_generated.go
@@ -364,7 +364,7 @@ var map_ImagePolicyConfig = map[string]string{
"scheduledImageImportMinimumIntervalSeconds": "ScheduledImageImportMinimumIntervalSeconds is the minimum number of seconds that can elapse between when image streams scheduled for background import are checked against the upstream repository. The default value is 15 minutes.",
"maxScheduledImageImportsPerMinute": "MaxScheduledImageImportsPerMinute is the maximum number of scheduled image streams that will be imported in the background per minute. The default value is 60. Set to -1 for unlimited.",
"allowedRegistriesForImport": "AllowedRegistriesForImport limits the container image registries that normal users may import images from. Set this list to the registries that you trust to contain valid Docker images and that you want applications to be able to import from. Users with permission to create Images or ImageStreamMappings via the API are not affected by this policy - typically only administrators or system integrations will have those permissions.",
- "internalRegistryHostname": "InternalRegistryHostname sets the hostname for the default internal image registry. The value must be in \"hostname[:port]\" format. For backward compatibility, users can still use OPENSHIFT_DEFAULT_REGISTRY environment variable but this setting overrides the environment variable.",
+ "internalRegistryHostname": "InternalRegistryHostname sets the hostname for the default internal image registry. The value must be in \"hostname[:port]\" format.",
"externalRegistryHostname": "ExternalRegistryHostname sets the hostname for the default external image registry. The external hostname should be set only when the image registry is exposed externally. The value is used in 'publicDockerImageRepository' field in ImageStreams. The value must be in \"hostname[:port]\" format.",
"additionalTrustedCA": "AdditionalTrustedCA is a path to a pem bundle file containing additional CAs that should be trusted during imagestream import.",
}
@@ -722,7 +722,7 @@ func (PodManifestConfig) SwaggerDoc() map[string]string {
}
var map_PolicyConfig = map[string]string{
- "": "\n holds the necessary configuration options for",
+ "": "holds the necessary configuration options for",
"userAgentMatchingConfig": "UserAgentMatchingConfig controls how API calls from *voluntarily* identifying clients will be handled. THIS DOES NOT DEFEND AGAINST MALICIOUS CLIENTS!",
}
@@ -731,7 +731,7 @@ func (PolicyConfig) SwaggerDoc() map[string]string {
}
var map_ProjectConfig = map[string]string{
- "": "\n holds the necessary configuration options for",
+ "": "holds the necessary configuration options for",
"defaultNodeSelector": "DefaultNodeSelector holds default project node label selector",
"projectRequestMessage": "ProjectRequestMessage is the string presented to a user if they are unable to request a project via the projectrequest api endpoint",
"projectRequestTemplate": "ProjectRequestTemplate is the template to use for creating projects in response to projectrequest. It is in the format namespace/template and it is optional. If it is not specified, a default template is used.",
diff --git a/vendor/github.com/openshift/api/machine/v1/0000_10_controlplanemachineset.crd.yaml b/vendor/github.com/openshift/api/machine/v1/0000_10_controlplanemachineset.crd.yaml
index e34db3399e..97c0ae6009 100644
--- a/vendor/github.com/openshift/api/machine/v1/0000_10_controlplanemachineset.crd.yaml
+++ b/vendor/github.com/openshift/api/machine/v1/0000_10_controlplanemachineset.crd.yaml
@@ -2,6 +2,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
+ capability.openshift.io/name: MachineAPI
api-approved.openshift.io: https://github.com/openshift/api/pull/1112
exclude.release.openshift.io/internal-openshift-hosted: "true"
include.release.openshift.io/self-managed-high-availability: "true"
@@ -228,6 +229,11 @@ spec:
required:
- zone
properties:
+ subnet:
+ description: subnet is the name of the network subnet in which the VM will be created. When omitted, the subnet value from the machine providerSpec template will be used.
+ type: string
+ maxLength: 80
+ pattern: ^[a-zA-Z0-9](?:[a-zA-Z0-9._-]*[a-zA-Z0-9_])?$
zone:
description: Availability Zone for the virtual machine. If nil, the virtual machine should be deployed to no zone.
type: string
@@ -260,7 +266,8 @@ spec:
rootVolume:
description: rootVolume contains settings that will be used by the OpenStack machine provider to create the root volume attached to the VM. If not specified, no root volume will be created.
type: object
- minProperties: 1
+ required:
+ - volumeType
properties:
availabilityZone:
description: availabilityZone specifies the Cinder availability zone where the root volume will be created. If not specifified, the root volume will be created in the availability zone specified by the volume type in the cinder configuration. If the volume type (configured in the OpenStack cluster) does not specify an availability zone, the root volume will be created in the default availability zone specified in the cinder configuration. See https://docs.openstack.org/cinder/latest/admin/availability-zone-type.html for more details. If the OpenStack cluster is deployed with the cross_az_attach configuration option set to false, the root volume will have to be in the same availability zone as the VM (defined by OpenStackFailureDomain.AvailabilityZone). Availability zone names must NOT contain spaces otherwise it will lead to volume that belongs to this availability zone register failure, see kubernetes/cloud-provider-openstack#1379 for further information. The maximum length of availability zone name is 63 as per labels limits.
@@ -268,6 +275,14 @@ spec:
maxLength: 63
minLength: 1
pattern: ^[^ ]*$
+ volumeType:
+ description: volumeType specifies the type of the root volume that will be provisioned. The maximum length of a volume type name is 255 characters, as per the OpenStack limit.
+ type: string
+ maxLength: 255
+ minLength: 1
+ x-kubernetes-validations:
+ - rule: '!has(self.availabilityZone) || !has(self.rootVolume) || has(self.rootVolume.availabilityZone)'
+ message: rootVolume.availabilityZone is required when availabilityZone is set
platform:
description: Platform identifies the platform for which the FailureDomain represents. Currently supported values are AWS, Azure, and GCP.
type: string
diff --git a/vendor/github.com/openshift/api/machine/v1/stable.controlplanemachineset.openstack.testsuite.yaml b/vendor/github.com/openshift/api/machine/v1/stable.controlplanemachineset.openstack.testsuite.yaml
index e29ccaff4c..a09de51e0f 100644
--- a/vendor/github.com/openshift/api/machine/v1/stable.controlplanemachineset.openstack.testsuite.yaml
+++ b/vendor/github.com/openshift/api/machine/v1/stable.controlplanemachineset.openstack.testsuite.yaml
@@ -71,6 +71,51 @@ tests:
platform: OpenStack
openstack: {}
expectedError: "spec.template.machines_v1beta1_machine_openshift_io.failureDomains.openstack in body must be of type array: \"object\""
+ - name: Should accept no failureDomains
+ initial: |
+ apiVersion: machine.openshift.io/v1
+ kind: ControlPlaneMachineSet
+ spec:
+ selector:
+ matchLabels:
+ machine.openshift.io/cluster-api-machine-role: master
+ machine.openshift.io/cluster-api-machine-type: master
+ template:
+ machineType: machines_v1beta1_machine_openshift_io
+ machines_v1beta1_machine_openshift_io:
+ metadata:
+ labels:
+ machine.openshift.io/cluster-api-machine-role: master
+ machine.openshift.io/cluster-api-machine-type: master
+ machine.openshift.io/cluster-api-cluster: cluster
+ spec:
+ providerSpec: {}
+ failureDomains:
+ platform: ""
+ expected: |
+ apiVersion: machine.openshift.io/v1
+ kind: ControlPlaneMachineSet
+ spec:
+ replicas: 3
+ state: Inactive
+ strategy:
+ type: RollingUpdate
+ selector:
+ matchLabels:
+ machine.openshift.io/cluster-api-machine-role: master
+ machine.openshift.io/cluster-api-machine-type: master
+ template:
+ machineType: machines_v1beta1_machine_openshift_io
+ machines_v1beta1_machine_openshift_io:
+ metadata:
+ labels:
+ machine.openshift.io/cluster-api-machine-role: master
+ machine.openshift.io/cluster-api-machine-type: master
+ machine.openshift.io/cluster-api-cluster: cluster
+ spec:
+ providerSpec: {}
+ failureDomains:
+ platform: ""
- name: Should reject an OpenStack configured failure domain with the wrong platform type
initial: |
apiVersion: machine.openshift.io/v1
@@ -168,6 +213,7 @@ tests:
openstack:
- rootVolume:
availabilityZone: foo
+ volumeType: fast
expected: |
apiVersion: machine.openshift.io/v1
kind: ControlPlaneMachineSet
@@ -195,6 +241,58 @@ tests:
openstack:
- rootVolume:
availabilityZone: foo
+ volumeType: fast
+ - name: Should accept an OpenStack failure domain with only the root volume type provided
+ initial: |
+ apiVersion: machine.openshift.io/v1
+ kind: ControlPlaneMachineSet
+ spec:
+ selector:
+ matchLabels:
+ machine.openshift.io/cluster-api-machine-role: master
+ machine.openshift.io/cluster-api-machine-type: master
+ template:
+ machineType: machines_v1beta1_machine_openshift_io
+ machines_v1beta1_machine_openshift_io:
+ metadata:
+ labels:
+ machine.openshift.io/cluster-api-machine-role: master
+ machine.openshift.io/cluster-api-machine-type: master
+ machine.openshift.io/cluster-api-cluster: cluster
+ spec:
+ providerSpec: {}
+ failureDomains:
+ platform: OpenStack
+ openstack:
+ - rootVolume:
+ volumeType: typeone
+ expected: |
+ apiVersion: machine.openshift.io/v1
+ kind: ControlPlaneMachineSet
+ spec:
+ replicas: 3
+ state: Inactive
+ strategy:
+ type: RollingUpdate
+ selector:
+ matchLabels:
+ machine.openshift.io/cluster-api-machine-role: master
+ machine.openshift.io/cluster-api-machine-type: master
+ template:
+ machineType: machines_v1beta1_machine_openshift_io
+ machines_v1beta1_machine_openshift_io:
+ metadata:
+ labels:
+ machine.openshift.io/cluster-api-machine-role: master
+ machine.openshift.io/cluster-api-machine-type: master
+ machine.openshift.io/cluster-api-cluster: cluster
+ spec:
+ providerSpec: {}
+ failureDomains:
+ platform: OpenStack
+ openstack:
+ - rootVolume:
+ volumeType: typeone
- name: Should accept an OpenStack failure domain with both availabilityZone and rootVolume provided
initial: |
apiVersion: machine.openshift.io/v1
@@ -220,6 +318,7 @@ tests:
- availabilityZone: foo
rootVolume:
availabilityZone: foo
+ volumeType: fast
expected: |
apiVersion: machine.openshift.io/v1
kind: ControlPlaneMachineSet
@@ -248,7 +347,8 @@ tests:
- availabilityZone: foo
rootVolume:
availabilityZone: foo
- - name: Should reject an OpenStack failure domain with an empty rootVolume provided
+ volumeType: fast
+ - name: Should accept an OpenStack failure domain with both availabilityZone and root volume type provided
initial: |
apiVersion: machine.openshift.io/v1
kind: ControlPlaneMachineSet
@@ -271,8 +371,140 @@ tests:
platform: OpenStack
openstack:
- availabilityZone: foo
- rootVolume: {}
- expectedError: "spec.template.machines_v1beta1_machine_openshift_io.failureDomains.openstack[0].rootVolume in body should have at least 1 properties"
+ rootVolume:
+ availabilityZone: foo
+ volumeType: bar
+ expected: |
+ apiVersion: machine.openshift.io/v1
+ kind: ControlPlaneMachineSet
+ spec:
+ replicas: 3
+ state: Inactive
+ strategy:
+ type: RollingUpdate
+ selector:
+ matchLabels:
+ machine.openshift.io/cluster-api-machine-role: master
+ machine.openshift.io/cluster-api-machine-type: master
+ template:
+ machineType: machines_v1beta1_machine_openshift_io
+ machines_v1beta1_machine_openshift_io:
+ metadata:
+ labels:
+ machine.openshift.io/cluster-api-machine-role: master
+ machine.openshift.io/cluster-api-machine-type: master
+ machine.openshift.io/cluster-api-cluster: cluster
+ spec:
+ providerSpec: {}
+ failureDomains:
+ platform: OpenStack
+ openstack:
+ - availabilityZone: foo
+ rootVolume:
+ availabilityZone: foo
+ volumeType: bar
+ - name: Should reject an OpenStack failure domain with no rootVolume volumeType provided
+ initial: |
+ apiVersion: machine.openshift.io/v1
+ kind: ControlPlaneMachineSet
+ spec:
+ selector:
+ matchLabels:
+ machine.openshift.io/cluster-api-machine-role: master
+ machine.openshift.io/cluster-api-machine-type: master
+ template:
+ machineType: machines_v1beta1_machine_openshift_io
+ machines_v1beta1_machine_openshift_io:
+ metadata:
+ labels:
+ machine.openshift.io/cluster-api-machine-role: master
+ machine.openshift.io/cluster-api-machine-type: master
+ machine.openshift.io/cluster-api-cluster: cluster
+ spec:
+ providerSpec: {}
+ failureDomains:
+ platform: OpenStack
+ openstack:
+ - rootVolume:
+ availabilityZone: foo
+ expectedError: "spec.template.machines_v1beta1_machine_openshift_io.failureDomains.openstack[0].rootVolume.volumeType: Required value,