diff --git a/constraint/Dockerfile b/constraint/Dockerfile
index fb2241642..07189aa3b 100644
--- a/constraint/Dockerfile
+++ b/constraint/Dockerfile
@@ -1,5 +1,5 @@
# Build the manager binary
-FROM golang:1.15 as builder
+FROM golang:1.16 as builder
RUN apt-get update &&\
apt-get install -y apt-utils make
@@ -21,11 +21,6 @@ RUN curl -L -O "https://github.com/kubernetes-sigs/kustomize/releases/download/v
mv kustomize_${version}_linux_${arch} /usr/bin/kustomize &&\
chmod u+x /usr/bin/kustomize
-# Install OPA
-WORKDIR /usr/bin
-RUN curl -L -o opa https://github.com/open-policy-agent/opa/releases/download/v0.10.5/opa_linux_amd64 &&\
- chmod 755 opa
-
# Copy in the go src
WORKDIR /go/src/github.com/open-policy-agent/frameworks/constraint
COPY . .
diff --git a/constraint/Makefile b/constraint/Makefile
index c529148d4..88b6cb540 100644
--- a/constraint/Makefile
+++ b/constraint/Makefile
@@ -32,7 +32,7 @@ install: manifests
# Install the generation dependencies on the local machine
gen-dependencies:
GO111MODULE=on go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.5.0
- GO111MODULE=on go get k8s.io/code-generator/cmd/conversion-gen@v0.20.2
+ GO111MODULE=on go get k8s.io/code-generator/cmd/conversion-gen@v0.21.1
# Generate manifests e.g. CRD, RBAC etc.
manifests:
diff --git a/constraint/go.mod b/constraint/go.mod
index 43bae0f71..a8bb9118c 100644
--- a/constraint/go.mod
+++ b/constraint/go.mod
@@ -1,33 +1,40 @@
module github.com/open-policy-agent/frameworks/constraint
-go 1.13
+go 1.16
require (
- github.com/OneOfOne/xxhash v1.2.8 // indirect
+ github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
github.com/davecgh/go-spew v1.1.1
- github.com/go-openapi/spec v0.19.5 // indirect
- github.com/gogo/protobuf v1.3.2 // indirect
- github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
- github.com/google/go-cmp v0.5.2
- github.com/kr/text v0.2.0 // indirect
- github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
- github.com/onsi/gomega v1.10.2
- github.com/open-policy-agent/opa v0.24.0
+ github.com/go-openapi/spec v0.20.3 // indirect
+ github.com/go-openapi/swag v0.19.15 // indirect
+ github.com/golang/glog v0.0.0-20210429001901-424d2337a529
+ github.com/google/go-cmp v0.5.6
+ github.com/google/gofuzz v1.2.0 // indirect
+ github.com/imdario/mergo v0.3.12 // indirect
+ github.com/json-iterator/go v1.1.11 // indirect
+ github.com/mailru/easyjson v0.7.7 // indirect
+ github.com/mitchellh/mapstructure v1.4.1 // indirect
+ github.com/onsi/gomega v1.10.5
+ github.com/open-policy-agent/opa v0.29.4
github.com/pkg/errors v0.9.1
- github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect
- github.com/spf13/cobra v1.1.1
+ github.com/prometheus/client_golang v1.10.0 // indirect
+ github.com/prometheus/common v0.25.0 // indirect
+ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
+ github.com/spf13/cobra v1.1.3
github.com/spf13/pflag v1.0.5
- golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449 // indirect
- golang.org/x/net v0.0.0-20210224082022-3d97a244fca7
- golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 // indirect
- golang.org/x/tools v0.1.0 // indirect
- gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
- gopkg.in/yaml.v2 v2.4.0 // indirect
+ golang.org/x/net v0.0.0-20210525063256-abc453219eb5
+ golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c // indirect
+ golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b // indirect
+ golang.org/x/term v0.0.0-20210503060354-a79de5458b56 // indirect
+ google.golang.org/appengine v1.6.7 // indirect
+ google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect
k8s.io/apiextensions-apiserver v0.20.2
k8s.io/apimachinery v0.20.2
k8s.io/client-go v0.20.2
- k8s.io/klog/v2 v2.8.0 // indirect
- k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 // indirect
- sigs.k8s.io/controller-runtime v0.8.2
- sigs.k8s.io/structured-merge-diff/v4 v4.1.0 // indirect
+ k8s.io/klog/v2 v2.9.0 // indirect
+ k8s.io/kube-openapi v0.0.0-20210527164424-3c818078ee3d // indirect
+ k8s.io/utils v0.0.0-20210527160623-6fdb442a123b // indirect
+ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19 // indirect
+ sigs.k8s.io/controller-runtime v0.8.3
+ sigs.k8s.io/structured-merge-diff/v4 v4.1.1 // indirect
)
diff --git a/constraint/go.sum b/constraint/go.sum
index a2909d39c..c4e9c135a 100644
--- a/constraint/go.sum
+++ b/constraint/go.sum
@@ -1,3 +1,5 @@
+4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo=
+bitbucket.org/creachadair/shell v0.0.6/go.mod h1:8Qqi/cYk7vPnsOePHroKXDJYmb5x7ENhtiFtfZq8K+M=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
@@ -9,18 +11,32 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
+cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
+cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
+cloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU=
+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/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/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/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
+cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
+cloud.google.com/go/pubsub v1.5.0/go.mod h1:ZEwJccE3z93Z2HWvstpri00jOg7oO4UZDtKhwDwqF0w=
+cloud.google.com/go/spanner v1.7.0/go.mod h1:sd3K2gZ9Fd0vMPLXzeCrF6fq4i63Q7aTLW/lBIfBkIk=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
+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=
+contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
@@ -32,91 +48,161 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
-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/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
+github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
+github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
+github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
+github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
+github.com/Masterminds/sprig v2.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
+github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
-github.com/OneOfOne/xxhash v1.2.7/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
+github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
+github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
+github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
+github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
+github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
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/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE=
+github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
+github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
+github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ=
+github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
+github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
-github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
+github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
+github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
+github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
+github.com/ashanbrown/forbidigo v1.1.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI=
+github.com/ashanbrown/makezero v0.0.0-20210308000810-4155955488a0/go.mod h1:oG9Dnez7/ESBqc4EdrdNlryeo7d0KcW1ftXHm7nU/UU=
+github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
+github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
+github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
+github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
+github.com/aws/aws-sdk-go v1.36.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
+github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
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/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
+github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
+github.com/bombsimon/wsl/v3 v3.3.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc=
+github.com/bytecodealliance/wasmtime-go v0.27.0 h1:b/mvyw1YJSwF5zNxqLH9V24ENkZGAvp+KgIKHOFHk1c=
+github.com/bytecodealliance/wasmtime-go v0.27.0/go.mod h1:q320gUxqyI8yB+ZqRuaJOEnGkAnHh6WtJjMaT2CW4wI=
+github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
+github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/charithe/durationcheck v0.0.6/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg=
+github.com/chavacava/garif v0.0.0-20210405163807-87a70f3d418b/go.mod h1:Qjyv4H3//PWVzTeCezG2b9IRn6myJxJSr4TD/xo6ojU=
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=
+github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
+github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
+github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
+github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/daixiang0/gci v0.2.8/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc=
+github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
+github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
+github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
+github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
+github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
+github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
+github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/esimonov/ifshort v1.0.2/go.mod h1:yZqNJUrNn20K8Q9n2CrjTKYyVEmX209Hgu+M1LBpeZE=
+github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY=
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
+github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
+github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
+github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
+github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
+github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
+github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
+github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
+github.com/fullstorydev/grpcurl v1.6.0/go.mod h1:ZQ+ayqbKMJNhzLmbpCiurTVlaK2M/3nqZCxaQ2Ze/sM=
+github.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-critic/go-critic v0.5.6/go.mod h1:cVjj0DfqewQVIlIAGexPCaGaZDAqGE29PYDDADIVNEo=
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/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
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-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-logr/logr v0.3.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
@@ -124,29 +210,51 @@ github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-logr/zapr v0.2.0 h1:v6Ji8yBW77pva6NkJKQdHLAJKrIJKRHz0RXwPqCHSR4=
github.com/go-logr/zapr v0.2.0/go.mod h1:qhKdvif7YF5GI9NWEpyxTSSBdGmzkNguibrdCNVPunU=
+github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
-github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
+github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
-github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
+github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM=
+github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
-github.com/go-openapi/spec v0.19.5 h1:Xm0Ao53uqnk9QE/LlYV5DEU09UAgpliA85QoT9LzqPw=
-github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
+github.com/go-openapi/spec v0.20.3 h1:uH9RQ6vdyPSs2pSy9fL8QPspDF2AMIMPtmK5coSSjtQ=
+github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
-github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
+github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
+github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
+github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
+github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4=
+github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ=
+github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
+github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw=
+github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU=
+github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI=
+github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc=
+github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
+github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU=
+github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU=
+github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
+github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
+github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
+github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
-github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
-github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/glog v0.0.0-20210429001901-424d2337a529 h1:2voWjNECnrZRbfwXxHB1/j8wa6xdKn85B5NzgVL/pTU=
+github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -158,12 +266,15 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/protobuf v0.0.0-20181025225059-d3de96c4c28e/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
+github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
+github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
@@ -171,27 +282,54 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4=
+github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk=
+github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8=
+github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU=
+github.com/golangci/golangci-lint v1.40.1/go.mod h1:OyFTr1muxaWeGTcHQcL3B7C4rETnDphTKYenZDgH2/g=
+github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg=
+github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o=
+github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA=
+github.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5/go.mod h1:LK+zW4MpyytAWQRz0M4xnzEk50lSvqDQKfx304apFkY=
+github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ=
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/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
+github.com/google/certificate-transparency-go v1.1.1/go.mod h1:FDKqPvSXawb2ecErVRrD+nfy23RCzyl7eqVCEmlT1Zs=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.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.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
+github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/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 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
+github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
+github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/trillian v1.3.11/go.mod h1:0tPraVHrSDkA3BO6vKX67zgLXs6SsOAbHEivX+9mPgw=
+github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
@@ -201,28 +339,51 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
github.com/googleapis/gnostic v0.5.1 h1:A8Yhf6EtqTv9RMsU6MQTyrtV1TjWlR6xU9BsZIwuTCM=
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
+github.com/gookit/color v1.3.8/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gorilla/mux v0.0.0-20181024020800-521ea7b17d02/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
+github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254/go.mod h1:M9mZEtGIsR1oDaZagNPNG9iq9n2HrhZ17dsXk73V3Lw=
+github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA=
+github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
+github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
+github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
+github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw=
+github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0=
+github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI=
+github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado=
+github.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak=
+github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
+github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
+github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@@ -234,25 +395,52 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
+github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
+github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/imdario/mergo v0.3.10 h1:6q5mVkdH/vYmqngx7kZQTjJ5HRsx+ImorDIEQ+beJgc=
+github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
+github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
+github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
+github.com/jgautheron/goconst v1.4.0/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4=
+github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4=
+github.com/jingyugao/rowserrcheck v0.0.0-20210315055705-d907ca737bb1/go.mod h1:TOQpc2SLx6huPfoFGK3UOnEG+u02D3C1GeosjupAKCA=
+github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
+github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
+github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
+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.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
+github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
+github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
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/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=
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/julz/importas v0.0.0-20210419104244-841f0c0fe66d/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0=
+github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
-github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/errcheck v1.6.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
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.2/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=
@@ -264,29 +452,69 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
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/kulti/thelper v0.4.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U=
+github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
+github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg=
+github.com/ldez/gomoddirectives v0.2.1/go.mod h1:sGicqkRgBOg//JfpXwkB9Hj0X5RyJ7mlACM5B9f6Me4=
+github.com/ldez/tagliatelle v0.2.0/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88=
+github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag=
+github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
+github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
+github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
+github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
+github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
+github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
+github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU=
+github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
+github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
-github.com/mattn/go-runewidth v0.0.0-20181025052659-b20a3daf6a39/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
+github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
+github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc=
+github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=
+github.com/mgechev/revive v1.0.6/go.mod h1:Lj5gIVxjBlH8REa3icEOkdfchwYc291nShzZ4QYWyMo=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
+github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
+github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
+github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
+github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+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/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
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=
@@ -294,154 +522,294 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
+github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k=
+github.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinKo8VaLxe6PWTPEXRXDIHz2QAwiaBaP5/4a8=
+github.com/mozilla/tls-observatory v0.0.0-20210209181001-cf43108d6880/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
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/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo=
+github.com/mwitkow/go-proto-validators v0.2.0/go.mod h1:ZfA1hW+UH/2ZHOWvQ3HnQaU0DtnpXu850MZiy+YUgcc=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
+github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c=
+github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
+github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
+github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
+github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
+github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
+github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
+github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
+github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
+github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ=
+github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ=
+github.com/nishanths/predeclared v0.2.1/go.mod h1:HvkGJcA3naj4lOwnFXFDkFxVtSqQMB9sbB1usJ+xjQE=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
+github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
+github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
+github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
+github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
+github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ=
+github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
-github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4=
github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
+github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4=
+github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
-github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs=
github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
-github.com/open-policy-agent/opa v0.24.0 h1:fnGOIux+TTGZsC0du1bRBtV8F+KPN55Hks12uE3Fq3E=
-github.com/open-policy-agent/opa v0.24.0/go.mod h1:qEyD/i8j+RQettHGp4f86yjrjvv+ZYia+JHCMv2G7wA=
+github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ=
+github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
+github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
+github.com/open-policy-agent/opa v0.29.4 h1:rNa/Gd3Fs0xWgL0aZoyblRwCZLJsSLDQOhnck6DWpaA=
+github.com/open-policy-agent/opa v0.29.4/go.mod h1:ZCOTD3yyFR8JvF8ETdWdiSPn9WcF1dXeQWOv7VoPorU=
+github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
+github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
+github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
+github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
+github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/peterh/liner v0.0.0-20170211195444-bf27d3ba8e1d/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
-github.com/pkg/errors v0.0.0-20181023235946-059132a15dd0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw=
+github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
+github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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=
+github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
+github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
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/polyfloyd/go-errorlint v0.0.0-20210418123303-74da32850375/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
-github.com/prometheus/client_golang v0.0.0-20181025174421-f30f42803563/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
-github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
+github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
+github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg=
+github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
-github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
+github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
+github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
+github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
+github.com/prometheus/common v0.25.0 h1:IjJYZJCI8HZYtqA3xYwGyDzSCy1r4CA2GRh+4vdOmtE=
+github.com/prometheus/common v0.25.0/go.mod h1:H6QK/N6XVT42whUeIdI3dp36w49c+/iMDk7UAI2qm7Q=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
-github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4=
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
+github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
+github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/pseudomuto/protoc-gen-doc v1.3.2/go.mod h1:y5+P6n3iGrbKG+9O04V5ld71in3v/bX88wUwgt+U8EA=
+github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q=
+github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
+github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30=
+github.com/quasilyte/go-ruleguard v0.3.4/go.mod h1:57FZgMnoo6jqxkYKmVj5Fc8vOt0rVzoE/UNAmFFIPqA=
+github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
+github.com/quasilyte/go-ruleguard/dsl v0.3.2/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
+github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc=
+github.com/quasilyte/go-ruleguard/rules v0.0.0-20210203162857-b223e0831f88/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50=
+github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
-github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ=
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
+github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+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.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
+github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/ryancurrah/gomodguard v1.2.0/go.mod h1:rNqbC4TOIdUDcVMSIpNNAzTbzXAZa6W5lnUepvuMMgQ=
+github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
+github.com/sanposhiho/wastedassign v1.0.0/go.mod h1:LGpq5Hsv74QaqM47WtIsRSF/ik9kqk07kchgv66tLVE=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
+github.com/securego/gosec/v2 v2.7.0/go.mod h1:xNbGArrGUspJLuz3LS5XCY1EBW/0vABAl/LWfSklmiM=
+github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
+github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs=
+github.com/shirou/gopsutil/v3 v3.21.4/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw=
+github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
+github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
-github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
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.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
+github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI=
+github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
+github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cobra v0.0.0-20181021141114-fe5e611709b0/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
-github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
+github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
+github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
+github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/spf13/pflag v0.0.0-20181024212040-082b515c9490/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
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/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
+github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
+github.com/ssgreg/nlreturn/v2 v2.1.0/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
+github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
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.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
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.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
+github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM=
+github.com/tetafro/godot v1.4.6/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8=
+github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
+github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek=
+github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/tomarrell/wrapcheck/v2 v2.1.0/go.mod h1:crK5eI4RGSUrb9duDTQ5GqcukbKZvi85vX6nbhsBAeI=
+github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4=
+github.com/tommy-muehle/go-mnd/v2 v2.3.2/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=
+github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
+github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
+github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
+github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA=
+github.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD5KW4lOuSdPKzY=
+github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
+github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE=
+github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
+github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yashtewari/glob-intersection v0.0.0-20180916065949-5c77d914dd0b h1:vVRagRXf67ESqAb72hG2C/ZwI8NtJF2u2V76EsuOHGY=
github.com/yashtewari/glob-intersection v0.0.0-20180916065949-5c77d914dd0b/go.mod h1:HptNXiXVDcJjXe9SqMd0v2FsL9f8dz4GnXgltU6q/co=
+github.com/yeya24/promlinter v0.1.0/go.mod h1:rs5vtZzeBHqqMwXqFScncpCF6u06lezhZepno9AB1Oc=
+github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
+github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
+github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
+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=
+github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
+go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
+go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6yfWfDmlWd35khcWpUa4L0xI/k=
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
+go.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403/go.mod h1:jHoPAGnDrCy6kaI2tAze5Prf0Nr0w/oNkROt2lw3n3o=
+go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
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=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
-go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
+go.uber.org/automaxprocs v1.4.0/go.mod h1:/mTEdr7LvHhs0v7mjdxDreTz1OG5zdZGqgOnhWiR/+Q=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
+go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
-go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.8.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM=
go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
+golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/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-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/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.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
+golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
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=
@@ -452,9 +820,9 @@ 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-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
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-20181023182221-1baf3a9d7d67/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -464,8 +832,8 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
@@ -474,8 +842,9 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
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/mod v0.3.1-0.20200828183125-ce943fd02449 h1:xUIPaMhvROX9dhPvRCenIJtU78+lbEenGbgqB5hfHCQ=
-golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.2/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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -484,6 +853,7 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/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-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -492,9 +862,12 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
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=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -502,25 +875,43 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200927032502-5d4f70055728/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+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-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 h1:OgUuv8lsRpBibGNbSizVwKWlysjaNzmC9gYMhPVfqFM=
-golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
+golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
+golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
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 h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c h1:pkQiBZBvdos9qq4wBAHqlzuZHEXo07pqV06ef90u1WI=
+golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+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.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
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=
@@ -528,7 +919,10 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/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-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/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-20190222072716-a9d3bda3a223/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=
@@ -540,49 +934,85 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/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-20200116001909-b77594299b42/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=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+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-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/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-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M=
-golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/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-20210601080250-7ecdf8ef093b h1:qh4f65QIVFjq9eBURLEYWqaEXmOyqdUyiBSgaXWccWk=
+golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w=
+golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
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.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
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-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s=
+golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
+golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
@@ -593,8 +1023,10 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -605,22 +1037,61 @@ golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
+golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200630154851-b2d8b0336632/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200706234117-b22de6825cf7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
+golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
+golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
+golang.org/x/tools v0.0.0-20201011145850-ed2f50202694/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
+golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201028025901-8cd080b735b3/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201114224030-61ea331ec02b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210104081019-d8d6ddbec6ee/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.2-0.20210512205948-8287d5da45e4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
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=
@@ -628,32 +1099,46 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1N
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gomodules.xyz/jsonpatch/v2 v2.1.0 h1:Phva6wqu+xR//Njw6iorylFFgn/z547tw5Ne3HZPQ+k=
gomodules.xyz/jsonpatch/v2 v2.1.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
+google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
+google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
+google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20181107211654-5fc9ac540362/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
+google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
@@ -663,18 +1148,46 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a h1:pOwg4OoaRYScjmR4LlLgdtnyoHYTSAVhhqe5uPdpII8=
+google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
+google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200707001353-8e8330bf89df/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+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-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0=
+google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
+google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
+google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
+google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
+google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
+google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
+google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
+google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
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=
@@ -684,8 +1197,10 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
-google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
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=
@@ -693,8 +1208,10 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
+gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
@@ -703,11 +1220,14 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
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.6/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=
@@ -717,13 +1237,15 @@ gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclp
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
+honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
-honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U=
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=
+honnef.co/go/tools v0.1.4/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
k8s.io/api v0.20.2 h1:y/HR22XDZY3pniu9hIFDLpUCPq2w5eQ6aV/VFQ7uJMw=
k8s.io/api v0.20.2/go.mod h1:d7n6Ehyzx+S+cE3VhTGfVNNqtGc/oL9DCdYYahlurV8=
@@ -749,24 +1271,31 @@ k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAE
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
-k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts=
-k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
+k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM=
+k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
-k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 h1:vEx13qjvaZ4yfObSSXW7BrMc/KQBBT/Jyee8XtLf4x0=
-k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
+k8s.io/kube-openapi v0.0.0-20210527164424-3c818078ee3d h1:lUK8GPtuJy8ClWZhuvKoaLdKGPLq9H1PxWp7VPBZBkU=
+k8s.io/kube-openapi v0.0.0-20210527164424-3c818078ee3d/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-k8s.io/utils v0.0.0-20210111153108-fddb29f9d009 h1:0T5IaWHO3sJTEmCP6mUlBvMukxPKUQWqiI/YuiBNMiQ=
k8s.io/utils v0.0.0-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
+k8s.io/utils v0.0.0-20210527160623-6fdb442a123b h1:MSqsVQ3pZvPGTqCjptfimO2WjG7A9un2zcpiHkA6M/s=
+k8s.io/utils v0.0.0-20210527160623-6fdb442a123b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
+mvdan.cc/gofumpt v0.1.1/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48=
+mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
+mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
+mvdan.cc/unparam v0.0.0-20210104141923-aac4ce9116a7/go.mod h1:hBpJkZE8H/sb+VRFvw2+rBpHNsTBcvSpk61hr8mzXZE=
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=
-sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14 h1:TihvEz9MPj2u0KWds6E2OBUXfwaL4qRJ33c7HGiJpqk=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
-sigs.k8s.io/controller-runtime v0.8.2 h1:SBWmI0b3uzMIUD/BIXWNegrCeZmPJ503pOtwxY0LPHM=
-sigs.k8s.io/controller-runtime v0.8.2/go.mod h1:U/l+DUopBc1ecfRZ5aviA9JDmGFQKvLf5YkZNx2e0sU=
+sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19 h1:0jaDAAxtqIrrqas4vtTqxct4xS5kHfRNycTRLTyJmVM=
+sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
+sigs.k8s.io/controller-runtime v0.8.3 h1:GMHvzjTmaWHQB8HadW+dIvBoJuLvZObYJ5YoZruPRao=
+sigs.k8s.io/controller-runtime v0.8.3/go.mod h1:U/l+DUopBc1ecfRZ5aviA9JDmGFQKvLf5YkZNx2e0sU=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
-sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8=
-sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
+sigs.k8s.io/structured-merge-diff/v4 v4.1.1 h1:nYqY2A6oy37sKLYuSBXuQhbj4JVclzJK13BOIvJG5XU=
+sigs.k8s.io/structured-merge-diff/v4 v4.1.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
+sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
diff --git a/constraint/vendor/github.com/asaskevich/govalidator/.gitignore b/constraint/vendor/github.com/asaskevich/govalidator/.gitignore
new file mode 100644
index 000000000..8d69a9418
--- /dev/null
+++ b/constraint/vendor/github.com/asaskevich/govalidator/.gitignore
@@ -0,0 +1,15 @@
+bin/
+.idea/
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
diff --git a/constraint/vendor/github.com/asaskevich/govalidator/.travis.yml b/constraint/vendor/github.com/asaskevich/govalidator/.travis.yml
index e29f8eef5..bb83c6670 100644
--- a/constraint/vendor/github.com/asaskevich/govalidator/.travis.yml
+++ b/constraint/vendor/github.com/asaskevich/govalidator/.travis.yml
@@ -1,14 +1,12 @@
language: go
-
+dist: xenial
go:
- - 1.1
- - 1.2
- - 1.3
- - 1.4
- - 1.5
- - 1.6
- - tip
+ - '1.10'
+ - '1.11'
+ - '1.12'
+ - '1.13'
+ - 'tip'
-notifications:
- email:
- - bwatas@gmail.com
+script:
+ - go test -coverpkg=./... -coverprofile=coverage.info -timeout=5s
+ - bash <(curl -s https://codecov.io/bash)
diff --git a/constraint/vendor/github.com/asaskevich/govalidator/CODE_OF_CONDUCT.md b/constraint/vendor/github.com/asaskevich/govalidator/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..4b462b0d8
--- /dev/null
+++ b/constraint/vendor/github.com/asaskevich/govalidator/CODE_OF_CONDUCT.md
@@ -0,0 +1,43 @@
+# Contributor Code of Conduct
+
+This project adheres to [The Code Manifesto](http://codemanifesto.com)
+as its guidelines for contributor interactions.
+
+## The Code Manifesto
+
+We want to work in an ecosystem that empowers developers to reach their
+potential — one that encourages growth and effective collaboration. A space
+that is safe for all.
+
+A space such as this benefits everyone that participates in it. It encourages
+new developers to enter our field. It is through discussion and collaboration
+that we grow, and through growth that we improve.
+
+In the effort to create such a place, we hold to these values:
+
+1. **Discrimination limits us.** This includes discrimination on the basis of
+ race, gender, sexual orientation, gender identity, age, nationality,
+ technology and any other arbitrary exclusion of a group of people.
+2. **Boundaries honor us.** Your comfort levels are not everyone’s comfort
+ levels. Remember that, and if brought to your attention, heed it.
+3. **We are our biggest assets.** None of us were born masters of our trade.
+ Each of us has been helped along the way. Return that favor, when and where
+ you can.
+4. **We are resources for the future.** As an extension of #3, share what you
+ know. Make yourself a resource to help those that come after you.
+5. **Respect defines us.** Treat others as you wish to be treated. Make your
+ discussions, criticisms and debates from a position of respectfulness. Ask
+ yourself, is it true? Is it necessary? Is it constructive? Anything less is
+ unacceptable.
+6. **Reactions require grace.** Angry responses are valid, but abusive language
+ and vindictive actions are toxic. When something happens that offends you,
+ handle it assertively, but be respectful. Escalate reasonably, and try to
+ allow the offender an opportunity to explain themselves, and possibly
+ correct the issue.
+7. **Opinions are just that: opinions.** Each and every one of us, due to our
+ background and upbringing, have varying opinions. That is perfectly
+ acceptable. Remember this: if you respect your own opinions, you should
+ respect the opinions of others.
+8. **To err is human.** You might not intend it, but mistakes do happen and
+ contribute to build experience. Tolerate honest mistakes, and don't
+ hesitate to apologize if you make one yourself.
diff --git a/constraint/vendor/github.com/asaskevich/govalidator/CONTRIBUTING.md b/constraint/vendor/github.com/asaskevich/govalidator/CONTRIBUTING.md
index f0f7e3a8a..7ed268a1e 100644
--- a/constraint/vendor/github.com/asaskevich/govalidator/CONTRIBUTING.md
+++ b/constraint/vendor/github.com/asaskevich/govalidator/CONTRIBUTING.md
@@ -11,7 +11,7 @@ If you don't know what to do, there are some features and functions that need to
- [ ] Update actual [list of functions](https://github.com/asaskevich/govalidator#list-of-functions)
- [ ] Update [list of validators](https://github.com/asaskevich/govalidator#validatestruct-2) that available for `ValidateStruct` and add new
- [ ] Implement new validators: `IsFQDN`, `IsIMEI`, `IsPostalCode`, `IsISIN`, `IsISRC` etc
-- [ ] Implement [validation by maps](https://github.com/asaskevich/govalidator/issues/224)
+- [x] Implement [validation by maps](https://github.com/asaskevich/govalidator/issues/224)
- [ ] Implement fuzzing testing
- [ ] Implement some struct/map/array utilities
- [ ] Implement map/array validation
@@ -37,7 +37,7 @@ Anyone can file an expense. If the expense makes sense for the development of th
### Contributors
Thank you to all the people who have already contributed to govalidator!
-
+
### Backers
diff --git a/constraint/vendor/github.com/asaskevich/govalidator/LICENSE b/constraint/vendor/github.com/asaskevich/govalidator/LICENSE
index 2f9a31fad..cacba9102 100644
--- a/constraint/vendor/github.com/asaskevich/govalidator/LICENSE
+++ b/constraint/vendor/github.com/asaskevich/govalidator/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2014 Alex Saskevich
+Copyright (c) 2014-2020 Alex Saskevich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/constraint/vendor/github.com/asaskevich/govalidator/README.md b/constraint/vendor/github.com/asaskevich/govalidator/README.md
index 40f9a8781..2c3fc35eb 100644
--- a/constraint/vendor/github.com/asaskevich/govalidator/README.md
+++ b/constraint/vendor/github.com/asaskevich/govalidator/README.md
@@ -1,7 +1,8 @@
govalidator
===========
-[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/asaskevich/govalidator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![GoDoc](https://godoc.org/github.com/asaskevich/govalidator?status.png)](https://godoc.org/github.com/asaskevich/govalidator) [![Coverage Status](https://img.shields.io/coveralls/asaskevich/govalidator.svg)](https://coveralls.io/r/asaskevich/govalidator?branch=master) [![wercker status](https://app.wercker.com/status/1ec990b09ea86c910d5f08b0e02c6043/s "wercker status")](https://app.wercker.com/project/bykey/1ec990b09ea86c910d5f08b0e02c6043)
-[![Build Status](https://travis-ci.org/asaskevich/govalidator.svg?branch=master)](https://travis-ci.org/asaskevich/govalidator) [![Go Report Card](https://goreportcard.com/badge/github.com/asaskevich/govalidator)](https://goreportcard.com/report/github.com/asaskevich/govalidator) [![GoSearch](http://go-search.org/badge?id=github.com%2Fasaskevich%2Fgovalidator)](http://go-search.org/view?id=github.com%2Fasaskevich%2Fgovalidator) [![Backers on Open Collective](https://opencollective.com/govalidator/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/govalidator/sponsors/badge.svg)](#sponsors) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_shield)
+[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/asaskevich/govalidator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![GoDoc](https://godoc.org/github.com/asaskevich/govalidator?status.png)](https://godoc.org/github.com/asaskevich/govalidator)
+[![Build Status](https://travis-ci.org/asaskevich/govalidator.svg?branch=master)](https://travis-ci.org/asaskevich/govalidator)
+[![Coverage](https://codecov.io/gh/asaskevich/govalidator/branch/master/graph/badge.svg)](https://codecov.io/gh/asaskevich/govalidator) [![Go Report Card](https://goreportcard.com/badge/github.com/asaskevich/govalidator)](https://goreportcard.com/report/github.com/asaskevich/govalidator) [![GoSearch](http://go-search.org/badge?id=github.com%2Fasaskevich%2Fgovalidator)](http://go-search.org/view?id=github.com%2Fasaskevich%2Fgovalidator) [![Backers on Open Collective](https://opencollective.com/govalidator/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/govalidator/sponsors/badge.svg)](#sponsors) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_shield)
A package of validators and sanitizers for strings, structs and collections. Based on [validator.js](https://github.com/chriso/validator.js).
@@ -13,7 +14,7 @@ Type the following command in your terminal:
or you can get specified release of the package with `gopkg.in`:
- go get gopkg.in/asaskevich/govalidator.v4
+ go get gopkg.in/asaskevich/govalidator.v10
After it the package is ready to use.
@@ -83,14 +84,14 @@ This was changed to prevent data races when accessing custom validators.
import "github.com/asaskevich/govalidator"
// before
-govalidator.CustomTypeTagMap["customByteArrayValidator"] = CustomTypeValidator(func(i interface{}, o interface{}) bool {
+govalidator.CustomTypeTagMap["customByteArrayValidator"] = func(i interface{}, o interface{}) bool {
// ...
-})
+}
// after
-govalidator.CustomTypeTagMap.Set("customByteArrayValidator", CustomTypeValidator(func(i interface{}, o interface{}) bool {
+govalidator.CustomTypeTagMap.Set("customByteArrayValidator", func(i interface{}, o interface{}) bool {
// ...
-}))
+})
```
#### List of functions:
@@ -108,23 +109,34 @@ func Filter(array []interface{}, iterator ConditionIterator) []interface{}
func Find(array []interface{}, iterator ConditionIterator) interface{}
func GetLine(s string, index int) (string, error)
func GetLines(s string) []string
-func InRange(value, left, right float64) bool
+func HasLowerCase(str string) bool
+func HasUpperCase(str string) bool
+func HasWhitespace(str string) bool
+func HasWhitespaceOnly(str string) bool
+func InRange(value interface{}, left interface{}, right interface{}) bool
+func InRangeFloat32(value, left, right float32) bool
+func InRangeFloat64(value, left, right float64) bool
+func InRangeInt(value, left, right interface{}) bool
func IsASCII(str string) bool
func IsAlpha(str string) bool
func IsAlphanumeric(str string) bool
func IsBase64(str string) bool
func IsByteLength(str string, min, max int) bool
func IsCIDR(str string) bool
+func IsCRC32(str string) bool
+func IsCRC32b(str string) bool
func IsCreditCard(str string) bool
func IsDNSName(str string) bool
func IsDataURI(str string) bool
func IsDialString(str string) bool
func IsDivisibleBy(str, num string) bool
func IsEmail(str string) bool
+func IsExistingEmail(email string) bool
func IsFilePath(str string) (bool, int)
func IsFloat(str string) bool
func IsFullWidth(str string) bool
func IsHalfWidth(str string) bool
+func IsHash(str string, algorithm string) bool
func IsHexadecimal(str string) bool
func IsHexcolor(str string) bool
func IsHost(str string) bool
@@ -136,22 +148,27 @@ func IsISBN10(str string) bool
func IsISBN13(str string) bool
func IsISO3166Alpha2(str string) bool
func IsISO3166Alpha3(str string) bool
+func IsISO4217(str string) bool
func IsISO693Alpha2(str string) bool
func IsISO693Alpha3b(str string) bool
-func IsISO4217(str string) bool
func IsIn(str string, params ...string) bool
+func IsInRaw(str string, params ...string) bool
func IsInt(str string) bool
func IsJSON(str string) bool
func IsLatitude(str string) bool
func IsLongitude(str string) bool
func IsLowerCase(str string) bool
func IsMAC(str string) bool
+func IsMD4(str string) bool
+func IsMD5(str string) bool
+func IsMagnetURI(str string) bool
func IsMongoID(str string) bool
func IsMultibyte(str string) bool
func IsNatural(value float64) bool
func IsNegative(value float64) bool
func IsNonNegative(value float64) bool
func IsNonPositive(value float64) bool
+func IsNotNull(str string) bool
func IsNull(str string) bool
func IsNumeric(str string) bool
func IsPort(str string) bool
@@ -160,11 +177,24 @@ func IsPrintableASCII(str string) bool
func IsRFC3339(str string) bool
func IsRFC3339WithoutZone(str string) bool
func IsRGBcolor(str string) bool
+func IsRegex(str string) bool
func IsRequestURI(rawurl string) bool
func IsRequestURL(rawurl string) bool
+func IsRipeMD128(str string) bool
+func IsRipeMD160(str string) bool
+func IsRsaPub(str string, params ...string) bool
+func IsRsaPublicKey(str string, keylen int) bool
+func IsSHA1(str string) bool
+func IsSHA256(str string) bool
+func IsSHA384(str string) bool
+func IsSHA512(str string) bool
func IsSSN(str string) bool
func IsSemver(str string) bool
+func IsTiger128(str string) bool
+func IsTiger160(str string) bool
+func IsTiger192(str string) bool
func IsTime(str string, format string) bool
+func IsType(v interface{}, params ...string) bool
func IsURL(str string) bool
func IsUTFDigit(str string) bool
func IsUTFLetter(str string) bool
@@ -174,16 +204,21 @@ func IsUUID(str string) bool
func IsUUIDv3(str string) bool
func IsUUIDv4(str string) bool
func IsUUIDv5(str string) bool
+func IsULID(str string) bool
+func IsUnixTime(str string) bool
func IsUpperCase(str string) bool
func IsVariableWidth(str string) bool
func IsWhole(value float64) bool
func LeftTrim(str, chars string) string
func Map(array []interface{}, iterator ResultIterator) []interface{}
func Matches(str, pattern string) bool
+func MaxStringLength(str string, params ...string) bool
+func MinStringLength(str string, params ...string) bool
func NormalizeEmail(str string) (string, error)
func PadBoth(str string, padStr string, padLen int) string
func PadLeft(str string, padStr string, padLen int) string
func PadRight(str string, padStr string, padLen int) string
+func PrependPathToErrors(err error, path string) error
func Range(str string, params ...string) bool
func RemoveTags(s string) string
func ReplacePattern(str, pattern, replace string) string
@@ -192,18 +227,21 @@ func RightTrim(str, chars string) string
func RuneLength(str string, params ...string) bool
func SafeFileName(str string) string
func SetFieldsRequiredByDefault(value bool)
+func SetNilPtrAllowedByRequired(value bool)
func Sign(value float64) float64
func StringLength(str string, params ...string) bool
func StringMatches(s string, params ...string) bool
func StripLow(str string, keepNewLines bool) string
func ToBoolean(str string) (bool, error)
func ToFloat(str string) (float64, error)
-func ToInt(str string) (int64, error)
+func ToInt(value interface{}) (res int64, err error)
func ToJSON(obj interface{}) (string, error)
func ToString(obj interface{}) string
func Trim(str, chars string) string
func Truncate(str string, length int, ending string) string
+func TruncatingErrorf(str string, args ...interface{}) error
func UnderscoreToCamelCase(s string) string
+func ValidateMap(inputMap map[string]interface{}, validationMap map[string]interface{}) (bool, error)
func ValidateStruct(s interface{}) (bool, error)
func WhiteList(str, chars string) string
type ConditionIterator
@@ -214,6 +252,8 @@ type Errors
func (es Errors) Error() string
func (es Errors) Errors() []error
type ISO3166Entry
+type ISO693Entry
+type InterfaceParamValidator
type Iterator
type ParamValidator
type ResultIterator
@@ -227,6 +267,27 @@ type Validator
```go
println(govalidator.IsURL(`http://user@pass:domain.com/path/page`))
```
+###### IsType
+```go
+println(govalidator.IsType("Bob", "string"))
+println(govalidator.IsType(1, "int"))
+i := 1
+println(govalidator.IsType(&i, "*int"))
+```
+
+IsType can be used through the tag `type` which is essential for map validation:
+```go
+type User struct {
+ Name string `valid:"type(string)"`
+ Age int `valid:"type(int)"`
+ Meta interface{} `valid:"type(string)"`
+}
+result, err := govalidator.ValidateStruct(User{"Bob", 20, "meta"})
+if err != nil {
+ println("error: " + err.Error())
+}
+println(result)
+```
###### ToString
```go
type User struct {
@@ -323,6 +384,7 @@ Here is a list of available validators for struct fields (validator - used funct
"rfc3339WithoutZone": IsRFC3339WithoutZone,
"ISO3166Alpha2": IsISO3166Alpha2,
"ISO3166Alpha3": IsISO3166Alpha3,
+"ulid": IsULID,
```
Validators with parameters
@@ -334,6 +396,13 @@ Validators with parameters
"matches(pattern)": StringMatches,
"in(string1|string2|...|stringN)": IsIn,
"rsapub(keylength)" : IsRsaPub,
+"minstringlength(int): MinStringLength,
+"maxstringlength(int): MaxStringLength,
+```
+Validators with parameters for any type
+
+```go
+"type(type)": IsType,
```
And here is small example of usage:
@@ -370,6 +439,41 @@ if err != nil {
}
println(result)
```
+###### ValidateMap [#2](https://github.com/asaskevich/govalidator/pull/338)
+If you want to validate maps, you can use the map to be validated and a validation map that contain the same tags used in ValidateStruct, both maps have to be in the form `map[string]interface{}`
+
+So here is small example of usage:
+```go
+var mapTemplate = map[string]interface{}{
+ "name":"required,alpha",
+ "family":"required,alpha",
+ "email":"required,email",
+ "cell-phone":"numeric",
+ "address":map[string]interface{}{
+ "line1":"required,alphanum",
+ "line2":"alphanum",
+ "postal-code":"numeric",
+ },
+}
+
+var inputMap = map[string]interface{}{
+ "name":"Bob",
+ "family":"Smith",
+ "email":"foo@bar.baz",
+ "address":map[string]interface{}{
+ "line1":"",
+ "line2":"",
+ "postal-code":"",
+ },
+}
+
+result, err := govalidator.ValidateMap(inputMap, mapTemplate)
+if err != nil {
+ println("error: " + err.Error())
+}
+println(result)
+```
+
###### WhiteList
```go
// Remove all characters from string ignoring characters between "a" and "z"
@@ -389,7 +493,7 @@ type StructWithCustomByteArray struct {
CustomMinLength int `valid:"-"`
}
-govalidator.CustomTypeTagMap.Set("customByteArrayValidator", CustomTypeValidator(func(i interface{}, context interface{}) bool {
+govalidator.CustomTypeTagMap.Set("customByteArrayValidator", func(i interface{}, context interface{}) bool {
switch v := context.(type) { // you can type switch on the context interface being validated
case StructWithCustomByteArray:
// you can check and validate against some other field in the context,
@@ -409,14 +513,25 @@ govalidator.CustomTypeTagMap.Set("customByteArrayValidator", CustomTypeValidator
}
}
return false
-}))
-govalidator.CustomTypeTagMap.Set("customMinLengthValidator", CustomTypeValidator(func(i interface{}, context interface{}) bool {
+})
+govalidator.CustomTypeTagMap.Set("customMinLengthValidator", func(i interface{}, context interface{}) bool {
switch v := context.(type) { // this validates a field against the value in another field, i.e. dependent validation
case StructWithCustomByteArray:
return len(v.ID) >= v.CustomMinLength
}
return false
-}))
+})
+```
+
+###### Loop over Error()
+By default .Error() returns all errors in a single String. To access each error you can do this:
+```go
+ if err != nil {
+ errs := err.(govalidator.Errors).Errors()
+ for _, e := range errs {
+ fmt.Println(e.Error())
+ }
+ }
```
###### Custom error messages
@@ -445,7 +560,7 @@ If you don't know what to do, there are some features and functions that need to
- [ ] Update actual [list of functions](https://github.com/asaskevich/govalidator#list-of-functions)
- [ ] Update [list of validators](https://github.com/asaskevich/govalidator#validatestruct-2) that available for `ValidateStruct` and add new
- [ ] Implement new validators: `IsFQDN`, `IsIMEI`, `IsPostalCode`, `IsISIN`, `IsISRC` etc
-- [ ] Implement [validation by maps](https://github.com/asaskevich/govalidator/issues/224)
+- [x] Implement [validation by maps](https://github.com/asaskevich/govalidator/issues/224)
- [ ] Implement fuzzing testing
- [ ] Implement some struct/map/array utilities
- [ ] Implement map/array validation
@@ -475,7 +590,7 @@ This project exists thanks to all the people who contribute. [[Contribute](CONTR
* [Matt Sanford](https://github.com/mzsanford)
* [Simon ccl1115](https://github.com/ccl1115)
-
+
### Backers
@@ -504,4 +619,4 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
## License
-[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_large)
\ No newline at end of file
+[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_large)
diff --git a/constraint/vendor/github.com/asaskevich/govalidator/arrays.go b/constraint/vendor/github.com/asaskevich/govalidator/arrays.go
index 5bace2654..3e1da7cb4 100644
--- a/constraint/vendor/github.com/asaskevich/govalidator/arrays.go
+++ b/constraint/vendor/github.com/asaskevich/govalidator/arrays.go
@@ -9,6 +9,35 @@ type ResultIterator func(interface{}, int) interface{}
// ConditionIterator is the function that accepts element of slice/array and its index and returns boolean
type ConditionIterator func(interface{}, int) bool
+// ReduceIterator is the function that accepts two element of slice/array and returns result of merging those values
+type ReduceIterator func(interface{}, interface{}) interface{}
+
+// Some validates that any item of array corresponds to ConditionIterator. Returns boolean.
+func Some(array []interface{}, iterator ConditionIterator) bool {
+ res := false
+ for index, data := range array {
+ res = res || iterator(data, index)
+ }
+ return res
+}
+
+// Every validates that every item of array corresponds to ConditionIterator. Returns boolean.
+func Every(array []interface{}, iterator ConditionIterator) bool {
+ res := true
+ for index, data := range array {
+ res = res && iterator(data, index)
+ }
+ return res
+}
+
+// Reduce boils down a list of values into a single value by ReduceIterator
+func Reduce(array []interface{}, iterator ReduceIterator, initialValue interface{}) interface{} {
+ for _, data := range array {
+ initialValue = iterator(initialValue, data)
+ }
+ return initialValue
+}
+
// Each iterates over the slice and apply Iterator to every item
func Each(array []interface{}, iterator Iterator) {
for index, data := range array {
diff --git a/constraint/vendor/github.com/asaskevich/govalidator/converter.go b/constraint/vendor/github.com/asaskevich/govalidator/converter.go
index cf1e5d569..d68e990fc 100644
--- a/constraint/vendor/github.com/asaskevich/govalidator/converter.go
+++ b/constraint/vendor/github.com/asaskevich/govalidator/converter.go
@@ -10,7 +10,7 @@ import (
// ToString convert the input to a string.
func ToString(obj interface{}) string {
res := fmt.Sprintf("%v", obj)
- return string(res)
+ return res
}
// ToJSON convert the input to a valid JSON string
@@ -23,12 +23,27 @@ func ToJSON(obj interface{}) (string, error) {
}
// ToFloat convert the input string to a float, or 0.0 if the input is not a float.
-func ToFloat(str string) (float64, error) {
- res, err := strconv.ParseFloat(str, 64)
- if err != nil {
- res = 0.0
+func ToFloat(value interface{}) (res float64, err error) {
+ val := reflect.ValueOf(value)
+
+ switch value.(type) {
+ case int, int8, int16, int32, int64:
+ res = float64(val.Int())
+ case uint, uint8, uint16, uint32, uint64:
+ res = float64(val.Uint())
+ case float32, float64:
+ res = val.Float()
+ case string:
+ res, err = strconv.ParseFloat(val.String(), 64)
+ if err != nil {
+ res = 0
+ }
+ default:
+ err = fmt.Errorf("ToInt: unknown interface type %T", value)
+ res = 0
}
- return res, err
+
+ return
}
// ToInt convert the input string or any int type to an integer type 64, or 0 if the input is not an integer.
@@ -40,6 +55,8 @@ func ToInt(value interface{}) (res int64, err error) {
res = val.Int()
case uint, uint8, uint16, uint32, uint64:
res = int64(val.Uint())
+ case float32, float64:
+ res = int64(val.Float())
case string:
if IsInt(val.String()) {
res, err = strconv.ParseInt(val.String(), 0, 64)
@@ -47,11 +64,11 @@ func ToInt(value interface{}) (res int64, err error) {
res = 0
}
} else {
- err = fmt.Errorf("math: square root of negative number %g", value)
+ err = fmt.Errorf("ToInt: invalid numeric format %g", value)
res = 0
}
default:
- err = fmt.Errorf("math: square root of negative number %g", value)
+ err = fmt.Errorf("ToInt: unknown interface type %T", value)
res = 0
}
diff --git a/constraint/vendor/github.com/asaskevich/govalidator/doc.go b/constraint/vendor/github.com/asaskevich/govalidator/doc.go
new file mode 100644
index 000000000..55dce62dc
--- /dev/null
+++ b/constraint/vendor/github.com/asaskevich/govalidator/doc.go
@@ -0,0 +1,3 @@
+package govalidator
+
+// A package of validators and sanitizers for strings, structures and collections.
diff --git a/constraint/vendor/github.com/asaskevich/govalidator/error.go b/constraint/vendor/github.com/asaskevich/govalidator/error.go
index 655b750cb..1da2336f4 100644
--- a/constraint/vendor/github.com/asaskevich/govalidator/error.go
+++ b/constraint/vendor/github.com/asaskevich/govalidator/error.go
@@ -1,6 +1,9 @@
package govalidator
-import "strings"
+import (
+ "sort"
+ "strings"
+)
// Errors is an array of multiple errors and conforms to the error interface.
type Errors []error
@@ -15,6 +18,7 @@ func (es Errors) Error() string {
for _, e := range es {
errs = append(errs, e.Error())
}
+ sort.Strings(errs)
return strings.Join(errs, ";")
}
diff --git a/constraint/vendor/github.com/asaskevich/govalidator/go.mod b/constraint/vendor/github.com/asaskevich/govalidator/go.mod
new file mode 100644
index 000000000..42d5b1f63
--- /dev/null
+++ b/constraint/vendor/github.com/asaskevich/govalidator/go.mod
@@ -0,0 +1,3 @@
+module github.com/asaskevich/govalidator
+
+go 1.13
diff --git a/constraint/vendor/github.com/asaskevich/govalidator/numerics.go b/constraint/vendor/github.com/asaskevich/govalidator/numerics.go
index 7e6c652e1..5041d9e86 100644
--- a/constraint/vendor/github.com/asaskevich/govalidator/numerics.go
+++ b/constraint/vendor/github.com/asaskevich/govalidator/numerics.go
@@ -2,7 +2,6 @@ package govalidator
import (
"math"
- "reflect"
)
// Abs returns absolute value of number
@@ -41,7 +40,7 @@ func IsNonPositive(value float64) bool {
return value <= 0
}
-// InRange returns true if value lies between left and right border
+// InRangeInt returns true if value lies between left and right border
func InRangeInt(value, left, right interface{}) bool {
value64, _ := ToInt(value)
left64, _ := ToInt(left)
@@ -52,7 +51,7 @@ func InRangeInt(value, left, right interface{}) bool {
return value64 >= left64 && value64 <= right64
}
-// InRange returns true if value lies between left and right border
+// InRangeFloat32 returns true if value lies between left and right border
func InRangeFloat32(value, left, right float32) bool {
if left > right {
left, right = right, left
@@ -60,7 +59,7 @@ func InRangeFloat32(value, left, right float32) bool {
return value >= left && value <= right
}
-// InRange returns true if value lies between left and right border
+// InRangeFloat64 returns true if value lies between left and right border
func InRangeFloat64(value, left, right float64) bool {
if left > right {
left, right = right, left
@@ -68,20 +67,24 @@ func InRangeFloat64(value, left, right float64) bool {
return value >= left && value <= right
}
-// InRange returns true if value lies between left and right border, generic type to handle int, float32 or float64, all types must the same type
+// InRange returns true if value lies between left and right border, generic type to handle int, float32, float64 and string.
+// All types must the same type.
+// False if value doesn't lie in range or if it incompatible or not comparable
func InRange(value interface{}, left interface{}, right interface{}) bool {
-
- reflectValue := reflect.TypeOf(value).Kind()
- reflectLeft := reflect.TypeOf(left).Kind()
- reflectRight := reflect.TypeOf(right).Kind()
-
- if reflectValue == reflect.Int && reflectLeft == reflect.Int && reflectRight == reflect.Int {
- return InRangeInt(value.(int), left.(int), right.(int))
- } else if reflectValue == reflect.Float32 && reflectLeft == reflect.Float32 && reflectRight == reflect.Float32 {
- return InRangeFloat32(value.(float32), left.(float32), right.(float32))
- } else if reflectValue == reflect.Float64 && reflectLeft == reflect.Float64 && reflectRight == reflect.Float64 {
- return InRangeFloat64(value.(float64), left.(float64), right.(float64))
- } else {
+ switch value.(type) {
+ case int:
+ intValue, _ := ToInt(value)
+ intLeft, _ := ToInt(left)
+ intRight, _ := ToInt(right)
+ return InRangeInt(intValue, intLeft, intRight)
+ case float32, float64:
+ intValue, _ := ToFloat(value)
+ intLeft, _ := ToFloat(left)
+ intRight, _ := ToFloat(right)
+ return InRangeFloat64(intValue, intLeft, intRight)
+ case string:
+ return value.(string) >= left.(string) && value.(string) <= right.(string)
+ default:
return false
}
}
diff --git a/constraint/vendor/github.com/asaskevich/govalidator/patterns.go b/constraint/vendor/github.com/asaskevich/govalidator/patterns.go
index 61a05d438..bafc3765e 100644
--- a/constraint/vendor/github.com/asaskevich/govalidator/patterns.go
+++ b/constraint/vendor/github.com/asaskevich/govalidator/patterns.go
@@ -4,49 +4,55 @@ import "regexp"
// Basic regular expressions for validating strings
const (
- Email string = "^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$"
- CreditCard string = "^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11})$"
- ISBN10 string = "^(?:[0-9]{9}X|[0-9]{10})$"
- ISBN13 string = "^(?:[0-9]{13})$"
- UUID3 string = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$"
- UUID4 string = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
- UUID5 string = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
- UUID string = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
- Alpha string = "^[a-zA-Z]+$"
- Alphanumeric string = "^[a-zA-Z0-9]+$"
- Numeric string = "^[0-9]+$"
- Int string = "^(?:[-+]?(?:0|[1-9][0-9]*))$"
- Float string = "^(?:[-+]?(?:[0-9]+))?(?:\\.[0-9]*)?(?:[eE][\\+\\-]?(?:[0-9]+))?$"
- Hexadecimal string = "^[0-9a-fA-F]+$"
- Hexcolor string = "^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$"
- RGBcolor string = "^rgb\\(\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*\\)$"
- ASCII string = "^[\x00-\x7F]+$"
- Multibyte string = "[^\x00-\x7F]"
- FullWidth string = "[^\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]"
- HalfWidth string = "[\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]"
- Base64 string = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$"
- PrintableASCII string = "^[\x20-\x7E]+$"
- DataURI string = "^data:.+\\/(.+);base64$"
- Latitude string = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$"
- Longitude string = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$"
- DNSName string = `^([a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62}){1}(\.[a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62})*[\._]?$`
- IP string = `(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))`
- URLSchema string = `((ftp|tcp|udp|wss?|https?):\/\/)`
- URLUsername string = `(\S+(:\S*)?@)`
- URLPath string = `((\/|\?|#)[^\s]*)`
- URLPort string = `(:(\d{1,5}))`
- URLIP string = `([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))`
- URLSubdomain string = `((www\.)|([a-zA-Z0-9]+([-_\.]?[a-zA-Z0-9])*[a-zA-Z0-9]\.[a-zA-Z0-9]+))`
- URL string = `^` + URLSchema + `?` + URLUsername + `?` + `((` + URLIP + `|(\[` + IP + `\])|(([a-zA-Z0-9]([a-zA-Z0-9-_]+)?[a-zA-Z0-9]([-\.][a-zA-Z0-9]+)*)|(` + URLSubdomain + `?))?(([a-zA-Z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-zA-Z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-zA-Z\x{00a1}-\x{ffff}]{1,}))?))\.?` + URLPort + `?` + URLPath + `?$`
- SSN string = `^\d{3}[- ]?\d{2}[- ]?\d{4}$`
- WinPath string = `^[a-zA-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$`
- UnixPath string = `^(/[^/\x00]*)+/?$`
- Semver string = "^v?(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(-(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\\+[0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*)?$"
- tagName string = "valid"
- hasLowerCase string = ".*[[:lower:]]"
- hasUpperCase string = ".*[[:upper:]]"
- hasWhitespace string = ".*[[:space:]]"
- hasWhitespaceOnly string = "^[[:space:]]+$"
+ Email string = "^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$"
+ CreditCard string = "^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11}|6[27][0-9]{14})$"
+ ISBN10 string = "^(?:[0-9]{9}X|[0-9]{10})$"
+ ISBN13 string = "^(?:[0-9]{13})$"
+ UUID3 string = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$"
+ UUID4 string = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
+ UUID5 string = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
+ UUID string = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
+ Alpha string = "^[a-zA-Z]+$"
+ Alphanumeric string = "^[a-zA-Z0-9]+$"
+ Numeric string = "^[0-9]+$"
+ Int string = "^(?:[-+]?(?:0|[1-9][0-9]*))$"
+ Float string = "^(?:[-+]?(?:[0-9]+))?(?:\\.[0-9]*)?(?:[eE][\\+\\-]?(?:[0-9]+))?$"
+ Hexadecimal string = "^[0-9a-fA-F]+$"
+ Hexcolor string = "^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$"
+ RGBcolor string = "^rgb\\(\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*\\)$"
+ ASCII string = "^[\x00-\x7F]+$"
+ Multibyte string = "[^\x00-\x7F]"
+ FullWidth string = "[^\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]"
+ HalfWidth string = "[\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]"
+ Base64 string = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$"
+ PrintableASCII string = "^[\x20-\x7E]+$"
+ DataURI string = "^data:.+\\/(.+);base64$"
+ MagnetURI string = "^magnet:\\?xt=urn:[a-zA-Z0-9]+:[a-zA-Z0-9]{32,40}&dn=.+&tr=.+$"
+ Latitude string = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$"
+ Longitude string = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$"
+ DNSName string = `^([a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62}){1}(\.[a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62})*[\._]?$`
+ IP string = `(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))`
+ URLSchema string = `((ftp|tcp|udp|wss?|https?):\/\/)`
+ URLUsername string = `(\S+(:\S*)?@)`
+ URLPath string = `((\/|\?|#)[^\s]*)`
+ URLPort string = `(:(\d{1,5}))`
+ URLIP string = `([1-9]\d?|1\d\d|2[01]\d|22[0-3]|24\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-5]))`
+ URLSubdomain string = `((www\.)|([a-zA-Z0-9]+([-_\.]?[a-zA-Z0-9])*[a-zA-Z0-9]\.[a-zA-Z0-9]+))`
+ URL = `^` + URLSchema + `?` + URLUsername + `?` + `((` + URLIP + `|(\[` + IP + `\])|(([a-zA-Z0-9]([a-zA-Z0-9-_]+)?[a-zA-Z0-9]([-\.][a-zA-Z0-9]+)*)|(` + URLSubdomain + `?))?(([a-zA-Z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-zA-Z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-zA-Z\x{00a1}-\x{ffff}]{1,}))?))\.?` + URLPort + `?` + URLPath + `?$`
+ SSN string = `^\d{3}[- ]?\d{2}[- ]?\d{4}$`
+ WinPath string = `^[a-zA-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$`
+ UnixPath string = `^(/[^/\x00]*)+/?$`
+ WinARPath string = `^(?:(?:[a-zA-Z]:|\\\\[a-z0-9_.$●-]+\\[a-z0-9_.$●-]+)\\|\\?[^\\/:*?"<>|\r\n]+\\?)(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$`
+ UnixARPath string = `^((\.{0,2}/)?([^/\x00]*))+/?$`
+ Semver string = "^v?(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(-(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\\+[0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*)?$"
+ tagName string = "valid"
+ hasLowerCase string = ".*[[:lower:]]"
+ hasUpperCase string = ".*[[:upper:]]"
+ hasWhitespace string = ".*[[:space:]]"
+ hasWhitespaceOnly string = "^[[:space:]]+$"
+ IMEI string = "^[0-9a-f]{14}$|^\\d{15}$|^\\d{18}$"
+ IMSI string = "^\\d{14,15}$"
+ E164 string = `^\+?[1-9]\d{1,14}$`
)
// Used by IsFilePath func
@@ -60,42 +66,48 @@ const (
)
var (
- userRegexp = regexp.MustCompile("^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~.-]+$")
- hostRegexp = regexp.MustCompile("^[^\\s]+\\.[^\\s]+$")
- userDotRegexp = regexp.MustCompile("(^[.]{1})|([.]{1}$)|([.]{2,})")
- rxEmail = regexp.MustCompile(Email)
- rxCreditCard = regexp.MustCompile(CreditCard)
- rxISBN10 = regexp.MustCompile(ISBN10)
- rxISBN13 = regexp.MustCompile(ISBN13)
- rxUUID3 = regexp.MustCompile(UUID3)
- rxUUID4 = regexp.MustCompile(UUID4)
- rxUUID5 = regexp.MustCompile(UUID5)
- rxUUID = regexp.MustCompile(UUID)
- rxAlpha = regexp.MustCompile(Alpha)
- rxAlphanumeric = regexp.MustCompile(Alphanumeric)
- rxNumeric = regexp.MustCompile(Numeric)
- rxInt = regexp.MustCompile(Int)
- rxFloat = regexp.MustCompile(Float)
- rxHexadecimal = regexp.MustCompile(Hexadecimal)
- rxHexcolor = regexp.MustCompile(Hexcolor)
- rxRGBcolor = regexp.MustCompile(RGBcolor)
- rxASCII = regexp.MustCompile(ASCII)
- rxPrintableASCII = regexp.MustCompile(PrintableASCII)
- rxMultibyte = regexp.MustCompile(Multibyte)
- rxFullWidth = regexp.MustCompile(FullWidth)
- rxHalfWidth = regexp.MustCompile(HalfWidth)
- rxBase64 = regexp.MustCompile(Base64)
- rxDataURI = regexp.MustCompile(DataURI)
- rxLatitude = regexp.MustCompile(Latitude)
- rxLongitude = regexp.MustCompile(Longitude)
- rxDNSName = regexp.MustCompile(DNSName)
- rxURL = regexp.MustCompile(URL)
- rxSSN = regexp.MustCompile(SSN)
- rxWinPath = regexp.MustCompile(WinPath)
- rxUnixPath = regexp.MustCompile(UnixPath)
- rxSemver = regexp.MustCompile(Semver)
- rxHasLowerCase = regexp.MustCompile(hasLowerCase)
- rxHasUpperCase = regexp.MustCompile(hasUpperCase)
- rxHasWhitespace = regexp.MustCompile(hasWhitespace)
- rxHasWhitespaceOnly = regexp.MustCompile(hasWhitespaceOnly)
+ userRegexp = regexp.MustCompile("^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~.-]+$")
+ hostRegexp = regexp.MustCompile("^[^\\s]+\\.[^\\s]+$")
+ userDotRegexp = regexp.MustCompile("(^[.]{1})|([.]{1}$)|([.]{2,})")
+ rxEmail = regexp.MustCompile(Email)
+ rxCreditCard = regexp.MustCompile(CreditCard)
+ rxISBN10 = regexp.MustCompile(ISBN10)
+ rxISBN13 = regexp.MustCompile(ISBN13)
+ rxUUID3 = regexp.MustCompile(UUID3)
+ rxUUID4 = regexp.MustCompile(UUID4)
+ rxUUID5 = regexp.MustCompile(UUID5)
+ rxUUID = regexp.MustCompile(UUID)
+ rxAlpha = regexp.MustCompile(Alpha)
+ rxAlphanumeric = regexp.MustCompile(Alphanumeric)
+ rxNumeric = regexp.MustCompile(Numeric)
+ rxInt = regexp.MustCompile(Int)
+ rxFloat = regexp.MustCompile(Float)
+ rxHexadecimal = regexp.MustCompile(Hexadecimal)
+ rxHexcolor = regexp.MustCompile(Hexcolor)
+ rxRGBcolor = regexp.MustCompile(RGBcolor)
+ rxASCII = regexp.MustCompile(ASCII)
+ rxPrintableASCII = regexp.MustCompile(PrintableASCII)
+ rxMultibyte = regexp.MustCompile(Multibyte)
+ rxFullWidth = regexp.MustCompile(FullWidth)
+ rxHalfWidth = regexp.MustCompile(HalfWidth)
+ rxBase64 = regexp.MustCompile(Base64)
+ rxDataURI = regexp.MustCompile(DataURI)
+ rxMagnetURI = regexp.MustCompile(MagnetURI)
+ rxLatitude = regexp.MustCompile(Latitude)
+ rxLongitude = regexp.MustCompile(Longitude)
+ rxDNSName = regexp.MustCompile(DNSName)
+ rxURL = regexp.MustCompile(URL)
+ rxSSN = regexp.MustCompile(SSN)
+ rxWinPath = regexp.MustCompile(WinPath)
+ rxUnixPath = regexp.MustCompile(UnixPath)
+ rxARWinPath = regexp.MustCompile(WinARPath)
+ rxARUnixPath = regexp.MustCompile(UnixARPath)
+ rxSemver = regexp.MustCompile(Semver)
+ rxHasLowerCase = regexp.MustCompile(hasLowerCase)
+ rxHasUpperCase = regexp.MustCompile(hasUpperCase)
+ rxHasWhitespace = regexp.MustCompile(hasWhitespace)
+ rxHasWhitespaceOnly = regexp.MustCompile(hasWhitespaceOnly)
+ rxIMEI = regexp.MustCompile(IMEI)
+ rxIMSI = regexp.MustCompile(IMSI)
+ rxE164 = regexp.MustCompile(E164)
)
diff --git a/constraint/vendor/github.com/asaskevich/govalidator/types.go b/constraint/vendor/github.com/asaskevich/govalidator/types.go
index 4f7e9274a..c573abb51 100644
--- a/constraint/vendor/github.com/asaskevich/govalidator/types.go
+++ b/constraint/vendor/github.com/asaskevich/govalidator/types.go
@@ -14,8 +14,11 @@ type Validator func(str string) bool
// The second parameter should be the context (in the case of validating a struct: the whole object being validated).
type CustomTypeValidator func(i interface{}, o interface{}) bool
-// ParamValidator is a wrapper for validator functions that accepts additional parameters.
+// ParamValidator is a wrapper for validator functions that accept additional parameters.
type ParamValidator func(str string, params ...string) bool
+
+// InterfaceParamValidator is a wrapper for functions that accept variants parameters for an interface value
+type InterfaceParamValidator func(in interface{}, params ...string) bool
type tagOptionsMap map[string]tagOption
func (t tagOptionsMap) orderedKeys() []string {
@@ -46,26 +49,40 @@ type UnsupportedTypeError struct {
// It implements the methods to sort by string.
type stringValues []reflect.Value
+// InterfaceParamTagMap is a map of functions accept variants parameters for an interface value
+var InterfaceParamTagMap = map[string]InterfaceParamValidator{
+ "type": IsType,
+}
+
+// InterfaceParamTagRegexMap maps interface param tags to their respective regexes.
+var InterfaceParamTagRegexMap = map[string]*regexp.Regexp{
+ "type": regexp.MustCompile(`^type\((.*)\)$`),
+}
+
// ParamTagMap is a map of functions accept variants parameters
var ParamTagMap = map[string]ParamValidator{
- "length": ByteLength,
- "range": Range,
- "runelength": RuneLength,
- "stringlength": StringLength,
- "matches": StringMatches,
- "in": isInRaw,
- "rsapub": IsRsaPub,
+ "length": ByteLength,
+ "range": Range,
+ "runelength": RuneLength,
+ "stringlength": StringLength,
+ "matches": StringMatches,
+ "in": IsInRaw,
+ "rsapub": IsRsaPub,
+ "minstringlength": MinStringLength,
+ "maxstringlength": MaxStringLength,
}
// ParamTagRegexMap maps param tags to their respective regexes.
var ParamTagRegexMap = map[string]*regexp.Regexp{
- "range": regexp.MustCompile("^range\\((\\d+)\\|(\\d+)\\)$"),
- "length": regexp.MustCompile("^length\\((\\d+)\\|(\\d+)\\)$"),
- "runelength": regexp.MustCompile("^runelength\\((\\d+)\\|(\\d+)\\)$"),
- "stringlength": regexp.MustCompile("^stringlength\\((\\d+)\\|(\\d+)\\)$"),
- "in": regexp.MustCompile(`^in\((.*)\)`),
- "matches": regexp.MustCompile(`^matches\((.+)\)$`),
- "rsapub": regexp.MustCompile("^rsapub\\((\\d+)\\)$"),
+ "range": regexp.MustCompile("^range\\((\\d+)\\|(\\d+)\\)$"),
+ "length": regexp.MustCompile("^length\\((\\d+)\\|(\\d+)\\)$"),
+ "runelength": regexp.MustCompile("^runelength\\((\\d+)\\|(\\d+)\\)$"),
+ "stringlength": regexp.MustCompile("^stringlength\\((\\d+)\\|(\\d+)\\)$"),
+ "in": regexp.MustCompile(`^in\((.*)\)`),
+ "matches": regexp.MustCompile(`^matches\((.+)\)$`),
+ "rsapub": regexp.MustCompile("^rsapub\\((\\d+)\\)$"),
+ "minstringlength": regexp.MustCompile("^minstringlength\\((\\d+)\\)$"),
+ "maxstringlength": regexp.MustCompile("^maxstringlength\\((\\d+)\\)$"),
}
type customTypeTagMap struct {
@@ -114,6 +131,7 @@ var TagMap = map[string]Validator{
"int": IsInt,
"float": IsFloat,
"null": IsNull,
+ "notnull": IsNotNull,
"uuid": IsUUID,
"uuidv3": IsUUIDv3,
"uuidv4": IsUUIDv4,
@@ -146,6 +164,8 @@ var TagMap = map[string]Validator{
"ISO3166Alpha2": IsISO3166Alpha2,
"ISO3166Alpha3": IsISO3166Alpha3,
"ISO4217": IsISO4217,
+ "IMEI": IsIMEI,
+ "ulid": IsULID,
}
// ISO3166Entry stores country codes
@@ -430,10 +450,10 @@ var ISO4217List = []string{
"PAB", "PEN", "PGK", "PHP", "PKR", "PLN", "PYG",
"QAR",
"RON", "RSD", "RUB", "RWF",
- "SAR", "SBD", "SCR", "SDG", "SEK", "SGD", "SHP", "SLL", "SOS", "SRD", "SSP", "STD", "SVC", "SYP", "SZL",
+ "SAR", "SBD", "SCR", "SDG", "SEK", "SGD", "SHP", "SLL", "SOS", "SRD", "SSP", "STD", "STN", "SVC", "SYP", "SZL",
"THB", "TJS", "TMT", "TND", "TOP", "TRY", "TTD", "TWD", "TZS",
- "UAH", "UGX", "USD", "USN", "UYI", "UYU", "UZS",
- "VEF", "VND", "VUV",
+ "UAH", "UGX", "USD", "USN", "UYI", "UYU", "UYW", "UZS",
+ "VEF", "VES", "VND", "VUV",
"WST",
"XAF", "XAG", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "XSU", "XTS", "XUA", "XXX",
"YER",
diff --git a/constraint/vendor/github.com/asaskevich/govalidator/utils.go b/constraint/vendor/github.com/asaskevich/govalidator/utils.go
index a0b706a74..f4c30f824 100644
--- a/constraint/vendor/github.com/asaskevich/govalidator/utils.go
+++ b/constraint/vendor/github.com/asaskevich/govalidator/utils.go
@@ -12,20 +12,20 @@ import (
"unicode/utf8"
)
-// Contains check if the string contains the substring.
+// Contains checks if the string contains the substring.
func Contains(str, substring string) bool {
return strings.Contains(str, substring)
}
-// Matches check if string matches the pattern (pattern is regular expression)
+// Matches checks if string matches the pattern (pattern is regular expression)
// In case of error return false
func Matches(str, pattern string) bool {
match, _ := regexp.MatchString(pattern, str)
return match
}
-// LeftTrim trim characters from the left-side of the input.
-// If second argument is empty, it's will be remove leading spaces.
+// LeftTrim trims characters from the left side of the input.
+// If second argument is empty, it will remove leading spaces.
func LeftTrim(str, chars string) string {
if chars == "" {
return strings.TrimLeftFunc(str, unicode.IsSpace)
@@ -34,8 +34,8 @@ func LeftTrim(str, chars string) string {
return r.ReplaceAllString(str, "")
}
-// RightTrim trim characters from the right-side of the input.
-// If second argument is empty, it's will be remove spaces.
+// RightTrim trims characters from the right side of the input.
+// If second argument is empty, it will remove trailing spaces.
func RightTrim(str, chars string) string {
if chars == "" {
return strings.TrimRightFunc(str, unicode.IsSpace)
@@ -44,27 +44,27 @@ func RightTrim(str, chars string) string {
return r.ReplaceAllString(str, "")
}
-// Trim trim characters from both sides of the input.
-// If second argument is empty, it's will be remove spaces.
+// Trim trims characters from both sides of the input.
+// If second argument is empty, it will remove spaces.
func Trim(str, chars string) string {
return LeftTrim(RightTrim(str, chars), chars)
}
-// WhiteList remove characters that do not appear in the whitelist.
+// WhiteList removes characters that do not appear in the whitelist.
func WhiteList(str, chars string) string {
pattern := "[^" + chars + "]+"
r, _ := regexp.Compile(pattern)
return r.ReplaceAllString(str, "")
}
-// BlackList remove characters that appear in the blacklist.
+// BlackList removes characters that appear in the blacklist.
func BlackList(str, chars string) string {
pattern := "[" + chars + "]+"
r, _ := regexp.Compile(pattern)
return r.ReplaceAllString(str, "")
}
-// StripLow remove characters with a numerical value < 32 and 127, mostly control characters.
+// StripLow removes characters with a numerical value < 32 and 127, mostly control characters.
// If keep_new_lines is true, newline characters are preserved (\n and \r, hex 0xA and 0xD).
func StripLow(str string, keepNewLines bool) string {
chars := ""
@@ -76,13 +76,13 @@ func StripLow(str string, keepNewLines bool) string {
return BlackList(str, chars)
}
-// ReplacePattern replace regular expression pattern in string
+// ReplacePattern replaces regular expression pattern in string
func ReplacePattern(str, pattern, replace string) string {
r, _ := regexp.Compile(pattern)
return r.ReplaceAllString(str, replace)
}
-// Escape replace <, >, & and " with HTML entities.
+// Escape replaces <, >, & and " with HTML entities.
var Escape = html.EscapeString
func addSegment(inrune, segment []rune) []rune {
@@ -120,7 +120,7 @@ func CamelCaseToUnderscore(str string) string {
return string(output)
}
-// Reverse return reversed string
+// Reverse returns reversed string
func Reverse(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
@@ -129,12 +129,12 @@ func Reverse(s string) string {
return string(r)
}
-// GetLines split string by "\n" and return array of lines
+// GetLines splits string by "\n" and return array of lines
func GetLines(s string) []string {
return strings.Split(s, "\n")
}
-// GetLine return specified line of multiline string
+// GetLine returns specified line of multiline string
func GetLine(s string, index int) (string, error) {
lines := GetLines(s)
if index < 0 || index >= len(lines) {
@@ -143,12 +143,12 @@ func GetLine(s string, index int) (string, error) {
return lines[index], nil
}
-// RemoveTags remove all tags from HTML string
+// RemoveTags removes all tags from HTML string
func RemoveTags(s string) string {
return ReplacePattern(s, "<[^>]*>", "")
}
-// SafeFileName return safe string that can be used in file names
+// SafeFileName returns safe string that can be used in file names
func SafeFileName(str string) string {
name := strings.ToLower(str)
name = path.Clean(path.Base(name))
@@ -210,23 +210,23 @@ func Truncate(str string, length int, ending string) string {
return str
}
-// PadLeft pad left side of string if size of string is less then indicated pad length
+// PadLeft pads left side of a string if size of string is less then indicated pad length
func PadLeft(str string, padStr string, padLen int) string {
return buildPadStr(str, padStr, padLen, true, false)
}
-// PadRight pad right side of string if size of string is less then indicated pad length
+// PadRight pads right side of a string if size of string is less then indicated pad length
func PadRight(str string, padStr string, padLen int) string {
return buildPadStr(str, padStr, padLen, false, true)
}
-// PadBoth pad sides of string if size of string is less then indicated pad length
+// PadBoth pads both sides of a string if size of string is less then indicated pad length
func PadBoth(str string, padStr string, padLen int) string {
return buildPadStr(str, padStr, padLen, true, true)
}
-// PadString either left, right or both sides, not the padding string can be unicode and more then one
-// character
+// PadString either left, right or both sides.
+// Note that padding string can be unicode and more then one character
func buildPadStr(str string, padStr string, padLen int, padLeft bool, padRight bool) string {
// When padded length is less then the current string size
diff --git a/constraint/vendor/github.com/asaskevich/govalidator/validator.go b/constraint/vendor/github.com/asaskevich/govalidator/validator.go
index b18bbcb4c..46ecfc84a 100644
--- a/constraint/vendor/github.com/asaskevich/govalidator/validator.go
+++ b/constraint/vendor/github.com/asaskevich/govalidator/validator.go
@@ -32,7 +32,7 @@ var (
const maxURLRuneCount = 2083
const minURLRuneCount = 3
-const RF3339WithoutZone = "2006-01-02T15:04:05"
+const rfc3339WithoutZone = "2006-01-02T15:04:05"
// SetFieldsRequiredByDefault causes validation to fail when struct fields
// do not include validations or are not explicitly marked as exempt (using `valid:"-"` or `valid:"email,optional"`).
@@ -63,13 +63,13 @@ func SetNilPtrAllowedByRequired(value bool) {
nilPtrAllowedByRequired = value
}
-// IsEmail check if the string is an email.
+// IsEmail checks if the string is an email.
func IsEmail(str string) bool {
// TODO uppercase letters are not supported
return rxEmail.MatchString(str)
}
-// IsExistingEmail check if the string is an email of existing domain
+// IsExistingEmail checks if the string is an email of existing domain
func IsExistingEmail(email string) bool {
if len(email) < 6 || len(email) > 254 {
@@ -84,13 +84,13 @@ func IsExistingEmail(email string) bool {
if len(user) > 64 {
return false
}
- if userDotRegexp.MatchString(user) || !userRegexp.MatchString(user) || !hostRegexp.MatchString(host) {
- return false
- }
switch host {
case "localhost", "example.com":
return true
}
+ if userDotRegexp.MatchString(user) || !userRegexp.MatchString(user) || !hostRegexp.MatchString(host) {
+ return false
+ }
if _, err := net.LookupMX(host); err != nil {
if _, err := net.LookupIP(host); err != nil {
return false
@@ -100,7 +100,7 @@ func IsExistingEmail(email string) bool {
return true
}
-// IsURL check if the string is an URL.
+// IsURL checks if the string is an URL.
func IsURL(str string) bool {
if str == "" || utf8.RuneCountInString(str) >= maxURLRuneCount || len(str) <= minURLRuneCount || strings.HasPrefix(str, ".") {
return false
@@ -124,7 +124,7 @@ func IsURL(str string) bool {
return rxURL.MatchString(str)
}
-// IsRequestURL check if the string rawurl, assuming
+// IsRequestURL checks if the string rawurl, assuming
// it was received in an HTTP request, is a valid
// URL confirm to RFC 3986
func IsRequestURL(rawurl string) bool {
@@ -138,7 +138,7 @@ func IsRequestURL(rawurl string) bool {
return true
}
-// IsRequestURI check if the string rawurl, assuming
+// IsRequestURI checks if the string rawurl, assuming
// it was received in an HTTP request, is an
// absolute URI or an absolute path.
func IsRequestURI(rawurl string) bool {
@@ -146,7 +146,7 @@ func IsRequestURI(rawurl string) bool {
return err == nil
}
-// IsAlpha check if the string contains only letters (a-zA-Z). Empty string is valid.
+// IsAlpha checks if the string contains only letters (a-zA-Z). Empty string is valid.
func IsAlpha(str string) bool {
if IsNull(str) {
return true
@@ -154,7 +154,7 @@ func IsAlpha(str string) bool {
return rxAlpha.MatchString(str)
}
-//IsUTFLetter check if the string contains only unicode letter characters.
+//IsUTFLetter checks if the string contains only unicode letter characters.
//Similar to IsAlpha but for all languages. Empty string is valid.
func IsUTFLetter(str string) bool {
if IsNull(str) {
@@ -170,7 +170,7 @@ func IsUTFLetter(str string) bool {
}
-// IsAlphanumeric check if the string contains only letters and numbers. Empty string is valid.
+// IsAlphanumeric checks if the string contains only letters and numbers. Empty string is valid.
func IsAlphanumeric(str string) bool {
if IsNull(str) {
return true
@@ -178,7 +178,7 @@ func IsAlphanumeric(str string) bool {
return rxAlphanumeric.MatchString(str)
}
-// IsUTFLetterNumeric check if the string contains only unicode letters and numbers. Empty string is valid.
+// IsUTFLetterNumeric checks if the string contains only unicode letters and numbers. Empty string is valid.
func IsUTFLetterNumeric(str string) bool {
if IsNull(str) {
return true
@@ -192,7 +192,7 @@ func IsUTFLetterNumeric(str string) bool {
}
-// IsNumeric check if the string contains only numbers. Empty string is valid.
+// IsNumeric checks if the string contains only numbers. Empty string is valid.
func IsNumeric(str string) bool {
if IsNull(str) {
return true
@@ -200,7 +200,7 @@ func IsNumeric(str string) bool {
return rxNumeric.MatchString(str)
}
-// IsUTFNumeric check if the string contains only unicode numbers of any kind.
+// IsUTFNumeric checks if the string contains only unicode numbers of any kind.
// Numbers can be 0-9 but also Fractions ¾,Roman Ⅸ and Hangzhou 〩. Empty string is valid.
func IsUTFNumeric(str string) bool {
if IsNull(str) {
@@ -222,7 +222,7 @@ func IsUTFNumeric(str string) bool {
}
-// IsUTFDigit check if the string contains only unicode radix-10 decimal digits. Empty string is valid.
+// IsUTFDigit checks if the string contains only unicode radix-10 decimal digits. Empty string is valid.
func IsUTFDigit(str string) bool {
if IsNull(str) {
return true
@@ -243,22 +243,22 @@ func IsUTFDigit(str string) bool {
}
-// IsHexadecimal check if the string is a hexadecimal number.
+// IsHexadecimal checks if the string is a hexadecimal number.
func IsHexadecimal(str string) bool {
return rxHexadecimal.MatchString(str)
}
-// IsHexcolor check if the string is a hexadecimal color.
+// IsHexcolor checks if the string is a hexadecimal color.
func IsHexcolor(str string) bool {
return rxHexcolor.MatchString(str)
}
-// IsRGBcolor check if the string is a valid RGB color in form rgb(RRR, GGG, BBB).
+// IsRGBcolor checks if the string is a valid RGB color in form rgb(RRR, GGG, BBB).
func IsRGBcolor(str string) bool {
return rxRGBcolor.MatchString(str)
}
-// IsLowerCase check if the string is lowercase. Empty string is valid.
+// IsLowerCase checks if the string is lowercase. Empty string is valid.
func IsLowerCase(str string) bool {
if IsNull(str) {
return true
@@ -266,7 +266,7 @@ func IsLowerCase(str string) bool {
return str == strings.ToLower(str)
}
-// IsUpperCase check if the string is uppercase. Empty string is valid.
+// IsUpperCase checks if the string is uppercase. Empty string is valid.
func IsUpperCase(str string) bool {
if IsNull(str) {
return true
@@ -274,7 +274,7 @@ func IsUpperCase(str string) bool {
return str == strings.ToUpper(str)
}
-// HasLowerCase check if the string contains at least 1 lowercase. Empty string is valid.
+// HasLowerCase checks if the string contains at least 1 lowercase. Empty string is valid.
func HasLowerCase(str string) bool {
if IsNull(str) {
return true
@@ -282,7 +282,7 @@ func HasLowerCase(str string) bool {
return rxHasLowerCase.MatchString(str)
}
-// HasUpperCase check if the string contians as least 1 uppercase. Empty string is valid.
+// HasUpperCase checks if the string contains as least 1 uppercase. Empty string is valid.
func HasUpperCase(str string) bool {
if IsNull(str) {
return true
@@ -290,7 +290,7 @@ func HasUpperCase(str string) bool {
return rxHasUpperCase.MatchString(str)
}
-// IsInt check if the string is an integer. Empty string is valid.
+// IsInt checks if the string is an integer. Empty string is valid.
func IsInt(str string) bool {
if IsNull(str) {
return true
@@ -298,12 +298,12 @@ func IsInt(str string) bool {
return rxInt.MatchString(str)
}
-// IsFloat check if the string is a float.
+// IsFloat checks if the string is a float.
func IsFloat(str string) bool {
return str != "" && rxFloat.MatchString(str)
}
-// IsDivisibleBy check if the string is a number that's divisible by another.
+// IsDivisibleBy checks if the string is a number that's divisible by another.
// If second argument is not valid integer or zero, it's return false.
// Otherwise, if first argument is not valid integer or zero, it's return true (Invalid string converts to zero).
func IsDivisibleBy(str, num string) bool {
@@ -316,49 +316,141 @@ func IsDivisibleBy(str, num string) bool {
return (p == 0) || (p%q == 0)
}
-// IsNull check if the string is null.
+// IsNull checks if the string is null.
func IsNull(str string) bool {
return len(str) == 0
}
+// IsNotNull checks if the string is not null.
+func IsNotNull(str string) bool {
+ return !IsNull(str)
+}
+
// HasWhitespaceOnly checks the string only contains whitespace
func HasWhitespaceOnly(str string) bool {
- return len(str) > 0 && rxHasWhitespaceOnly.MatchString(str)
+ return len(str) > 0 && rxHasWhitespaceOnly.MatchString(str)
}
// HasWhitespace checks if the string contains any whitespace
func HasWhitespace(str string) bool {
- return len(str) > 0 && rxHasWhitespace.MatchString(str)
+ return len(str) > 0 && rxHasWhitespace.MatchString(str)
}
-// IsByteLength check if the string's length (in bytes) falls in a range.
+// IsByteLength checks if the string's length (in bytes) falls in a range.
func IsByteLength(str string, min, max int) bool {
return len(str) >= min && len(str) <= max
}
-// IsUUIDv3 check if the string is a UUID version 3.
+// IsUUIDv3 checks if the string is a UUID version 3.
func IsUUIDv3(str string) bool {
return rxUUID3.MatchString(str)
}
-// IsUUIDv4 check if the string is a UUID version 4.
+// IsUUIDv4 checks if the string is a UUID version 4.
func IsUUIDv4(str string) bool {
return rxUUID4.MatchString(str)
}
-// IsUUIDv5 check if the string is a UUID version 5.
+// IsUUIDv5 checks if the string is a UUID version 5.
func IsUUIDv5(str string) bool {
return rxUUID5.MatchString(str)
}
-// IsUUID check if the string is a UUID (version 3, 4 or 5).
+// IsUUID checks if the string is a UUID (version 3, 4 or 5).
func IsUUID(str string) bool {
return rxUUID.MatchString(str)
}
-// IsCreditCard check if the string is a credit card.
+// Byte to index table for O(1) lookups when unmarshaling.
+// We use 0xFF as sentinel value for invalid indexes.
+var ulidDec = [...]byte{
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
+ 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
+ 0x0F, 0x10, 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14, 0x15, 0xFF,
+ 0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C, 0x1D, 0x1E,
+ 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C,
+ 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14,
+ 0x15, 0xFF, 0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C,
+ 0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+}
+
+// EncodedSize is the length of a text encoded ULID.
+const ulidEncodedSize = 26
+
+// IsULID checks if the string is a ULID.
+//
+// Implementation got from:
+// https://github.com/oklog/ulid (Apache-2.0 License)
+//
+func IsULID(str string) bool {
+ // Check if a base32 encoded ULID is the right length.
+ if len(str) != ulidEncodedSize {
+ return false
+ }
+
+ // Check if all the characters in a base32 encoded ULID are part of the
+ // expected base32 character set.
+ if ulidDec[str[0]] == 0xFF ||
+ ulidDec[str[1]] == 0xFF ||
+ ulidDec[str[2]] == 0xFF ||
+ ulidDec[str[3]] == 0xFF ||
+ ulidDec[str[4]] == 0xFF ||
+ ulidDec[str[5]] == 0xFF ||
+ ulidDec[str[6]] == 0xFF ||
+ ulidDec[str[7]] == 0xFF ||
+ ulidDec[str[8]] == 0xFF ||
+ ulidDec[str[9]] == 0xFF ||
+ ulidDec[str[10]] == 0xFF ||
+ ulidDec[str[11]] == 0xFF ||
+ ulidDec[str[12]] == 0xFF ||
+ ulidDec[str[13]] == 0xFF ||
+ ulidDec[str[14]] == 0xFF ||
+ ulidDec[str[15]] == 0xFF ||
+ ulidDec[str[16]] == 0xFF ||
+ ulidDec[str[17]] == 0xFF ||
+ ulidDec[str[18]] == 0xFF ||
+ ulidDec[str[19]] == 0xFF ||
+ ulidDec[str[20]] == 0xFF ||
+ ulidDec[str[21]] == 0xFF ||
+ ulidDec[str[22]] == 0xFF ||
+ ulidDec[str[23]] == 0xFF ||
+ ulidDec[str[24]] == 0xFF ||
+ ulidDec[str[25]] == 0xFF {
+ return false
+ }
+
+ // Check if the first character in a base32 encoded ULID will overflow. This
+ // happens because the base32 representation encodes 130 bits, while the
+ // ULID is only 128 bits.
+ //
+ // See https://github.com/oklog/ulid/issues/9 for details.
+ if str[0] > '7' {
+ return false
+ }
+ return true
+}
+
+// IsCreditCard checks if the string is a credit card.
func IsCreditCard(str string) bool {
- sanitized := notNumberRegexp.ReplaceAllString(str, "")
+ sanitized := whiteSpacesAndMinus.ReplaceAllString(str, "")
if !rxCreditCard.MatchString(sanitized) {
return false
}
@@ -372,7 +464,7 @@ func IsCreditCard(str string) bool {
if shouldDouble {
tmpNum *= 2
if tmpNum >= 10 {
- sum += ((tmpNum % 10) + 1)
+ sum += (tmpNum % 10) + 1
} else {
sum += tmpNum
}
@@ -385,18 +477,18 @@ func IsCreditCard(str string) bool {
return sum%10 == 0
}
-// IsISBN10 check if the string is an ISBN version 10.
+// IsISBN10 checks if the string is an ISBN version 10.
func IsISBN10(str string) bool {
return IsISBN(str, 10)
}
-// IsISBN13 check if the string is an ISBN version 13.
+// IsISBN13 checks if the string is an ISBN version 13.
func IsISBN13(str string) bool {
return IsISBN(str, 13)
}
-// IsISBN check if the string is an ISBN (version 10 or 13).
-// If version value is not equal to 10 or 13, it will be check both variants.
+// IsISBN checks if the string is an ISBN (version 10 or 13).
+// If version value is not equal to 10 or 13, it will be checks both variants.
func IsISBN(str string, version int) bool {
sanitized := whiteSpacesAndMinus.ReplaceAllString(str, "")
var checksum int32
@@ -430,13 +522,13 @@ func IsISBN(str string, version int) bool {
return IsISBN(str, 10) || IsISBN(str, 13)
}
-// IsJSON check if the string is valid JSON (note: uses json.Unmarshal).
+// IsJSON checks if the string is valid JSON (note: uses json.Unmarshal).
func IsJSON(str string) bool {
var js json.RawMessage
return json.Unmarshal([]byte(str), &js) == nil
}
-// IsMultibyte check if the string contains one or more multibyte chars. Empty string is valid.
+// IsMultibyte checks if the string contains one or more multibyte chars. Empty string is valid.
func IsMultibyte(str string) bool {
if IsNull(str) {
return true
@@ -444,7 +536,7 @@ func IsMultibyte(str string) bool {
return rxMultibyte.MatchString(str)
}
-// IsASCII check if the string contains ASCII chars only. Empty string is valid.
+// IsASCII checks if the string contains ASCII chars only. Empty string is valid.
func IsASCII(str string) bool {
if IsNull(str) {
return true
@@ -452,7 +544,7 @@ func IsASCII(str string) bool {
return rxASCII.MatchString(str)
}
-// IsPrintableASCII check if the string contains printable ASCII chars only. Empty string is valid.
+// IsPrintableASCII checks if the string contains printable ASCII chars only. Empty string is valid.
func IsPrintableASCII(str string) bool {
if IsNull(str) {
return true
@@ -460,7 +552,7 @@ func IsPrintableASCII(str string) bool {
return rxPrintableASCII.MatchString(str)
}
-// IsFullWidth check if the string contains any full-width chars. Empty string is valid.
+// IsFullWidth checks if the string contains any full-width chars. Empty string is valid.
func IsFullWidth(str string) bool {
if IsNull(str) {
return true
@@ -468,7 +560,7 @@ func IsFullWidth(str string) bool {
return rxFullWidth.MatchString(str)
}
-// IsHalfWidth check if the string contains any half-width chars. Empty string is valid.
+// IsHalfWidth checks if the string contains any half-width chars. Empty string is valid.
func IsHalfWidth(str string) bool {
if IsNull(str) {
return true
@@ -476,7 +568,7 @@ func IsHalfWidth(str string) bool {
return rxHalfWidth.MatchString(str)
}
-// IsVariableWidth check if the string contains a mixture of full and half-width chars. Empty string is valid.
+// IsVariableWidth checks if the string contains a mixture of full and half-width chars. Empty string is valid.
func IsVariableWidth(str string) bool {
if IsNull(str) {
return true
@@ -484,12 +576,12 @@ func IsVariableWidth(str string) bool {
return rxHalfWidth.MatchString(str) && rxFullWidth.MatchString(str)
}
-// IsBase64 check if a string is base64 encoded.
+// IsBase64 checks if a string is base64 encoded.
func IsBase64(str string) bool {
return rxBase64.MatchString(str)
}
-// IsFilePath check is a string is Win or Unix file path and returns it's type.
+// IsFilePath checks is a string is Win or Unix file path and returns it's type.
func IsFilePath(str string) (bool, int) {
if rxWinPath.MatchString(str) {
//check windows path limit see:
@@ -504,6 +596,27 @@ func IsFilePath(str string) (bool, int) {
return false, Unknown
}
+//IsWinFilePath checks both relative & absolute paths in Windows
+func IsWinFilePath(str string) bool {
+ if rxARWinPath.MatchString(str) {
+ //check windows path limit see:
+ // http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath
+ if len(str[3:]) > 32767 {
+ return false
+ }
+ return true
+ }
+ return false
+}
+
+//IsUnixFilePath checks both relative & absolute paths in Unix
+func IsUnixFilePath(str string) bool {
+ if rxARUnixPath.MatchString(str) {
+ return true
+ }
+ return false
+}
+
// IsDataURI checks if a string is base64 encoded data URI such as an image
func IsDataURI(str string) bool {
dataURI := strings.Split(str, ",")
@@ -513,6 +626,11 @@ func IsDataURI(str string) bool {
return IsBase64(dataURI[1])
}
+// IsMagnetURI checks if a string is valid magnet URI
+func IsMagnetURI(str string) bool {
+ return rxMagnetURI.MatchString(str)
+}
+
// IsISO3166Alpha2 checks if a string is valid two-letter country code
func IsISO3166Alpha2(str string) bool {
for _, entry := range ISO3166List {
@@ -565,7 +683,7 @@ func IsDNSName(str string) bool {
// IsHash checks if a string is a hash of type algorithm.
// Algorithm is one of ['md4', 'md5', 'sha1', 'sha256', 'sha384', 'sha512', 'ripemd128', 'ripemd160', 'tiger128', 'tiger160', 'tiger192', 'crc32', 'crc32b']
func IsHash(str string, algorithm string) bool {
- len := "0"
+ var len string
algo := strings.ToLower(algorithm)
if algo == "crc32" || algo == "crc32b" {
@@ -576,11 +694,13 @@ func IsHash(str string, algorithm string) bool {
len = "40"
} else if algo == "tiger192" {
len = "48"
- } else if algo == "sha256" {
+ } else if algo == "sha3-224" {
+ len = "56"
+ } else if algo == "sha256" || algo == "sha3-256" {
len = "64"
- } else if algo == "sha384" {
+ } else if algo == "sha384" || algo == "sha3-384" {
len = "96"
- } else if algo == "sha512" {
+ } else if algo == "sha512" || algo == "sha3-512" {
len = "128"
} else {
return false
@@ -589,9 +709,93 @@ func IsHash(str string, algorithm string) bool {
return Matches(str, "^[a-f0-9]{"+len+"}$")
}
+// IsSHA3224 checks is a string is a SHA3-224 hash. Alias for `IsHash(str, "sha3-224")`
+func IsSHA3224(str string) bool {
+ return IsHash(str, "sha3-224")
+}
+
+// IsSHA3256 checks is a string is a SHA3-256 hash. Alias for `IsHash(str, "sha3-256")`
+func IsSHA3256(str string) bool {
+ return IsHash(str, "sha3-256")
+}
+
+// IsSHA3384 checks is a string is a SHA3-384 hash. Alias for `IsHash(str, "sha3-384")`
+func IsSHA3384(str string) bool {
+ return IsHash(str, "sha3-384")
+}
+
+// IsSHA3512 checks is a string is a SHA3-512 hash. Alias for `IsHash(str, "sha3-512")`
+func IsSHA3512(str string) bool {
+ return IsHash(str, "sha3-512")
+}
+
+// IsSHA512 checks is a string is a SHA512 hash. Alias for `IsHash(str, "sha512")`
+func IsSHA512(str string) bool {
+ return IsHash(str, "sha512")
+}
+
+// IsSHA384 checks is a string is a SHA384 hash. Alias for `IsHash(str, "sha384")`
+func IsSHA384(str string) bool {
+ return IsHash(str, "sha384")
+}
+
+// IsSHA256 checks is a string is a SHA256 hash. Alias for `IsHash(str, "sha256")`
+func IsSHA256(str string) bool {
+ return IsHash(str, "sha256")
+}
+
+// IsTiger192 checks is a string is a Tiger192 hash. Alias for `IsHash(str, "tiger192")`
+func IsTiger192(str string) bool {
+ return IsHash(str, "tiger192")
+}
+
+// IsTiger160 checks is a string is a Tiger160 hash. Alias for `IsHash(str, "tiger160")`
+func IsTiger160(str string) bool {
+ return IsHash(str, "tiger160")
+}
+
+// IsRipeMD160 checks is a string is a RipeMD160 hash. Alias for `IsHash(str, "ripemd160")`
+func IsRipeMD160(str string) bool {
+ return IsHash(str, "ripemd160")
+}
+
+// IsSHA1 checks is a string is a SHA-1 hash. Alias for `IsHash(str, "sha1")`
+func IsSHA1(str string) bool {
+ return IsHash(str, "sha1")
+}
+
+// IsTiger128 checks is a string is a Tiger128 hash. Alias for `IsHash(str, "tiger128")`
+func IsTiger128(str string) bool {
+ return IsHash(str, "tiger128")
+}
+
+// IsRipeMD128 checks is a string is a RipeMD128 hash. Alias for `IsHash(str, "ripemd128")`
+func IsRipeMD128(str string) bool {
+ return IsHash(str, "ripemd128")
+}
+
+// IsCRC32 checks is a string is a CRC32 hash. Alias for `IsHash(str, "crc32")`
+func IsCRC32(str string) bool {
+ return IsHash(str, "crc32")
+}
+
+// IsCRC32b checks is a string is a CRC32b hash. Alias for `IsHash(str, "crc32b")`
+func IsCRC32b(str string) bool {
+ return IsHash(str, "crc32b")
+}
+
+// IsMD5 checks is a string is a MD5 hash. Alias for `IsHash(str, "md5")`
+func IsMD5(str string) bool {
+ return IsHash(str, "md5")
+}
+
+// IsMD4 checks is a string is a MD4 hash. Alias for `IsHash(str, "md4")`
+func IsMD4(str string) bool {
+ return IsHash(str, "md4")
+}
+
// IsDialString validates the given string for usage with the various Dial() functions
func IsDialString(str string) bool {
-
if h, p, err := net.SplitHostPort(str); err == nil && h != "" && p != "" && (IsDNSName(h) || IsIP(h)) && IsPort(p) {
return true
}
@@ -599,7 +803,7 @@ func IsDialString(str string) bool {
return false
}
-// IsIP checks if a string is either IP version 4 or 6.
+// IsIP checks if a string is either IP version 4 or 6. Alias for `net.ParseIP`
func IsIP(str string) bool {
return net.ParseIP(str) != nil
}
@@ -612,25 +816,25 @@ func IsPort(str string) bool {
return false
}
-// IsIPv4 check if the string is an IP version 4.
+// IsIPv4 checks if the string is an IP version 4.
func IsIPv4(str string) bool {
ip := net.ParseIP(str)
return ip != nil && strings.Contains(str, ".")
}
-// IsIPv6 check if the string is an IP version 6.
+// IsIPv6 checks if the string is an IP version 6.
func IsIPv6(str string) bool {
ip := net.ParseIP(str)
return ip != nil && strings.Contains(str, ":")
}
-// IsCIDR check if the string is an valid CIDR notiation (IPV4 & IPV6)
+// IsCIDR checks if the string is an valid CIDR notiation (IPV4 & IPV6)
func IsCIDR(str string) bool {
_, _, err := net.ParseCIDR(str)
return err == nil
}
-// IsMAC check if a string is valid MAC address.
+// IsMAC checks if a string is valid MAC address.
// Possible MAC formats:
// 01:23:45:67:89:ab
// 01:23:45:67:89:ab:cd:ef
@@ -648,22 +852,70 @@ func IsHost(str string) bool {
return IsIP(str) || IsDNSName(str)
}
-// IsMongoID check if the string is a valid hex-encoded representation of a MongoDB ObjectId.
+// IsMongoID checks if the string is a valid hex-encoded representation of a MongoDB ObjectId.
func IsMongoID(str string) bool {
return rxHexadecimal.MatchString(str) && (len(str) == 24)
}
-// IsLatitude check if a string is valid latitude.
+// IsLatitude checks if a string is valid latitude.
func IsLatitude(str string) bool {
return rxLatitude.MatchString(str)
}
-// IsLongitude check if a string is valid longitude.
+// IsLongitude checks if a string is valid longitude.
func IsLongitude(str string) bool {
return rxLongitude.MatchString(str)
}
-// IsRsaPublicKey check if a string is valid public key with provided length
+// IsIMEI checks if a string is valid IMEI
+func IsIMEI(str string) bool {
+ return rxIMEI.MatchString(str)
+}
+
+// IsIMSI checks if a string is valid IMSI
+func IsIMSI(str string) bool {
+ if !rxIMSI.MatchString(str) {
+ return false
+ }
+
+ mcc, err := strconv.ParseInt(str[0:3], 10, 32)
+ if err != nil {
+ return false
+ }
+
+ switch mcc {
+ case 202, 204, 206, 208, 212, 213, 214, 216, 218, 219:
+ case 220, 221, 222, 226, 228, 230, 231, 232, 234, 235:
+ case 238, 240, 242, 244, 246, 247, 248, 250, 255, 257:
+ case 259, 260, 262, 266, 268, 270, 272, 274, 276, 278:
+ case 280, 282, 283, 284, 286, 288, 289, 290, 292, 293:
+ case 294, 295, 297, 302, 308, 310, 311, 312, 313, 314:
+ case 315, 316, 330, 332, 334, 338, 340, 342, 344, 346:
+ case 348, 350, 352, 354, 356, 358, 360, 362, 363, 364:
+ case 365, 366, 368, 370, 372, 374, 376, 400, 401, 402:
+ case 404, 405, 406, 410, 412, 413, 414, 415, 416, 417:
+ case 418, 419, 420, 421, 422, 424, 425, 426, 427, 428:
+ case 429, 430, 431, 432, 434, 436, 437, 438, 440, 441:
+ case 450, 452, 454, 455, 456, 457, 460, 461, 466, 467:
+ case 470, 472, 502, 505, 510, 514, 515, 520, 525, 528:
+ case 530, 536, 537, 539, 540, 541, 542, 543, 544, 545:
+ case 546, 547, 548, 549, 550, 551, 552, 553, 554, 555:
+ case 602, 603, 604, 605, 606, 607, 608, 609, 610, 611:
+ case 612, 613, 614, 615, 616, 617, 618, 619, 620, 621:
+ case 622, 623, 624, 625, 626, 627, 628, 629, 630, 631:
+ case 632, 633, 634, 635, 636, 637, 638, 639, 640, 641:
+ case 642, 643, 645, 646, 647, 648, 649, 650, 651, 652:
+ case 653, 654, 655, 657, 658, 659, 702, 704, 706, 708:
+ case 710, 712, 714, 716, 722, 724, 730, 732, 734, 736:
+ case 738, 740, 742, 744, 746, 748, 750, 995:
+ return true
+ default:
+ return false
+ }
+ return true
+}
+
+// IsRsaPublicKey checks if a string is valid public key with provided length
func IsRsaPublicKey(str string, keylen int) bool {
bb := bytes.NewBufferString(str)
pemBytes, err := ioutil.ReadAll(bb)
@@ -697,6 +949,14 @@ func IsRsaPublicKey(str string, keylen int) bool {
return bitlen == int(keylen)
}
+// IsRegex checks if a give string is a valid regex with RE2 syntax or not
+func IsRegex(str string) bool {
+ if _, err := regexp.Compile(str); err == nil {
+ return true
+ }
+ return false
+}
+
func toJSONName(tag string) string {
if tag == "" {
return ""
@@ -717,7 +977,7 @@ func toJSONName(tag string) string {
return name
}
-func PrependPathToErrors(err error, path string) error {
+func prependPathToErrors(err error, path string) error {
switch err2 := err.(type) {
case Error:
err2.Path = append([]string{path}, err2.Path...)
@@ -725,16 +985,125 @@ func PrependPathToErrors(err error, path string) error {
case Errors:
errors := err2.Errors()
for i, err3 := range errors {
- errors[i] = PrependPathToErrors(err3, path)
+ errors[i] = prependPathToErrors(err3, path)
}
return err2
}
- fmt.Println(err)
return err
}
+// ValidateArray performs validation according to condition iterator that validates every element of the array
+func ValidateArray(array []interface{}, iterator ConditionIterator) bool {
+ return Every(array, iterator)
+}
+
+// ValidateMap use validation map for fields.
+// result will be equal to `false` if there are any errors.
+// s is the map containing the data to be validated.
+// m is the validation map in the form:
+// map[string]interface{}{"name":"required,alpha","address":map[string]interface{}{"line1":"required,alphanum"}}
+func ValidateMap(s map[string]interface{}, m map[string]interface{}) (bool, error) {
+ if s == nil {
+ return true, nil
+ }
+ result := true
+ var err error
+ var errs Errors
+ var index int
+ val := reflect.ValueOf(s)
+ for key, value := range s {
+ presentResult := true
+ validator, ok := m[key]
+ if !ok {
+ presentResult = false
+ var err error
+ err = fmt.Errorf("all map keys has to be present in the validation map; got %s", key)
+ err = prependPathToErrors(err, key)
+ errs = append(errs, err)
+ }
+ valueField := reflect.ValueOf(value)
+ mapResult := true
+ typeResult := true
+ structResult := true
+ resultField := true
+ switch subValidator := validator.(type) {
+ case map[string]interface{}:
+ var err error
+ if v, ok := value.(map[string]interface{}); !ok {
+ mapResult = false
+ err = fmt.Errorf("map validator has to be for the map type only; got %s", valueField.Type().String())
+ err = prependPathToErrors(err, key)
+ errs = append(errs, err)
+ } else {
+ mapResult, err = ValidateMap(v, subValidator)
+ if err != nil {
+ mapResult = false
+ err = prependPathToErrors(err, key)
+ errs = append(errs, err)
+ }
+ }
+ case string:
+ if (valueField.Kind() == reflect.Struct ||
+ (valueField.Kind() == reflect.Ptr && valueField.Elem().Kind() == reflect.Struct)) &&
+ subValidator != "-" {
+ var err error
+ structResult, err = ValidateStruct(valueField.Interface())
+ if err != nil {
+ err = prependPathToErrors(err, key)
+ errs = append(errs, err)
+ }
+ }
+ resultField, err = typeCheck(valueField, reflect.StructField{
+ Name: key,
+ PkgPath: "",
+ Type: val.Type(),
+ Tag: reflect.StructTag(fmt.Sprintf("%s:%q", tagName, subValidator)),
+ Offset: 0,
+ Index: []int{index},
+ Anonymous: false,
+ }, val, nil)
+ if err != nil {
+ errs = append(errs, err)
+ }
+ case nil:
+ // already handlerd when checked before
+ default:
+ typeResult = false
+ err = fmt.Errorf("map validator has to be either map[string]interface{} or string; got %s", valueField.Type().String())
+ err = prependPathToErrors(err, key)
+ errs = append(errs, err)
+ }
+ result = result && presentResult && typeResult && resultField && structResult && mapResult
+ index++
+ }
+ // checks required keys
+ requiredResult := true
+ for key, value := range m {
+ if schema, ok := value.(string); ok {
+ tags := parseTagIntoMap(schema)
+ if required, ok := tags["required"]; ok {
+ if _, ok := s[key]; !ok {
+ requiredResult = false
+ if required.customErrorMessage != "" {
+ err = Error{key, fmt.Errorf(required.customErrorMessage), true, "required", []string{}}
+ } else {
+ err = Error{key, fmt.Errorf("required field missing"), false, "required", []string{}}
+ }
+ errs = append(errs, err)
+ }
+ }
+ }
+ }
+
+ if len(errs) > 0 {
+ err = errs
+ }
+ return result && requiredResult, err
+}
+
// ValidateStruct use tags for fields.
// result will be equal to `false` if there are any errors.
+// todo currently there is no guarantee that errors will be returned in predictable order (tests may to fail)
func ValidateStruct(s interface{}) (bool, error) {
if s == nil {
return true, nil
@@ -766,7 +1135,7 @@ func ValidateStruct(s interface{}) (bool, error) {
var err error
structResult, err = ValidateStruct(valueField.Interface())
if err != nil {
- err = PrependPathToErrors(err, typeField.Name)
+ err = prependPathToErrors(err, typeField.Name)
errs = append(errs, err)
}
}
@@ -803,6 +1172,42 @@ func ValidateStruct(s interface{}) (bool, error) {
return result, err
}
+// ValidateStructAsync performs async validation of the struct and returns results through the channels
+func ValidateStructAsync(s interface{}) (<-chan bool, <-chan error) {
+ res := make(chan bool)
+ errors := make(chan error)
+
+ go func() {
+ defer close(res)
+ defer close(errors)
+
+ isValid, isFailed := ValidateStruct(s)
+
+ res <- isValid
+ errors <- isFailed
+ }()
+
+ return res, errors
+}
+
+// ValidateMapAsync performs async validation of the map and returns results through the channels
+func ValidateMapAsync(s map[string]interface{}, m map[string]interface{}) (<-chan bool, <-chan error) {
+ res := make(chan bool)
+ errors := make(chan error)
+
+ go func() {
+ defer close(res)
+ defer close(errors)
+
+ isValid, isFailed := ValidateMap(s, m)
+
+ res <- isValid
+ errors <- isFailed
+ }()
+
+ return res, errors
+}
+
// parseTagIntoMap parses a struct tag `valid:required~Some error message,length(2|3)` into map[string]string{"required": "Some error message", "length(2|3)": ""}
func parseTagIntoMap(tag string) tagOptionsMap {
optionsMap := make(tagOptionsMap)
@@ -851,28 +1256,45 @@ func IsSSN(str string) bool {
return rxSSN.MatchString(str)
}
-// IsSemver check if string is valid semantic version
+// IsSemver checks if string is valid semantic version
func IsSemver(str string) bool {
return rxSemver.MatchString(str)
}
-// IsTime check if string is valid according to given format
+// IsType checks if interface is of some type
+func IsType(v interface{}, params ...string) bool {
+ if len(params) == 1 {
+ typ := params[0]
+ return strings.Replace(reflect.TypeOf(v).String(), " ", "", -1) == strings.Replace(typ, " ", "", -1)
+ }
+ return false
+}
+
+// IsTime checks if string is valid according to given format
func IsTime(str string, format string) bool {
_, err := time.Parse(format, str)
return err == nil
}
-// IsRFC3339 check if string is valid timestamp value according to RFC3339
+// IsUnixTime checks if string is valid unix timestamp value
+func IsUnixTime(str string) bool {
+ if _, err := strconv.Atoi(str); err == nil {
+ return true
+ }
+ return false
+}
+
+// IsRFC3339 checks if string is valid timestamp value according to RFC3339
func IsRFC3339(str string) bool {
return IsTime(str, time.RFC3339)
}
-// IsRFC3339WithoutZone check if string is valid timestamp value according to RFC3339 which excludes the timezone.
+// IsRFC3339WithoutZone checks if string is valid timestamp value according to RFC3339 which excludes the timezone.
func IsRFC3339WithoutZone(str string) bool {
- return IsTime(str, RF3339WithoutZone)
+ return IsTime(str, rfc3339WithoutZone)
}
-// IsISO4217 check if string is valid ISO currency code
+// IsISO4217 checks if string is valid ISO currency code
func IsISO4217(str string) bool {
for _, currency := range ISO4217List {
if str == currency {
@@ -883,7 +1305,7 @@ func IsISO4217(str string) bool {
return false
}
-// ByteLength check string's length
+// ByteLength checks string's length
func ByteLength(str string, params ...string) bool {
if len(params) == 2 {
min, _ := ToInt(params[0])
@@ -894,13 +1316,13 @@ func ByteLength(str string, params ...string) bool {
return false
}
-// RuneLength check string's length
+// RuneLength checks string's length
// Alias for StringLength
func RuneLength(str string, params ...string) bool {
return StringLength(str, params...)
}
-// IsRsaPub check whether string is valid RSA key
+// IsRsaPub checks whether string is valid RSA key
// Alias for IsRsaPublicKey
func IsRsaPub(str string, params ...string) bool {
if len(params) == 1 {
@@ -920,7 +1342,7 @@ func StringMatches(s string, params ...string) bool {
return false
}
-// StringLength check string's length (including multi byte strings)
+// StringLength checks string's length (including multi byte strings)
func StringLength(str string, params ...string) bool {
if len(params) == 2 {
@@ -933,7 +1355,31 @@ func StringLength(str string, params ...string) bool {
return false
}
-// Range check string's length
+// MinStringLength checks string's minimum length (including multi byte strings)
+func MinStringLength(str string, params ...string) bool {
+
+ if len(params) == 1 {
+ strLength := utf8.RuneCountInString(str)
+ min, _ := ToInt(params[0])
+ return strLength >= int(min)
+ }
+
+ return false
+}
+
+// MaxStringLength checks string's maximum length (including multi byte strings)
+func MaxStringLength(str string, params ...string) bool {
+
+ if len(params) == 1 {
+ strLength := utf8.RuneCountInString(str)
+ max, _ := ToInt(params[0])
+ return strLength <= int(max)
+ }
+
+ return false
+}
+
+// Range checks string's length
func Range(str string, params ...string) bool {
if len(params) == 2 {
value, _ := ToFloat(str)
@@ -945,7 +1391,8 @@ func Range(str string, params ...string) bool {
return false
}
-func isInRaw(str string, params ...string) bool {
+// IsInRaw checks if string is in list of allowed values
+func IsInRaw(str string, params ...string) bool {
if len(params) == 1 {
rawParams := params[0]
@@ -957,7 +1404,7 @@ func isInRaw(str string, params ...string) bool {
return false
}
-// IsIn check if string str is a member of the set of strings params
+// IsIn checks if string str is a member of the set of strings params
func IsIn(str string, params ...string) bool {
for _, param := range params {
if str == param {
@@ -995,7 +1442,7 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options
tag := t.Tag.Get(tagName)
- // Check if the field should be ignored
+ // checks if the field should be ignored
switch tag {
case "":
if v.Kind() != reflect.Slice && v.Kind() != reflect.Map {
@@ -1015,7 +1462,7 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options
}
if isEmptyValue(v) {
- // an empty value is not validated, check only required
+ // an empty value is not validated, checks only required
isValid, resultErr = checkRequired(v, t, options)
for key := range options {
delete(options, key)
@@ -1062,26 +1509,65 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options
}()
}
+ for _, validatorSpec := range optionsOrder {
+ validatorStruct := options[validatorSpec]
+ var negate bool
+ validator := validatorSpec
+ customMsgExists := len(validatorStruct.customErrorMessage) > 0
+
+ // checks whether the tag looks like '!something' or 'something'
+ if validator[0] == '!' {
+ validator = validator[1:]
+ negate = true
+ }
+
+ // checks for interface param validators
+ for key, value := range InterfaceParamTagRegexMap {
+ ps := value.FindStringSubmatch(validator)
+ if len(ps) == 0 {
+ continue
+ }
+
+ validatefunc, ok := InterfaceParamTagMap[key]
+ if !ok {
+ continue
+ }
+
+ delete(options, validatorSpec)
+
+ field := fmt.Sprint(v)
+ if result := validatefunc(v.Interface(), ps[1:]...); (!result && !negate) || (result && negate) {
+ if customMsgExists {
+ return false, Error{t.Name, TruncatingErrorf(validatorStruct.customErrorMessage, field, validator), customMsgExists, stripParams(validatorSpec), []string{}}
+ }
+ if negate {
+ return false, Error{t.Name, fmt.Errorf("%s does validate as %s", field, validator), customMsgExists, stripParams(validatorSpec), []string{}}
+ }
+ return false, Error{t.Name, fmt.Errorf("%s does not validate as %s", field, validator), customMsgExists, stripParams(validatorSpec), []string{}}
+ }
+ }
+ }
+
switch v.Kind() {
case reflect.Bool,
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
reflect.Float32, reflect.Float64,
reflect.String:
- // for each tag option check the map of validator functions
+ // for each tag option checks the map of validator functions
for _, validatorSpec := range optionsOrder {
validatorStruct := options[validatorSpec]
var negate bool
validator := validatorSpec
customMsgExists := len(validatorStruct.customErrorMessage) > 0
- // Check whether the tag looks like '!something' or 'something'
+ // checks whether the tag looks like '!something' or 'something'
if validator[0] == '!' {
validator = validator[1:]
negate = true
}
- // Check for param validators
+ // checks for param validators
for key, value := range ParamTagRegexMap {
ps := value.FindStringSubmatch(validator)
if len(ps) == 0 {
@@ -1121,10 +1607,10 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options
delete(options, validatorSpec)
switch v.Kind() {
- case reflect.String,
- reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
- reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
- reflect.Float32, reflect.Float64:
+ case reflect.String,
+ reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+ reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
+ reflect.Float32, reflect.Float64:
field := fmt.Sprint(v) // make value into string, then validate with regex
if result := validatefunc(field); !result && !negate || result && negate {
if customMsgExists {
@@ -1162,7 +1648,7 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options
} else {
resultItem, err = ValidateStruct(v.MapIndex(k).Interface())
if err != nil {
- err = PrependPathToErrors(err, t.Name+"."+sv[i].Interface().(string))
+ err = prependPathToErrors(err, t.Name+"."+sv[i].Interface().(string))
return false, err
}
}
@@ -1182,7 +1668,7 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options
} else {
resultItem, err = ValidateStruct(v.Index(i).Interface())
if err != nil {
- err = PrependPathToErrors(err, t.Name+"."+strconv.Itoa(i))
+ err = prependPathToErrors(err, t.Name+"."+strconv.Itoa(i))
return false, err
}
}
@@ -1196,13 +1682,13 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options
}
return ValidateStruct(v.Interface())
case reflect.Ptr:
- // If the value is a pointer then check its element
+ // If the value is a pointer then checks its element
if v.IsNil() {
return true, nil
}
return typeCheck(v.Elem(), t, o, options)
case reflect.Struct:
- return ValidateStruct(v.Interface())
+ return true, nil
default:
return false, &UnsupportedTypeError{v.Type()}
}
@@ -1212,6 +1698,7 @@ func stripParams(validatorString string) string {
return paramsRegexp.ReplaceAllString(validatorString, "")
}
+// isEmptyValue checks whether value empty or not
func isEmptyValue(v reflect.Value) bool {
switch v.Kind() {
case reflect.String, reflect.Array:
@@ -1252,11 +1739,11 @@ func ErrorsByField(e error) map[string]string {
}
// prototype for ValidateStruct
- switch e.(type) {
+ switch e := e.(type) {
case Error:
- m[e.(Error).Name] = e.(Error).Err.Error()
+ m[e.Name] = e.Err.Error()
case Errors:
- for _, item := range e.(Errors).Errors() {
+ for _, item := range e.Errors() {
n := ErrorsByField(item)
for k, v := range n {
m[k] = v
@@ -1276,3 +1763,7 @@ func (sv stringValues) Len() int { return len(sv) }
func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
func (sv stringValues) get(i int) string { return sv[i].String() }
+
+func IsE164(str string) bool {
+ return rxE164.MatchString(str)
+}
diff --git a/constraint/vendor/github.com/asaskevich/govalidator/wercker.yml b/constraint/vendor/github.com/asaskevich/govalidator/wercker.yml
index cac7a5fcf..bc5f7b086 100644
--- a/constraint/vendor/github.com/asaskevich/govalidator/wercker.yml
+++ b/constraint/vendor/github.com/asaskevich/govalidator/wercker.yml
@@ -12,4 +12,4 @@ build:
- script:
name: go test
code: |
- go test -race ./...
+ go test -race -v ./...
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/BUILD.bazel b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/BUILD.bazel
new file mode 100644
index 000000000..12d32c8f9
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/BUILD.bazel
@@ -0,0 +1,101 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+cc_library(
+ name = "wasmtime",
+ srcs = select({
+ "@io_bazel_rules_go//go/platform:darwin_amd64": ["build/macos-x86_64/libwasmtime.a"],
+ "@io_bazel_rules_go//go/platform:linux_amd64": ["build/linux-x86_64/libwasmtime.a"],
+ "@io_bazel_rules_go//go/platform:windows_amd64": ["build/windows-x86_64/libwasmtime.a"],
+ }),
+ hdrs = glob(["build/include/*.h"]),
+ includes = ["build/include"],
+ visibility = ["//visibility:public"],
+)
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "config.go",
+ "doc.go",
+ "engine.go",
+ "error.go",
+ "exporttype.go",
+ "extern.go",
+ "externtype.go",
+ "ffi.go",
+ "freelist.go",
+ "func.go",
+ "functype.go",
+ "global.go",
+ "globaltype.go",
+ "importtype.go",
+ "instance.go",
+ "instancetype.go",
+ "limits.go",
+ "linker.go",
+ "maybe_gc_no.go",
+ "memory.go",
+ "memorytype.go",
+ "module.go",
+ "moduletype.go",
+ "shims.c",
+ "shims.h",
+ "slab.go",
+ "store.go",
+ "table.go",
+ "tabletype.go",
+ "trap.go",
+ "val.go",
+ "valtype.go",
+ "wasi.go",
+ "wat2wasm.go",
+ ],
+ cdeps = [":wasmtime"], # add wasmtime dep
+ cgo = True,
+ clinkopts = select({
+ "@io_bazel_rules_go//go/platform:windows": [
+ "-luserenv -lole32 -lntdll -lws2_32 -lkernel32 -lbcrypt",
+ ],
+ "//conditions:default": ["-lm -ldl"],
+ }),
+ copts = [
+ "-Ibuild/include",
+ ] + select({
+ "@io_bazel_rules_go//go/platform:windows": [
+ "-DWASM_API_EXTERN= -DWASI_API_EXTERN=",
+ ],
+ "//conditions:default": [],
+ }),
+ importpath = "github.com/bytecodealliance/wasmtime-go",
+ visibility = ["//visibility:public"],
+)
+
+go_test(
+ name = "go_default_test",
+ srcs = [
+ "config_test.go",
+ "doc_test.go",
+ "engine_test.go",
+ "exporttype_test.go",
+ "func_test.go",
+ "functype_test.go",
+ "global_test.go",
+ "globaltype_test.go",
+ "importtype_test.go",
+ "instance_test.go",
+ "linker_test.go",
+ "memorytype_test.go",
+ "module_linking_test.go",
+ "module_test.go",
+ "reftypes_test.go",
+ "slab_test.go",
+ "store_test.go",
+ "table_test.go",
+ "tabletype_test.go",
+ "trap_test.go",
+ "valtype_test.go",
+ "wasi_test.go",
+ "wasm2wat_test.go",
+ ],
+ embed = [":go_default_library"],
+)
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/LICENSE b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/LICENSE
new file mode 100644
index 000000000..f9d81955f
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/LICENSE
@@ -0,0 +1,220 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+--- LLVM Exceptions to the Apache 2.0 License ----
+
+As an exception, if, as a result of your compiling your source code, portions
+of this Software are embedded into an Object form of such source code, you
+may redistribute such embedded portions in such Object form without complying
+with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+
+In addition, if you combine or link compiled forms of this Software with
+software that is licensed under the GPLv2 ("Combined Software") and if a
+court of competent jurisdiction determines that the patent provision (Section
+3), the indemnity provision (Section 9) or other Section of the License
+conflicts with the conditions of the GPLv2, you may retroactively and
+prospectively choose to deem waived or otherwise exclude such Section(s) of
+the License, but only in their entirety and only with respect to the Combined
+Software.
+
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/README.md b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/README.md
new file mode 100644
index 000000000..f008cf637
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/README.md
@@ -0,0 +1,153 @@
+
+
+## Installation
+
+```sh
+go get -u github.com/bytecodealliance/wasmtime-go@v0.27.0
+```
+
+Be sure to check out the [API documentation][api]!
+
+This Go library uses CGO to consume the C API of the [Wasmtime
+project][wasmtime] which is written in Rust. Precompiled binaries of Wasmtime
+are checked into this repository on tagged releases so you won't have to install
+Wasmtime locally, but it means that this project only works on Linux x86\_64,
+macOS x86\_64 , and Windows x86\_64 currently. Building on other platforms will
+need to arrange to build Wasmtime and use `CGO_*` env vars to compile correctly.
+
+This project has been tested with Go 1.13 or later. It is not recommended to
+use Go 1.14 earlier than Go 1.14.11 on macOS due to a [bug in the Go runtime][bug].
+
+[api]: https://pkg.go.dev/github.com/bytecodealliance/wasmtime-go
+[wasmtime]: https://github.com/bytecodealliance/wasmtime
+[bug]: https://github.com/golang/go/issues/39079
+
+
+If you are a bazel user, add following to your WORKSPACE file:
+
+```
+go_repository(
+ name = "com_github_bytecodealliance_wasmtime_go",
+ importpath = "github.com/bytecodealliance/wasmtime-go",
+ version = "v0.27.0",
+)
+```
+
+## Usage
+
+A "Hello, world!" example of using this package looks like:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/bytecodealliance/wasmtime-go"
+)
+
+func main() {
+ // Almost all operations in wasmtime require a contextual `store`
+ // argument to share, so create that first
+ store := wasmtime.NewStore(wasmtime.NewEngine())
+
+ // Compiling modules requires WebAssembly binary input, but the wasmtime
+ // package also supports converting the WebAssembly text format to the
+ // binary format.
+ wasm, err := wasmtime.Wat2Wasm(`
+ (module
+ (import "" "hello" (func $hello))
+ (func (export "run")
+ (call $hello))
+ )
+ `)
+ check(err)
+
+ // Once we have our binary `wasm` we can compile that into a `*Module`
+ // which represents compiled JIT code.
+ module, err := wasmtime.NewModule(store.Engine, wasm)
+ check(err)
+
+ // Our `hello.wat` file imports one item, so we create that function
+ // here.
+ item := wasmtime.WrapFunc(store, func() {
+ fmt.Println("Hello from Go!")
+ })
+
+ // Next up we instantiate a module which is where we link in all our
+ // imports. We've got one import so we pass that in here.
+ instance, err := wasmtime.NewInstance(store,module, []*wasmtime.Extern{item.AsExtern()})
+ check(err)
+
+ // After we've instantiated we can lookup our `run` function and call
+ // it.
+ run := instance.GetExport("run").Func()
+ _, err = run.Call()
+ check(err)
+}
+
+func check(e error) {
+ if e != nil {
+ panic(e)
+ }
+}
+```
+
+## Contributing
+
+So far this extension has been written by folks who are primarily Rust
+programmers, so it's highly likely that there's some faux pas in terms of Go
+idioms. Feel free to send a PR to help make things more idiomatic if you see
+something!
+
+To work on this extension locally you'll first want to clone the project:
+
+```sh
+$ git clone https://github.com/bytecodealliance/wasmtime-go
+```
+
+Next up you'll want to have a [local Wasmtime build
+available](https://bytecodealliance.github.io/wasmtime/contributing-building.html).
+
+You'll need to build at least the `wasmtime-c-api` crate, which, at the time of
+this writing, would be:
+
+```sh
+$ cargo build -p wasmtime-c-api
+```
+
+Once you've got that you can set up the environment of this library with:
+
+```sh
+$ ./ci/local.sh /path/to/wasmtime
+```
+
+This will create a `build` directory which has the compiled libraries and header
+files. Next up you can run normal commands such as:
+
+```sh
+$ go test
+```
+
+And after that you should be good to go!
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/WORKSPACE b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/WORKSPACE
new file mode 100644
index 000000000..f2dcd75d1
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/WORKSPACE
@@ -0,0 +1,16 @@
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+
+http_archive(
+ name = "io_bazel_rules_go",
+ sha256 = "7904dbecbaffd068651916dce77ff3437679f9d20e1a7956bff43826e7645fcc",
+ urls = [
+ "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.25.1/rules_go-v0.25.1.tar.gz",
+ "https://github.com/bazelbuild/rules_go/releases/download/v0.25.1/rules_go-v0.25.1.tar.gz",
+ ],
+)
+
+load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains")
+
+go_rules_dependencies()
+
+go_register_toolchains(version = "1.16")
\ No newline at end of file
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/include/empty.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/include/empty.go
new file mode 100644
index 000000000..8e731cdfc
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/include/empty.go
@@ -0,0 +1 @@
+package include
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/include/wasi.h b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/include/wasi.h
new file mode 100644
index 000000000..92271496c
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/include/wasi.h
@@ -0,0 +1,213 @@
+/**
+ * \file wasi.h
+ *
+ * C API for WASI
+ */
+
+#ifndef WASI_H
+#define WASI_H
+
+#include "wasm.h"
+
+#ifndef WASI_API_EXTERN
+#ifdef _WIN32
+#define WASI_API_EXTERN __declspec(dllimport)
+#else
+#define WASI_API_EXTERN
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define own
+
+#define WASI_DECLARE_OWN(name) \
+ typedef struct wasi_##name##_t wasi_##name##_t; \
+ WASI_API_EXTERN void wasi_##name##_delete(own wasi_##name##_t*);
+
+/**
+ * \typedef wasi_config_t
+ * \brief Convenience alias for #wasi_config_t
+ *
+ * \struct wasi_config_t
+ * \brief Opaque type used to create a #wasi_instance_t.
+ *
+ * \fn void wasi_config_delete(own wasi_config_t *);
+ * \brief Deletes a configuration object.
+ */
+WASI_DECLARE_OWN(config)
+
+/**
+ * \brief Creates a new empty configuration object.
+ *
+ * The caller is expected to deallocate the returned configuration
+ */
+WASI_API_EXTERN own wasi_config_t* wasi_config_new();
+
+/**
+ * \brief Sets the argv list for this configuration object.
+ *
+ * By default WASI programs have an empty argv list, but this can be used to
+ * explicitly specify what the argv list for the program is.
+ *
+ * The arguments are copied into the `config` object as part of this function
+ * call, so the `argv` pointer only needs to stay alive for this function call.
+ */
+WASI_API_EXTERN void wasi_config_set_argv(wasi_config_t* config, int argc, const char* argv[]);
+
+/**
+ * \brief Indicates that the argv list should be inherited from this process's
+ * argv list.
+ */
+WASI_API_EXTERN void wasi_config_inherit_argv(wasi_config_t* config);
+
+/**
+ * \brief Sets the list of environment variables available to the WASI instance.
+ *
+ * By default WASI programs have a blank environment, but this can be used to
+ * define some environment variables for them.
+ *
+ * It is required that the `names` and `values` lists both have `envc` entries.
+ *
+ * The env vars are copied into the `config` object as part of this function
+ * call, so the `names` and `values` pointers only need to stay alive for this
+ * function call.
+ */
+WASI_API_EXTERN void wasi_config_set_env(wasi_config_t* config, int envc, const char* names[], const char* values[]);
+
+/**
+ * \brief Indicates that the entire environment of the calling process should be
+ * inherited by this WASI configuration.
+ */
+WASI_API_EXTERN void wasi_config_inherit_env(wasi_config_t* config);
+
+/**
+ * \brief Configures standard input to be taken from the specified file.
+ *
+ * By default WASI programs have no stdin, but this configures the specified
+ * file to be used as stdin for this configuration.
+ *
+ * If the stdin location does not exist or it cannot be opened for reading then
+ * `false` is returned. Otherwise `true` is returned.
+ */
+WASI_API_EXTERN bool wasi_config_set_stdin_file(wasi_config_t* config, const char* path);
+
+/**
+ * \brief Configures this process's own stdin stream to be used as stdin for
+ * this WASI configuration.
+ */
+WASI_API_EXTERN void wasi_config_inherit_stdin(wasi_config_t* config);
+
+/**
+ * \brief Configures standard output to be written to the specified file.
+ *
+ * By default WASI programs have no stdout, but this configures the specified
+ * file to be used as stdout.
+ *
+ * If the stdout location could not be opened for writing then `false` is
+ * returned. Otherwise `true` is returned.
+ */
+WASI_API_EXTERN bool wasi_config_set_stdout_file(wasi_config_t* config, const char* path);
+
+/**
+ * \brief Configures this process's own stdout stream to be used as stdout for
+ * this WASI configuration.
+ */
+WASI_API_EXTERN void wasi_config_inherit_stdout(wasi_config_t* config);
+
+/**
+ * \brief Configures standard output to be written to the specified file.
+ *
+ * By default WASI programs have no stderr, but this configures the specified
+ * file to be used as stderr.
+ *
+ * If the stderr location could not be opened for writing then `false` is
+ * returned. Otherwise `true` is returned.
+ */
+WASI_API_EXTERN bool wasi_config_set_stderr_file(wasi_config_t* config, const char* path);
+
+/**
+ * \brief Configures this process's own stderr stream to be used as stderr for
+ * this WASI configuration.
+ */
+WASI_API_EXTERN void wasi_config_inherit_stderr(wasi_config_t* config);
+
+/**
+ * \brief Configures a "preopened directory" to be available to WASI APIs.
+ *
+ * By default WASI programs do not have access to anything on the filesystem.
+ * This API can be used to grant WASI programs access to a directory on the
+ * filesystem, but only that directory (its whole contents but nothing above it).
+ *
+ * The `path` argument here is a path name on the host filesystem, and
+ * `guest_path` is the name by which it will be known in wasm.
+ */
+WASI_API_EXTERN bool wasi_config_preopen_dir(wasi_config_t* config, const char* path, const char* guest_path);
+
+/**
+ * \typedef wasi_instance_t
+ * \brief Convenience alias for #wasi_instance_t
+ *
+ * \struct wasi_instance_t
+ * \brief Opaque type representing a WASI instance.
+ *
+ * \fn void wasi_instance_delete(own wasi_instance_t *);
+ * \brief Deletes an instance object.
+ */
+WASI_DECLARE_OWN(instance)
+
+/**
+ * \brief Creates a new WASI instance from the specified configuration.
+ *
+ * \param store the store which functions will be attached to
+ * \param name the WASI module name that is being instantiated, currently either
+ * `wasi_unstable` or `wasi_snapshot_preview`.
+ * \param config the configuration object which has settings for how WASI APIs
+ * will behave.
+ * \param trap a location, if `NULL` is returned, that contains information
+ * about why instantiation failed.
+ *
+ * \return a #wasi_instance_t owned by the caller on success or `NULL` on
+ * failure.
+ *
+ * Note that this function takes ownership of the `config` argument whether this
+ * function succeeds or not. Ownership of the #wasi_instance_t and #wasm_trap_t
+ * are transferred to the caller.
+ *
+ * With a #wasi_instance_t you'll likely call either
+ * #wasmtime_linker_define_wasi or #wasi_instance_bind_import afterwards.
+ */
+WASI_API_EXTERN own wasi_instance_t* wasi_instance_new(
+ wasm_store_t* store,
+ const char* name,
+ own wasi_config_t* config,
+ own wasm_trap_t** trap
+);
+
+/**
+ * \brief Extracts a matching item for the given import from a #wasi_instance_t.
+ *
+ * \param instance the WASI instance an export is extracted from
+ * \param import the desired import type that is being extracted, typically
+ * acquired from #wasm_module_imports.
+ *
+ * \return a #wasm_extern_t which can be used to satisfy the `import`
+ * requested, or `NULL` if the provided `instance` cannot satisfy `import`.
+ *
+ * This function does not take ownership of its arguments, and the lifetime of
+ * the #wasm_extern_t is tied to the #wasi_instance_t argument.
+ */
+WASI_API_EXTERN const wasm_extern_t* wasi_instance_bind_import(
+ const wasi_instance_t* instance,
+ const wasm_importtype_t* import
+);
+
+#undef own
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // #ifdef WASI_H
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/include/wasm.h b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/include/wasm.h
new file mode 100644
index 000000000..325e618b6
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/include/wasm.h
@@ -0,0 +1,723 @@
+// WebAssembly C API
+
+#ifndef WASM_H
+#define WASM_H
+
+#include
+#include
+#include
+#include
+#include
+
+#ifndef WASM_API_EXTERN
+#ifdef _WIN32
+#define WASM_API_EXTERN __declspec(dllimport)
+#else
+#define WASM_API_EXTERN
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// Auxiliaries
+
+// Machine types
+
+inline void assertions(void) {
+ static_assert(sizeof(float) == sizeof(uint32_t), "incompatible float type");
+ static_assert(sizeof(double) == sizeof(uint64_t), "incompatible double type");
+ static_assert(sizeof(intptr_t) == sizeof(uint32_t) ||
+ sizeof(intptr_t) == sizeof(uint64_t),
+ "incompatible pointer type");
+}
+
+typedef char byte_t;
+typedef float float32_t;
+typedef double float64_t;
+
+
+// Ownership
+
+#define own
+
+// The qualifier `own` is used to indicate ownership of data in this API.
+// It is intended to be interpreted similar to a `const` qualifier:
+//
+// - `own wasm_xxx_t*` owns the pointed-to data
+// - `own wasm_xxx_t` distributes to all fields of a struct or union `xxx`
+// - `own wasm_xxx_vec_t` owns the vector as well as its elements(!)
+// - an `own` function parameter passes ownership from caller to callee
+// - an `own` function result passes ownership from callee to caller
+// - an exception are `own` pointer parameters named `out`, which are copy-back
+// output parameters passing back ownership from callee to caller
+//
+// Own data is created by `wasm_xxx_new` functions and some others.
+// It must be released with the corresponding `wasm_xxx_delete` function.
+//
+// Deleting a reference does not necessarily delete the underlying object,
+// it merely indicates that this owner no longer uses it.
+//
+// For vectors, `const wasm_xxx_vec_t` is used informally to indicate that
+// neither the vector nor its elements should be modified.
+// TODO: introduce proper `wasm_xxx_const_vec_t`?
+
+
+#define WASM_DECLARE_OWN(name) \
+ typedef struct wasm_##name##_t wasm_##name##_t; \
+ \
+ WASM_API_EXTERN void wasm_##name##_delete(own wasm_##name##_t*);
+
+
+// Vectors
+
+#define WASM_DECLARE_VEC(name, ptr_or_none) \
+ typedef struct wasm_##name##_vec_t { \
+ size_t size; \
+ wasm_##name##_t ptr_or_none* data; \
+ } wasm_##name##_vec_t; \
+ \
+ WASM_API_EXTERN void wasm_##name##_vec_new_empty(own wasm_##name##_vec_t* out); \
+ WASM_API_EXTERN void wasm_##name##_vec_new_uninitialized( \
+ own wasm_##name##_vec_t* out, size_t); \
+ WASM_API_EXTERN void wasm_##name##_vec_new( \
+ own wasm_##name##_vec_t* out, \
+ size_t, own wasm_##name##_t ptr_or_none const[]); \
+ WASM_API_EXTERN void wasm_##name##_vec_copy( \
+ own wasm_##name##_vec_t* out, const wasm_##name##_vec_t*); \
+ WASM_API_EXTERN void wasm_##name##_vec_delete(own wasm_##name##_vec_t*);
+
+
+// Byte vectors
+
+typedef byte_t wasm_byte_t;
+WASM_DECLARE_VEC(byte, )
+
+typedef wasm_byte_vec_t wasm_name_t;
+
+#define wasm_name wasm_byte_vec
+#define wasm_name_new wasm_byte_vec_new
+#define wasm_name_new_empty wasm_byte_vec_new_empty
+#define wasm_name_new_new_uninitialized wasm_byte_vec_new_uninitialized
+#define wasm_name_copy wasm_byte_vec_copy
+#define wasm_name_delete wasm_byte_vec_delete
+
+static inline void wasm_name_new_from_string(
+ own wasm_name_t* out, const char* s
+) {
+ wasm_name_new(out, strlen(s), s);
+}
+
+static inline void wasm_name_new_from_string_nt(
+ own wasm_name_t* out, const char* s
+) {
+ wasm_name_new(out, strlen(s) + 1, s);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Runtime Environment
+
+// Configuration
+
+WASM_DECLARE_OWN(config)
+
+WASM_API_EXTERN own wasm_config_t* wasm_config_new(void);
+
+// Embedders may provide custom functions for manipulating configs.
+
+
+// Engine
+
+WASM_DECLARE_OWN(engine)
+
+WASM_API_EXTERN own wasm_engine_t* wasm_engine_new(void);
+WASM_API_EXTERN own wasm_engine_t* wasm_engine_new_with_config(own wasm_config_t*);
+
+
+// Store
+
+WASM_DECLARE_OWN(store)
+
+WASM_API_EXTERN own wasm_store_t* wasm_store_new(wasm_engine_t*);
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Type Representations
+
+// Type attributes
+
+typedef uint8_t wasm_mutability_t;
+enum wasm_mutability_enum {
+ WASM_CONST,
+ WASM_VAR,
+};
+
+typedef struct wasm_limits_t {
+ uint32_t min;
+ uint32_t max;
+} wasm_limits_t;
+
+static const uint32_t wasm_limits_max_default = 0xffffffff;
+
+
+// Generic
+
+#define WASM_DECLARE_TYPE(name) \
+ WASM_DECLARE_OWN(name) \
+ WASM_DECLARE_VEC(name, *) \
+ \
+ WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_copy(const wasm_##name##_t*);
+
+
+// Value Types
+
+WASM_DECLARE_TYPE(valtype)
+
+typedef uint8_t wasm_valkind_t;
+enum wasm_valkind_enum {
+ WASM_I32,
+ WASM_I64,
+ WASM_F32,
+ WASM_F64,
+ WASM_ANYREF = 128,
+ WASM_FUNCREF,
+};
+
+WASM_API_EXTERN own wasm_valtype_t* wasm_valtype_new(wasm_valkind_t);
+
+WASM_API_EXTERN wasm_valkind_t wasm_valtype_kind(const wasm_valtype_t*);
+
+static inline bool wasm_valkind_is_num(wasm_valkind_t k) {
+ return k < WASM_ANYREF;
+}
+static inline bool wasm_valkind_is_ref(wasm_valkind_t k) {
+ return k >= WASM_ANYREF;
+}
+
+static inline bool wasm_valtype_is_num(const wasm_valtype_t* t) {
+ return wasm_valkind_is_num(wasm_valtype_kind(t));
+}
+static inline bool wasm_valtype_is_ref(const wasm_valtype_t* t) {
+ return wasm_valkind_is_ref(wasm_valtype_kind(t));
+}
+
+
+// Function Types
+
+WASM_DECLARE_TYPE(functype)
+
+WASM_API_EXTERN own wasm_functype_t* wasm_functype_new(
+ own wasm_valtype_vec_t* params, own wasm_valtype_vec_t* results);
+
+WASM_API_EXTERN const wasm_valtype_vec_t* wasm_functype_params(const wasm_functype_t*);
+WASM_API_EXTERN const wasm_valtype_vec_t* wasm_functype_results(const wasm_functype_t*);
+
+
+// Global Types
+
+WASM_DECLARE_TYPE(globaltype)
+
+WASM_API_EXTERN own wasm_globaltype_t* wasm_globaltype_new(
+ own wasm_valtype_t*, wasm_mutability_t);
+
+WASM_API_EXTERN const wasm_valtype_t* wasm_globaltype_content(const wasm_globaltype_t*);
+WASM_API_EXTERN wasm_mutability_t wasm_globaltype_mutability(const wasm_globaltype_t*);
+
+
+// Table Types
+
+WASM_DECLARE_TYPE(tabletype)
+
+WASM_API_EXTERN own wasm_tabletype_t* wasm_tabletype_new(
+ own wasm_valtype_t*, const wasm_limits_t*);
+
+WASM_API_EXTERN const wasm_valtype_t* wasm_tabletype_element(const wasm_tabletype_t*);
+WASM_API_EXTERN const wasm_limits_t* wasm_tabletype_limits(const wasm_tabletype_t*);
+
+
+// Memory Types
+
+WASM_DECLARE_TYPE(memorytype)
+
+WASM_API_EXTERN own wasm_memorytype_t* wasm_memorytype_new(const wasm_limits_t*);
+
+WASM_API_EXTERN const wasm_limits_t* wasm_memorytype_limits(const wasm_memorytype_t*);
+
+
+// Extern Types
+
+WASM_DECLARE_TYPE(externtype)
+
+typedef uint8_t wasm_externkind_t;
+enum wasm_externkind_enum {
+ WASM_EXTERN_FUNC,
+ WASM_EXTERN_GLOBAL,
+ WASM_EXTERN_TABLE,
+ WASM_EXTERN_MEMORY,
+};
+
+WASM_API_EXTERN wasm_externkind_t wasm_externtype_kind(const wasm_externtype_t*);
+
+WASM_API_EXTERN wasm_externtype_t* wasm_functype_as_externtype(wasm_functype_t*);
+WASM_API_EXTERN wasm_externtype_t* wasm_globaltype_as_externtype(wasm_globaltype_t*);
+WASM_API_EXTERN wasm_externtype_t* wasm_tabletype_as_externtype(wasm_tabletype_t*);
+WASM_API_EXTERN wasm_externtype_t* wasm_memorytype_as_externtype(wasm_memorytype_t*);
+
+WASM_API_EXTERN wasm_functype_t* wasm_externtype_as_functype(wasm_externtype_t*);
+WASM_API_EXTERN wasm_globaltype_t* wasm_externtype_as_globaltype(wasm_externtype_t*);
+WASM_API_EXTERN wasm_tabletype_t* wasm_externtype_as_tabletype(wasm_externtype_t*);
+WASM_API_EXTERN wasm_memorytype_t* wasm_externtype_as_memorytype(wasm_externtype_t*);
+
+WASM_API_EXTERN const wasm_externtype_t* wasm_functype_as_externtype_const(const wasm_functype_t*);
+WASM_API_EXTERN const wasm_externtype_t* wasm_globaltype_as_externtype_const(const wasm_globaltype_t*);
+WASM_API_EXTERN const wasm_externtype_t* wasm_tabletype_as_externtype_const(const wasm_tabletype_t*);
+WASM_API_EXTERN const wasm_externtype_t* wasm_memorytype_as_externtype_const(const wasm_memorytype_t*);
+
+WASM_API_EXTERN const wasm_functype_t* wasm_externtype_as_functype_const(const wasm_externtype_t*);
+WASM_API_EXTERN const wasm_globaltype_t* wasm_externtype_as_globaltype_const(const wasm_externtype_t*);
+WASM_API_EXTERN const wasm_tabletype_t* wasm_externtype_as_tabletype_const(const wasm_externtype_t*);
+WASM_API_EXTERN const wasm_memorytype_t* wasm_externtype_as_memorytype_const(const wasm_externtype_t*);
+
+
+// Import Types
+
+WASM_DECLARE_TYPE(importtype)
+
+WASM_API_EXTERN own wasm_importtype_t* wasm_importtype_new(
+ own wasm_name_t* module, own wasm_name_t* name, own wasm_externtype_t*);
+
+WASM_API_EXTERN const wasm_name_t* wasm_importtype_module(const wasm_importtype_t*);
+WASM_API_EXTERN const wasm_name_t* wasm_importtype_name(const wasm_importtype_t*);
+WASM_API_EXTERN const wasm_externtype_t* wasm_importtype_type(const wasm_importtype_t*);
+
+
+// Export Types
+
+WASM_DECLARE_TYPE(exporttype)
+
+WASM_API_EXTERN own wasm_exporttype_t* wasm_exporttype_new(
+ own wasm_name_t*, own wasm_externtype_t*);
+
+WASM_API_EXTERN const wasm_name_t* wasm_exporttype_name(const wasm_exporttype_t*);
+WASM_API_EXTERN const wasm_externtype_t* wasm_exporttype_type(const wasm_exporttype_t*);
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Runtime Objects
+
+// Values
+
+struct wasm_ref_t;
+
+typedef struct wasm_val_t {
+ wasm_valkind_t kind;
+ union {
+ int32_t i32;
+ int64_t i64;
+ float32_t f32;
+ float64_t f64;
+ struct wasm_ref_t* ref;
+ } of;
+} wasm_val_t;
+
+WASM_API_EXTERN void wasm_val_delete(own wasm_val_t* v);
+WASM_API_EXTERN void wasm_val_copy(own wasm_val_t* out, const wasm_val_t*);
+
+WASM_DECLARE_VEC(val, )
+
+
+// References
+
+#define WASM_DECLARE_REF_BASE(name) \
+ WASM_DECLARE_OWN(name) \
+ \
+ WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_copy(const wasm_##name##_t*); \
+ WASM_API_EXTERN bool wasm_##name##_same(const wasm_##name##_t*, const wasm_##name##_t*); \
+ \
+ WASM_API_EXTERN void* wasm_##name##_get_host_info(const wasm_##name##_t*); \
+ WASM_API_EXTERN void wasm_##name##_set_host_info(wasm_##name##_t*, void*); \
+ WASM_API_EXTERN void wasm_##name##_set_host_info_with_finalizer( \
+ wasm_##name##_t*, void*, void (*)(void*));
+
+#define WASM_DECLARE_REF(name) \
+ WASM_DECLARE_REF_BASE(name) \
+ \
+ WASM_API_EXTERN wasm_ref_t* wasm_##name##_as_ref(wasm_##name##_t*); \
+ WASM_API_EXTERN wasm_##name##_t* wasm_ref_as_##name(wasm_ref_t*); \
+ WASM_API_EXTERN const wasm_ref_t* wasm_##name##_as_ref_const(const wasm_##name##_t*); \
+ WASM_API_EXTERN const wasm_##name##_t* wasm_ref_as_##name##_const(const wasm_ref_t*);
+
+#define WASM_DECLARE_SHARABLE_REF(name) \
+ WASM_DECLARE_REF(name) \
+ WASM_DECLARE_OWN(shared_##name) \
+ \
+ WASM_API_EXTERN own wasm_shared_##name##_t* wasm_##name##_share(const wasm_##name##_t*); \
+ WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_obtain(wasm_store_t*, const wasm_shared_##name##_t*);
+
+
+WASM_DECLARE_REF_BASE(ref)
+
+
+// Frames
+
+WASM_DECLARE_OWN(frame)
+WASM_DECLARE_VEC(frame, *)
+WASM_API_EXTERN own wasm_frame_t* wasm_frame_copy(const wasm_frame_t*);
+
+WASM_API_EXTERN struct wasm_instance_t* wasm_frame_instance(const wasm_frame_t*);
+WASM_API_EXTERN uint32_t wasm_frame_func_index(const wasm_frame_t*);
+WASM_API_EXTERN size_t wasm_frame_func_offset(const wasm_frame_t*);
+WASM_API_EXTERN size_t wasm_frame_module_offset(const wasm_frame_t*);
+
+
+// Traps
+
+typedef wasm_name_t wasm_message_t; // null terminated
+
+WASM_DECLARE_REF(trap)
+
+WASM_API_EXTERN own wasm_trap_t* wasm_trap_new(wasm_store_t* store, const wasm_message_t*);
+
+WASM_API_EXTERN void wasm_trap_message(const wasm_trap_t*, own wasm_message_t* out);
+WASM_API_EXTERN own wasm_frame_t* wasm_trap_origin(const wasm_trap_t*);
+WASM_API_EXTERN void wasm_trap_trace(const wasm_trap_t*, own wasm_frame_vec_t* out);
+
+
+// Foreign Objects
+
+WASM_DECLARE_REF(foreign)
+
+WASM_API_EXTERN own wasm_foreign_t* wasm_foreign_new(wasm_store_t*);
+
+
+// Modules
+
+WASM_DECLARE_SHARABLE_REF(module)
+
+WASM_API_EXTERN own wasm_module_t* wasm_module_new(
+ wasm_store_t*, const wasm_byte_vec_t* binary);
+
+WASM_API_EXTERN bool wasm_module_validate(wasm_store_t*, const wasm_byte_vec_t* binary);
+
+WASM_API_EXTERN void wasm_module_imports(const wasm_module_t*, own wasm_importtype_vec_t* out);
+WASM_API_EXTERN void wasm_module_exports(const wasm_module_t*, own wasm_exporttype_vec_t* out);
+
+WASM_API_EXTERN void wasm_module_serialize(const wasm_module_t*, own wasm_byte_vec_t* out);
+WASM_API_EXTERN own wasm_module_t* wasm_module_deserialize(wasm_store_t*, const wasm_byte_vec_t*);
+
+
+// Function Instances
+
+WASM_DECLARE_REF(func)
+
+typedef own wasm_trap_t* (*wasm_func_callback_t)(
+ const wasm_val_vec_t* args, own wasm_val_vec_t* results);
+typedef own wasm_trap_t* (*wasm_func_callback_with_env_t)(
+ void* env, const wasm_val_vec_t* args, wasm_val_vec_t* results);
+
+WASM_API_EXTERN own wasm_func_t* wasm_func_new(
+ wasm_store_t*, const wasm_functype_t*, wasm_func_callback_t);
+WASM_API_EXTERN own wasm_func_t* wasm_func_new_with_env(
+ wasm_store_t*, const wasm_functype_t* type, wasm_func_callback_with_env_t,
+ void* env, void (*finalizer)(void*));
+
+WASM_API_EXTERN own wasm_functype_t* wasm_func_type(const wasm_func_t*);
+WASM_API_EXTERN size_t wasm_func_param_arity(const wasm_func_t*);
+WASM_API_EXTERN size_t wasm_func_result_arity(const wasm_func_t*);
+
+WASM_API_EXTERN own wasm_trap_t* wasm_func_call(
+ const wasm_func_t*, const wasm_val_vec_t* args, wasm_val_vec_t* results);
+
+
+// Global Instances
+
+WASM_DECLARE_REF(global)
+
+WASM_API_EXTERN own wasm_global_t* wasm_global_new(
+ wasm_store_t*, const wasm_globaltype_t*, const wasm_val_t*);
+
+WASM_API_EXTERN own wasm_globaltype_t* wasm_global_type(const wasm_global_t*);
+
+WASM_API_EXTERN void wasm_global_get(const wasm_global_t*, own wasm_val_t* out);
+WASM_API_EXTERN void wasm_global_set(wasm_global_t*, const wasm_val_t*);
+
+
+// Table Instances
+
+WASM_DECLARE_REF(table)
+
+typedef uint32_t wasm_table_size_t;
+
+WASM_API_EXTERN own wasm_table_t* wasm_table_new(
+ wasm_store_t*, const wasm_tabletype_t*, wasm_ref_t* init);
+
+WASM_API_EXTERN own wasm_tabletype_t* wasm_table_type(const wasm_table_t*);
+
+WASM_API_EXTERN own wasm_ref_t* wasm_table_get(const wasm_table_t*, wasm_table_size_t index);
+WASM_API_EXTERN bool wasm_table_set(wasm_table_t*, wasm_table_size_t index, wasm_ref_t*);
+
+WASM_API_EXTERN wasm_table_size_t wasm_table_size(const wasm_table_t*);
+WASM_API_EXTERN bool wasm_table_grow(wasm_table_t*, wasm_table_size_t delta, wasm_ref_t* init);
+
+
+// Memory Instances
+
+WASM_DECLARE_REF(memory)
+
+typedef uint32_t wasm_memory_pages_t;
+
+static const size_t MEMORY_PAGE_SIZE = 0x10000;
+
+WASM_API_EXTERN own wasm_memory_t* wasm_memory_new(wasm_store_t*, const wasm_memorytype_t*);
+
+WASM_API_EXTERN own wasm_memorytype_t* wasm_memory_type(const wasm_memory_t*);
+
+WASM_API_EXTERN byte_t* wasm_memory_data(wasm_memory_t*);
+WASM_API_EXTERN size_t wasm_memory_data_size(const wasm_memory_t*);
+
+WASM_API_EXTERN wasm_memory_pages_t wasm_memory_size(const wasm_memory_t*);
+WASM_API_EXTERN bool wasm_memory_grow(wasm_memory_t*, wasm_memory_pages_t delta);
+
+
+// Externals
+
+WASM_DECLARE_REF(extern)
+WASM_DECLARE_VEC(extern, *)
+
+WASM_API_EXTERN wasm_externkind_t wasm_extern_kind(const wasm_extern_t*);
+WASM_API_EXTERN own wasm_externtype_t* wasm_extern_type(const wasm_extern_t*);
+
+WASM_API_EXTERN wasm_extern_t* wasm_func_as_extern(wasm_func_t*);
+WASM_API_EXTERN wasm_extern_t* wasm_global_as_extern(wasm_global_t*);
+WASM_API_EXTERN wasm_extern_t* wasm_table_as_extern(wasm_table_t*);
+WASM_API_EXTERN wasm_extern_t* wasm_memory_as_extern(wasm_memory_t*);
+
+WASM_API_EXTERN wasm_func_t* wasm_extern_as_func(wasm_extern_t*);
+WASM_API_EXTERN wasm_global_t* wasm_extern_as_global(wasm_extern_t*);
+WASM_API_EXTERN wasm_table_t* wasm_extern_as_table(wasm_extern_t*);
+WASM_API_EXTERN wasm_memory_t* wasm_extern_as_memory(wasm_extern_t*);
+
+WASM_API_EXTERN const wasm_extern_t* wasm_func_as_extern_const(const wasm_func_t*);
+WASM_API_EXTERN const wasm_extern_t* wasm_global_as_extern_const(const wasm_global_t*);
+WASM_API_EXTERN const wasm_extern_t* wasm_table_as_extern_const(const wasm_table_t*);
+WASM_API_EXTERN const wasm_extern_t* wasm_memory_as_extern_const(const wasm_memory_t*);
+
+WASM_API_EXTERN const wasm_func_t* wasm_extern_as_func_const(const wasm_extern_t*);
+WASM_API_EXTERN const wasm_global_t* wasm_extern_as_global_const(const wasm_extern_t*);
+WASM_API_EXTERN const wasm_table_t* wasm_extern_as_table_const(const wasm_extern_t*);
+WASM_API_EXTERN const wasm_memory_t* wasm_extern_as_memory_const(const wasm_extern_t*);
+
+
+// Module Instances
+
+WASM_DECLARE_REF(instance)
+
+WASM_API_EXTERN own wasm_instance_t* wasm_instance_new(
+ wasm_store_t*, const wasm_module_t*, const wasm_extern_vec_t* imports,
+ own wasm_trap_t**
+);
+
+WASM_API_EXTERN void wasm_instance_exports(const wasm_instance_t*, own wasm_extern_vec_t* out);
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Convenience
+
+// Vectors
+
+#define WASM_EMPTY_VEC {0, NULL}
+#define WASM_ARRAY_VEC(array) {sizeof(array)/sizeof(*(array)), array}
+
+
+// Value Type construction short-hands
+
+static inline own wasm_valtype_t* wasm_valtype_new_i32(void) {
+ return wasm_valtype_new(WASM_I32);
+}
+static inline own wasm_valtype_t* wasm_valtype_new_i64(void) {
+ return wasm_valtype_new(WASM_I64);
+}
+static inline own wasm_valtype_t* wasm_valtype_new_f32(void) {
+ return wasm_valtype_new(WASM_F32);
+}
+static inline own wasm_valtype_t* wasm_valtype_new_f64(void) {
+ return wasm_valtype_new(WASM_F64);
+}
+
+static inline own wasm_valtype_t* wasm_valtype_new_anyref(void) {
+ return wasm_valtype_new(WASM_ANYREF);
+}
+static inline own wasm_valtype_t* wasm_valtype_new_funcref(void) {
+ return wasm_valtype_new(WASM_FUNCREF);
+}
+
+
+// Function Types construction short-hands
+
+static inline own wasm_functype_t* wasm_functype_new_0_0(void) {
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new_empty(¶ms);
+ wasm_valtype_vec_new_empty(&results);
+ return wasm_functype_new(¶ms, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_1_0(
+ own wasm_valtype_t* p
+) {
+ wasm_valtype_t* ps[1] = {p};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(¶ms, 1, ps);
+ wasm_valtype_vec_new_empty(&results);
+ return wasm_functype_new(¶ms, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_2_0(
+ own wasm_valtype_t* p1, own wasm_valtype_t* p2
+) {
+ wasm_valtype_t* ps[2] = {p1, p2};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(¶ms, 2, ps);
+ wasm_valtype_vec_new_empty(&results);
+ return wasm_functype_new(¶ms, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_3_0(
+ own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3
+) {
+ wasm_valtype_t* ps[3] = {p1, p2, p3};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(¶ms, 3, ps);
+ wasm_valtype_vec_new_empty(&results);
+ return wasm_functype_new(¶ms, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_0_1(
+ own wasm_valtype_t* r
+) {
+ wasm_valtype_t* rs[1] = {r};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new_empty(¶ms);
+ wasm_valtype_vec_new(&results, 1, rs);
+ return wasm_functype_new(¶ms, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_1_1(
+ own wasm_valtype_t* p, own wasm_valtype_t* r
+) {
+ wasm_valtype_t* ps[1] = {p};
+ wasm_valtype_t* rs[1] = {r};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(¶ms, 1, ps);
+ wasm_valtype_vec_new(&results, 1, rs);
+ return wasm_functype_new(¶ms, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_2_1(
+ own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* r
+) {
+ wasm_valtype_t* ps[2] = {p1, p2};
+ wasm_valtype_t* rs[1] = {r};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(¶ms, 2, ps);
+ wasm_valtype_vec_new(&results, 1, rs);
+ return wasm_functype_new(¶ms, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_3_1(
+ own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3,
+ own wasm_valtype_t* r
+) {
+ wasm_valtype_t* ps[3] = {p1, p2, p3};
+ wasm_valtype_t* rs[1] = {r};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(¶ms, 3, ps);
+ wasm_valtype_vec_new(&results, 1, rs);
+ return wasm_functype_new(¶ms, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_0_2(
+ own wasm_valtype_t* r1, own wasm_valtype_t* r2
+) {
+ wasm_valtype_t* rs[2] = {r1, r2};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new_empty(¶ms);
+ wasm_valtype_vec_new(&results, 2, rs);
+ return wasm_functype_new(¶ms, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_1_2(
+ own wasm_valtype_t* p, own wasm_valtype_t* r1, own wasm_valtype_t* r2
+) {
+ wasm_valtype_t* ps[1] = {p};
+ wasm_valtype_t* rs[2] = {r1, r2};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(¶ms, 1, ps);
+ wasm_valtype_vec_new(&results, 2, rs);
+ return wasm_functype_new(¶ms, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_2_2(
+ own wasm_valtype_t* p1, own wasm_valtype_t* p2,
+ own wasm_valtype_t* r1, own wasm_valtype_t* r2
+) {
+ wasm_valtype_t* ps[2] = {p1, p2};
+ wasm_valtype_t* rs[2] = {r1, r2};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(¶ms, 2, ps);
+ wasm_valtype_vec_new(&results, 2, rs);
+ return wasm_functype_new(¶ms, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_3_2(
+ own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3,
+ own wasm_valtype_t* r1, own wasm_valtype_t* r2
+) {
+ wasm_valtype_t* ps[3] = {p1, p2, p3};
+ wasm_valtype_t* rs[2] = {r1, r2};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(¶ms, 3, ps);
+ wasm_valtype_vec_new(&results, 2, rs);
+ return wasm_functype_new(¶ms, &results);
+}
+
+
+// Value construction short-hands
+
+static inline void wasm_val_init_ptr(own wasm_val_t* out, void* p) {
+#if UINTPTR_MAX == UINT32_MAX
+ out->kind = WASM_I32;
+ out->of.i32 = (intptr_t)p;
+#elif UINTPTR_MAX == UINT64_MAX
+ out->kind = WASM_I64;
+ out->of.i64 = (intptr_t)p;
+#endif
+}
+
+static inline void* wasm_val_ptr(const wasm_val_t* val) {
+#if UINTPTR_MAX == UINT32_MAX
+ return (void*)(intptr_t)val->of.i32;
+#elif UINTPTR_MAX == UINT64_MAX
+ return (void*)(intptr_t)val->of.i64;
+#endif
+}
+
+#define WASM_I32_VAL(i) {.kind = WASM_I32, .of = {.i32 = i}}
+#define WASM_I64_VAL(i) {.kind = WASM_I64, .of = {.i64 = i}}
+#define WASM_F32_VAL(z) {.kind = WASM_F32, .of = {.f32 = z}}
+#define WASM_F64_VAL(z) {.kind = WASM_F64, .of = {.f64 = z}}
+#define WASM_REF_VAL(r) {.kind = WASM_ANYREF, .of = {.ref = r}}
+#define WASM_INIT_VAL {.kind = WASM_ANYREF, .of = {.ref = NULL}}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+#undef own
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // #ifdef WASM_H
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/include/wasmtime.h b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/include/wasmtime.h
new file mode 100644
index 000000000..f163f923b
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/include/wasmtime.h
@@ -0,0 +1,1300 @@
+/**
+ * @file
+ *
+ * Wasmtime-specific extensions to the WebAssembly C API.
+ *
+ * This file contains all of the Wasmtime-specific functions which will not be
+ * present in other engines. The intention of this file is to augment the
+ * functionality provided in `wasm.h`.
+ */
+
+
+#ifndef WASMTIME_API_H
+#define WASMTIME_API_H
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define own
+
+#define WASMTIME_DECLARE_OWN(name) \
+ typedef struct wasmtime_##name##_t wasmtime_##name##_t; \
+ \
+ WASM_API_EXTERN void wasmtime_##name##_delete(own wasmtime_##name##_t*);
+
+/**
+ * \typedef wasmtime_error_t
+ * \brief Convenience alias for #wasmtime_error_t
+ *
+ * \struct wasmtime_error_t
+ * \brief Errors generated by Wasmtime.
+ *
+ * This opaque type represents an error that happened as part of one of the
+ * functions below. Errors primarily have an error message associated with them
+ * at this time, which you can acquire by calling #wasmtime_error_message.
+ *
+ * \fn void wasmtime_error_delete(own wasmtime_error_t *);
+ * \brief Deletes an error.
+ */
+WASMTIME_DECLARE_OWN(error)
+
+/**
+ * \brief Returns the string description of this error.
+ *
+ * This will "render" the error to a string and then return the string
+ * representation of the error to the caller. The `message` argument should be
+ * uninitialized before this function is called and the caller is responsible
+ * for deallocating it with #wasm_byte_vec_delete afterwards.
+ */
+WASM_API_EXTERN void wasmtime_error_message(
+ const wasmtime_error_t *error,
+ own wasm_name_t *message
+);
+
+/**
+ * \brief Specifier for how Wasmtime will compile code, values are in
+ * #wasmtime_strategy_enum
+ */
+typedef uint8_t wasmtime_strategy_t;
+
+/**
+ * \brief Different ways that Wasmtime can compile WebAssembly
+ *
+ * The default value is #WASMTIME_STRATEGY_AUTO.
+ */
+enum wasmtime_strategy_enum { // Strategy
+ /// Wasmtime will automatically determine whether to use Cranelift or
+ /// Lightbeam, and currently it will always pick Cranelift. This default may
+ /// change over time though.
+ WASMTIME_STRATEGY_AUTO,
+
+ /// Indicates that Cranelift will unconditionally use Cranelift to compile
+ /// WebAssembly code.
+ WASMTIME_STRATEGY_CRANELIFT,
+
+ /// Indicates that Cranelift will unconditionally use Lightbeam to compile
+ /// WebAssembly code. Note that Lightbeam isn't always enabled at compile
+ /// time, and if that's the case an error will be returned.
+ WASMTIME_STRATEGY_LIGHTBEAM,
+};
+
+/**
+ * \brief Specifier of what optimization level to use for generated JIT code.
+ *
+ * See #wasmtime_opt_level_enum for possible values.
+ */
+typedef uint8_t wasmtime_opt_level_t;
+
+/**
+ * \brief Different ways Wasmtime can optimize generated code.
+ *
+ * The default value is #WASMTIME_OPT_LEVEL_SPEED.
+ */
+enum wasmtime_opt_level_enum { // OptLevel
+ /// Generated code will not be optimized at all.
+ WASMTIME_OPT_LEVEL_NONE,
+ /// Generated code will be optimized purely for speed.
+ WASMTIME_OPT_LEVEL_SPEED,
+ /// Generated code will be optimized, but some speed optimizations are
+ /// disabled if they cause the generated code to be significantly larger.
+ WASMTIME_OPT_LEVEL_SPEED_AND_SIZE,
+};
+
+/**
+ * \brief Different ways wasmtime can enable profiling JIT code.
+ *
+ * See #wasmtime_profiling_strategy_enum for possible values.
+ */
+typedef uint8_t wasmtime_profiling_strategy_t;
+
+/**
+ * \brief Different ways to profile JIT code.
+ *
+ * The default is #WASMTIME_PROFILING_STRATEGY_NONE.
+ */
+enum wasmtime_profiling_strategy_enum { // ProfilingStrategy
+ /// No profiling is enabled at runtime.
+ WASMTIME_PROFILING_STRATEGY_NONE,
+ /// Linux's "jitdump" support in `perf` is enabled and when Wasmtime is run
+ /// under `perf` necessary calls will be made to profile generated JIT code.
+ WASMTIME_PROFILING_STRATEGY_JITDUMP,
+ /// Support for VTune will be enabled and the VTune runtime will be informed,
+ /// at runtime, about JIT code.
+ ///
+ /// Note that this isn't always enabled at build time.
+ WASMTIME_PROFILING_STRATEGY_VTUNE,
+};
+
+#define WASMTIME_CONFIG_PROP(ret, name, ty) \
+ WASM_API_EXTERN ret wasmtime_config_##name##_set(wasm_config_t*, ty);
+
+/**
+ * \brief Configures whether DWARF debug information is constructed at runtime
+ * to describe JIT code.
+ *
+ * This setting is `false` by default. When enabled it will attempt to inform
+ * native debuggers about DWARF debugging information for JIT code to more
+ * easily debug compiled WebAssembly via native debuggers. This can also
+ * sometimes improve the quality of output when profiling is enabled.
+ */
+WASMTIME_CONFIG_PROP(void, debug_info, bool)
+
+/**
+ * \brief Enables WebAssembly code to be interrupted.
+ *
+ * This setting is `false` by default. When enabled it will enable getting an
+ * interrupt handle via #wasmtime_interrupt_handle_new which can be used to
+ * interrupt currently-executing WebAssembly code.
+ */
+WASMTIME_CONFIG_PROP(void, interruptable, bool)
+
+/**
+ * \brief Whether or not fuel is enabled for generated code.
+ *
+ * This setting is `false` by default. When enabled it will enable fuel counting
+ * meaning that fuel will be consumed every time a wasm instruction is executed,
+ * and trap when reaching zero.
+ */
+WASMTIME_CONFIG_PROP(void, consume_fuel, bool)
+
+/**
+ * \brief Configures the maximum stack size, in bytes, that JIT code can use.
+ *
+ * This setting is 2MB by default. Configuring this setting will limit the
+ * amount of native stack space that JIT code can use while it is executing. If
+ * you're hitting stack overflow you can try making this setting larger, or if
+ * you'd like to limit wasm programs to less stack you can also configure this.
+ *
+ * Note that this setting is not interpreted with 100% precision. Additionally
+ * the amount of stack space that wasm takes is always relative to the first
+ * invocation of wasm on the stack, so recursive calls with host frames in the
+ * middle will all need to fit within this setting.
+ */
+WASMTIME_CONFIG_PROP(void, max_wasm_stack, size_t)
+
+/**
+ * \brief Configures whether the WebAssembly threading proposal is enabled.
+ *
+ * This setting is `false` by default.
+ *
+ * Note that threads are largely unimplemented in Wasmtime at this time.
+ */
+WASMTIME_CONFIG_PROP(void, wasm_threads, bool)
+
+/**
+ * \brief Configures whether the WebAssembly reference types proposal is
+ * enabled.
+ *
+ * This setting is `false` by default.
+ */
+WASMTIME_CONFIG_PROP(void, wasm_reference_types, bool)
+
+/**
+ * \brief Configures whether the WebAssembly SIMD proposal is
+ * enabled.
+ *
+ * This setting is `false` by default.
+ */
+WASMTIME_CONFIG_PROP(void, wasm_simd, bool)
+
+/**
+ * \brief Configures whether the WebAssembly bulk memory proposal is
+ * enabled.
+ *
+ * This setting is `false` by default.
+ */
+WASMTIME_CONFIG_PROP(void, wasm_bulk_memory, bool)
+
+/**
+ * \brief Configures whether the WebAssembly multi value proposal is
+ * enabled.
+ *
+ * This setting is `true` by default.
+ */
+WASMTIME_CONFIG_PROP(void, wasm_multi_value, bool)
+
+/**
+ * \brief Configures whether the WebAssembly module linking proposal is
+ * enabled.
+ *
+ * This setting is `false` by default.
+ */
+WASMTIME_CONFIG_PROP(void, wasm_module_linking, bool)
+
+/**
+ * \brief Configures how JIT code will be compiled.
+ *
+ * This setting is #WASMTIME_STRATEGY_AUTO by default.
+ *
+ * If the compilation strategy selected could not be enabled then an error is
+ * returned.
+ */
+WASMTIME_CONFIG_PROP(wasmtime_error_t*, strategy, wasmtime_strategy_t)
+
+/**
+ * \brief Configures whether Cranelift's debug verifier is enabled.
+ *
+ * This setting in `false` by default.
+ *
+ * When cranelift is used for compilation this enables expensive debug checks
+ * within Cranelift itself to verify it's correct.
+ */
+WASMTIME_CONFIG_PROP(void, cranelift_debug_verifier, bool)
+
+/**
+ * \brief Configures Cranelift's optimization level for JIT code.
+ *
+ * This setting in #WASMTIME_OPT_LEVEL_SPEED by default.
+ */
+WASMTIME_CONFIG_PROP(void, cranelift_opt_level, wasmtime_opt_level_t)
+
+/**
+ * \brief Configures the profiling strategy used for JIT code.
+ *
+ * This setting in #WASMTIME_PROFILING_STRATEGY_NONE by default.
+ */
+WASMTIME_CONFIG_PROP(wasmtime_error_t*, profiler, wasmtime_profiling_strategy_t)
+
+/**
+ * \brief Configures the maximum size for memory to be considered "static"
+ *
+ * For more information see the Rust documentation at
+ * https://bytecodealliance.github.io/wasmtime/api/wasmtime/struct.Config.html#method.static_memory_maximum_size.
+ */
+WASMTIME_CONFIG_PROP(void, static_memory_maximum_size, uint64_t)
+
+/**
+ * \brief Configures the guard region size for "static" memory.
+ *
+ * For more information see the Rust documentation at
+ * https://bytecodealliance.github.io/wasmtime/api/wasmtime/struct.Config.html#method.static_memory_guard_size.
+ */
+WASMTIME_CONFIG_PROP(void, static_memory_guard_size, uint64_t)
+
+/**
+ * \brief Configures the guard region size for "dynamic" memory.
+ *
+ * For more information see the Rust documentation at
+ * https://bytecodealliance.github.io/wasmtime/api/wasmtime/struct.Config.html#method.dynamic_memory_guard_size.
+ */
+WASMTIME_CONFIG_PROP(void, dynamic_memory_guard_size, uint64_t)
+
+/**
+ * \brief Enables Wasmtime's cache and loads configuration from the specified
+ * path.
+ *
+ * By default the Wasmtime compilation cache is disabled. The configuration path
+ * here can be `NULL` to use the default settings, and otherwise the argument
+ * here must be a file on the filesystem with TOML configuration -
+ * https://bytecodealliance.github.io/wasmtime/cli-cache.html.
+ *
+ * An error is returned if the cache configuration could not be loaded or if the
+ * cache could not be enabled.
+ */
+WASM_API_EXTERN wasmtime_error_t* wasmtime_config_cache_config_load(wasm_config_t*, const char*);
+
+/**
+ * \brief Converts from the text format of WebAssembly to to the binary format.
+ *
+ * \param wat this it the input buffer with the WebAssembly Text Format inside of
+ * it. This will be parsed and converted to the binary format.
+ * \param ret if the conversion is successful, this byte vector is filled in with
+ * the WebAssembly binary format.
+ *
+ * \return a non-null error if parsing fails, or returns `NULL`. If parsing
+ * fails then `ret` isn't touched.
+ *
+ * This function does not take ownership of `wat`, and the caller is expected to
+ * deallocate the returned #wasmtime_error_t and #wasm_byte_vec_t.
+ */
+WASM_API_EXTERN own wasmtime_error_t* wasmtime_wat2wasm(
+ const wasm_byte_vec_t *wat,
+ own wasm_byte_vec_t *ret
+);
+
+/**
+ * \brief Perform garbage collection within the given store.
+ *
+ * Garbage collects `externref`s that are used within this store. Any
+ * `externref`s that are discovered to be unreachable by other code or objects
+ * will have their finalizers run.
+ *
+ * The `store` argument must not be NULL.
+ */
+WASM_API_EXTERN void wasmtime_store_gc(wasm_store_t* store);
+
+/**
+ * \typedef wasmtime_linker_t
+ * \brief Convenience alias for #wasmtime_linker_t
+ *
+ * \struct wasmtime_linker_t
+ * \brief Object used to conveniently link together and instantiate wasm
+ * modules.
+ *
+ * This type corresponds to the `wasmtime::Linker` type in Rust. This
+ * Wasmtime-specific extension is intended to make it easier to manage a set of
+ * modules that link together, or to make it easier to link WebAssembly modules
+ * to WASI.
+ *
+ * A #wasmtime_linker_t is a higher level way to instantiate a module than
+ * #wasm_instance_new since it works at the "string" level of imports rather
+ * than requiring 1:1 mappings.
+ *
+ * \fn void wasmtime_linker_delete(own wasmtime_linker_t *);
+ * \brief Deletes a linker.
+ */
+WASMTIME_DECLARE_OWN(linker)
+
+/**
+ * \brief Creates a new linker which will link together objects in the specified
+ * store.
+ *
+ * This function does not take ownership of the store argument, and the caller
+ * is expected to delete the returned linker.
+ */
+WASM_API_EXTERN own wasmtime_linker_t* wasmtime_linker_new(wasm_store_t* store);
+
+/**
+ * \brief Configures whether this linker allows later definitions to shadow
+ * previous definitions.
+ *
+ * By default this setting is `false`.
+ */
+WASM_API_EXTERN void wasmtime_linker_allow_shadowing(wasmtime_linker_t* linker, bool allow_shadowing);
+
+/**
+ * \brief Defines a new item in this linker.
+ *
+ * \param linker the linker the name is being defined in.
+ * \param module the module name the item is defined under.
+ * \param name the field name the item is defined under
+ * \param item the item that is being defined in this linker.
+ *
+ * \return On success `NULL` is returned, otherwise an error is returned which
+ * describes why the definition failed.
+ *
+ * For more information about name resolution consult the [Rust
+ * documentation](https://bytecodealliance.github.io/wasmtime/api/wasmtime/struct.Linker.html#name-resolution).
+ */
+WASM_API_EXTERN own wasmtime_error_t* wasmtime_linker_define(
+ wasmtime_linker_t *linker,
+ const wasm_name_t *module,
+ const wasm_name_t *name,
+ const wasm_extern_t *item
+);
+
+/**
+ * \brief Defines a WASI instance in this linker.
+ *
+ * \param linker the linker the name is being defined in.
+ * \param instance a previously-created WASI instance.
+ *
+ * \return On success `NULL` is returned, otherwise an error is returned which
+ * describes why the definition failed.
+ *
+ * For more information about name resolution consult the [Rust
+ * documentation](https://bytecodealliance.github.io/wasmtime/api/wasmtime/struct.Linker.html#name-resolution).
+ */
+WASM_API_EXTERN own wasmtime_error_t* wasmtime_linker_define_wasi(
+ wasmtime_linker_t *linker,
+ const wasi_instance_t *instance
+);
+
+/**
+ * \brief Defines an instance under the specified name in this linker.
+ *
+ * \param linker the linker the name is being defined in.
+ * \param name the module name to define `instance` under.
+ * \param instance a previously-created instance.
+ *
+ * \return On success `NULL` is returned, otherwise an error is returned which
+ * describes why the definition failed.
+ *
+ * This function will take all of the exports of the `instance` provided and
+ * defined them under a module called `name` with a field name as the export's
+ * own name.
+ *
+ * For more information about name resolution consult the [Rust
+ * documentation](https://bytecodealliance.github.io/wasmtime/api/wasmtime/struct.Linker.html#name-resolution).
+ */
+WASM_API_EXTERN own wasmtime_error_t* wasmtime_linker_define_instance(
+ wasmtime_linker_t *linker,
+ const wasm_name_t *name,
+ const wasm_instance_t *instance
+);
+
+/**
+ * \brief Instantiates a #wasm_module_t with the items defined in this linker.
+ *
+ * \param linker the linker used to instantiate the provided module.
+ * \param module the module that is being instantiated.
+ * \param instance the returned instance, if successful.
+ * \param trap a trap returned, if the start function traps.
+ *
+ * \return One of three things can happen as a result of this function. First
+ * the module could be successfully instantiated and returned through
+ * `instance`, meaning the return value and `trap` are both set to `NULL`.
+ * Second the start function may trap, meaning the return value and `instance`
+ * are set to `NULL` and `trap` describes the trap that happens. Finally
+ * instantiation may fail for another reason, in which case an error is returned
+ * and `trap` and `instance` are set to `NULL`.
+ *
+ * This function will attempt to satisfy all of the imports of the `module`
+ * provided with items previously defined in this linker. If any name isn't
+ * defined in the linker than an error is returned. (or if the previously
+ * defined item is of the wrong type).
+ */
+WASM_API_EXTERN own wasmtime_error_t* wasmtime_linker_instantiate(
+ const wasmtime_linker_t *linker,
+ const wasm_module_t *module,
+ own wasm_instance_t **instance,
+ own wasm_trap_t **trap
+);
+
+/**
+ * \brief Defines automatic instantiations of a #wasm_module_t in this linker.
+ *
+ * \param linker the linker the module is being added to
+ * \param name the name of the module within the linker
+ * \param module the module that's being instantiated
+ *
+ * \return An error if the module could not be instantiated or added or `NULL`
+ * on success.
+ *
+ * This function automatically handles [Commands and
+ * Reactors](https://github.com/WebAssembly/WASI/blob/master/design/application-abi.md#current-unstable-abi)
+ * instantiation and initialization.
+ *
+ * For more information see the [Rust
+ * documentation](https://bytecodealliance.github.io/wasmtime/api/wasmtime/struct.Linker.html#method.module).
+ */
+WASM_API_EXTERN own wasmtime_error_t* wasmtime_linker_module(
+ const wasmtime_linker_t *linker,
+ const wasm_name_t *name,
+ const wasm_module_t *module
+);
+
+/**
+ * \brief Acquires the "default export" of the named module in this linker.
+ *
+ * \param linker the linker to load from
+ * \param name the name of the module to get the default export for
+ * \param func where to store the extracted default function.
+ *
+ * \return An error is returned if the default export could not be found, or
+ * `NULL` is returned and `func` is filled in otherwise.
+ *
+ * For more information see the [Rust
+ * documentation](https://bytecodealliance.github.io/wasmtime/api/wasmtime/struct.Linker.html#method.get_default).
+ */
+WASM_API_EXTERN own wasmtime_error_t* wasmtime_linker_get_default(
+ const wasmtime_linker_t *linker,
+ const wasm_name_t *name,
+ own wasm_func_t **func
+);
+
+/**
+ * \brief Loads an item by name from this linker.
+ *
+ * \param linker the linker to load from
+ * \param module the name of the module to get
+ * \param name the name of the field to get
+ * \param item where to store the extracted item
+ *
+ * \return An error is returned if the item isn't defined or has more than one
+ * definition, or `NULL` is returned and `item` is filled in otherwise.
+ */
+WASM_API_EXTERN own wasmtime_error_t* wasmtime_linker_get_one_by_name(
+ const wasmtime_linker_t *linker,
+ const wasm_name_t *module,
+ const wasm_name_t *name,
+ own wasm_extern_t **item
+);
+
+/**
+ * \brief Structure used to learn about the caller of a host-defined function.
+ *
+ * This structure is the first argument of #wasmtime_func_callback_t and
+ * wasmtime_func_callback_with_env_t. The main purpose of this structure is for
+ * building a WASI-like API which can inspect the memory of the caller,
+ * regardless of the caller.
+ *
+ * This is intended to be a temporary API extension until interface types have
+ * become more prevalent. This is not intended to be supported until the end of
+ * time, but it will be supported so long as WASI requires it.
+ */
+typedef struct wasmtime_caller_t wasmtime_caller_t;
+
+/**
+ * \brief Callback signature for #wasmtime_func_new.
+ *
+ * This function is the same as #wasm_func_callback_t except that its first
+ * argument is a #wasmtime_caller_t which allows learning information about the
+ * caller.
+ */
+typedef own wasm_trap_t* (*wasmtime_func_callback_t)(const wasmtime_caller_t* caller, const wasm_val_vec_t *args, wasm_val_vec_t *results);
+
+/**
+ * \brief Callback signature for #wasmtime_func_new_with_env.
+ *
+ * This function is the same as #wasm_func_callback_with_env_t except that its
+ * first argument is a #wasmtime_caller_t which allows learning information
+ * about the caller.
+ */
+typedef own wasm_trap_t* (*wasmtime_func_callback_with_env_t)(const wasmtime_caller_t* caller, void* env, const wasm_val_vec_t *args, wasm_val_vec_t *results);
+
+/**
+ * \brief Creates a new host-defined function.
+ *
+ * This function is the same as #wasm_func_new, except the callback has the type
+ * signature #wasmtime_func_callback_t which gives a #wasmtime_caller_t as its
+ * first argument.
+ */
+WASM_API_EXTERN own wasm_func_t* wasmtime_func_new(wasm_store_t*, const wasm_functype_t*, wasmtime_func_callback_t callback);
+
+/**
+ * \brief Creates a new host-defined function.
+ *
+ * This function is the same as #wasm_func_new_with_env, except the callback
+ * has the type signature #wasmtime_func_callback_with_env_t which gives a
+ * #wasmtime_caller_t as its first argument.
+ */
+WASM_API_EXTERN own wasm_func_t* wasmtime_func_new_with_env(
+ wasm_store_t* store,
+ const wasm_functype_t* type,
+ wasmtime_func_callback_with_env_t callback,
+ void* env,
+ void (*finalizer)(void*)
+);
+
+/**
+ * \brief Creates a new `funcref` value referencing `func`.
+ *
+ * Create a `funcref` value that references `func` and writes it to `funcrefp`.
+ *
+ * Gives ownership fo the `funcref` value written to `funcrefp`.
+ *
+ * Both `func` and `funcrefp` must not be NULL.
+ */
+WASM_API_EXTERN void wasmtime_func_as_funcref(const wasm_func_t* func, wasm_val_t* funcrefp);
+
+/**
+ * \brief Get the `wasm_func_t*` referenced by the given `funcref` value.
+ *
+ * Gets an owning handle to the `wasm_func_t*` that the given `funcref` value is
+ * referencing. Returns NULL if the value is not a `funcref`, or if the value is
+ * a null function reference.
+ *
+ * The `val` pointer must not be NULL.
+ */
+WASM_API_EXTERN own wasm_func_t* wasmtime_funcref_as_func(const wasm_val_t* val);
+
+/**
+ * \brief Loads a #wasm_extern_t from the caller's context
+ *
+ * This function will attempt to look up the export named `name` on the caller
+ * instance provided. If it is found then the #wasm_extern_t for that is
+ * returned, otherwise `NULL` is returned.
+ *
+ * Note that this only works for exported memories right now for WASI
+ * compatibility.
+ */
+WASM_API_EXTERN own wasm_extern_t* wasmtime_caller_export_get(const wasmtime_caller_t* caller, const wasm_name_t* name);
+
+/**
+ * \typedef wasmtime_interrupt_handle_t
+ * \brief Convenience alias for #wasmtime_interrupt_handle_t
+ *
+ * \struct wasmtime_interrupt_handle_t
+ * \brief A handle used to interrupt executing WebAssembly code.
+ *
+ * This structure is an opaque handle that represents a handle to a store. This
+ * handle can be used to remotely (from another thread) interrupt currently
+ * executing WebAssembly code.
+ *
+ * This structure is safe to share from multiple threads.
+ *
+ * \fn void wasmtime_interrupt_handle_delete(own wasmtime_interrupt_handle_t *);
+ * \brief Deletes an interrupt handle.
+ */
+WASMTIME_DECLARE_OWN(interrupt_handle)
+
+/**
+ * \brief Creates a new interrupt handle to interrupt executing WebAssembly from
+ * the provided store.
+ *
+ * There are a number of caveats about how interrupt is handled in Wasmtime. For
+ * more information see the [Rust
+ * documentation](https://bytecodealliance.github.io/wasmtime/api/wasmtime/struct.Store.html#method.interrupt_handle).
+ *
+ * This function returns `NULL` if the store's configuration does not have
+ * interrupts enabled. See #wasmtime_config_interruptable_set.
+ */
+WASM_API_EXTERN own wasmtime_interrupt_handle_t *wasmtime_interrupt_handle_new(wasm_store_t *store);
+
+/**
+ * \brief Adds fuel to this Store for wasm to consume while executing.
+ *
+ * For this method to work fuel consumption must be enabled via
+ * #wasmtime_config_consume_fuel_set. By default a Store starts with 0 fuel
+ * for wasm to execute with (meaning it will immediately trap).
+ * This function must be called for the store to have
+ * some fuel to allow WebAssembly to execute.
+ *
+ * Note that at this time when fuel is entirely consumed it will cause
+ * wasm to trap. More usages of fuel are planned for the future.
+ *
+ * If fuel is not enabled within this store then an error is returned. If fuel
+ * is successfully added then NULL is returned.
+ */
+WASM_API_EXTERN own wasmtime_error_t *wasmtime_store_add_fuel(wasm_store_t *store, uint64_t fuel);
+
+/**
+ * \brief Returns the amount of fuel consumed by this store's execution so far.
+ *
+ * If fuel consumption is not enabled via #wasmtime_config_consume_fuel_set
+ * then this function will return false. Otherwise true is returned and the
+ * fuel parameter is filled in with fuel consuemd so far.
+ *
+ * Also note that fuel, if enabled, must be originally configured via
+ * #wasmtime_store_add_fuel.
+ */
+WASM_API_EXTERN bool wasmtime_store_fuel_consumed(wasm_store_t *store, uint64_t *fuel);
+
+/**
+ * \brief Requests that WebAssembly code running in the store attached to this
+ * interrupt handle is interrupted.
+ *
+ * For more information about interrupts see #wasmtime_interrupt_handle_new.
+ *
+ * Note that this is safe to call from any thread.
+ */
+WASM_API_EXTERN void wasmtime_interrupt_handle_interrupt(wasmtime_interrupt_handle_t *handle);
+
+/**
+ * \brief Attempts to extract a WASI-specific exit status from this trap.
+ *
+ * Returns `true` if the trap is a WASI "exit" trap and has a return status. If
+ * `true` is returned then the exit status is returned through the `status`
+ * pointer. If `false` is returned then this is not a wasi exit trap.
+ */
+WASM_API_EXTERN bool wasmtime_trap_exit_status(const wasm_trap_t*, int *status);
+
+/**
+ * \brief Returns a human-readable name for this frame's function.
+ *
+ * This function will attempt to load a human-readable name for function this
+ * frame points to. This function may return `NULL`.
+ *
+ * The lifetime of the returned name is the same as the #wasm_frame_t itself.
+ */
+WASM_API_EXTERN const wasm_name_t *wasmtime_frame_func_name(const wasm_frame_t*);
+
+/**
+ * \brief Returns a human-readable name for this frame's module.
+ *
+ * This function will attempt to load a human-readable name for module this
+ * frame points to. This function may return `NULL`.
+ *
+ * The lifetime of the returned name is the same as the #wasm_frame_t itself.
+ */
+WASM_API_EXTERN const wasm_name_t *wasmtime_frame_module_name(const wasm_frame_t*);
+
+/**
+ * \brief Call a WebAssembly function.
+ *
+ * This function is similar to #wasm_func_call, but with a few tweaks:
+ *
+ * * An error *and* a trap can be returned
+ * * Errors are returned if `args` have the wrong types, if the args/results
+ * arrays have the wrong lengths, or if values come from the wrong store.
+ *
+ * There are three possible return states from this function:
+ *
+ * 1. The returned error is non-null. This means `results`
+ * wasn't written to and `trap` will have `NULL` written to it. This state
+ * means that programmer error happened when calling the function (e.g. the
+ * size of the args/results were wrong)
+ * 2. The trap pointer is filled in. This means the returned error is `NULL` and
+ * `results` was not written to. This state means that the function was
+ * executing but hit a wasm trap while executing.
+ * 3. The error and trap returned are both `NULL` and `results` are written to.
+ * This means that the function call worked and the specified results were
+ * produced.
+ *
+ * The `trap` pointer cannot be `NULL`. The `args` and `results` pointers may be
+ * `NULL` if the corresponding length is zero.
+ *
+ * Does not take ownership of `wasm_val_t` arguments. Gives ownership of
+ * `wasm_val_t` results.
+ */
+WASM_API_EXTERN own wasmtime_error_t *wasmtime_func_call(
+ wasm_func_t *func,
+ const wasm_val_vec_t *args,
+ wasm_val_vec_t *results,
+ own wasm_trap_t **trap
+);
+
+/**
+ * \brief Creates a new global value.
+ *
+ * Similar to #wasm_global_new, but with a few tweaks:
+ *
+ * * An error is returned instead of #wasm_global_t, which is taken as an
+ * out-parameter
+ * * An error happens when the `type` specified does not match the type of the
+ * value `val`, or if it comes from a different store than `store`.
+ *
+ * This function does not take ownership of any of its arguments but returned
+ * values are owned by the caller.
+ */
+WASM_API_EXTERN own wasmtime_error_t *wasmtime_global_new(
+ wasm_store_t *store,
+ const wasm_globaltype_t *type,
+ const wasm_val_t *val,
+ own wasm_global_t **ret
+);
+
+/**
+ * \brief Sets a global to a new value.
+ *
+ * This function is the same as #wasm_global_set, except in the case of an error
+ * a #wasmtime_error_t is returned.
+ */
+WASM_API_EXTERN own wasmtime_error_t *wasmtime_global_set(
+ wasm_global_t *global,
+ const wasm_val_t *val
+);
+
+/**
+ * \brief Wasmtime-specific function to instantiate a module.
+ *
+ * This function is similar to #wasm_instance_new, but with a few tweaks:
+ *
+ * * An error message can be returned from this function.
+ * * The `trap` pointer is required to not be NULL.
+ *
+ * The states of return values from this function are similar to
+ * #wasmtime_func_call where an error can be returned meaning something like a
+ * link error in this context. A trap can be returned (meaning no error or
+ * instance is returned), or an instance can be returned (meaning no error or
+ * trap is returned).
+ *
+ * This function does not take ownership of any of its arguments, but all return
+ * values are owned by the caller.
+ *
+ * See #wasm_instance_new for information about how to fill in the `imports`
+ * array.
+ */
+WASM_API_EXTERN own wasmtime_error_t *wasmtime_instance_new(
+ wasm_store_t *store,
+ const wasm_module_t *module,
+ const wasm_extern_vec_t* imports,
+ own wasm_instance_t **instance,
+ own wasm_trap_t **trap
+);
+
+/**
+ * \brief Wasmtime-specific function to compile a module.
+ *
+ * This function will compile a WebAssembly binary into an owned #wasm_module_t.
+ * This performs the same as #wasm_module_new except that it returns a
+ * #wasmtime_error_t type to get richer error information.
+ *
+ * On success the returned #wasmtime_error_t is `NULL` and the `ret` pointer is
+ * filled in with a #wasm_module_t. On failure the #wasmtime_error_t is
+ * non-`NULL` and the `ret` pointer is unmodified.
+ *
+ * This function does not take ownership of any of its arguments, but the
+ * returned error and module are owned by the caller.
+ */
+WASM_API_EXTERN own wasmtime_error_t *wasmtime_module_new(
+ wasm_engine_t *engine,
+ const wasm_byte_vec_t *binary,
+ own wasm_module_t **ret
+);
+
+/**
+ * \brief Wasmtime-specific function to validate a module.
+ *
+ * This function will validate the provided byte sequence to determine if it is
+ * a valid WebAssembly binary. This function performs the same as
+ * #wasm_module_validate except that it returns a #wasmtime_error_t which
+ * contains an error message if validation fails.
+ *
+ * This function does not take ownership of its arguments but the caller is
+ * expected to deallocate the returned error if it is non-`NULL`.
+ *
+ * If the binary validates then `NULL` is returned, otherwise the error returned
+ * describes why the binary did not validate.
+ */
+WASM_API_EXTERN own wasmtime_error_t *wasmtime_module_validate(
+ wasm_store_t *store,
+ const wasm_byte_vec_t *binary
+);
+
+
+/**
+ * \brief Creates a new host-defined wasm table.
+ *
+ * This function is the same as #wasm_table_new except that it's specialized for
+ * funcref tables by taking a `wasm_func_t` initialization value. Additionally
+ * it returns errors via #wasmtime_error_t.
+ *
+ * This function does not take ownership of any of its parameters, but yields
+ * ownership of returned values (the table and error).
+ */
+WASM_API_EXTERN own wasmtime_error_t *wasmtime_funcref_table_new(
+ wasm_store_t *store,
+ const wasm_tabletype_t *element_ty,
+ wasm_func_t *init,
+ own wasm_table_t **table
+);
+
+/**
+ * \brief Gets a value in a table.
+ *
+ * This function is the same as #wasm_table_get except that it's specialized for
+ * funcref tables by returning a `wasm_func_t` value. Additionally a `bool`
+ * return value indicates whether the `index` provided was in bounds.
+ *
+ * This function does not take ownership of any of its parameters, but yields
+ * ownership of returned #wasm_func_t.
+ */
+WASM_API_EXTERN bool wasmtime_funcref_table_get(
+ const wasm_table_t *table,
+ wasm_table_size_t index,
+ own wasm_func_t **func
+);
+
+/**
+ * \brief Sets a value in a table.
+ *
+ * This function is similar to #wasm_table_set, but has a few differences:
+ *
+ * * An error is returned through #wasmtime_error_t describing erroneous
+ * situations.
+ * * The value being set is specialized to #wasm_func_t.
+ *
+ * This function does not take ownership of any of its parameters, but yields
+ * ownership of returned #wasmtime_error_t.
+ */
+WASM_API_EXTERN own wasmtime_error_t *wasmtime_funcref_table_set(
+ wasm_table_t *table,
+ wasm_table_size_t index,
+ const wasm_func_t *value
+);
+
+/**
+ * \brief Grows a table.
+ *
+ * This function is similar to #wasm_table_grow, but has a few differences:
+ *
+ * * An error is returned through #wasmtime_error_t describing erroneous
+ * situations.
+ * * The initialization value is specialized to #wasm_func_t.
+ * * The previous size of the table is returned through `prev_size`.
+ *
+ * This function does not take ownership of any of its parameters, but yields
+ * ownership of returned #wasmtime_error_t.
+ */
+WASM_API_EXTERN wasmtime_error_t *wasmtime_funcref_table_grow(
+ wasm_table_t *table,
+ wasm_table_size_t delta,
+ const wasm_func_t *init,
+ wasm_table_size_t *prev_size
+);
+
+/**
+ * \brief Create a new `externref` value.
+ *
+ * Creates a new `externref` value wrapping the provided data, and writes it to
+ * `valp`.
+ *
+ * This function does not take an associated finalizer to clean up the data when
+ * the reference is reclaimed. If you need a finalizer to clean up the data,
+ * then use #wasmtime_externref_new_with_finalizer.
+ *
+ * Gives ownership of the newly created `externref` value.
+ */
+WASM_API_EXTERN void wasmtime_externref_new(own void *data, wasm_val_t *valp);
+
+/**
+ * \brief A finalizer for an `externref`'s wrapped data.
+ *
+ * A finalizer callback to clean up an `externref`'s wrapped data after the
+ * `externref` has been reclaimed. This is an opportunity to run destructors,
+ * free dynamically allocated memory, close file handles, etc.
+ */
+typedef void (*wasmtime_externref_finalizer_t)(void*);
+
+/**
+ * \brief Create a new `externref` value with a finalizer.
+ *
+ * Creates a new `externref` value wrapping the provided data, and writes it to
+ * `valp`.
+ *
+ * When the reference is reclaimed, the wrapped data is cleaned up with the
+ * provided finalizer. If you do not need to clean up the wrapped data, then use
+ * #wasmtime_externref_new.
+ *
+ * Gives ownership of the newly created `externref` value.
+ */
+WASM_API_EXTERN void wasmtime_externref_new_with_finalizer(
+ own void *data,
+ wasmtime_externref_finalizer_t finalizer,
+ wasm_val_t *valp
+);
+
+/**
+ * \brief Get an `externref`'s wrapped data
+ *
+ * If the given value is a reference to a non-null `externref`, writes the
+ * wrapped data that was passed into #wasmtime_externref_new or
+ * #wasmtime_externref_new_with_finalizer when creating the given `externref` to
+ * `datap`, and returns `true`.
+ *
+ * If the value is a reference to a null `externref`, writes `NULL` to `datap`
+ * and returns `true`.
+ *
+ * If the given value is not an `externref`, returns `false` and leaves `datap`
+ * unmodified.
+ *
+ * Does not take ownership of `val`. Does not give up ownership of the `void*`
+ * data written to `datap`.
+ *
+ * Both `val` and `datap` must not be `NULL`.
+ */
+WASM_API_EXTERN bool wasmtime_externref_data(wasm_val_t* val, void** datap);
+
+/**
+ * \brief This function serializes compiled module artifacts
+ * as blob data.
+ *
+ * \param module the module
+ * \param ret if the conversion is successful, this byte vector is filled in with
+ * the serialized compiled module.
+ *
+ * \return a non-null error if parsing fails, or returns `NULL`. If parsing
+ * fails then `ret` isn't touched.
+ *
+ * This function does not take ownership of `module`, and the caller is
+ * expected to deallocate the returned #wasmtime_error_t and #wasm_byte_vec_t.
+ */
+WASM_API_EXTERN own wasmtime_error_t* wasmtime_module_serialize(
+ wasm_module_t* module,
+ own wasm_byte_vec_t *ret
+);
+
+/**
+ * \brief Build a module from serialized data.
+ *
+ * This function does not take ownership of any of its arguments, but the
+ * returned error and module are owned by the caller.
+ *
+ * This function is not safe to receive arbitrary user input. See the Rust
+ * documentation for more information on what inputs are safe to pass in here
+ * (e.g. only that of #wasmtime_module_serialize)
+ */
+WASM_API_EXTERN own wasmtime_error_t *wasmtime_module_deserialize(
+ wasm_engine_t *engine,
+ const wasm_byte_vec_t *serialized,
+ own wasm_module_t **ret
+);
+
+/**
+ * \struct wasm_instancetype_t
+ * \brief An opaque object representing the type of a function.
+ *
+ * \typedef wasm_instancetype_t
+ * \brief Convenience alias for #wasm_instancetype_t
+ *
+ * \struct wasm_instancetype_vec_t
+ * \brief A list of #wasm_instancetype_t values.
+ *
+ * \var wasm_instancetype_vec_t::size
+ * \brief Length of this vector.
+ *
+ * \var wasm_instancetype_vec_t::data
+ * \brief Pointer to the base of this vector
+ *
+ * \typedef wasm_instancetype_vec_t
+ * \brief Convenience alias for #wasm_instancetype_vec_t
+ *
+ * \fn void wasm_instancetype_delete(own wasm_instancetype_t *);
+ * \brief Deletes a type.
+ *
+ * \fn void wasm_instancetype_vec_new_empty(own wasm_instancetype_vec_t *out);
+ * \brief Creates an empty vector.
+ *
+ * See #wasm_byte_vec_new_empty for more information.
+ *
+ * \fn void wasm_instancetype_vec_new_uninitialized(own wasm_instancetype_vec_t *out, size_t);
+ * \brief Creates a vector with the given capacity.
+ *
+ * See #wasm_byte_vec_new_uninitialized for more information.
+ *
+ * \fn void wasm_instancetype_vec_new(own wasm_instancetype_vec_t *out, size_t, own wasm_instancetype_t *const[]);
+ * \brief Creates a vector with the provided contents.
+ *
+ * See #wasm_byte_vec_new for more information.
+ *
+ * \fn void wasm_instancetype_vec_copy(own wasm_instancetype_vec_t *out, const wasm_instancetype_vec_t *)
+ * \brief Copies one vector to another
+ *
+ * See #wasm_byte_vec_copy for more information.
+ *
+ * \fn void wasm_instancetype_vec_delete(own wasm_instancetype_vec_t *out)
+ * \brief Deallocates memory for a vector.
+ *
+ * See #wasm_byte_vec_delete for more information.
+ *
+ * \fn own wasm_instancetype_t* wasm_instancetype_copy(const wasm_instancetype_t *)
+ * \brief Creates a new value which matches the provided one.
+ *
+ * The caller is responsible for deleting the returned value.
+ */
+WASM_DECLARE_TYPE(instancetype)
+
+/**
+ * \brief Returns the list of exports that this instance type provides.
+ *
+ * This function does not take ownership of the provided instance type but
+ * ownership of `out` is passed to the caller. Note that `out` is treated as
+ * uninitialized when passed to this function.
+ */
+WASM_API_EXTERN void wasm_instancetype_exports(const wasm_instancetype_t*, own wasm_exporttype_vec_t* out);
+
+/**
+ * \brief Converts a #wasm_instancetype_t to a #wasm_externtype_t
+ *
+ * The returned value is owned by the #wasm_instancetype_t argument and should not
+ * be deleted.
+ */
+WASM_API_EXTERN wasm_externtype_t* wasm_instancetype_as_externtype(wasm_instancetype_t*);
+
+/**
+ * \brief Attempts to convert a #wasm_externtype_t to a #wasm_instancetype_t
+ *
+ * The returned value is owned by the #wasm_instancetype_t argument and should not
+ * be deleted. Returns `NULL` if the provided argument is not a
+ * #wasm_instancetype_t.
+ */
+WASM_API_EXTERN wasm_instancetype_t* wasm_externtype_as_instancetype(wasm_externtype_t*);
+
+/**
+ * \brief Converts a #wasm_instancetype_t to a #wasm_externtype_t
+ *
+ * The returned value is owned by the #wasm_instancetype_t argument and should not
+ * be deleted.
+ */
+WASM_API_EXTERN const wasm_externtype_t* wasm_instancetype_as_externtype_const(const wasm_instancetype_t*);
+
+/**
+ * \brief Attempts to convert a #wasm_externtype_t to a #wasm_instancetype_t
+ *
+ * The returned value is owned by the #wasm_instancetype_t argument and should not
+ * be deleted. Returns `NULL` if the provided argument is not a
+ * #wasm_instancetype_t.
+ */
+WASM_API_EXTERN const wasm_instancetype_t* wasm_externtype_as_instancetype_const(const wasm_externtype_t*);
+
+/**
+ * \struct wasm_moduletype_t
+ * \brief An opaque object representing the type of a function.
+ *
+ * \typedef wasm_moduletype_t
+ * \brief Convenience alias for #wasm_moduletype_t
+ *
+ * \struct wasm_moduletype_vec_t
+ * \brief A list of #wasm_moduletype_t values.
+ *
+ * \var wasm_moduletype_vec_t::size
+ * \brief Length of this vector.
+ *
+ * \var wasm_moduletype_vec_t::data
+ * \brief Pointer to the base of this vector
+ *
+ * \typedef wasm_moduletype_vec_t
+ * \brief Convenience alias for #wasm_moduletype_vec_t
+ *
+ * \fn void wasm_moduletype_delete(own wasm_moduletype_t *);
+ * \brief Deletes a type.
+ *
+ * \fn void wasm_moduletype_vec_new_empty(own wasm_moduletype_vec_t *out);
+ * \brief Creates an empty vector.
+ *
+ * See #wasm_byte_vec_new_empty for more information.
+ *
+ * \fn void wasm_moduletype_vec_new_uninitialized(own wasm_moduletype_vec_t *out, size_t);
+ * \brief Creates a vector with the given capacity.
+ *
+ * See #wasm_byte_vec_new_uninitialized for more information.
+ *
+ * \fn void wasm_moduletype_vec_new(own wasm_moduletype_vec_t *out, size_t, own wasm_moduletype_t *const[]);
+ * \brief Creates a vector with the provided contents.
+ *
+ * See #wasm_byte_vec_new for more information.
+ *
+ * \fn void wasm_moduletype_vec_copy(own wasm_moduletype_vec_t *out, const wasm_moduletype_vec_t *)
+ * \brief Copies one vector to another
+ *
+ * See #wasm_byte_vec_copy for more information.
+ *
+ * \fn void wasm_moduletype_vec_delete(own wasm_moduletype_vec_t *out)
+ * \brief Deallocates memory for a vector.
+ *
+ * See #wasm_byte_vec_delete for more information.
+ *
+ * \fn own wasm_moduletype_t* wasm_moduletype_copy(const wasm_moduletype_t *)
+ * \brief Creates a new value which matches the provided one.
+ *
+ * The caller is responsible for deleting the returned value.
+ */
+WASM_DECLARE_TYPE(moduletype)
+
+/**
+ * \brief Returns the list of imports that this module type requires.
+ *
+ * This function does not take ownership of the provided module type but
+ * ownership of `out` is passed to the caller. Note that `out` is treated as
+ * uninitialized when passed to this function.
+ */
+WASM_API_EXTERN void wasm_moduletype_imports(const wasm_moduletype_t*, own wasm_importtype_vec_t* out);
+
+/**
+ * \brief Returns the list of exports that this module type provides.
+ *
+ * This function does not take ownership of the provided module type but
+ * ownership of `out` is passed to the caller. Note that `out` is treated as
+ * uninitialized when passed to this function.
+ */
+WASM_API_EXTERN void wasm_moduletype_exports(const wasm_moduletype_t*, own wasm_exporttype_vec_t* out);
+
+/**
+ * \brief Converts a #wasm_moduletype_t to a #wasm_externtype_t
+ *
+ * The returned value is owned by the #wasm_moduletype_t argument and should not
+ * be deleted.
+ */
+WASM_API_EXTERN wasm_externtype_t* wasm_moduletype_as_externtype(wasm_moduletype_t*);
+
+/**
+ * \brief Attempts to convert a #wasm_externtype_t to a #wasm_moduletype_t
+ *
+ * The returned value is owned by the #wasm_moduletype_t argument and should not
+ * be deleted. Returns `NULL` if the provided argument is not a
+ * #wasm_moduletype_t.
+ */
+WASM_API_EXTERN wasm_moduletype_t* wasm_externtype_as_moduletype(wasm_externtype_t*);
+
+/**
+ * \brief Converts a #wasm_moduletype_t to a #wasm_externtype_t
+ *
+ * The returned value is owned by the #wasm_moduletype_t argument and should not
+ * be deleted.
+ */
+WASM_API_EXTERN const wasm_externtype_t* wasm_moduletype_as_externtype_const(const wasm_moduletype_t*);
+
+/**
+ * \brief Attempts to convert a #wasm_externtype_t to a #wasm_moduletype_t
+ *
+ * The returned value is owned by the #wasm_moduletype_t argument and should not
+ * be deleted. Returns `NULL` if the provided argument is not a
+ * #wasm_moduletype_t.
+ */
+WASM_API_EXTERN const wasm_moduletype_t* wasm_externtype_as_moduletype_const(const wasm_externtype_t*);
+
+/**
+ * \brief Converts a #wasm_module_t to #wasm_extern_t.
+ *
+ * The returned #wasm_extern_t is owned by the #wasm_module_t argument. Callers
+ * should not delete the returned value, and it only lives as long as the
+ * #wasm_module_t argument.
+ */
+WASM_API_EXTERN wasm_extern_t* wasm_module_as_extern(wasm_module_t*);
+
+/**
+ * \brief Converts a #wasm_extern_t to #wasm_module_t.
+ *
+ * The returned #wasm_module_t is owned by the #wasm_extern_t argument. Callers
+ * should not delete the returned value, and it only lives as long as the
+ * #wasm_extern_t argument.
+ *
+ * If the #wasm_extern_t argument isn't a #wasm_module_t then `NULL` is returned.
+ */
+WASM_API_EXTERN wasm_module_t* wasm_extern_as_module(wasm_extern_t*);
+
+/**
+ * \brief Converts a #wasm_extern_t to #wasm_instance_t.
+ *
+ * The returned #wasm_instance_t is owned by the #wasm_extern_t argument. Callers
+ * should not delete the returned value, and it only lives as long as the
+ * #wasm_extern_t argument.
+ */
+WASM_API_EXTERN const wasm_module_t* wasm_extern_as_module_const(const wasm_extern_t*);
+
+/**
+ * \brief Converts a #wasm_instance_t to #wasm_extern_t.
+ *
+ * The returned #wasm_extern_t is owned by the #wasm_instance_t argument. Callers
+ * should not delete the returned value, and it only lives as long as the
+ * #wasm_instance_t argument.
+ */
+WASM_API_EXTERN wasm_extern_t* wasm_instance_as_extern(wasm_instance_t*);
+
+/**
+ * \brief Converts a #wasm_extern_t to #wasm_instance_t.
+ *
+ * The returned #wasm_instance_t is owned by the #wasm_extern_t argument. Callers
+ * should not delete the returned value, and it only lives as long as the
+ * #wasm_extern_t argument.
+ *
+ * If the #wasm_extern_t argument isn't a #wasm_instance_t then `NULL` is returned.
+ */
+WASM_API_EXTERN wasm_instance_t* wasm_extern_as_instance(wasm_extern_t*);
+
+/**
+ * \brief Converts a #wasm_extern_t to #wasm_instance_t.
+ *
+ * The returned #wasm_instance_t is owned by the #wasm_extern_t argument. Callers
+ * should not delete the returned value, and it only lives as long as the
+ * #wasm_extern_t argument.
+ */
+WASM_API_EXTERN const wasm_instance_t* wasm_extern_as_instance_const(const wasm_extern_t*);
+
+/**
+ * \brief Returns the type of this instance.
+ *
+ * The returned #wasm_instancetype_t is expected to be deallocated by the caller.
+ */
+WASM_API_EXTERN own wasm_instancetype_t* wasm_instance_type(const wasm_instance_t*);
+
+/**
+ * \brief Returns the type of this module.
+ *
+ * The returned #wasm_moduletype_t is expected to be deallocated by the caller.
+ */
+WASM_API_EXTERN own wasm_moduletype_t* wasm_module_type(const wasm_module_t*);
+
+/**
+ * \brief Value of #wasm_externkind_enum corresponding to a wasm module.
+ */
+#define WASM_EXTERN_MODULE 4
+
+/**
+ * \brief Value of #wasm_externkind_enum corresponding to a wasm instance.
+ */
+#define WASM_EXTERN_INSTANCE 5
+
+#undef own
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // WASMTIME_API_H
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/linux-x86_64/empty.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/linux-x86_64/empty.go
new file mode 100644
index 000000000..da5524747
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/linux-x86_64/empty.go
@@ -0,0 +1 @@
+package linux_x86_64
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/linux-x86_64/libwasmtime.a b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/linux-x86_64/libwasmtime.a
new file mode 100644
index 000000000..67b3c8187
Binary files /dev/null and b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/linux-x86_64/libwasmtime.a differ
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/macos-x86_64/empty.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/macos-x86_64/empty.go
new file mode 100644
index 000000000..0aa17a7b5
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/macos-x86_64/empty.go
@@ -0,0 +1 @@
+package macos_x86_64
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/macos-x86_64/libwasmtime.a b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/macos-x86_64/libwasmtime.a
new file mode 100644
index 000000000..ab859f2d7
Binary files /dev/null and b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/macos-x86_64/libwasmtime.a differ
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/windows-x86_64/empty.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/windows-x86_64/empty.go
new file mode 100644
index 000000000..0cd04cf85
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/windows-x86_64/empty.go
@@ -0,0 +1 @@
+package windows_x86_64
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/windows-x86_64/libwasmtime.a b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/windows-x86_64/libwasmtime.a
new file mode 100644
index 000000000..e821f2014
Binary files /dev/null and b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/build/windows-x86_64/libwasmtime.a differ
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/config.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/config.go
new file mode 100644
index 000000000..96f96e897
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/config.go
@@ -0,0 +1,181 @@
+package wasmtime
+
+// #include
+// #include
+// #include
+import "C"
+import (
+ "runtime"
+ "unsafe"
+)
+
+// Strategy is the compilation strategies for wasmtime
+type Strategy C.wasmtime_strategy_t
+
+const (
+ // StrategyAuto will let wasmtime automatically pick an appropriate compilation strategy
+ StrategyAuto Strategy = C.WASMTIME_STRATEGY_AUTO
+ // StrategyCranelift will force wasmtime to use the Cranelift backend
+ StrategyCranelift Strategy = C.WASMTIME_STRATEGY_CRANELIFT
+ // StrategyLightbeam will force wasmtime to use the lightbeam backend
+ StrategyLightbeam Strategy = C.WASMTIME_STRATEGY_LIGHTBEAM
+)
+
+// OptLevel decides what degree of optimization wasmtime will perform on generated machine code
+type OptLevel C.wasmtime_opt_level_t
+
+const (
+ // OptLevelNone will perform no optimizations
+ OptLevelNone OptLevel = C.WASMTIME_OPT_LEVEL_NONE
+ // OptLevelSpeed will optimize machine code to be as fast as possible
+ OptLevelSpeed OptLevel = C.WASMTIME_OPT_LEVEL_SPEED
+ // OptLevelSpeedAndSize will optimize machine code for speed, but also optimize
+ // to be small, sometimes at the cost of speed.
+ OptLevelSpeedAndSize OptLevel = C.WASMTIME_OPT_LEVEL_SPEED_AND_SIZE
+)
+
+// ProfilingStrategy decides what sort of profiling to enable, if any.
+type ProfilingStrategy C.wasmtime_profiling_strategy_t
+
+const (
+ // ProfilingStrategyNone means no profiler will be used
+ ProfilingStrategyNone ProfilingStrategy = C.WASMTIME_PROFILING_STRATEGY_NONE
+ // ProfilingStrategyJitdump will use the "jitdump" linux support
+ ProfilingStrategyJitdump ProfilingStrategy = C.WASMTIME_PROFILING_STRATEGY_JITDUMP
+)
+
+// Config holds options used to create an Engine and customize its behavior.
+type Config struct {
+ _ptr *C.wasm_config_t
+}
+
+// NewConfig creates a new `Config` with all default options configured.
+func NewConfig() *Config {
+ config := &Config{_ptr: C.wasm_config_new()}
+ runtime.SetFinalizer(config, func(config *Config) {
+ C.wasm_config_delete(config._ptr)
+ })
+ return config
+}
+
+// SetDebugInfo configures whether dwarf debug information for JIT code is enabled
+func (cfg *Config) SetDebugInfo(enabled bool) {
+ C.wasmtime_config_debug_info_set(cfg.ptr(), C.bool(enabled))
+ runtime.KeepAlive(cfg)
+}
+
+// SetWasmThreads configures whether the wasm threads proposal is enabled
+func (cfg *Config) SetWasmThreads(enabled bool) {
+ C.wasmtime_config_wasm_threads_set(cfg.ptr(), C.bool(enabled))
+ runtime.KeepAlive(cfg)
+}
+
+// SetWasmReferenceTypes configures whether the wasm reference types proposal is enabled
+func (cfg *Config) SetWasmReferenceTypes(enabled bool) {
+ C.wasmtime_config_wasm_reference_types_set(cfg.ptr(), C.bool(enabled))
+ runtime.KeepAlive(cfg)
+}
+
+// SetWasmSIMD configures whether the wasm SIMD proposal is enabled
+func (cfg *Config) SetWasmSIMD(enabled bool) {
+ C.wasmtime_config_wasm_simd_set(cfg.ptr(), C.bool(enabled))
+ runtime.KeepAlive(cfg)
+}
+
+// SetWasmBulkMemory configures whether the wasm bulk memory proposal is enabled
+func (cfg *Config) SetWasmBulkMemory(enabled bool) {
+ C.wasmtime_config_wasm_bulk_memory_set(cfg.ptr(), C.bool(enabled))
+ runtime.KeepAlive(cfg)
+}
+
+// SetWasmMultiValue configures whether the wasm multi value proposal is enabled
+func (cfg *Config) SetWasmMultiValue(enabled bool) {
+ C.wasmtime_config_wasm_multi_value_set(cfg.ptr(), C.bool(enabled))
+ runtime.KeepAlive(cfg)
+}
+
+// SetWasmModuleLinking configures whether the wasm module linking proposal is enabled
+func (cfg *Config) SetWasmModuleLinking(enabled bool) {
+ C.wasmtime_config_wasm_module_linking_set(cfg.ptr(), C.bool(enabled))
+ runtime.KeepAlive(cfg)
+}
+
+// SetStrategy configures what compilation strategy is used to compile wasm code
+func (cfg *Config) SetStrategy(strat Strategy) error {
+ err := C.wasmtime_config_strategy_set(cfg.ptr(), C.wasmtime_strategy_t(strat))
+ runtime.KeepAlive(cfg)
+ if err != nil {
+ return mkError(err)
+ }
+ return nil
+}
+
+// SetCraneliftDebugVerifier configures whether the cranelift debug verifier will be active when
+// cranelift is used to compile wasm code.
+func (cfg *Config) SetCraneliftDebugVerifier(enabled bool) {
+ C.wasmtime_config_cranelift_debug_verifier_set(cfg.ptr(), C.bool(enabled))
+ runtime.KeepAlive(cfg)
+}
+
+// SetCraneliftOptLevel configures the cranelift optimization level for generated code
+func (cfg *Config) SetCraneliftOptLevel(level OptLevel) {
+ C.wasmtime_config_cranelift_opt_level_set(cfg.ptr(), C.wasmtime_opt_level_t(level))
+ runtime.KeepAlive(cfg)
+}
+
+// SetProfiler configures what profiler strategy to use for generated code
+func (cfg *Config) SetProfiler(profiler ProfilingStrategy) error {
+ err := C.wasmtime_config_profiler_set(cfg.ptr(), C.wasmtime_profiling_strategy_t(profiler))
+ runtime.KeepAlive(cfg)
+ if err != nil {
+ return mkError(err)
+ }
+ return nil
+}
+
+// CacheConfigLoadDefault enables compiled code caching for this `Config` using the default settings
+// configuration can be found.
+//
+// For more information about caching see
+// https://bytecodealliance.github.io/wasmtime/cli-cache.html
+func (cfg *Config) CacheConfigLoadDefault() error {
+ err := C.wasmtime_config_cache_config_load(cfg.ptr(), nil)
+ runtime.KeepAlive(cfg)
+ if err != nil {
+ return mkError(err)
+ }
+ return nil
+}
+
+// CacheConfigLoad enables compiled code caching for this `Config` using the settings specified
+// in the configuration file `path`.
+//
+// For more information about caching and configuration options see
+// https://bytecodealliance.github.io/wasmtime/cli-cache.html
+func (cfg *Config) CacheConfigLoad(path string) error {
+ cstr := C.CString(path)
+ err := C.wasmtime_config_cache_config_load(cfg.ptr(), cstr)
+ C.free(unsafe.Pointer(cstr))
+ runtime.KeepAlive(cfg)
+ if err != nil {
+ return mkError(err)
+ }
+ return nil
+}
+
+// SetInterruptable configures whether generated wasm code can be interrupted via interrupt
+// handles.
+func (cfg *Config) SetInterruptable(interruptable bool) {
+ C.wasmtime_config_interruptable_set(cfg.ptr(), C.bool(interruptable))
+ runtime.KeepAlive(cfg)
+}
+
+// See comments in `ffi.go` for what's going on here
+func (cfg *Config) ptr() *C.wasm_config_t {
+ ret := cfg._ptr
+ maybeGC()
+ if ret == nil {
+ panic("Config has already been used up")
+ }
+ return ret
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/doc.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/doc.go
new file mode 100644
index 000000000..ef44184bc
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/doc.go
@@ -0,0 +1,18 @@
+/*
+Package wasmtime is a WebAssembly runtime for Go powered by Wasmtime.
+
+This package provides everything necessary to compile and execute WebAssembly
+modules as part of a Go program. Wasmtime is a JIT compiler written in Rust,
+and can be found at https://github.com/bytecodealliance/wasmtime. This package
+is a binding to the C API provided by Wasmtime.
+
+The API of this Go package is intended to mirror the Rust API
+(https://docs.rs/wasmtime) relatively closely, so if you find something is
+under-documented here then you may have luck consulting the Rust documentation
+as well. As always though feel free to file any issues at
+https://github.com/bytecodealliance/wasmtime-go/issues/new.
+
+It's also worth pointing out that the authors of this package up to this point
+primarily work in Rust, so if you've got suggestions of how to make this package
+more idiomatic for Go we'd love to hear your thoughts! */
+package wasmtime
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/engine.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/engine.go
new file mode 100644
index 000000000..47daf8667
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/engine.go
@@ -0,0 +1,44 @@
+package wasmtime
+
+// #include
+import "C"
+import "runtime"
+
+// Engine is an instance of a wasmtime engine which is used to create a `Store`.
+//
+// Engines are a form of global configuration for wasm compilations and modules
+// and such.
+type Engine struct {
+ _ptr *C.wasm_engine_t
+}
+
+// NewEngine creates a new `Engine` with default configuration.
+func NewEngine() *Engine {
+ engine := &Engine{_ptr: C.wasm_engine_new()}
+ runtime.SetFinalizer(engine, func(engine *Engine) {
+ C.wasm_engine_delete(engine._ptr)
+ })
+ return engine
+}
+
+// NewEngineWithConfig creates a new `Engine` with the `Config` provided
+//
+// Note that once a `Config` is passed to this method it cannot be used again.
+func NewEngineWithConfig(config *Config) *Engine {
+ if config.ptr() == nil {
+ panic("config already used")
+ }
+ engine := &Engine{_ptr: C.wasm_engine_new_with_config(config.ptr())}
+ runtime.SetFinalizer(config, nil)
+ config._ptr = nil
+ runtime.SetFinalizer(engine, func(engine *Engine) {
+ C.wasm_engine_delete(engine._ptr)
+ })
+ return engine
+}
+
+func (engine *Engine) ptr() *C.wasm_engine_t {
+ ret := engine._ptr
+ maybeGC()
+ return ret
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/error.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/error.go
new file mode 100644
index 000000000..026b9410e
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/error.go
@@ -0,0 +1,32 @@
+package wasmtime
+
+// #include
+import "C"
+import "runtime"
+
+type Error struct {
+ _ptr *C.wasmtime_error_t
+}
+
+func mkError(ptr *C.wasmtime_error_t) *Error {
+ err := &Error{_ptr: ptr}
+ runtime.SetFinalizer(err, func(err *Error) {
+ C.wasmtime_error_delete(err._ptr)
+ })
+ return err
+}
+
+func (e *Error) ptr() *C.wasmtime_error_t {
+ ret := e._ptr
+ maybeGC()
+ return ret
+}
+
+func (e *Error) Error() string {
+ message := C.wasm_byte_vec_t{}
+ C.wasmtime_error_message(e.ptr(), &message)
+ ret := C.GoStringN(message.data, C.int(message.size))
+ runtime.KeepAlive(e)
+ C.wasm_byte_vec_delete(&message)
+ return ret
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/exporttype.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/exporttype.go
new file mode 100644
index 000000000..393e23099
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/exporttype.go
@@ -0,0 +1,66 @@
+package wasmtime
+
+// #include
+import "C"
+import "runtime"
+
+// ExportType is one of the exports component.
+// A module defines a set of exports that become accessible to the host environment once the module has been instantiated.
+type ExportType struct {
+ _ptr *C.wasm_exporttype_t
+ _owner interface{}
+}
+
+// NewExportType creates a new `ExportType` with the `name` and the type provided.
+func NewExportType(name string, ty AsExternType) *ExportType {
+ nameVec := stringToByteVec(name)
+
+ // Creating an export type requires taking ownership, so create a copy
+ // so we don't have to invalidate pointers here. Shouldn't be too
+ // costly in theory anyway.
+ extern := ty.AsExternType()
+ ptr := C.wasm_externtype_copy(extern.ptr())
+ runtime.KeepAlive(extern)
+
+ // And once we've got all that create the export type!
+ exportPtr := C.wasm_exporttype_new(&nameVec, ptr)
+
+ return mkExportType(exportPtr, nil)
+}
+
+func mkExportType(ptr *C.wasm_exporttype_t, owner interface{}) *ExportType {
+ exporttype := &ExportType{_ptr: ptr, _owner: owner}
+ if owner == nil {
+ runtime.SetFinalizer(exporttype, func(exporttype *ExportType) {
+ C.wasm_exporttype_delete(exporttype._ptr)
+ })
+ }
+ return exporttype
+}
+
+func (ty *ExportType) ptr() *C.wasm_exporttype_t {
+ ret := ty._ptr
+ maybeGC()
+ return ret
+}
+
+func (ty *ExportType) owner() interface{} {
+ if ty._owner != nil {
+ return ty._owner
+ }
+ return ty
+}
+
+// Name returns the name in the module this export type is exporting
+func (ty *ExportType) Name() string {
+ ptr := C.wasm_exporttype_name(ty.ptr())
+ ret := C.GoStringN(ptr.data, C.int(ptr.size))
+ runtime.KeepAlive(ty)
+ return ret
+}
+
+// Type returns the type of item this export type expects
+func (ty *ExportType) Type() *ExternType {
+ ptr := C.wasm_exporttype_type(ty.ptr())
+ return mkExternType(ptr, ty.owner())
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/extern.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/extern.go
new file mode 100644
index 000000000..9aee69772
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/extern.go
@@ -0,0 +1,116 @@
+package wasmtime
+
+// #include
+import "C"
+import "runtime"
+
+// Extern is an external value, which is the runtime representation of an entity that can be imported or exported.
+// It is an address denoting either a function instance, table instance, memory instance, or global instances in the shared store.
+// Read more in [spec](https://webassembly.github.io/spec/core/exec/runtime.html#external-values)
+//
+type Extern struct {
+ _ptr *C.wasm_extern_t
+ _owner interface{}
+ freelist *freeList
+}
+
+// AsExtern is an interface for all types which can be imported or exported as an Extern
+type AsExtern interface {
+ AsExtern() *Extern
+}
+
+func mkExtern(ptr *C.wasm_extern_t, freelist *freeList, owner interface{}) *Extern {
+ f := &Extern{_ptr: ptr, _owner: owner, freelist: freelist}
+ if owner == nil {
+ runtime.SetFinalizer(f, func(f *Extern) {
+ f.freelist.lock.Lock()
+ defer f.freelist.lock.Unlock()
+ f.freelist.externs = append(f.freelist.externs, f._ptr)
+ })
+ }
+ return f
+}
+
+func (e *Extern) ptr() *C.wasm_extern_t {
+ ret := e._ptr
+ maybeGC()
+ return ret
+}
+
+func (e *Extern) owner() interface{} {
+ if e._owner != nil {
+ return e._owner
+ }
+ return e
+}
+
+// Type returns the type of this export
+func (e *Extern) Type() *ExternType {
+ ptr := C.wasm_extern_type(e.ptr())
+ runtime.KeepAlive(e)
+ return mkExternType(ptr, nil)
+}
+
+// Func returns a Func if this export is a function or nil otherwise
+func (e *Extern) Func() *Func {
+ ret := C.wasm_extern_as_func(e.ptr())
+ if ret == nil {
+ return nil
+ }
+
+ return mkFunc(ret, e.freelist, e.owner())
+}
+
+// Global returns a Global if this export is a global or nil otherwise
+func (e *Extern) Global() *Global {
+ ret := C.wasm_extern_as_global(e.ptr())
+ if ret == nil {
+ return nil
+ }
+
+ return mkGlobal(ret, e.freelist, e.owner())
+}
+
+// Memory returns a Memory if this export is a memory or nil otherwise
+func (e *Extern) Memory() *Memory {
+ ret := C.wasm_extern_as_memory(e.ptr())
+ if ret == nil {
+ return nil
+ }
+
+ return mkMemory(ret, e.freelist, e.owner())
+}
+
+// Table returns a Table if this export is a table or nil otherwise
+func (e *Extern) Table() *Table {
+ ret := C.wasm_extern_as_table(e.ptr())
+ if ret == nil {
+ return nil
+ }
+
+ return mkTable(ret, e.freelist, e.owner())
+}
+
+// Module returns a Module if this export is a module or nil otherwise
+func (e *Extern) Module() *Module {
+ ret := C.wasm_extern_as_module(e.ptr())
+ if ret == nil {
+ return nil
+ }
+
+ return mkModule(ret, e.owner())
+}
+
+// Instance returns a Instance if this export is a module or nil otherwise
+func (e *Extern) Instance() *Instance {
+ ret := C.wasm_extern_as_instance(e.ptr())
+ if ret == nil {
+ return nil
+ }
+
+ return mkInstance(ret, e.freelist, e.owner())
+}
+
+func (e *Extern) AsExtern() *Extern {
+ return e
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/externtype.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/externtype.go
new file mode 100644
index 000000000..622904c55
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/externtype.go
@@ -0,0 +1,84 @@
+package wasmtime
+
+// #include
+import "C"
+import "runtime"
+
+// ExternType means one of external types which classify imports and external values with their respective types.
+type ExternType struct {
+ _ptr *C.wasm_externtype_t
+ _owner interface{}
+}
+
+// AsExternType is an interface for all types which can be ExternType.
+type AsExternType interface {
+ AsExternType() *ExternType
+}
+
+func mkExternType(ptr *C.wasm_externtype_t, owner interface{}) *ExternType {
+ externtype := &ExternType{_ptr: ptr, _owner: owner}
+ if owner == nil {
+ runtime.SetFinalizer(externtype, func(externtype *ExternType) {
+ C.wasm_externtype_delete(externtype._ptr)
+ })
+ }
+ return externtype
+}
+
+func (ty *ExternType) ptr() *C.wasm_externtype_t {
+ ret := ty._ptr
+ maybeGC()
+ return ret
+}
+
+func (ty *ExternType) owner() interface{} {
+ if ty._owner != nil {
+ return ty._owner
+ }
+ return ty
+}
+
+// FuncType returns the underlying `FuncType` for this `ExternType` if it's a function
+// type. Otherwise returns `nil`.
+func (ty *ExternType) FuncType() *FuncType {
+ ptr := C.wasm_externtype_as_functype(ty.ptr())
+ if ptr == nil {
+ return nil
+ }
+ return mkFuncType(ptr, ty.owner())
+}
+
+// GlobalType returns the underlying `GlobalType` for this `ExternType` if it's a *global* type.
+// Otherwise returns `nil`.
+func (ty *ExternType) GlobalType() *GlobalType {
+ ptr := C.wasm_externtype_as_globaltype(ty.ptr())
+ if ptr == nil {
+ return nil
+ }
+ return mkGlobalType(ptr, ty.owner())
+}
+
+// TableType returns the underlying `TableType` for this `ExternType` if it's a *table* type.
+// Otherwise returns `nil`.
+func (ty *ExternType) TableType() *TableType {
+ ptr := C.wasm_externtype_as_tabletype(ty.ptr())
+ if ptr == nil {
+ return nil
+ }
+ return mkTableType(ptr, ty.owner())
+}
+
+// MemoryType returns the underlying `MemoryType` for this `ExternType` if it's a *memory* type.
+// Otherwise returns `nil`.
+func (ty *ExternType) MemoryType() *MemoryType {
+ ptr := C.wasm_externtype_as_memorytype(ty.ptr())
+ if ptr == nil {
+ return nil
+ }
+ return mkMemoryType(ptr, ty.owner())
+}
+
+// AsExternType returns this type itself
+func (ty *ExternType) AsExternType() *ExternType {
+ return ty
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/ffi.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/ffi.go
new file mode 100644
index 000000000..0aa6f4cf8
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/ffi.go
@@ -0,0 +1,54 @@
+package wasmtime
+
+// #cgo CFLAGS:-I${SRCDIR}/build/include
+// #cgo !windows LDFLAGS:-lwasmtime -lm -ldl
+// #cgo windows CFLAGS:-DWASM_API_EXTERN= -DWASI_API_EXTERN=
+// #cgo windows LDFLAGS:-lwasmtime -luserenv -lole32 -lntdll -lws2_32 -lkernel32 -lbcrypt
+// #cgo linux,amd64 LDFLAGS:-L${SRCDIR}/build/linux-x86_64
+// #cgo darwin,amd64 LDFLAGS:-L${SRCDIR}/build/macos-x86_64
+// #cgo windows,amd64 LDFLAGS:-L${SRCDIR}/build/windows-x86_64
+// #include
+import "C"
+import "runtime"
+import "unsafe"
+
+// # What's up with `ptr()` methods?
+//
+// We use `runtime.SetFinalizer` to free all objects we allocate from C. This
+// is intended to make usage of the API much simpler since you don't have to
+// close/free anything. The tricky part here though is laid out in
+// `runtime.SetFinalizer`'s documentation which is that if you read a
+// non-gc-value (like a C pointer) from a GC object then after the value is
+// read the GC value might get garbage collected. This is quite bad for us
+// because the garbage collection will free the C pointer, making the C pointer
+// actually invalid.
+//
+// The solution is to add `runtime.KeepAlive` calls after C function calls to
+// ensure that the GC object lives at least as long as the C function call
+// itself. This is naturally quite error-prone, so the goal here with `ptr()`
+// methods is to make us a bit more resilient to these sorts of errors and
+// expose segfaults during development.
+//
+// Each `ptr()` method has the basic structure of doing these steps:
+//
+// 1. First it reads the pointer value from the GC object
+// 2. Next it conditionally calls `runtime.GC()`, depending on build flags
+// 3. Finally it returns the original pointer value
+//
+// The goal here is to as aggressively as we can collect GC objects when
+// testing and trigger finalizers as frequently as we can. This naturally
+// slows things down quite a bit, so conditional compilation (with the `debug`
+// tag) is used to enable this. Our CI runs tests with `-tag debug` to make
+// sure this is at least run somewhere.
+//
+// If anyone else has a better idea of what to handle all this it would be very
+// much appreciated :)
+
+// Convert a Go string into an owned `wasm_byte_vec_t`
+func stringToByteVec(s string) C.wasm_byte_vec_t {
+ vec := C.wasm_byte_vec_t{}
+ C.wasm_byte_vec_new_uninitialized(&vec, C.size_t(len(s)))
+ C.memcpy(unsafe.Pointer(vec.data), unsafe.Pointer(C._GoStringPtr(s)), vec.size)
+ runtime.KeepAlive(s)
+ return vec
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/freelist.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/freelist.go
new file mode 100644
index 000000000..54028335d
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/freelist.go
@@ -0,0 +1,123 @@
+package wasmtime
+
+// #include
+// #include
+import "C"
+import (
+ "runtime"
+ "sync"
+)
+
+// A structure used to defer deletion of C API objects to the main thread.
+//
+// The C API is not threadsafe and objects must be destroyed on the original
+// thread that they came from. We also, however, want to use `SetFinalizer` to
+// free objects because it's vastly more convenient than explicit free
+// methods. The `SetFinalizer` routine will spin up a goroutine for finalizers
+// that might run concurrently, however. To fix this we use this structure to
+// collect pointers which need to be free'd.
+//
+// When a `SetFinalizer` finalizer runs it will enqueue a pointer inside of
+// this freelist. This list is then periodically checked to clear out any
+// pointers on the main thread with the store. Pointers contained here are
+// basically those all connected to a `wasm_store_t`.
+//
+// This isn't really a great solution but at this time I can't really think
+// of anything else unfortunately. I'm hoping that we can continue to optimize
+// this over time if necessary, but otherwise this should at least fix crashes
+// seen on CI and ensure that everything is free'd correctly.
+type freeList struct {
+ // The freelist can be modified from both the main thread with a store
+ // and from finalizers, so because that can happen concurrently we
+ // protect the arrays below with a lock.
+ lock sync.Mutex
+
+ // All the various kinds of pointers that we'll store to get deallocated
+ // here.
+
+ stores []*C.wasm_store_t
+ memories []*C.wasm_memory_t
+ funcs []*C.wasm_func_t
+ tables []*C.wasm_table_t
+ globals []*C.wasm_global_t
+ instances []*C.wasm_instance_t
+ externs []*C.wasm_extern_t
+ linkers []*C.wasmtime_linker_t
+ wasiInstances []*C.wasi_instance_t
+ externVecs []*C.wasm_extern_vec_t
+ vals []*C.wasm_val_t
+}
+
+func newFreeList() *freeList {
+ // freelists have their own finalizer which clears out all the contents
+ // once the freelist itself has gone away. If this happens that should
+ // be safe to do because no other live objects have access to the
+ // freelist, so whatever thread is running the freelist is "the thread
+ // which own things" so it's safe to clear everything out, we know that
+ // no other concurrent accesses will be happening.
+ ret := &freeList{}
+ runtime.SetFinalizer(ret, func(f *freeList) { f.clear() })
+ return ret
+}
+
+// Clears out this freelist, actually deleting all pointers that are contained
+// within it.
+func (f *freeList) clear() {
+ f.lock.Lock()
+ defer f.lock.Unlock()
+
+ for _, p := range f.memories {
+ C.wasm_memory_delete(p)
+ }
+ f.memories = nil
+
+ for _, p := range f.stores {
+ C.wasm_store_delete(p)
+ }
+ f.stores = nil
+
+ for _, p := range f.funcs {
+ C.wasm_func_delete(p)
+ }
+ f.funcs = nil
+
+ for _, p := range f.tables {
+ C.wasm_table_delete(p)
+ }
+ f.tables = nil
+
+ for _, p := range f.globals {
+ C.wasm_global_delete(p)
+ }
+ f.globals = nil
+
+ for _, p := range f.instances {
+ C.wasm_instance_delete(p)
+ }
+ f.instances = nil
+
+ for _, p := range f.externs {
+ C.wasm_extern_delete(p)
+ }
+ f.externs = nil
+
+ for _, p := range f.linkers {
+ C.wasmtime_linker_delete(p)
+ }
+ f.linkers = nil
+
+ for _, p := range f.wasiInstances {
+ C.wasi_instance_delete(p)
+ }
+ f.wasiInstances = nil
+
+ for _, p := range f.externVecs {
+ C.wasm_extern_vec_delete(p)
+ }
+ f.externVecs = nil
+
+ for _, p := range f.vals {
+ C.wasm_val_delete(p)
+ }
+ f.vals = nil
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/func.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/func.go
new file mode 100644
index 000000000..d4a5c20ce
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/func.go
@@ -0,0 +1,620 @@
+package wasmtime
+
+// #include "shims.h"
+import "C"
+import (
+ "errors"
+ "reflect"
+ "runtime"
+ "sync"
+ "unsafe"
+)
+
+// Func is a function instance, which is the runtime representation of a function.
+// It effectively is a closure of the original function over the runtime module instance of its originating module.
+// The module instance is used to resolve references to other definitions during execution of the function.
+// Read more in [spec](https://webassembly.github.io/spec/core/exec/runtime.html#function-instances)
+type Func struct {
+ _ptr *C.wasm_func_t
+ _owner interface{}
+ freelist *freeList
+}
+
+// TODO
+type Caller struct {
+ ptr *C.wasmtime_caller_t
+ freelist *freeList
+}
+
+// Note that `newMapEntry` and `wrapMapEntry` here need to be careful to not
+// close over any state that can retain the `freelist` or other wasmtime
+// objects. Otherwise that'll create a cycle between the Rust and Go heaps
+// which can't be garbage collected.
+type newMapEntry struct {
+ callback func(*Caller, []Val) ([]Val, *Trap)
+ results []*ValType
+ caller_id C.size_t
+}
+
+type wrapMapEntry struct {
+ callback reflect.Value
+ caller_id C.size_t
+}
+
+type callerState struct {
+ freelist *freeList
+ lastPanic interface{}
+ cnt uint
+}
+
+var gLock sync.Mutex
+var gNewMap = make(map[int]newMapEntry)
+var gNewMapSlab slab
+var gWrapMap = make(map[int]wrapMapEntry)
+var gWrapMapSlab slab
+var gCallerState = make(map[C.size_t]*callerState)
+
+// NewFunc creates a new `Func` with the given `ty` which, when called, will call `f`
+//
+// The `ty` given is the wasm type signature of the `Func` to create. When called
+// the `f` callback receives two arguments. The first is a `Caller` to learn
+// information about the calling context and the second is a list of arguments
+// represented as a `Val`. The parameters are guaranteed to match the parameters
+// types specified in `ty`.
+//
+// The `f` callback is expected to produce one of two values. Results can be
+// returned as an array of `[]Val`. The number and types of these results much
+// match the `ty` given, otherwise the program will panic. The `f` callback can
+// also produce a trap which will trigger trap unwinding in wasm, and the trap
+// will be returned to the original caller.
+//
+// If the `f` callback panics then the panic will be propagated to the caller
+// as well.
+func NewFunc(
+ store *Store,
+ ty *FuncType,
+ f func(*Caller, []Val) ([]Val, *Trap),
+) *Func {
+ gLock.Lock()
+ idx := gNewMapSlab.allocate()
+ gNewMap[idx] = newMapEntry{
+ callback: f,
+ results: ty.Results(),
+ caller_id: C.size_t(uintptr(unsafe.Pointer(store.freelist))),
+ }
+ gLock.Unlock()
+
+ ptr := C.c_func_new_with_env(
+ store.ptr(),
+ ty.ptr(),
+ C.size_t(idx),
+ 0,
+ )
+ runtime.KeepAlive(store)
+ runtime.KeepAlive(ty)
+
+ return mkFunc(ptr, store.freelist, nil)
+}
+
+//export goTrampolineNew
+func goTrampolineNew(
+ callerPtr *C.wasmtime_caller_t,
+ env C.size_t,
+ argsPtr *C.wasm_val_vec_t,
+ resultsPtr *C.wasm_val_vec_t,
+) *C.wasm_trap_t {
+ idx := int(env)
+ gLock.Lock()
+ entry := gNewMap[idx]
+ caller_id := entry.caller_id
+ freelist := gCallerState[caller_id].freelist
+ gLock.Unlock()
+
+ caller := &Caller{ptr: callerPtr, freelist: freelist}
+ defer func() { caller.ptr = nil }()
+
+ params := make([]Val, int(argsPtr.size))
+ var val C.wasm_val_t
+ base := unsafe.Pointer(argsPtr.data)
+ for i := 0; i < len(params); i++ {
+ ptr := (*C.wasm_val_t)(unsafe.Pointer(uintptr(base) + uintptr(i)*unsafe.Sizeof(val)))
+ params[i] = mkVal(ptr, freelist)
+ }
+
+ var results []Val
+ var trap *Trap
+ var lastPanic interface{}
+ func() {
+ defer func() { lastPanic = recover() }()
+ results, trap = entry.callback(caller, params)
+ if trap != nil {
+ return
+ }
+ if len(results) != len(entry.results) {
+ panic("callback didn't produce the correct number of results")
+ }
+ for i, ty := range entry.results {
+ if results[i].Kind() != ty.Kind() {
+ panic("callback produced wrong type of result")
+ }
+ }
+ }()
+ if trap == nil && lastPanic != nil {
+ gLock.Lock()
+ gCallerState[caller_id].lastPanic = lastPanic
+ gLock.Unlock()
+ return nil
+ }
+ if trap != nil {
+ runtime.SetFinalizer(trap, nil)
+ return trap.ptr()
+ }
+
+ base = unsafe.Pointer(resultsPtr.data)
+ for i := 0; i < len(results); i++ {
+ ptr := (*C.wasm_val_t)(unsafe.Pointer(uintptr(base) + uintptr(i)*unsafe.Sizeof(val)))
+ C.wasm_val_copy(ptr, results[i].ptr())
+ }
+ runtime.KeepAlive(results)
+ return nil
+}
+
+//export goFinalizeNew
+func goFinalizeNew(env unsafe.Pointer) {
+ idx := int(uintptr(env))
+ gLock.Lock()
+ defer gLock.Unlock()
+ delete(gNewMap, idx)
+ gNewMapSlab.deallocate(idx)
+}
+
+// WrapFunc wraps a native Go function, `f`, as a wasm `Func`.
+//
+// This function differs from `NewFunc` in that it will determine the type
+// signature of the wasm function given the input value `f`. The `f` value
+// provided must be a Go function. It may take any number of the following
+// types as arguments:
+//
+// `int32` - a wasm `i32`
+//
+// `int64` - a wasm `i64`
+//
+// `float32` - a wasm `f32`
+//
+// `float64` - a wasm `f32`
+//
+// `*Caller` - information about the caller's instance
+//
+// `*Func` - a wasm `funcref`
+//
+// anything else - a wasm `externref`
+//
+// The Go function may return any number of values. It can return any number of
+// primitive wasm values (integers/floats), and the last return value may
+// optionally be `*Trap`. If a `*Trap` returned is `nil` then the other values
+// are returned from the wasm function. Otherwise the `*Trap` is returned and
+// it's considered as if the host function trapped.
+//
+// If the function `f` panics then the panic will be propagated to the caller.
+func WrapFunc(
+ store *Store,
+ f interface{},
+) *Func {
+ // Make sure the `interface{}` passed in was indeed a function
+ val := reflect.ValueOf(f)
+ ty := val.Type()
+ if ty.Kind() != reflect.Func {
+ panic("callback provided must be a `func`")
+ }
+
+ // infer the parameter types, and `*Caller` type is special in the
+ // parameters so be sure to case on that as well.
+ params := make([]*ValType, 0, ty.NumIn())
+ var caller *Caller
+ for i := 0; i < ty.NumIn(); i++ {
+ paramTy := ty.In(i)
+ if paramTy != reflect.TypeOf(caller) {
+ params = append(params, typeToValType(paramTy))
+ }
+ }
+
+ // Then infer the result types, where a final `*Trap` result value is
+ // also special.
+ results := make([]*ValType, 0, ty.NumOut())
+ var trap *Trap
+ for i := 0; i < ty.NumOut(); i++ {
+ resultTy := ty.Out(i)
+ if i == ty.NumOut()-1 && resultTy == reflect.TypeOf(trap) {
+ continue
+ }
+ results = append(results, typeToValType(resultTy))
+ }
+ wasmTy := NewFuncType(params, results)
+
+ // Store our `f` callback into the slab for wrapped functions, and now
+ // we've got everything necessary to make thw asm handle.
+ gLock.Lock()
+ idx := gWrapMapSlab.allocate()
+ gWrapMap[idx] = wrapMapEntry{
+ callback: val,
+ caller_id: C.size_t(uintptr(unsafe.Pointer(store.freelist))),
+ }
+ gLock.Unlock()
+
+ ptr := C.c_func_new_with_env(
+ store.ptr(),
+ wasmTy.ptr(),
+ C.size_t(idx),
+ 1, // this is `WrapFunc`, not `NewFunc`
+ )
+ runtime.KeepAlive(store)
+ runtime.KeepAlive(wasmTy)
+ return mkFunc(ptr, store.freelist, nil)
+}
+
+func typeToValType(ty reflect.Type) *ValType {
+ var a int32
+ if ty == reflect.TypeOf(a) {
+ return NewValType(KindI32)
+ }
+ var b int64
+ if ty == reflect.TypeOf(b) {
+ return NewValType(KindI64)
+ }
+ var c float32
+ if ty == reflect.TypeOf(c) {
+ return NewValType(KindF32)
+ }
+ var d float64
+ if ty == reflect.TypeOf(d) {
+ return NewValType(KindF64)
+ }
+ var f *Func
+ if ty == reflect.TypeOf(f) {
+ return NewValType(KindFuncref)
+ }
+ return NewValType(KindExternref)
+}
+
+//export goTrampolineWrap
+func goTrampolineWrap(
+ callerPtr *C.wasmtime_caller_t,
+ env C.size_t,
+ argsPtr *C.wasm_val_vec_t,
+ resultsPtr *C.wasm_val_vec_t,
+) *C.wasm_trap_t {
+ // Convert all our parameters to `[]reflect.Value`, taking special care
+ // for `*Caller` but otherwise reading everything through `Val`.
+ idx := int(env)
+ gLock.Lock()
+ entry := gWrapMap[idx]
+ caller_id := entry.caller_id
+ freelist := gCallerState[caller_id].freelist
+ gLock.Unlock()
+
+ // Wrap our `Caller` argument in case it's needed
+ caller := &Caller{ptr: callerPtr, freelist: freelist}
+ defer func() { caller.ptr = nil }()
+
+ ty := entry.callback.Type()
+ params := make([]reflect.Value, ty.NumIn())
+ base := unsafe.Pointer(argsPtr.data)
+ var raw C.wasm_val_t
+ for i := 0; i < len(params); i++ {
+ if ty.In(i) == reflect.TypeOf(caller) {
+ params[i] = reflect.ValueOf(caller)
+ } else {
+ ptr := (*C.wasm_val_t)(base)
+ val := mkVal(ptr, freelist)
+ params[i] = reflect.ValueOf(val.Get())
+ base = unsafe.Pointer(uintptr(base) + unsafe.Sizeof(raw))
+ }
+ }
+
+ // Invoke the function, catching any panics to propagate later. Panics
+ // result in immediately returning a trap.
+ var results []reflect.Value
+ var lastPanic interface{}
+ func() {
+ defer func() { lastPanic = recover() }()
+ results = entry.callback.Call(params)
+ }()
+ if lastPanic != nil {
+ gLock.Lock()
+ gCallerState[caller_id].lastPanic = lastPanic
+ gLock.Unlock()
+ return nil
+ }
+
+ // And now we write all the results into memory depending on the type
+ // of value that was returned.
+ base = unsafe.Pointer(resultsPtr.data)
+ for _, result := range results {
+ ptr := (*C.wasm_val_t)(base)
+ switch val := result.Interface().(type) {
+ case int32:
+ *ptr = *ValI32(val).ptr()
+ case int64:
+ *ptr = *ValI64(val).ptr()
+ case float32:
+ *ptr = *ValF32(val).ptr()
+ case float64:
+ *ptr = *ValF64(val).ptr()
+ case *Func:
+ raw := ValFuncref(val)
+ C.wasm_val_copy(ptr, raw.ptr())
+ runtime.KeepAlive(raw)
+ case *Trap:
+ if val != nil {
+ runtime.SetFinalizer(val, nil)
+ return val.ptr()
+ }
+ default:
+ raw := ValExternref(val)
+ C.wasm_val_copy(ptr, raw.ptr())
+ runtime.KeepAlive(raw)
+ }
+ base = unsafe.Pointer(uintptr(base) + unsafe.Sizeof(raw))
+ }
+ return nil
+}
+
+//export goFinalizeWrap
+func goFinalizeWrap(env unsafe.Pointer) {
+ idx := int(uintptr(env))
+ gLock.Lock()
+ defer gLock.Unlock()
+ delete(gWrapMap, idx)
+ gWrapMapSlab.deallocate(idx)
+}
+
+func mkFunc(ptr *C.wasm_func_t, freelist *freeList, owner interface{}) *Func {
+ f := &Func{_ptr: ptr, _owner: owner, freelist: freelist}
+ if owner == nil {
+ runtime.SetFinalizer(f, func(f *Func) {
+ f.freelist.lock.Lock()
+ defer f.freelist.lock.Unlock()
+ f.freelist.funcs = append(f.freelist.funcs, f._ptr)
+ })
+ }
+ return f
+}
+
+func (f *Func) ptr() *C.wasm_func_t {
+ f.freelist.clear()
+ ret := f._ptr
+ maybeGC()
+ return ret
+}
+
+func (f *Func) owner() interface{} {
+ if f._owner != nil {
+ return f._owner
+ }
+ return f
+}
+
+// Type returns the type of this func
+func (f *Func) Type() *FuncType {
+ ptr := C.wasm_func_type(f.ptr())
+ runtime.KeepAlive(f)
+ return mkFuncType(ptr, nil)
+}
+
+// ParamArity returns the numer of parameters this function expects
+func (f *Func) ParamArity() int {
+ ret := C.wasm_func_param_arity(f.ptr())
+ runtime.KeepAlive(f)
+ return int(ret)
+}
+
+// ResultArity returns the numer of results this function produces
+func (f *Func) ResultArity() int {
+ ret := C.wasm_func_result_arity(f.ptr())
+ runtime.KeepAlive(f)
+ return int(ret)
+}
+
+// Call invokes this function with the provided `args`.
+//
+// This variadic function must be invoked with the correct number and type of
+// `args` as specified by the type of this function. This property is checked
+// at runtime. Each `args` may have one of the following types:
+//
+// `int32` - a wasm `i32`
+//
+// `int64` - a wasm `i64`
+//
+// `float32` - a wasm `f32`
+//
+// `float64` - a wasm `f64`
+//
+// `Val` - correspond to a wasm value
+//
+// `*Func` - a wasm `funcref`
+//
+// anything else - a wasm `externref`
+//
+// This function will have one of three results:
+//
+// 1. If the function returns successfully, then the `interface{}` return
+// argument will be the result of the function. If there were 0 results then
+// this value is `nil`. If there was one result then this is that result.
+// Otherwise if there were multiple results then `[]Val` is returned.
+//
+// 2. If this function invocation traps, then the returned `interface{}` value
+// will be `nil` and a non-`nil` `*Trap` will be returned with information
+// about the trap that happened.
+//
+// 3. If a panic in Go ends up happening somewhere, then this function will
+// panic.
+func (f *Func) Call(args ...interface{}) (interface{}, error) {
+ params := f.Type().Params()
+ if len(args) > len(params) {
+ return nil, errors.New("too many arguments provided")
+ }
+ paramsVec := C.wasm_val_vec_t{}
+ C.wasm_val_vec_new_uninitialized(¶msVec, C.size_t(len(args)))
+ for i, param := range args {
+ var rawVal Val
+ switch val := param.(type) {
+ case int:
+ switch params[i].Kind() {
+ case KindI32:
+ rawVal = ValI32(int32(val))
+ case KindI64:
+ rawVal = ValI64(int64(val))
+ default:
+ return nil, errors.New("integer provided for non-integer argument")
+ }
+ case int32:
+ rawVal = ValI32(val)
+ case int64:
+ rawVal = ValI64(val)
+ case float32:
+ rawVal = ValF32(val)
+ case float64:
+ rawVal = ValF64(val)
+ case *Func:
+ rawVal = ValFuncref(val)
+ case Val:
+ rawVal = val
+
+ default:
+ rawVal = ValExternref(val)
+ }
+
+ base := unsafe.Pointer(paramsVec.data)
+ ptr := rawVal.ptr()
+ C.wasm_val_copy(
+ (*C.wasm_val_t)(unsafe.Pointer(uintptr(base)+unsafe.Sizeof(*ptr)*uintptr(i))),
+ ptr,
+ )
+ runtime.KeepAlive(rawVal)
+ }
+
+ resultsVec := C.wasm_val_vec_t{}
+ C.wasm_val_vec_new_uninitialized(&resultsVec, C.size_t(f.ResultArity()))
+
+ var err *C.wasmtime_error_t
+ trap := enterWasm(f.freelist, func(trap **C.wasm_trap_t) {
+ err = C.go_wasmtime_func_call(
+ f.ptr(),
+ ¶msVec,
+ &resultsVec,
+ trap,
+ )
+ })
+ runtime.KeepAlive(f)
+ runtime.KeepAlive(args)
+ C.wasm_val_vec_delete(¶msVec)
+
+ if trap != nil {
+ return nil, trap
+ }
+
+ if err != nil {
+ return nil, mkError(err)
+ }
+
+ if resultsVec.size == 0 {
+ return nil, nil
+ } else if resultsVec.size == 1 {
+ ret := mkVal(resultsVec.data, f.freelist).Get()
+ C.wasm_val_vec_delete(&resultsVec)
+ return ret, nil
+ } else {
+ results := make([]Val, int(resultsVec.size))
+ base := unsafe.Pointer(resultsVec.data)
+ var val C.wasm_val_t
+ for i := 0; i < int(resultsVec.size); i++ {
+ ptr := (*C.wasm_val_t)(unsafe.Pointer(uintptr(base) + unsafe.Sizeof(val)*uintptr(i)))
+ results[i] = mkVal(ptr, f.freelist)
+ }
+ C.wasm_val_vec_delete(&resultsVec)
+ return results, nil
+ }
+
+}
+
+func (f *Func) AsExtern() *Extern {
+ ptr := C.wasm_func_as_extern(f.ptr())
+ return mkExtern(ptr, f.freelist, f.owner())
+}
+
+// GetExport gets an exported item from the caller's module.
+//
+// May return `nil` if the export doesn't, if it's not a memory, if there isn't
+// a caller, etc.
+func (c *Caller) GetExport(name string) *Extern {
+ if c.ptr == nil {
+ return nil
+ }
+ ptr := C.go_caller_export_get(
+ c.ptr,
+ C._GoStringPtr(name),
+ C._GoStringLen(name),
+ )
+ runtime.KeepAlive(name)
+ runtime.KeepAlive(c)
+ if ptr == nil {
+ return nil
+ }
+
+ return mkExtern(ptr, c.freelist, nil)
+}
+
+// Shim function that's expected to wrap any invocations of WebAssembly from Go
+// itself.
+func enterWasm(freelist *freeList, wasm func(**C.wasm_trap_t)) *Trap {
+ // First thing we need to do is update `gCallerState` with the actual
+ // pointer to `freelist` since when calling wasm we may call a Go
+ // function which needs the freelist.
+ //
+ // Note that if there's already an entry in the map we just increase
+ // the reference count.
+ gLock.Lock()
+ caller_id := C.size_t(uintptr(unsafe.Pointer(freelist)))
+ if _, ok := gCallerState[caller_id]; !ok {
+ gCallerState[caller_id] = &callerState{freelist: freelist}
+ }
+ gCallerState[caller_id].cnt++
+ gLock.Unlock()
+
+ // After `gCallerState` is configured we can actually enter the wasm
+ // code. We handle traps/panics here so we pass in the trap pointer.
+ //
+ // Note that it's assumed that this never panics.
+ var trap *C.wasm_trap_t
+ wasm(&trap)
+
+ // After wasm has finished we need to remove `freelist` from the global
+ // `gCallerState` map to ensure it can eventually get GC'd. Here we
+ // also propagate any Go-originating panics if they're found.
+ gLock.Lock()
+ state := gCallerState[caller_id]
+ lastPanic := state.lastPanic
+ state.lastPanic = nil
+ state.cnt--
+ if state.cnt == 0 {
+ delete(gCallerState, caller_id)
+ }
+ gLock.Unlock()
+
+ // Take ownership of the return trapped pointer to ensure we don't leak
+ // it, even if Go panicked.
+ var wrappedTrap *Trap
+ if trap != nil {
+ wrappedTrap = mkTrap(trap)
+ }
+
+ // Check to see if we called a Go host function which panicked, in
+ // which case we propagate that here.
+ if lastPanic != nil {
+ panic(lastPanic)
+ }
+
+ // And otherwise if Go didn't panic we return whether the function
+ // trapped or not.
+ return wrappedTrap
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/functype.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/functype.go
new file mode 100644
index 000000000..8c071c362
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/functype.go
@@ -0,0 +1,91 @@
+package wasmtime
+
+// #include
+import "C"
+import (
+ "runtime"
+ "unsafe"
+)
+
+// FuncType is one of function types which classify the signature of functions, mapping a vector of parameters to a vector of results.
+// They are also used to classify the inputs and outputs of instructions.
+type FuncType struct {
+ _ptr *C.wasm_functype_t
+ _owner interface{}
+}
+
+// NewFuncType creates a new `FuncType` with the `kind` provided
+func NewFuncType(params, results []*ValType) *FuncType {
+ paramVec := mkValTypeList(params)
+ resultVec := mkValTypeList(results)
+
+ ptr := C.wasm_functype_new(¶mVec, &resultVec)
+
+ return mkFuncType(ptr, nil)
+}
+
+func mkValTypeList(tys []*ValType) C.wasm_valtype_vec_t {
+ vec := C.wasm_valtype_vec_t{}
+ C.wasm_valtype_vec_new_uninitialized(&vec, C.size_t(len(tys)))
+ base := unsafe.Pointer(vec.data)
+ for i, ty := range tys {
+ ptr := C.wasm_valtype_new(C.wasm_valtype_kind(ty.ptr()))
+ *(**C.wasm_valtype_t)(unsafe.Pointer(uintptr(base) + unsafe.Sizeof(ptr)*uintptr(i))) = ptr
+ }
+ runtime.KeepAlive(tys)
+ return vec
+}
+
+func mkFuncType(ptr *C.wasm_functype_t, owner interface{}) *FuncType {
+ functype := &FuncType{_ptr: ptr, _owner: owner}
+ if owner == nil {
+ runtime.SetFinalizer(functype, func(functype *FuncType) {
+ C.wasm_functype_delete(functype._ptr)
+ })
+ }
+ return functype
+}
+
+func (ty *FuncType) ptr() *C.wasm_functype_t {
+ ret := ty._ptr
+ maybeGC()
+ return ret
+}
+
+func (ty *FuncType) owner() interface{} {
+ if ty._owner != nil {
+ return ty._owner
+ }
+ return ty
+}
+
+// Params returns the parameter types of this function type
+func (ty *FuncType) Params() []*ValType {
+ ptr := C.wasm_functype_params(ty.ptr())
+ return ty.convertTypeList(ptr)
+}
+
+// Results returns the result types of this function type
+func (ty *FuncType) Results() []*ValType {
+ ptr := C.wasm_functype_results(ty.ptr())
+ return ty.convertTypeList(ptr)
+}
+
+func (ty *FuncType) convertTypeList(list *C.wasm_valtype_vec_t) []*ValType {
+ ret := make([]*ValType, list.size)
+
+ base := unsafe.Pointer(list.data)
+ var ptr *C.wasm_valtype_t
+ for i := 0; i < int(list.size); i++ {
+ ptr := *(**C.wasm_valtype_t)(unsafe.Pointer(uintptr(base) + unsafe.Sizeof(ptr)*uintptr(i)))
+ ty := mkValType(ptr, ty.owner())
+ ret[i] = ty
+ }
+ return ret
+}
+
+// AsExternType converts this type to an instance of `ExternType`
+func (ty *FuncType) AsExternType() *ExternType {
+ ptr := C.wasm_functype_as_externtype_const(ty.ptr())
+ return mkExternType(ptr, ty.owner())
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/global.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/global.go
new file mode 100644
index 000000000..fb1af01c2
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/global.go
@@ -0,0 +1,95 @@
+package wasmtime
+
+// #include
+import "C"
+import "runtime"
+
+// Global is a global instance, which is the runtime representation of a global variable.
+// It holds an individual value and a flag indicating whether it is mutable.
+// Read more in [spec](https://webassembly.github.io/spec/core/exec/runtime.html#global-instances)
+type Global struct {
+ _ptr *C.wasm_global_t
+ _owner interface{}
+ freelist *freeList
+}
+
+// NewGlobal creates a new `Global` in the given `Store` with the specified `ty` and
+// initial value `val`.
+func NewGlobal(
+ store *Store,
+ ty *GlobalType,
+ val Val,
+) (*Global, error) {
+ var ptr *C.wasm_global_t
+ err := C.wasmtime_global_new(
+ store.ptr(),
+ ty.ptr(),
+ val.ptr(),
+ &ptr,
+ )
+ runtime.KeepAlive(store)
+ runtime.KeepAlive(ty)
+ runtime.KeepAlive(val)
+ if err != nil {
+ return nil, mkError(err)
+ }
+
+ return mkGlobal(ptr, store.freelist, nil), nil
+}
+
+func mkGlobal(ptr *C.wasm_global_t, freelist *freeList, owner interface{}) *Global {
+ f := &Global{_ptr: ptr, _owner: owner, freelist: freelist}
+ if owner == nil {
+ runtime.SetFinalizer(f, func(f *Global) {
+ f.freelist.lock.Lock()
+ defer f.freelist.lock.Unlock()
+ f.freelist.globals = append(f.freelist.globals, f._ptr)
+ })
+ }
+ return f
+}
+
+func (g *Global) ptr() *C.wasm_global_t {
+ ret := g._ptr
+ maybeGC()
+ return ret
+}
+
+func (g *Global) owner() interface{} {
+ if g._owner != nil {
+ return g._owner
+ }
+ return g
+}
+
+// Type returns the type of this global
+func (g *Global) Type() *GlobalType {
+ ptr := C.wasm_global_type(g.ptr())
+ runtime.KeepAlive(g)
+ return mkGlobalType(ptr, nil)
+}
+
+// Get gets the value of this global
+func (g *Global) Get() Val {
+ ret := C.wasm_val_t{}
+ C.wasm_global_get(g.ptr(), &ret)
+ runtime.KeepAlive(g)
+ return takeVal(&ret, g.freelist)
+}
+
+// Set sets the value of this global
+func (g *Global) Set(val Val) error {
+ err := C.wasmtime_global_set(g.ptr(), val.ptr())
+ runtime.KeepAlive(g)
+ runtime.KeepAlive(val)
+ if err == nil {
+ return nil
+ }
+
+ return mkError(err)
+}
+
+func (g *Global) AsExtern() *Extern {
+ ptr := C.wasm_global_as_extern(g.ptr())
+ return mkExtern(ptr, g.freelist, g.owner())
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/globaltype.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/globaltype.go
new file mode 100644
index 000000000..b948febaf
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/globaltype.go
@@ -0,0 +1,67 @@
+package wasmtime
+
+// #include
+import "C"
+import "runtime"
+
+// GlobalType is a ValType, which classify global variables and hold a value and can either be mutable or immutable.
+type GlobalType struct {
+ _ptr *C.wasm_globaltype_t
+ _owner interface{}
+}
+
+// NewGlobalType creates a new `GlobalType` with the `kind` provided and whether it's
+// `mutable` or not
+func NewGlobalType(content *ValType, mutable bool) *GlobalType {
+ mutability := C.WASM_CONST
+ if mutable {
+ mutability = C.WASM_VAR
+ }
+ contentPtr := C.wasm_valtype_new(C.wasm_valtype_kind(content.ptr()))
+ runtime.KeepAlive(content)
+ ptr := C.wasm_globaltype_new(contentPtr, C.wasm_mutability_t(mutability))
+
+ return mkGlobalType(ptr, nil)
+}
+
+func mkGlobalType(ptr *C.wasm_globaltype_t, owner interface{}) *GlobalType {
+ globaltype := &GlobalType{_ptr: ptr, _owner: owner}
+ if owner == nil {
+ runtime.SetFinalizer(globaltype, func(globaltype *GlobalType) {
+ C.wasm_globaltype_delete(globaltype._ptr)
+ })
+ }
+ return globaltype
+}
+
+func (ty *GlobalType) ptr() *C.wasm_globaltype_t {
+ ret := ty._ptr
+ maybeGC()
+ return ret
+}
+
+func (ty *GlobalType) owner() interface{} {
+ if ty._owner != nil {
+ return ty._owner
+ }
+ return ty
+}
+
+// Content returns the type of value stored in this global
+func (ty *GlobalType) Content() *ValType {
+ ptr := C.wasm_globaltype_content(ty.ptr())
+ return mkValType(ptr, ty.owner())
+}
+
+// Mutable returns whether this global type is mutable or not
+func (ty *GlobalType) Mutable() bool {
+ ret := C.wasm_globaltype_mutability(ty.ptr()) == C.WASM_VAR
+ runtime.KeepAlive(ty)
+ return ret
+}
+
+// AsExternType converts this type to an instance of `ExternType`
+func (ty *GlobalType) AsExternType() *ExternType {
+ ptr := C.wasm_globaltype_as_externtype_const(ty.ptr())
+ return mkExternType(ptr, ty.owner())
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/go.mod b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/go.mod
new file mode 100644
index 000000000..7f140bb0b
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/go.mod
@@ -0,0 +1,3 @@
+module github.com/bytecodealliance/wasmtime-go
+
+go 1.14
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/importtype.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/importtype.go
new file mode 100644
index 000000000..a8f2fced5
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/importtype.go
@@ -0,0 +1,82 @@
+package wasmtime
+
+// #include
+import "C"
+import "runtime"
+
+// ImportType is one of the imports component
+// A module defines a set of imports that are required for instantiation.
+type ImportType struct {
+ _ptr *C.wasm_importtype_t
+ _owner interface{}
+}
+
+// NewImportType creates a new `ImportType` with the given `module` and `name` and the type
+// provided.
+func NewImportType(module, name string, ty AsExternType) *ImportType {
+ moduleVec := stringToByteVec(module)
+ nameVec := stringToByteVec(name)
+
+ // Creating an import type requires taking ownership, so create a copy
+ // so we don't have to invalidate pointers here. Shouldn't be too
+ // costly in theory anyway.
+ extern := ty.AsExternType()
+ ptr := C.wasm_externtype_copy(extern.ptr())
+ runtime.KeepAlive(extern)
+
+ // And once we've got all that create the import type!
+ importPtr := C.wasm_importtype_new(&moduleVec, &nameVec, ptr)
+
+ return mkImportType(importPtr, nil)
+}
+
+func mkImportType(ptr *C.wasm_importtype_t, owner interface{}) *ImportType {
+ importtype := &ImportType{_ptr: ptr, _owner: owner}
+ if owner == nil {
+ runtime.SetFinalizer(importtype, func(importtype *ImportType) {
+ C.wasm_importtype_delete(importtype._ptr)
+ })
+ }
+ return importtype
+}
+
+func (ty *ImportType) ptr() *C.wasm_importtype_t {
+ ret := ty._ptr
+ maybeGC()
+ return ret
+}
+
+func (ty *ImportType) owner() interface{} {
+ if ty._owner != nil {
+ return ty._owner
+ }
+ return ty
+}
+
+// Module returns the name in the module this import type is importing
+func (ty *ImportType) Module() string {
+ ptr := C.wasm_importtype_module(ty.ptr())
+ ret := C.GoStringN(ptr.data, C.int(ptr.size))
+ runtime.KeepAlive(ty)
+ return ret
+}
+
+// Name returns the name in the module this import type is importing.
+//
+// Note that the returned string may be `nil` with the module linking proposal
+// where this field is optional in the import type.
+func (ty *ImportType) Name() *string {
+ ptr := C.wasm_importtype_name(ty.ptr())
+ if ptr == nil {
+ return nil
+ }
+ ret := C.GoStringN(ptr.data, C.int(ptr.size))
+ runtime.KeepAlive(ty)
+ return &ret
+}
+
+// Type returns the type of item this import type expects
+func (ty *ImportType) Type() *ExternType {
+ ptr := C.wasm_importtype_type(ty.ptr())
+ return mkExternType(ptr, ty.owner())
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/instance.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/instance.go
new file mode 100644
index 000000000..c8b105c09
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/instance.go
@@ -0,0 +1,160 @@
+package wasmtime
+
+// #include
+import "C"
+import (
+ "runtime"
+ "unsafe"
+)
+
+// Instance is an instantiated module instance.
+// Once a module has been instantiated as an Instance, any exported function can be invoked externally via its function address funcaddr in the store S and an appropriate list val∗ of argument values.
+type Instance struct {
+ _ptr *C.wasm_instance_t
+ exports map[string]*Extern
+ exportsPopulated bool
+ freelist *freeList
+ _owner interface{}
+}
+
+// NewInstance instantiates a WebAssembly `module` with the `imports` provided.
+//
+// This function will attempt to create a new wasm instance given the provided
+// imports. This can fail if the wrong number of imports are specified, the
+// imports aren't of the right type, or for other resource-related issues.
+//
+// This will also run the `start` function of the instance, returning an error
+// if it traps.
+func NewInstance(store *Store, module *Module, imports []*Extern) (*Instance, error) {
+ importsRaw := C.wasm_extern_vec_t{}
+ C.wasm_extern_vec_new_uninitialized(&importsRaw, C.size_t(len(imports)))
+ base := unsafe.Pointer(importsRaw.data)
+ for i, imp := range imports {
+ ptr := C.wasm_extern_copy(imp.ptr())
+ *(**C.wasm_extern_t)(unsafe.Pointer(uintptr(base) + unsafe.Sizeof(ptr)*uintptr(i))) = ptr
+ }
+ var ptr *C.wasm_instance_t
+ var err *C.wasmtime_error_t
+ trap := enterWasm(store.freelist, func(trap **C.wasm_trap_t) {
+ err = C.wasmtime_instance_new(
+ store.ptr(),
+ module.ptr(),
+ &importsRaw,
+ &ptr,
+ trap,
+ )
+ })
+ runtime.KeepAlive(store)
+ runtime.KeepAlive(module)
+ C.wasm_extern_vec_delete(&importsRaw)
+ if trap != nil {
+ return nil, trap
+ }
+ if err != nil {
+ return nil, mkError(err)
+ }
+ return mkInstance(ptr, store.freelist, nil), nil
+}
+
+func mkInstance(ptr *C.wasm_instance_t, freelist *freeList, owner interface{}) *Instance {
+ instance := &Instance{
+ _ptr: ptr,
+ exports: make(map[string]*Extern),
+ exportsPopulated: false,
+ freelist: freelist,
+ _owner: owner,
+ }
+ if owner == nil {
+ runtime.SetFinalizer(instance, func(instance *Instance) {
+ freelist := instance.freelist
+ freelist.lock.Lock()
+ defer freelist.lock.Unlock()
+ freelist.instances = append(freelist.instances, instance._ptr)
+ })
+ }
+ return instance
+}
+
+func (i *Instance) ptr() *C.wasm_instance_t {
+ ret := i._ptr
+ maybeGC()
+ return ret
+}
+
+func (i *Instance) owner() interface{} {
+ if i._owner != nil {
+ return i._owner
+ }
+ return i
+}
+
+// Type returns an `InstanceType` that corresponds for this instance.
+func (i *Instance) Type() *InstanceType {
+ ptr := C.wasm_instance_type(i.ptr())
+ runtime.KeepAlive(i)
+ return mkInstanceType(ptr, nil)
+}
+
+type externList struct {
+ vec C.wasm_extern_vec_t
+}
+
+// Exports returns a list of exports from this instance.
+//
+// Each export is returned as a `*Extern` and lines up with the exports list of
+// the associated `Module`.
+func (i *Instance) Exports() []*Extern {
+ externs := &externList{}
+ C.wasm_instance_exports(i.ptr(), &externs.vec)
+ runtime.KeepAlive(i)
+ freelist := i.freelist
+ runtime.SetFinalizer(externs, func(externs *externList) {
+ freelist.lock.Lock()
+ defer freelist.lock.Unlock()
+ freelist.externVecs = append(freelist.externVecs, &externs.vec)
+ })
+
+ ret := make([]*Extern, int(externs.vec.size))
+ base := unsafe.Pointer(externs.vec.data)
+ var ptr *C.wasm_extern_t
+ for i := 0; i < int(externs.vec.size); i++ {
+ ptr := *(**C.wasm_extern_t)(unsafe.Pointer(uintptr(base) + unsafe.Sizeof(ptr)*uintptr(i)))
+ ty := mkExtern(ptr, freelist, externs)
+ ret[i] = ty
+ }
+ return ret
+}
+
+// GetExport attempts to find an export on this instance by `name`
+//
+// May return `nil` if this instance has no export named `name`
+func (i *Instance) GetExport(name string) *Extern {
+ if !i.exportsPopulated {
+ i.populateExports()
+ }
+ return i.exports[name]
+}
+
+// GetFunc attemps to find a function on this instance by `name`.
+//
+// May return `nil` if this instance has no function named `name`,
+// it is not a function, etc.
+func (i *Instance) GetFunc(name string) *Func {
+ f := i.GetExport(name)
+ if f == nil {
+ return nil
+ }
+ return f.Func()
+}
+
+func (i *Instance) populateExports() {
+ exports := i.Exports()
+ for j, ty := range i.Type().Exports() {
+ i.exports[ty.Name()] = exports[j]
+ }
+}
+
+func (i *Instance) AsExtern() *Extern {
+ ptr := C.wasm_instance_as_extern(i.ptr())
+ return mkExtern(ptr, i.freelist, i.owner())
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/instancetype.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/instancetype.go
new file mode 100644
index 000000000..7164bcb05
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/instancetype.go
@@ -0,0 +1,49 @@
+package wasmtime
+
+// #include
+import "C"
+import "runtime"
+
+// InstanceType describes the exports of an instance.
+type InstanceType struct {
+ _ptr *C.wasm_instancetype_t
+ _owner interface{}
+}
+
+func mkInstanceType(ptr *C.wasm_instancetype_t, owner interface{}) *InstanceType {
+ instancetype := &InstanceType{_ptr: ptr, _owner: owner}
+ if owner == nil {
+ runtime.SetFinalizer(instancetype, func(instancetype *InstanceType) {
+ C.wasm_instancetype_delete(instancetype._ptr)
+ })
+ }
+ return instancetype
+}
+
+func (ty *InstanceType) ptr() *C.wasm_instancetype_t {
+ ret := ty._ptr
+ maybeGC()
+ return ret
+}
+
+func (ty *InstanceType) owner() interface{} {
+ if ty._owner != nil {
+ return ty._owner
+ }
+ return ty
+}
+
+// AsExternType converts this type to an instance of `ExternType`
+func (ty *InstanceType) AsExternType() *ExternType {
+ ptr := C.wasm_instancetype_as_externtype_const(ty.ptr())
+ return mkExternType(ptr, ty.owner())
+}
+
+// Exports returns a list of `ExportType` items which are the items that will
+// be exported by this instance after instantiation.
+func (ty *InstanceType) Exports() []*ExportType {
+ exports := &exportTypeList{}
+ C.wasm_instancetype_exports(ty.ptr(), &exports.vec)
+ runtime.KeepAlive(ty)
+ return exports.mkGoList()
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/limits.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/limits.go
new file mode 100644
index 000000000..7655dc7b9
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/limits.go
@@ -0,0 +1,45 @@
+package wasmtime
+
+// #include
+import "C"
+import "runtime"
+
+// LimitsMaxNone is the value for the Max field in Limits
+const LimitsMaxNone = 0xffffffff
+
+// Limits is the resource limits specified for a TableType and MemoryType
+type Limits struct {
+ // The minimum size of this resource, in units specified by the resource
+ // itself.
+ Min uint32
+ // The maximum size of this resource, in units specified by the resource
+ // itself.
+ //
+ // A value of LimitsMaxNone will mean that there is no maximum.
+ Max uint32
+}
+
+// NewLimits creates a new resource limits specified for a TableType and MemoryType,
+// in which min and max are the minimum and maximum size of this resource.
+func NewLimits(min, max uint32) *Limits {
+ return &Limits{
+ Min: min,
+ Max: max,
+ }
+}
+
+func (limits Limits) ffi() C.wasm_limits_t {
+ return C.wasm_limits_t{
+ min: C.uint32_t(limits.Min),
+ max: C.uint32_t(limits.Max),
+ }
+}
+
+func mkLimits(ptr *C.wasm_limits_t, owner interface{}) Limits {
+ ret := Limits{
+ Min: uint32(ptr.min),
+ Max: uint32(ptr.max),
+ }
+ runtime.KeepAlive(owner)
+ return ret
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/linker.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/linker.go
new file mode 100644
index 000000000..851ed4898
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/linker.go
@@ -0,0 +1,202 @@
+package wasmtime
+
+// #include
+// #include "shims.h"
+import "C"
+import "runtime"
+
+// Linker implements a wasmtime Linking module, which can link instantiated modules together.
+// More details you can see [examples for C](https://bytecodealliance.github.io/wasmtime/examples-c-linking.html) or
+// [examples for Rust](https://bytecodealliance.github.io/wasmtime/examples-rust-linking.html)
+type Linker struct {
+ _ptr *C.wasmtime_linker_t
+ Store *Store
+}
+
+func NewLinker(store *Store) *Linker {
+ ptr := C.wasmtime_linker_new(store.ptr())
+ runtime.KeepAlive(store)
+ return mkLinker(ptr, store)
+}
+
+func mkLinker(ptr *C.wasmtime_linker_t, store *Store) *Linker {
+ linker := &Linker{_ptr: ptr, Store: store}
+ runtime.SetFinalizer(linker, func(linker *Linker) {
+ freelist := linker.Store.freelist
+ freelist.lock.Lock()
+ defer freelist.lock.Unlock()
+ freelist.linkers = append(freelist.linkers, linker._ptr)
+ })
+ return linker
+}
+
+func (l *Linker) ptr() *C.wasmtime_linker_t {
+ ret := l._ptr
+ maybeGC()
+ return ret
+}
+
+// AllowShadowing configures whether names can be redefined after they've already been defined
+// in this linker.
+func (l *Linker) AllowShadowing(allow bool) {
+ C.wasmtime_linker_allow_shadowing(l.ptr(), C.bool(allow))
+ runtime.KeepAlive(l)
+}
+
+// Define defines a new item in this linker with the given module/name pair. Returns
+// an error if shadowing is disallowed and the module/name is already defined.
+func (l *Linker) Define(module, name string, item AsExtern) error {
+ extern := item.AsExtern()
+ err := C.go_linker_define(
+ l.ptr(),
+ C._GoStringPtr(module),
+ C._GoStringLen(module),
+ C._GoStringPtr(name),
+ C._GoStringLen(name),
+ extern.ptr(),
+ )
+ runtime.KeepAlive(l)
+ runtime.KeepAlive(module)
+ runtime.KeepAlive(name)
+ runtime.KeepAlive(extern)
+ if err == nil {
+ return nil
+ }
+
+ return mkError(err)
+}
+
+// DefineFunc acts as a convenience wrapper to calling Define and WrapFunc.
+//
+// Returns an error if shadowing is disabled and the name is already defined.
+func (l *Linker) DefineFunc(module, name string, f interface{}) error {
+ return l.Define(module, name, WrapFunc(l.Store, f))
+}
+
+// DefineInstance defines all exports of an instance provided under the module name provided.
+//
+// Returns an error if shadowing is disabled and names are already defined.
+func (l *Linker) DefineInstance(module string, instance *Instance) error {
+ err := C.go_linker_define_instance(
+ l.ptr(),
+ C._GoStringPtr(module),
+ C._GoStringLen(module),
+ instance.ptr(),
+ )
+ runtime.KeepAlive(l)
+ runtime.KeepAlive(module)
+ runtime.KeepAlive(instance)
+ if err == nil {
+ return nil
+ }
+
+ return mkError(err)
+}
+
+// DefineModule defines automatic instantiations of the module in this linker.
+//
+// The `name` of the module is the name within the linker, and the `module` is
+// the one that's being instantiated. This function automatically handles
+// WASI Commands and Reactors for instantiation and initialization. For more
+// information see the Rust documentation --
+// https://docs.wasmtime.dev/api/wasmtime/struct.Linker.html#method.module.
+func (l *Linker) DefineModule(name string, module *Module) error {
+ err := C.go_linker_define_module(
+ l.ptr(),
+ C._GoStringPtr(name),
+ C._GoStringLen(name),
+ module.ptr(),
+ )
+ runtime.KeepAlive(l)
+ runtime.KeepAlive(name)
+ runtime.KeepAlive(module)
+ if err == nil {
+ return nil
+ }
+
+ return mkError(err)
+}
+
+// DefineWasi links a WASI module into this linker, ensuring that all exported functions
+// are available for linking.
+//
+// Returns an error if shadowing is disabled and names are already defined.
+func (l *Linker) DefineWasi(instance *WasiInstance) error {
+ err := C.wasmtime_linker_define_wasi(l.ptr(), instance.ptr())
+ runtime.KeepAlive(l)
+ runtime.KeepAlive(instance)
+ if err == nil {
+ return nil
+ }
+
+ return mkError(err)
+}
+
+// Instantiate instantates a module with all imports defined in this linker.
+//
+// Returns an error if the instance's imports couldn't be satisfied, had the
+// wrong types, or if a trap happened executing the start function.
+func (l *Linker) Instantiate(module *Module) (*Instance, error) {
+ var ret *C.wasm_instance_t
+ var err *C.wasmtime_error_t
+ trap := enterWasm(l.Store.freelist, func(trap **C.wasm_trap_t) {
+ err = C.wasmtime_linker_instantiate(l.ptr(), module.ptr(), &ret, trap)
+ })
+ runtime.KeepAlive(l)
+ runtime.KeepAlive(module)
+ if trap != nil {
+ return nil, trap
+ }
+ if err != nil {
+ return nil, mkError(err)
+ }
+ return mkInstance(ret, l.Store.freelist, nil), nil
+}
+
+// GetDefault acquires the "default export" of the named module in this linker.
+//
+// If there is no default item then an error is returned, otherwise the default
+// function is returned.
+//
+// For more information see the Rust documentation --
+// https://docs.wasmtime.dev/api/wasmtime/struct.Linker.html#method.get_default.
+func (l *Linker) GetDefault(name string) (*Func, error) {
+ var ret *C.wasm_func_t
+ err := C.go_linker_get_default(
+ l.ptr(),
+ C._GoStringPtr(name),
+ C._GoStringLen(name),
+ &ret,
+ )
+ runtime.KeepAlive(l)
+ runtime.KeepAlive(name)
+ if err != nil {
+ return nil, mkError(err)
+ }
+ return mkFunc(ret, l.Store.freelist, nil), nil
+
+}
+
+// GetOneByName loads an item by name from this linker.
+//
+// If the item isn't defined then an error is returned, otherwise the item is
+// returned.
+func (l *Linker) GetOneByName(module, name string) (*Extern, error) {
+ var ret *C.wasm_extern_t
+ err := C.go_linker_get_one_by_name(
+ l.ptr(),
+ C._GoStringPtr(module),
+ C._GoStringLen(module),
+ C._GoStringPtr(name),
+ C._GoStringLen(name),
+ &ret,
+ )
+ runtime.KeepAlive(l)
+ runtime.KeepAlive(name)
+ runtime.KeepAlive(module)
+ if err != nil {
+ return nil, mkError(err)
+ }
+ return mkExtern(ret, l.Store.freelist, nil), nil
+
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/maybe_gc_actual.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/maybe_gc_actual.go
new file mode 100644
index 000000000..7ef37c434
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/maybe_gc_actual.go
@@ -0,0 +1,11 @@
+// +build debug
+
+package wasmtime
+
+// See `ffi.go` documentation about `ptr()` for what's going on here.
+
+import "runtime"
+
+func maybeGC() {
+ runtime.GC()
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/maybe_gc_no.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/maybe_gc_no.go
new file mode 100644
index 000000000..5b8f39821
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/maybe_gc_no.go
@@ -0,0 +1,8 @@
+// +build !debug
+
+package wasmtime
+
+// See `ffi.go` documentation about `ptr()` for what's going on here.
+
+func maybeGC() {
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/memory.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/memory.go
new file mode 100644
index 000000000..ce7bddd73
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/memory.go
@@ -0,0 +1,111 @@
+package wasmtime
+
+// #include
+import "C"
+import (
+ "runtime"
+ "unsafe"
+)
+
+// Memory instance is the runtime representation of a linear memory.
+// It holds a vector of bytes and an optional maximum size, if one was specified at the definition site of the memory.
+// Read more in [spec](https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances)
+// In wasmtime-go, you can get the vector of bytes by the unsafe pointer of memory from `Memory.Data()`, or go style byte slice from `Memory.UnsafeData()`
+type Memory struct {
+ _ptr *C.wasm_memory_t
+ freelist *freeList
+ _owner interface{}
+}
+
+// NewMemory creates a new `Memory` in the given `Store` with the specified `ty`.
+func NewMemory(store *Store, ty *MemoryType) *Memory {
+ ptr := C.wasm_memory_new(store.ptr(), ty.ptr())
+ runtime.KeepAlive(store)
+ runtime.KeepAlive(ty)
+ return mkMemory(ptr, store.freelist, nil)
+}
+
+func mkMemory(ptr *C.wasm_memory_t, freelist *freeList, owner interface{}) *Memory {
+ f := &Memory{_ptr: ptr, _owner: owner, freelist: freelist}
+ if owner == nil {
+ runtime.SetFinalizer(f, func(f *Memory) {
+ f.freelist.lock.Lock()
+ defer f.freelist.lock.Unlock()
+ f.freelist.memories = append(f.freelist.memories, f._ptr)
+ })
+ }
+ return f
+}
+
+func (mem *Memory) ptr() *C.wasm_memory_t {
+ ret := mem._ptr
+ maybeGC()
+ return ret
+}
+
+func (mem *Memory) owner() interface{} {
+ if mem._owner != nil {
+ return mem._owner
+ }
+ return mem
+}
+
+// Type returns the type of this memory
+func (mem *Memory) Type() *MemoryType {
+ ptr := C.wasm_memory_type(mem.ptr())
+ runtime.KeepAlive(mem)
+ return mkMemoryType(ptr, nil)
+}
+
+// Data returns the raw pointer in memory of where this memory starts
+func (mem *Memory) Data() unsafe.Pointer {
+ ret := unsafe.Pointer(C.wasm_memory_data(mem.ptr()))
+ runtime.KeepAlive(mem)
+ return ret
+}
+
+// UnsafeData returns the raw memory backed by this `Memory` as a byte slice (`[]byte`).
+//
+// This is not a safe method to call, hence the "unsafe" in the name. The byte
+// slice returned from this function is not managed by the Go garbage collector.
+// You need to ensure that `m`, the original `Memory`, lives longer than the
+// `[]byte` returned.
+//
+// Note that you may need to use `runtime.KeepAlive` to keep the original memory
+// `m` alive for long enough while you're using the `[]byte` slice. If the
+// `[]byte` slice is used after `m` is GC'd then that is undefined behavior.
+func (mem *Memory) UnsafeData() []byte {
+ // see https://github.com/golang/go/wiki/cgo#turning-c-arrays-into-go-slices
+ const MaxLen = 1 << 32
+ length := mem.DataSize()
+ if length >= MaxLen {
+ panic("memory is too big")
+ }
+ return (*[MaxLen]byte)(mem.Data())[:length:length]
+}
+
+// DataSize returns the size, in bytes, that `Data()` is valid for
+func (mem *Memory) DataSize() uintptr {
+ ret := uintptr(C.wasm_memory_data_size(mem.ptr()))
+ runtime.KeepAlive(mem)
+ return ret
+}
+
+// Size returns the size, in wasm pages, of this memory
+func (mem *Memory) Size() uint32 {
+ ret := uint32(C.wasm_memory_size(mem.ptr()))
+ runtime.KeepAlive(mem)
+ return ret
+}
+
+// Grow grows this memory by `delta` pages
+func (mem *Memory) Grow(delta uint) bool {
+ ret := C.wasm_memory_grow(mem.ptr(), C.wasm_memory_pages_t(delta))
+ runtime.KeepAlive(mem)
+ return bool(ret)
+}
+
+func (mem *Memory) AsExtern() *Extern {
+ ptr := C.wasm_memory_as_extern(mem.ptr())
+ return mkExtern(ptr, mem.freelist, mem.owner())
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/memorytype.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/memorytype.go
new file mode 100644
index 000000000..fb354cf7b
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/memorytype.go
@@ -0,0 +1,54 @@
+package wasmtime
+
+// #include
+import "C"
+import "runtime"
+
+// MemoryType is one of Memory types which classify linear memories and their size range.
+// The limits constrain the minimum and optionally the maximum size of a memory. The limits are given in units of page size.
+type MemoryType struct {
+ _ptr *C.wasm_memorytype_t
+ _owner interface{}
+}
+
+// NewMemoryType creates a new `MemoryType` with the `limits` on size provided
+func NewMemoryType(limits Limits) *MemoryType {
+ limitsFFI := limits.ffi()
+ ptr := C.wasm_memorytype_new(&limitsFFI)
+ return mkMemoryType(ptr, nil)
+}
+
+func mkMemoryType(ptr *C.wasm_memorytype_t, owner interface{}) *MemoryType {
+ memorytype := &MemoryType{_ptr: ptr, _owner: owner}
+ if owner == nil {
+ runtime.SetFinalizer(memorytype, func(memorytype *MemoryType) {
+ C.wasm_memorytype_delete(memorytype._ptr)
+ })
+ }
+ return memorytype
+}
+
+func (ty *MemoryType) ptr() *C.wasm_memorytype_t {
+ ret := ty._ptr
+ maybeGC()
+ return ret
+}
+
+func (ty *MemoryType) owner() interface{} {
+ if ty._owner != nil {
+ return ty._owner
+ }
+ return ty
+}
+
+// Limits returns the limits on the size of this memory type
+func (ty *MemoryType) Limits() Limits {
+ ptr := C.wasm_memorytype_limits(ty.ptr())
+ return mkLimits(ptr, ty.owner())
+}
+
+// AsExternType converts this type to an instance of `ExternType`
+func (ty *MemoryType) AsExternType() *ExternType {
+ ptr := C.wasm_memorytype_as_externtype_const(ty.ptr())
+ return mkExternType(ptr, ty.owner())
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/module.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/module.go
new file mode 100644
index 000000000..47f75136d
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/module.go
@@ -0,0 +1,260 @@
+package wasmtime
+
+// #include
+//
+// wasmtime_error_t *go_module_new(wasm_engine_t *engine, uint8_t *bytes, size_t len, wasm_module_t **ret) {
+// wasm_byte_vec_t vec;
+// vec.data = (wasm_byte_t*) bytes;
+// vec.size = len;
+// return wasmtime_module_new(engine, &vec, ret);
+// }
+//
+// wasmtime_error_t *go_module_validate(wasm_store_t *store, uint8_t *bytes, size_t len) {
+// wasm_byte_vec_t vec;
+// vec.data = (wasm_byte_t*) bytes;
+// vec.size = len;
+// return wasmtime_module_validate(store, &vec);
+// }
+//
+// wasmtime_error_t *go_module_deserialize(wasm_engine_t *engine, uint8_t *bytes, size_t len, wasm_module_t **ret) {
+// wasm_byte_vec_t vec;
+// vec.data = (wasm_byte_t*) bytes;
+// vec.size = len;
+// return wasmtime_module_deserialize(engine, &vec, ret);
+// }
+import "C"
+import (
+ "io/ioutil"
+ "runtime"
+ "unsafe"
+)
+
+// Module is a module which collects definitions for types, functions, tables, memories, and globals.
+// In addition, it can declare imports and exports and provide initialization logic in the form of data and element segments or a start function.
+// Modules organized WebAssembly programs as the unit of deployment, loading, and compilation.
+type Module struct {
+ _ptr *C.wasm_module_t
+ _owner interface{}
+}
+
+// NewModule compiles a new `Module` from the `wasm` provided with the given configuration
+// in `engine`.
+func NewModule(engine *Engine, wasm []byte) (*Module, error) {
+ // We can't create the `wasm_byte_vec_t` here and pass it in because
+ // that runs into the error of "passed a pointer to a pointer" because
+ // the vec itself is passed by pointer and it contains a pointer to
+ // `wasm`. To work around this we insert some C shims above and call
+ // them.
+ var wasmPtr *C.uint8_t
+ if len(wasm) > 0 {
+ wasmPtr = (*C.uint8_t)(unsafe.Pointer(&wasm[0]))
+ }
+ var ptr *C.wasm_module_t
+ err := C.go_module_new(engine.ptr(), wasmPtr, C.size_t(len(wasm)), &ptr)
+ runtime.KeepAlive(engine)
+ runtime.KeepAlive(wasm)
+
+ if err != nil {
+ return nil, mkError(err)
+ }
+
+ return mkModule(ptr, nil), nil
+}
+
+// NewModuleFromFile reads the contents of the `file` provided and interprets them as either the
+// text format or the binary format for WebAssembly.
+//
+// Afterwards delegates to the `NewModule` constructor with the contents read.
+func NewModuleFromFile(engine *Engine, file string) (*Module, error) {
+ wasm, err := ioutil.ReadFile(file)
+ if err != nil {
+ return nil, err
+ }
+ // If this wasm isn't actually wasm, treat it as the text format and
+ // parse it as such.
+ if len(wasm) > 0 && wasm[0] != 0 {
+ wasm, err = Wat2Wasm(string(wasm))
+ if err != nil {
+ return nil, err
+ }
+ }
+ return NewModule(engine, wasm)
+
+}
+
+// ModuleValidate validates whether `wasm` would be a valid wasm module according to the
+// configuration in `store`
+func ModuleValidate(store *Store, wasm []byte) error {
+ var wasmPtr *C.uint8_t
+ if len(wasm) > 0 {
+ wasmPtr = (*C.uint8_t)(unsafe.Pointer(&wasm[0]))
+ }
+ err := C.go_module_validate(store.ptr(), wasmPtr, C.size_t(len(wasm)))
+ runtime.KeepAlive(store)
+ runtime.KeepAlive(wasm)
+ if err == nil {
+ return nil
+ }
+
+ return mkError(err)
+}
+
+func mkModule(ptr *C.wasm_module_t, owner interface{}) *Module {
+ module := &Module{_ptr: ptr}
+ if owner == nil {
+ runtime.SetFinalizer(module, func(module *Module) {
+ C.wasm_module_delete(module._ptr)
+ })
+ }
+ return module
+}
+
+func (m *Module) ptr() *C.wasm_module_t {
+ ret := m._ptr
+ maybeGC()
+ return ret
+}
+
+func (m *Module) owner() interface{} {
+ if m._owner != nil {
+ return m._owner
+ }
+ return m
+}
+
+// Type returns a `ModuleType` that corresponds for this module.
+func (m *Module) Type() *ModuleType {
+ ptr := C.wasm_module_type(m.ptr())
+ runtime.KeepAlive(m)
+ return mkModuleType(ptr, nil)
+}
+
+type importTypeList struct {
+ vec C.wasm_importtype_vec_t
+}
+
+func (list *importTypeList) mkGoList() []*ImportType {
+ runtime.SetFinalizer(list, func(imports *importTypeList) {
+ C.wasm_importtype_vec_delete(&imports.vec)
+ })
+
+ ret := make([]*ImportType, int(list.vec.size))
+ base := unsafe.Pointer(list.vec.data)
+ var ptr *C.wasm_importtype_t
+ for i := 0; i < int(list.vec.size); i++ {
+ ptr := *(**C.wasm_importtype_t)(unsafe.Pointer(uintptr(base) + unsafe.Sizeof(ptr)*uintptr(i)))
+ ty := mkImportType(ptr, list)
+ ret[i] = ty
+ }
+ return ret
+}
+
+// Imports returns a list of `ImportType` items which are the items imported by this
+// module and are required for instantiation.
+func (m *Module) Imports() []*ImportType {
+ imports := &importTypeList{}
+ C.wasm_module_imports(m.ptr(), &imports.vec)
+ runtime.KeepAlive(m)
+ runtime.SetFinalizer(imports, func(imports *importTypeList) {
+ C.wasm_importtype_vec_delete(&imports.vec)
+ })
+
+ ret := make([]*ImportType, int(imports.vec.size))
+ base := unsafe.Pointer(imports.vec.data)
+ var ptr *C.wasm_importtype_t
+ for i := 0; i < int(imports.vec.size); i++ {
+ ptr := *(**C.wasm_importtype_t)(unsafe.Pointer(uintptr(base) + unsafe.Sizeof(ptr)*uintptr(i)))
+ ty := mkImportType(ptr, imports)
+ ret[i] = ty
+ }
+ return ret
+}
+
+type exportTypeList struct {
+ vec C.wasm_exporttype_vec_t
+}
+
+func (list *exportTypeList) mkGoList() []*ExportType {
+ runtime.SetFinalizer(list, func(exports *exportTypeList) {
+ C.wasm_exporttype_vec_delete(&exports.vec)
+ })
+
+ ret := make([]*ExportType, int(list.vec.size))
+ base := unsafe.Pointer(list.vec.data)
+ var ptr *C.wasm_exporttype_t
+ for i := 0; i < int(list.vec.size); i++ {
+ ptr := *(**C.wasm_exporttype_t)(unsafe.Pointer(uintptr(base) + unsafe.Sizeof(ptr)*uintptr(i)))
+ ty := mkExportType(ptr, list)
+ ret[i] = ty
+ }
+ return ret
+}
+
+// Exports returns a list of `ExportType` items which are the items that will
+// be exported by this module after instantiation.
+func (m *Module) Exports() []*ExportType {
+ exports := &exportTypeList{}
+ C.wasm_module_exports(m.ptr(), &exports.vec)
+ runtime.KeepAlive(m)
+ return exports.mkGoList()
+}
+
+// NewModuleDeserialize decodes and deserializes in-memory bytes previously
+// produced by `module.Serialize()`.
+//
+// This function does not take a WebAssembly binary as input. It takes
+// as input the results of a previous call to `Serialize()`, and only takes
+// that as input.
+//
+// If deserialization is successful then a compiled module is returned,
+// otherwise nil and an error are returned.
+//
+// Note that to deserialize successfully the bytes provided must have beeen
+// produced with an `Engine` that has the same commpilation options as the
+// provided engine, and from the same version of this library.
+func NewModuleDeserialize(engine *Engine, encoded []byte) (*Module, error) {
+ var encodedPtr *C.uint8_t
+ var ptr *C.wasm_module_t
+ if len(encoded) > 0 {
+ encodedPtr = (*C.uint8_t)(unsafe.Pointer(&encoded[0]))
+ }
+ err := C.go_module_deserialize(
+ engine.ptr(),
+ encodedPtr,
+ C.size_t(len(encoded)),
+ &ptr,
+ )
+ runtime.KeepAlive(engine)
+ runtime.KeepAlive(encoded)
+
+ if err != nil {
+ return nil, mkError(err)
+ }
+
+ return mkModule(ptr, nil), nil
+}
+
+// Serialize will convert this in-memory compiled module into a list of bytes.
+//
+// The purpose of this method is to extract an artifact which can be stored
+// elsewhere from this `Module`. The returned bytes can, for example, be stored
+// on disk or in an object store. The `NewModuleDeserialize` function can be
+// used to deserialize the returned bytes at a later date to get the module
+// back.
+func (m *Module) Serialize() ([]byte, error) {
+ retVec := C.wasm_byte_vec_t{}
+ err := C.wasmtime_module_serialize(m.ptr(), &retVec)
+ runtime.KeepAlive(m)
+
+ if err != nil {
+ return nil, mkError(err)
+ }
+ ret := C.GoBytes(unsafe.Pointer(retVec.data), C.int(retVec.size))
+ C.wasm_byte_vec_delete(&retVec)
+ return ret, nil
+}
+
+func (m *Module) AsExtern() *Extern {
+ ptr := C.wasm_module_as_extern(m.ptr())
+ return mkExtern(ptr, nil, m.owner())
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/moduletype.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/moduletype.go
new file mode 100644
index 000000000..8fb0ba71d
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/moduletype.go
@@ -0,0 +1,58 @@
+package wasmtime
+
+// #include
+import "C"
+import "runtime"
+
+// ModuleType describes the imports/exports of a module.
+type ModuleType struct {
+ _ptr *C.wasm_moduletype_t
+ _owner interface{}
+}
+
+func mkModuleType(ptr *C.wasm_moduletype_t, owner interface{}) *ModuleType {
+ moduletype := &ModuleType{_ptr: ptr, _owner: owner}
+ if owner == nil {
+ runtime.SetFinalizer(moduletype, func(moduletype *ModuleType) {
+ C.wasm_moduletype_delete(moduletype._ptr)
+ })
+ }
+ return moduletype
+}
+
+func (ty *ModuleType) ptr() *C.wasm_moduletype_t {
+ ret := ty._ptr
+ maybeGC()
+ return ret
+}
+
+func (ty *ModuleType) owner() interface{} {
+ if ty._owner != nil {
+ return ty._owner
+ }
+ return ty
+}
+
+// AsExternType converts this type to an instance of `ExternType`
+func (ty *ModuleType) AsExternType() *ExternType {
+ ptr := C.wasm_moduletype_as_externtype_const(ty.ptr())
+ return mkExternType(ptr, ty.owner())
+}
+
+// Imports returns a list of `ImportType` items which are the items imported by
+// this module and are required for instantiation.
+func (m *ModuleType) Imports() []*ImportType {
+ imports := &importTypeList{}
+ C.wasm_moduletype_imports(m.ptr(), &imports.vec)
+ runtime.KeepAlive(m)
+ return imports.mkGoList()
+}
+
+// Exports returns a list of `ExportType` items which are the items that will
+// be exported by this module after instantiation.
+func (m *ModuleType) Exports() []*ExportType {
+ exports := &exportTypeList{}
+ C.wasm_moduletype_exports(m.ptr(), &exports.vec)
+ runtime.KeepAlive(m)
+ return exports.mkGoList()
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/shims.c b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/shims.c
new file mode 100644
index 000000000..84ed37d79
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/shims.c
@@ -0,0 +1,133 @@
+#include "_cgo_export.h"
+#include "shims.h"
+
+static wasm_trap_t* trampoline(
+ const wasmtime_caller_t *caller,
+ void *env,
+ const wasm_val_vec_t *args,
+ wasm_val_vec_t *results
+) {
+ return goTrampolineNew((wasmtime_caller_t*) caller, (size_t) env, (wasm_val_vec_t*) args, results);
+}
+
+static wasm_trap_t* wrap_trampoline(
+ const wasmtime_caller_t *caller,
+ void *env,
+ const wasm_val_vec_t *args,
+ wasm_val_vec_t *results
+) {
+ return goTrampolineWrap((wasmtime_caller_t*) caller, (size_t) env, (wasm_val_vec_t*) args, results);
+}
+
+wasm_func_t *c_func_new_with_env(wasm_store_t *store, wasm_functype_t *ty, size_t env, int wrap) {
+ if (wrap)
+ return wasmtime_func_new_with_env(store, ty, wrap_trampoline, (void*) env, goFinalizeWrap);
+ return wasmtime_func_new_with_env(store, ty, trampoline, (void*) env, goFinalizeNew);
+}
+
+wasmtime_error_t *go_wasmtime_func_call(
+ wasm_func_t *func,
+ const wasm_val_vec_t *args,
+ wasm_val_vec_t *results,
+ wasm_trap_t **trap
+) {
+ wasmtime_error_t *ret = wasmtime_func_call(func, args, results, trap);
+ return ret;
+}
+
+wasm_extern_t* go_caller_export_get(
+ const wasmtime_caller_t* caller,
+ char *name_ptr,
+ size_t name_len
+) {
+ wasm_byte_vec_t name;
+ name.data = name_ptr;
+ name.size = name_len;
+ return wasmtime_caller_export_get(caller, &name);
+}
+
+wasmtime_error_t* go_linker_define(
+ wasmtime_linker_t *linker,
+ char *module_ptr,
+ size_t module_len,
+ char *name_ptr,
+ size_t name_len,
+ wasm_extern_t *item
+) {
+ wasm_byte_vec_t module;
+ module.data = module_ptr;
+ module.size = module_len;
+ wasm_byte_vec_t name;
+ name.data = name_ptr;
+ name.size = name_len;
+ return wasmtime_linker_define(linker, &module, &name, item);
+}
+
+wasmtime_error_t* go_linker_define_instance(
+ wasmtime_linker_t *linker,
+ char *name_ptr,
+ size_t name_len,
+ wasm_instance_t *instance
+) {
+ wasm_byte_vec_t name;
+ name.data = name_ptr;
+ name.size = name_len;
+ return wasmtime_linker_define_instance(linker, &name, instance);
+}
+
+wasmtime_error_t* go_linker_define_module(
+ wasmtime_linker_t *linker,
+ char *name_ptr,
+ size_t name_len,
+ wasm_module_t *module
+) {
+ wasm_byte_vec_t name;
+ name.data = name_ptr;
+ name.size = name_len;
+ return wasmtime_linker_module(linker, &name, module);
+}
+
+wasmtime_error_t* go_linker_get_default(
+ wasmtime_linker_t *linker,
+ char *name_ptr,
+ size_t name_len,
+ wasm_func_t **func
+) {
+ wasm_byte_vec_t name;
+ name.data = name_ptr;
+ name.size = name_len;
+ return wasmtime_linker_get_default(linker, &name, func);
+}
+
+wasmtime_error_t* go_linker_get_one_by_name(
+ wasmtime_linker_t *linker,
+ char *module_ptr,
+ size_t module_len,
+ char *name_ptr,
+ size_t name_len,
+ wasm_extern_t **item
+) {
+ wasm_byte_vec_t module, name;
+ module.data = module_ptr;
+ module.size = module_len;
+ name.data = name_ptr;
+ name.size = name_len;
+ return wasmtime_linker_get_one_by_name(linker, &module,&name, item);
+}
+
+void go_externref_new_with_finalizer(
+ size_t env,
+ wasm_val_t *valp
+) {
+ wasmtime_externref_new_with_finalizer((void*) env, goFinalizeExternref, valp);
+}
+
+void go_init_i32(wasm_val_t *val, int32_t i) { val->of.i32 = i; }
+void go_init_i64(wasm_val_t *val, int64_t i) { val->of.i64 = i; }
+void go_init_f32(wasm_val_t *val, float i) { val->of.f32 = i; }
+void go_init_f64(wasm_val_t *val, double i) { val->of.f64 = i; }
+
+int32_t go_get_i32(wasm_val_t *val) { return val->of.i32; }
+int64_t go_get_i64(wasm_val_t *val) { return val->of.i64; }
+float go_get_f32(wasm_val_t *val) { return val->of.f32; }
+double go_get_f64(wasm_val_t *val) { return val->of.f64; }
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/shims.h b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/shims.h
new file mode 100644
index 000000000..50fda7867
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/shims.h
@@ -0,0 +1,58 @@
+#include
+#include
+
+wasm_func_t *c_func_new_with_env(wasm_store_t *store, wasm_functype_t *ty, size_t env, int wrap);
+wasm_extern_t* go_caller_export_get(const wasmtime_caller_t* caller, char *name_ptr, size_t name_len);
+wasmtime_error_t* go_linker_define(
+ wasmtime_linker_t *linker,
+ char *module_ptr,
+ size_t module_len,
+ char *name_ptr,
+ size_t name_len,
+ wasm_extern_t *item
+);
+wasmtime_error_t* go_linker_define_instance(
+ wasmtime_linker_t *linker,
+ char *name_ptr,
+ size_t name_len,
+ wasm_instance_t *item
+);
+wasmtime_error_t* go_linker_define_module(
+ wasmtime_linker_t *linker,
+ char *name_ptr,
+ size_t name_len,
+ wasm_module_t *item
+);
+wasmtime_error_t* go_linker_get_default(
+ wasmtime_linker_t *linker,
+ char *name_ptr,
+ size_t name_len,
+ wasm_func_t **func
+);
+wasmtime_error_t* go_linker_get_one_by_name(
+ wasmtime_linker_t *linker,
+ char *module_ptr,
+ size_t module_len,
+ char *name_ptr,
+ size_t name_len,
+ wasm_extern_t **item
+);
+void go_externref_new_with_finalizer(
+ size_t env,
+ wasm_val_t *valp
+);
+wasmtime_error_t *go_wasmtime_func_call(
+ wasm_func_t *func,
+ const wasm_val_vec_t *args,
+ wasm_val_vec_t *results,
+ wasm_trap_t **trap
+);
+void go_init_i32(wasm_val_t *val, int32_t i);
+void go_init_i64(wasm_val_t *val, int64_t i);
+void go_init_f32(wasm_val_t *val, float i);
+void go_init_f64(wasm_val_t *val, double i);
+
+int32_t go_get_i32(wasm_val_t *val);
+int64_t go_get_i64(wasm_val_t *val);
+float go_get_f32(wasm_val_t *val);
+double go_get_f64(wasm_val_t *val);
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/slab.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/slab.go
new file mode 100644
index 000000000..decc62250
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/slab.go
@@ -0,0 +1,20 @@
+package wasmtime
+
+type slab struct {
+ list []int
+ next int
+}
+
+func (s *slab) allocate() int {
+ if s.next == len(s.list) {
+ s.list = append(s.list, s.next+1)
+ }
+ ret := s.next
+ s.next = s.list[ret]
+ return ret
+}
+
+func (s *slab) deallocate(slot int) {
+ s.list[slot] = s.next
+ s.next = slot
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/store.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/store.go
new file mode 100644
index 000000000..2b2e4d0a0
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/store.go
@@ -0,0 +1,90 @@
+package wasmtime
+
+// #include
+// #include
+import "C"
+import (
+ "errors"
+ "runtime"
+)
+
+// Store is a general group of wasm instances, and many objects
+// must all be created with and reference the same `Store`
+type Store struct {
+ _ptr *C.wasm_store_t
+ freelist *freeList
+ Engine *Engine
+}
+
+// NewStore creates a new `Store` from the configuration provided in `engine`
+func NewStore(engine *Engine) *Store {
+ store := &Store{
+ _ptr: C.wasm_store_new(engine.ptr()),
+ freelist: newFreeList(),
+ Engine: engine,
+ }
+ runtime.KeepAlive(engine)
+ runtime.SetFinalizer(store, func(store *Store) {
+ freelist := store.freelist
+ freelist.lock.Lock()
+ defer freelist.lock.Unlock()
+ freelist.stores = append(freelist.stores, store._ptr)
+ })
+ return store
+}
+
+func (store *Store) InterruptHandle() (*InterruptHandle, error) {
+ ptr := C.wasmtime_interrupt_handle_new(store.ptr())
+ runtime.KeepAlive(store)
+ if ptr == nil {
+ return nil, errors.New("interrupts not enabled in `Config`")
+ }
+
+ handle := &InterruptHandle{_ptr: ptr}
+ runtime.SetFinalizer(handle, func(handle *InterruptHandle) {
+ C.wasmtime_interrupt_handle_delete(handle._ptr)
+ })
+ return handle, nil
+}
+
+// GC will clean up any `externref` values that are no longer actually
+// referenced.
+//
+// This function is not required to be called for correctness, it's only an
+// optimization if desired to clean out any extra `externref` values.
+func (store *Store) GC() {
+ C.wasmtime_store_gc(store.ptr())
+ runtime.KeepAlive(store)
+}
+
+func (store *Store) ptr() *C.wasm_store_t {
+ store.freelist.clear()
+ ret := store._ptr
+ maybeGC()
+ return ret
+}
+
+// InterruptHandle is used to interrupt the execution of currently running
+// wasm code.
+//
+// For more information see
+// https://bytecodealliance.github.io/wasmtime/api/wasmtime/struct.Store.html#method.interrupt_handle
+type InterruptHandle struct {
+ _ptr *C.wasmtime_interrupt_handle_t
+}
+
+// Interrupt interrupts currently executing WebAssembly code, if it's currently running,
+// or interrupts wasm the next time it starts running.
+//
+// For more information see
+// https://bytecodealliance.github.io/wasmtime/api/wasmtime/struct.Store.html#method.interrupt_handle
+func (i *InterruptHandle) Interrupt() {
+ C.wasmtime_interrupt_handle_interrupt(i.ptr())
+ runtime.KeepAlive(i)
+}
+
+func (i *InterruptHandle) ptr() *C.wasmtime_interrupt_handle_t {
+ ret := i._ptr
+ maybeGC()
+ return ret
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/table.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/table.go
new file mode 100644
index 000000000..c05610fa5
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/table.go
@@ -0,0 +1,169 @@
+package wasmtime
+
+// #include
+//
+// wasm_ref_t *go_get_ref(wasm_val_t *val) { return val->of.ref; }
+// void go_init_ref(wasm_val_t *val, wasm_ref_t *i) { val->of.ref = i; }
+import "C"
+import (
+ "errors"
+ "runtime"
+)
+
+// Table is a table instance, which is the runtime representation of a table.
+//
+// It holds a vector of reference types and an optional maximum size, if one was
+// specified in the table type at the table’s definition site.
+// Read more in [spec](https://webassembly.github.io/spec/core/exec/runtime.html#table-instances)
+type Table struct {
+ _ptr *C.wasm_table_t
+ _owner interface{}
+ freelist *freeList
+}
+
+// NewTable creates a new `Table` in the given `Store` with the specified `ty`.
+//
+// The `ty` must be a reference type (`funref` or `externref`) and `init`
+// is the initial value for all table slots and must have the type specified by
+// `ty`.
+func NewTable(store *Store, ty *TableType, init Val) (*Table, error) {
+ initPtr, err := getRefPtr(init)
+ if err != nil {
+ return nil, err
+ }
+ ptr := C.wasm_table_new(store.ptr(), ty.ptr(), initPtr)
+ runtime.KeepAlive(store)
+ runtime.KeepAlive(ty)
+ runtime.KeepAlive(init)
+ if ptr == nil {
+ return nil, errors.New("failed to create table")
+ }
+ return mkTable(ptr, store.freelist, nil), nil
+}
+
+func mkTable(ptr *C.wasm_table_t, freelist *freeList, owner interface{}) *Table {
+ f := &Table{_ptr: ptr, _owner: owner, freelist: freelist}
+ if owner == nil {
+ runtime.SetFinalizer(f, func(f *Table) {
+ f.freelist.lock.Lock()
+ defer f.freelist.lock.Unlock()
+ f.freelist.tables = append(f.freelist.tables, f._ptr)
+ })
+ }
+ return f
+}
+
+func (t *Table) ptr() *C.wasm_table_t {
+ ret := t._ptr
+ maybeGC()
+ return ret
+}
+
+func (t *Table) owner() interface{} {
+ if t._owner != nil {
+ return t._owner
+ }
+ return t
+}
+
+// Size returns the size of this table in units of elements.
+func (t *Table) Size() uint32 {
+ ret := C.wasm_table_size(t.ptr())
+ runtime.KeepAlive(t)
+ return uint32(ret)
+}
+
+// Grow grows this table by the number of units specified, using the
+// specified initializer value for new slots.
+//
+// Returns an error if the table failed to grow, or the previous size of the
+// table if growth was successful.
+func (t *Table) Grow(delta uint32, init Val) (uint32, error) {
+ if t.Type().Element().Kind() != init.Kind() {
+ return 0, errors.New("wrong type of initializer passed to `Grow`")
+ }
+ ptr, err := getRefPtr(init)
+ if err != nil {
+ return 0, err
+ }
+ ok := C.wasm_table_grow(t.ptr(), C.uint32_t(delta), ptr)
+ runtime.KeepAlive(t)
+ runtime.KeepAlive(init)
+ if ok {
+ return t.Size() - delta, nil
+ }
+
+ return 0, errors.New("failed to grow table")
+}
+
+func (t *Table) nullValue() Val {
+ switch t.Type().Element().Kind() {
+ case KindFuncref:
+ return ValFuncref(nil)
+ case KindExternref:
+ return ValExternref(nil)
+ default:
+ panic("unsupported table type")
+ }
+}
+
+// Get gets an item from this table from the specified index.
+//
+// Returns an error if the index is out of bounds, or returns a value (which
+// may be internally null) if the index is in bounds corresponding to the entry
+// at the specified index.
+func (t *Table) Get(idx uint32) (Val, error) {
+ null := t.nullValue()
+ if idx >= t.Size() {
+ return null, errors.New("index out of bounds")
+ }
+ valPtr := C.wasm_table_get(t.ptr(), C.uint32_t(idx))
+ runtime.KeepAlive(t)
+ if valPtr == nil {
+ return null, nil
+ }
+ C.go_init_ref(null.ptr(), valPtr)
+ ret := takeVal(null.ptr(), t.freelist)
+ runtime.KeepAlive(null)
+ return ret, nil
+}
+
+// Set sets an item in this table at the specified index.
+//
+// Returns an error if the index is out of bounds.
+func (t *Table) Set(idx uint32, val Val) error {
+ if t.Type().Element().Kind() != val.Kind() {
+ return errors.New("wrong type of initializer passed to `Grow`")
+ }
+ ptr, err := getRefPtr(val)
+ if err != nil {
+ return err
+ }
+ ok := C.wasm_table_set(t.ptr(), C.uint32_t(idx), ptr)
+ runtime.KeepAlive(t)
+ runtime.KeepAlive(val)
+ if !ok {
+ return errors.New("failed to set table index")
+ }
+ return nil
+}
+
+// Type returns the underlying type of this table
+func (t *Table) Type() *TableType {
+ ptr := C.wasm_table_type(t.ptr())
+ runtime.KeepAlive(t)
+ return mkTableType(ptr, nil)
+}
+
+func (t *Table) AsExtern() *Extern {
+ ptr := C.wasm_table_as_extern(t.ptr())
+ return mkExtern(ptr, t.freelist, t.owner())
+}
+
+func getRefPtr(val Val) (*C.wasm_ref_t, error) {
+ switch val.Kind() {
+ case KindExternref, KindFuncref:
+ return C.go_get_ref(val.ptr()), nil
+ }
+ return nil, errors.New("not a reference type")
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/tabletype.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/tabletype.go
new file mode 100644
index 000000000..a7a293006
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/tabletype.go
@@ -0,0 +1,63 @@
+package wasmtime
+
+// #include
+import "C"
+import "runtime"
+
+// TableType is one of table types which classify tables over elements of element types within a size range.
+type TableType struct {
+ _ptr *C.wasm_tabletype_t
+ _owner interface{}
+}
+
+// NewTableType creates a new `TableType` with the `element` type provided as well as
+// `limits` on its size.
+func NewTableType(element *ValType, limits Limits) *TableType {
+ valptr := C.wasm_valtype_new(C.wasm_valtype_kind(element.ptr()))
+ runtime.KeepAlive(element)
+ limitsFFI := limits.ffi()
+ ptr := C.wasm_tabletype_new(valptr, &limitsFFI)
+
+ return mkTableType(ptr, nil)
+}
+
+func mkTableType(ptr *C.wasm_tabletype_t, owner interface{}) *TableType {
+ tabletype := &TableType{_ptr: ptr, _owner: owner}
+ if owner == nil {
+ runtime.SetFinalizer(tabletype, func(tabletype *TableType) {
+ C.wasm_tabletype_delete(tabletype._ptr)
+ })
+ }
+ return tabletype
+}
+
+func (ty *TableType) ptr() *C.wasm_tabletype_t {
+ ret := ty._ptr
+ maybeGC()
+ return ret
+}
+
+func (ty *TableType) owner() interface{} {
+ if ty._owner != nil {
+ return ty._owner
+ }
+ return ty
+}
+
+// Element returns the type of value stored in this table
+func (ty *TableType) Element() *ValType {
+ ptr := C.wasm_tabletype_element(ty.ptr())
+ return mkValType(ptr, ty.owner())
+}
+
+// Limits returns limits on the size of this table type
+func (ty *TableType) Limits() Limits {
+ ptr := C.wasm_tabletype_limits(ty.ptr())
+ return mkLimits(ptr, ty.owner())
+}
+
+// AsExternType converts this type to an instance of `ExternType`
+func (ty *TableType) AsExternType() *ExternType {
+ ptr := C.wasm_tabletype_as_externtype_const(ty.ptr())
+ return mkExternType(ptr, ty.owner())
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/trap.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/trap.go
new file mode 100644
index 000000000..ce12bd831
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/trap.go
@@ -0,0 +1,151 @@
+package wasmtime
+
+// #include
+// #include
+// #include
+import "C"
+
+import (
+ "runtime"
+ "unsafe"
+)
+
+// Trap is the trap instruction which represents the occurrence of a trap.
+// Traps are bubbled up through nested instruction sequences, ultimately reducing the entire program to a single trap instruction, signalling abrupt termination.
+type Trap struct {
+ _ptr *C.wasm_trap_t
+}
+
+// Frame is one of activation frames which carry the return arity n of the respective function,
+// hold the values of its locals (including arguments) in the order corresponding to their static local indices,
+// and a reference to the function’s own module instance
+type Frame struct {
+ _ptr *C.wasm_frame_t
+ _owner interface{}
+}
+
+// NewTrap creates a new `Trap` with the `name` and the type provided.
+func NewTrap(store *Store, message string) *Trap {
+ cs := C.CString(message)
+ messageVec := C.wasm_byte_vec_t{
+ data: cs,
+ size: C.size_t(len(message) + 1),
+ }
+ ptr := C.wasm_trap_new(store.ptr(), &messageVec)
+ C.free(unsafe.Pointer(cs))
+ runtime.KeepAlive(store)
+ return mkTrap(ptr)
+}
+
+func mkTrap(ptr *C.wasm_trap_t) *Trap {
+ trap := &Trap{_ptr: ptr}
+ runtime.SetFinalizer(trap, func(trap *Trap) {
+ C.wasm_trap_delete(trap._ptr)
+ })
+ return trap
+}
+
+func (t *Trap) ptr() *C.wasm_trap_t {
+ ret := t._ptr
+ maybeGC()
+ return ret
+}
+
+// Message returns the name in the module this export type is exporting
+func (t *Trap) Message() string {
+ message := C.wasm_byte_vec_t{}
+ C.wasm_trap_message(t.ptr(), &message)
+ ret := C.GoStringN(message.data, C.int(message.size-1))
+ runtime.KeepAlive(t)
+ C.wasm_byte_vec_delete(&message)
+ return ret
+}
+
+func (t *Trap) Error() string {
+ return t.Message()
+}
+
+func unwrapStrOr(s *string, other string) string {
+ if s == nil {
+ return other
+ }
+
+ return *s
+}
+
+type frameList struct {
+ vec C.wasm_frame_vec_t
+}
+
+// Frames returns the wasm function frames that make up this trap
+func (t *Trap) Frames() []*Frame {
+ frames := &frameList{}
+ C.wasm_trap_trace(t.ptr(), &frames.vec)
+ runtime.KeepAlive(t)
+ runtime.SetFinalizer(frames, func(frames *frameList) {
+ C.wasm_frame_vec_delete(&frames.vec)
+ })
+
+ ret := make([]*Frame, int(frames.vec.size))
+ base := unsafe.Pointer(frames.vec.data)
+ var ptr *C.wasm_frame_t
+ for i := 0; i < int(frames.vec.size); i++ {
+ ptr := *(**C.wasm_frame_t)(unsafe.Pointer(uintptr(base) + unsafe.Sizeof(ptr)*uintptr(i)))
+ ret[i] = &Frame{
+ _ptr: ptr,
+ _owner: frames,
+ }
+ }
+ return ret
+}
+
+func (f *Frame) ptr() *C.wasm_frame_t {
+ ret := f._ptr
+ maybeGC()
+ return ret
+}
+
+// FuncIndex returns the function index in the wasm module that this frame represents
+func (f *Frame) FuncIndex() uint32 {
+ ret := C.wasm_frame_func_index(f.ptr())
+ runtime.KeepAlive(f)
+ return uint32(ret)
+}
+
+// FuncName returns the name, if available, for this frame's function
+func (f *Frame) FuncName() *string {
+ ret := C.wasmtime_frame_func_name(f.ptr())
+ if ret == nil {
+ runtime.KeepAlive(f)
+ return nil
+ }
+ str := C.GoStringN(ret.data, C.int(ret.size))
+ runtime.KeepAlive(f)
+ return &str
+}
+
+// ModuleName returns the name, if available, for this frame's module
+func (f *Frame) ModuleName() *string {
+ ret := C.wasmtime_frame_module_name(f.ptr())
+ if ret == nil {
+ runtime.KeepAlive(f)
+ return nil
+ }
+ str := C.GoStringN(ret.data, C.int(ret.size))
+ runtime.KeepAlive(f)
+ return &str
+}
+
+// ModuleOffset returns offset of this frame's instruction into the original module
+func (f *Frame) ModuleOffset() uint {
+ ret := uint(C.wasm_frame_module_offset(f.ptr()))
+ runtime.KeepAlive(f)
+ return ret
+}
+
+// FuncOffset returns offset of this frame's instruction into the original function
+func (f *Frame) FuncOffset() uint {
+ ret := uint(C.wasm_frame_func_offset(f.ptr()))
+ runtime.KeepAlive(f)
+ return ret
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/val.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/val.go
new file mode 100644
index 000000000..9cb42f2e5
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/val.go
@@ -0,0 +1,230 @@
+package wasmtime
+
+// #include
+// #include "shims.h"
+import "C"
+import (
+ "runtime"
+ "sync"
+ "unsafe"
+)
+
+var gExternrefLock sync.Mutex
+var gExternrefMap = make(map[int]interface{})
+var gExternrefSlab slab
+
+// Val is a primitive numeric value.
+// Moreover, in the definition of programs, immutable sequences of values occur to represent more complex data, such as text strings or other vectors.
+type Val struct {
+ _raw *C.wasm_val_t
+ freelist *freeList
+}
+
+// ValI32 converts a go int32 to a i32 Val
+func ValI32(val int32) Val {
+ ret := Val{_raw: &C.wasm_val_t{kind: C.WASM_I32}}
+ C.go_init_i32(ret.ptr(), C.int32_t(val))
+ return ret
+}
+
+// ValI64 converts a go int64 to a i64 Val
+func ValI64(val int64) Val {
+ ret := Val{_raw: &C.wasm_val_t{kind: C.WASM_I64}}
+ C.go_init_i64(ret.ptr(), C.int64_t(val))
+ return ret
+}
+
+// ValF32 converts a go float32 to a f32 Val
+func ValF32(val float32) Val {
+ ret := Val{_raw: &C.wasm_val_t{kind: C.WASM_F32}}
+ C.go_init_f32(ret.ptr(), C.float(val))
+ return ret
+}
+
+// ValF64 converts a go float64 to a f64 Val
+func ValF64(val float64) Val {
+ ret := Val{_raw: &C.wasm_val_t{kind: C.WASM_F64}}
+ C.go_init_f64(ret.ptr(), C.double(val))
+ return ret
+}
+
+// ValFuncref converts a Func to a funcref Val
+//
+// Note that `f` can be `nil` to represent a null `funcref`.
+func ValFuncref(f *Func) Val {
+ ret := Val{_raw: &C.wasm_val_t{kind: C.WASM_FUNCREF}}
+ if f != nil {
+ ret.freelist = f.freelist
+ C.wasmtime_func_as_funcref(f.ptr(), ret.ptr())
+ runtime.KeepAlive(f)
+ ret.setDtor()
+ }
+ return ret
+}
+
+// ValExternref converts a go value to a externref Val
+//
+// Using `externref` is a way to pass arbitrary Go data into a WebAssembly
+// module for it to store. Later, when you get a `Val`, you can extract the type
+// with the `Externref()` method.
+func ValExternref(val interface{}) Val {
+ ret := Val{_raw: &C.wasm_val_t{kind: C.WASM_ANYREF}}
+
+ // If we have a non-nil value then store it in our global map of all
+ // externref values. Otherwise there's nothing for us to do since the
+ // `ref` field will already be a nil pointer.
+ //
+ // Note that we add 1 so all non-null externref values are created with
+ // non-null pointers.
+ if val != nil {
+ gExternrefLock.Lock()
+ defer gExternrefLock.Unlock()
+ index := gExternrefSlab.allocate()
+ gExternrefMap[index] = val
+ C.go_externref_new_with_finalizer(C.size_t(index+1), ret.ptr())
+ ret.setDtor()
+ }
+ return ret
+}
+
+//export goFinalizeExternref
+func goFinalizeExternref(env unsafe.Pointer) {
+ idx := int(uintptr(env)) - 1
+ gExternrefLock.Lock()
+ defer gExternrefLock.Unlock()
+ delete(gExternrefMap, idx)
+ gExternrefSlab.deallocate(idx)
+}
+
+func mkVal(src *C.wasm_val_t, freelist *freeList) Val {
+ ret := Val{_raw: &C.wasm_val_t{}, freelist: freelist}
+ C.wasm_val_copy(ret.ptr(), src)
+ ret.setDtor()
+ return ret
+}
+
+func takeVal(src *C.wasm_val_t, freelist *freeList) Val {
+ ret := Val{_raw: &C.wasm_val_t{}, freelist: freelist}
+ *ret.ptr() = *src
+ ret.setDtor()
+ return ret
+}
+
+func (v Val) setDtor() {
+ freelist := v.freelist
+ if v.Kind() == KindFuncref && freelist == nil {
+ panic("freelist not set")
+ }
+ // If we're deleting a funcref, that needs to happen on the thread with
+ // the original `Store`. Otherwise we can delete values on any thread,
+ // such as externrefs.
+ runtime.SetFinalizer(v.ptr(), func(ptr *C.wasm_val_t) {
+ if ptr.kind == C.WASM_FUNCREF {
+ freelist.lock.Lock()
+ defer freelist.lock.Unlock()
+ freelist.vals = append(freelist.vals, ptr)
+ } else {
+ C.wasm_val_delete(ptr)
+ }
+ })
+}
+
+func (v Val) ptr() *C.wasm_val_t {
+ ret := v._raw
+ maybeGC()
+ return ret
+}
+
+// Kind returns the kind of value that this `Val` contains.
+func (v Val) Kind() ValKind {
+ return ValKind(v.ptr().kind)
+}
+
+// I32 returns the underlying 32-bit integer if this is an `i32`, or panics.
+func (v Val) I32() int32 {
+ if v.Kind() != KindI32 {
+ panic("not an i32")
+ }
+ return int32(C.go_get_i32(v.ptr()))
+}
+
+// I64 returns the underlying 64-bit integer if this is an `i64`, or panics.
+func (v Val) I64() int64 {
+ if v.Kind() != KindI64 {
+ panic("not an i64")
+ }
+ return int64(C.go_get_i64(v.ptr()))
+}
+
+// F32 returns the underlying 32-bit float if this is an `f32`, or panics.
+func (v Val) F32() float32 {
+ if v.Kind() != KindF32 {
+ panic("not an f32")
+ }
+ return float32(C.go_get_f32(v.ptr()))
+}
+
+// F64 returns the underlying 64-bit float if this is an `f64`, or panics.
+func (v Val) F64() float64 {
+ if v.Kind() != KindF64 {
+ panic("not an f64")
+ }
+ return float64(C.go_get_f64(v.ptr()))
+}
+
+// Funcref returns the underlying function if this is a `funcref`, or panics.
+//
+// Note that a null `funcref` is returned as `nil`.
+func (v Val) Funcref() *Func {
+ if v.Kind() != KindFuncref {
+ panic("not a funcref")
+ }
+ ptr := C.wasmtime_funcref_as_func(v.ptr())
+ runtime.KeepAlive(v)
+ if ptr != nil {
+ if v.freelist == nil {
+ panic("freelist not available")
+ }
+ return mkFunc(ptr, v.freelist, nil)
+ } else {
+ return nil
+ }
+}
+
+// Externref returns the underlying value if this is an `externref`, or panics.
+//
+// Note that a null `externref` is returned as `nil`.
+func (v Val) Externref() interface{} {
+ var data unsafe.Pointer
+ ok := C.wasmtime_externref_data(v.ptr(), &data)
+ runtime.KeepAlive(v)
+ if !ok {
+ panic("not an externref")
+ }
+ if data == nil {
+ return nil
+ }
+
+ gExternrefLock.Lock()
+ defer gExternrefLock.Unlock()
+ return gExternrefMap[int(uintptr(data))-1]
+}
+
+// Get returns the underlying 64-bit float if this is an `f64`, or panics.
+func (v Val) Get() interface{} {
+ switch v.Kind() {
+ case KindI32:
+ return v.I32()
+ case KindI64:
+ return v.I64()
+ case KindF32:
+ return v.F32()
+ case KindF64:
+ return v.F64()
+ case KindFuncref:
+ return v.Funcref()
+ case KindExternref:
+ return v.Externref()
+ }
+ panic("failed to get value of `Val`")
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/valtype.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/valtype.go
new file mode 100644
index 000000000..1ddb00a6a
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/valtype.go
@@ -0,0 +1,90 @@
+package wasmtime
+
+// #include
+import "C"
+import "runtime"
+
+// ValKind enumeration of different kinds of value types
+type ValKind C.wasm_valkind_t
+
+const (
+ // KindI32 is the types i32 classify 32 bit integers. Integers are not inherently signed or unsigned, their interpretation is determined by individual operations.
+ KindI32 ValKind = C.WASM_I32
+ // KindI64 is the types i64 classify 64 bit integers. Integers are not inherently signed or unsigned, their interpretation is determined by individual operations.
+ KindI64 ValKind = C.WASM_I64
+ // KindF32 is the types f32 classify 32 bit floating-point data. They correspond to the respective binary floating-point representations, also known as single and double precision, as defined by the IEEE 754-2019 standard.
+ KindF32 ValKind = C.WASM_F32
+ // KindF64 is the types f64 classify 64 bit floating-point data. They correspond to the respective binary floating-point representations, also known as single and double precision, as defined by the IEEE 754-2019 standard.
+ KindF64 ValKind = C.WASM_F64
+ // TODO: Unknown
+ KindExternref ValKind = C.WASM_ANYREF
+ // KindFuncref is the infinite union of all function types.
+ KindFuncref ValKind = C.WASM_FUNCREF
+)
+
+// String renders this kind as a string, similar to the `*.wat` format
+func (ty ValKind) String() string {
+ switch ty {
+ case KindI32:
+ return "i32"
+ case KindI64:
+ return "i64"
+ case KindF32:
+ return "f32"
+ case KindF64:
+ return "f64"
+ case KindExternref:
+ return "externref"
+ case KindFuncref:
+ return "funcref"
+ }
+ panic("unknown kind")
+}
+
+// ValType means one of the value types, which classify the individual values that WebAssembly code can compute with and the values that a variable accepts.
+type ValType struct {
+ _ptr *C.wasm_valtype_t
+ _owner interface{}
+}
+
+// NewValType creates a new `ValType` with the `kind` provided
+func NewValType(kind ValKind) *ValType {
+ ptr := C.wasm_valtype_new(C.wasm_valkind_t(kind))
+ return mkValType(ptr, nil)
+}
+
+func mkValType(ptr *C.wasm_valtype_t, owner interface{}) *ValType {
+ valtype := &ValType{_ptr: ptr, _owner: owner}
+ if owner == nil {
+ runtime.SetFinalizer(valtype, func(valtype *ValType) {
+ C.wasm_valtype_delete(valtype._ptr)
+ })
+ }
+ return valtype
+}
+
+// Kind returns the corresponding `ValKind` for this `ValType`
+func (t *ValType) Kind() ValKind {
+ ret := ValKind(C.wasm_valtype_kind(t.ptr()))
+ runtime.KeepAlive(t)
+ return ret
+}
+
+// Converts this `ValType` into a string according to the string representation
+// of `ValKind`.
+func (t *ValType) String() string {
+ return t.Kind().String()
+}
+
+func (t *ValType) ptr() *C.wasm_valtype_t {
+ ret := t._ptr
+ maybeGC()
+ return ret
+}
+
+func (t *ValType) owner() interface{} {
+ if t._owner != nil {
+ return t._owner
+ }
+ return t
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/wasi.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/wasi.go
new file mode 100644
index 000000000..14d716620
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/wasi.go
@@ -0,0 +1,216 @@
+package wasmtime
+
+// #include
+// #include
+import "C"
+import (
+ "errors"
+ "runtime"
+ "unsafe"
+)
+
+type WasiConfig struct {
+ _ptr *C.wasi_config_t
+}
+
+func NewWasiConfig() *WasiConfig {
+ ptr := C.wasi_config_new()
+ config := &WasiConfig{_ptr: ptr}
+ runtime.SetFinalizer(config, func(config *WasiConfig) {
+ C.wasi_config_delete(config._ptr)
+ })
+ return config
+}
+
+func (c *WasiConfig) ptr() *C.wasi_config_t {
+ ret := c._ptr
+ maybeGC()
+ return ret
+}
+
+// SetArgv will explicitly configure the argv for this WASI configuration.
+// Note that this field can only be set, it cannot be read
+func (c *WasiConfig) SetArgv(argv []string) {
+ ptrs := make([]*C.char, len(argv))
+ for i, arg := range argv {
+ ptrs[i] = C.CString(arg)
+ }
+ var argvRaw **C.char
+ if len(ptrs) > 0 {
+ argvRaw = &ptrs[0]
+ }
+ C.wasi_config_set_argv(c.ptr(), C.int(len(argv)), argvRaw)
+ runtime.KeepAlive(c)
+ for _, ptr := range ptrs {
+ C.free(unsafe.Pointer(ptr))
+ }
+}
+
+func (c *WasiConfig) InheritArgv() {
+ C.wasi_config_inherit_argv(c.ptr())
+ runtime.KeepAlive(c)
+}
+
+// SetEnv configures environment variables to be returned for this WASI configuration.
+// The pairs provided must be an iterable list of key/value pairs of environment variables.
+// Note that this field can only be set, it cannot be read
+func (c *WasiConfig) SetEnv(keys, values []string) {
+ if len(keys) != len(values) {
+ panic("mismatched numbers of keys and values")
+ }
+ namePtrs := make([]*C.char, len(values))
+ valuePtrs := make([]*C.char, len(values))
+ for i, key := range keys {
+ namePtrs[i] = C.CString(key)
+ }
+ for i, value := range values {
+ valuePtrs[i] = C.CString(value)
+ }
+ var namesRaw, valuesRaw **C.char
+ if len(keys) > 0 {
+ namesRaw = &namePtrs[0]
+ valuesRaw = &valuePtrs[0]
+ }
+ C.wasi_config_set_env(c.ptr(), C.int(len(keys)), namesRaw, valuesRaw)
+ runtime.KeepAlive(c)
+ for i, ptr := range namePtrs {
+ C.free(unsafe.Pointer(ptr))
+ C.free(unsafe.Pointer(valuePtrs[i]))
+ }
+}
+
+func (c *WasiConfig) InheritEnv() {
+ C.wasi_config_inherit_env(c.ptr())
+ runtime.KeepAlive(c)
+}
+
+func (c *WasiConfig) SetStdinFile(path string) error {
+ pathC := C.CString(path)
+ ok := C.wasi_config_set_stdin_file(c.ptr(), pathC)
+ runtime.KeepAlive(c)
+ C.free(unsafe.Pointer(pathC))
+ if ok {
+ return nil
+ }
+
+ return errors.New("failed to open file")
+}
+
+func (c *WasiConfig) InheritStdin() {
+ C.wasi_config_inherit_stdin(c.ptr())
+ runtime.KeepAlive(c)
+}
+
+func (c *WasiConfig) SetStdoutFile(path string) error {
+ pathC := C.CString(path)
+ ok := C.wasi_config_set_stdout_file(c.ptr(), pathC)
+ runtime.KeepAlive(c)
+ C.free(unsafe.Pointer(pathC))
+ if ok {
+ return nil
+ }
+
+ return errors.New("failed to open file")
+}
+
+func (c *WasiConfig) InheritStdout() {
+ C.wasi_config_inherit_stdout(c.ptr())
+ runtime.KeepAlive(c)
+}
+
+func (c *WasiConfig) SetStderrFile(path string) error {
+ pathC := C.CString(path)
+ ok := C.wasi_config_set_stderr_file(c.ptr(), pathC)
+ runtime.KeepAlive(c)
+ C.free(unsafe.Pointer(pathC))
+ if ok {
+ return nil
+ }
+
+ return errors.New("failed to open file")
+}
+
+func (c *WasiConfig) InheritStderr() {
+ C.wasi_config_inherit_stderr(c.ptr())
+ runtime.KeepAlive(c)
+}
+
+func (c *WasiConfig) PreopenDir(path, guestPath string) error {
+ pathC := C.CString(path)
+ guestPathC := C.CString(guestPath)
+ ok := C.wasi_config_preopen_dir(c.ptr(), pathC, guestPathC)
+ runtime.KeepAlive(c)
+ C.free(unsafe.Pointer(pathC))
+ C.free(unsafe.Pointer(guestPathC))
+ if ok {
+ return nil
+ }
+
+ return errors.New("failed to preopen directory")
+}
+
+type WasiInstance struct {
+ _ptr *C.wasi_instance_t
+ freelist *freeList
+}
+
+// NewWasiInstance creates a new instance of WASI with the given configuration.
+//
+// The version of WASI must be explicitly requested via `name`.
+func NewWasiInstance(store *Store, config *WasiConfig, name string) (*WasiInstance, error) {
+ if config._ptr == nil {
+ panic("config already used to create wasi instance")
+ }
+ var trap *C.wasm_trap_t
+ namePtr := C.CString(name)
+ ptr := C.wasi_instance_new(
+ store.ptr(),
+ namePtr,
+ config.ptr(),
+ &trap,
+ )
+ runtime.KeepAlive(store)
+ config._ptr = nil
+ runtime.SetFinalizer(config, nil)
+ C.free(unsafe.Pointer(namePtr))
+
+ if ptr == nil {
+ if trap != nil {
+ return nil, mkTrap(trap)
+ }
+ return nil, errors.New("failed to create instance")
+ }
+
+ instance := &WasiInstance{
+ _ptr: ptr,
+ freelist: store.freelist,
+ }
+ runtime.SetFinalizer(instance, func(instance *WasiInstance) {
+ freelist := instance.freelist
+ freelist.lock.Lock()
+ defer freelist.lock.Unlock()
+ freelist.wasiInstances = append(freelist.wasiInstances, instance._ptr)
+ })
+ return instance, nil
+}
+
+func (i *WasiInstance) ptr() *C.wasi_instance_t {
+ ret := i._ptr
+ maybeGC()
+ return ret
+}
+
+// BindImport attempts to bind the `imp` import provided, returning an Extern suitable for
+// satisfying the import if one can be found.
+//
+// If `imp` isn't defined by this instance of WASI then `nil` is returned.
+func (i *WasiInstance) BindImport(imp *ImportType) *Extern {
+ ret := C.wasi_instance_bind_import(i.ptr(), imp.ptr())
+ runtime.KeepAlive(i)
+ runtime.KeepAlive(imp)
+ if ret == nil {
+ return nil
+ }
+
+ return mkExtern(ret, i.freelist, nil)
+}
diff --git a/constraint/vendor/github.com/bytecodealliance/wasmtime-go/wat2wasm.go b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/wat2wasm.go
new file mode 100644
index 000000000..eb6a62af0
--- /dev/null
+++ b/constraint/vendor/github.com/bytecodealliance/wasmtime-go/wat2wasm.go
@@ -0,0 +1,41 @@
+package wasmtime
+
+// #include
+//
+// wasmtime_error_t *go_wat2wasm(
+// char *wat_ptr,
+// size_t wat_len,
+// wasm_byte_vec_t *ret
+// ) {
+// wasm_byte_vec_t wat;
+// wat.data = wat_ptr;
+// wat.size = wat_len;
+// return wasmtime_wat2wasm(&wat, ret);
+// }
+import "C"
+import (
+ "runtime"
+ "unsafe"
+)
+
+// Wat2Wasm converts the text format of WebAssembly to the binary format.
+//
+// Takes the text format in-memory as input, and returns either the binary
+// encoding of the text format or an error if parsing fails.
+func Wat2Wasm(wat string) ([]byte, error) {
+ retVec := C.wasm_byte_vec_t{}
+ err := C.go_wat2wasm(
+ C._GoStringPtr(wat),
+ C._GoStringLen(wat),
+ &retVec,
+ )
+ runtime.KeepAlive(wat)
+
+ if err == nil {
+ ret := C.GoBytes(unsafe.Pointer(retVec.data), C.int(retVec.size))
+ C.wasm_byte_vec_delete(&retVec)
+ return ret, nil
+ }
+
+ return nil, mkError(err)
+}
diff --git a/constraint/vendor/github.com/go-openapi/jsonpointer/.travis.yml b/constraint/vendor/github.com/go-openapi/jsonpointer/.travis.yml
index 9aef9184e..03a22fe06 100644
--- a/constraint/vendor/github.com/go-openapi/jsonpointer/.travis.yml
+++ b/constraint/vendor/github.com/go-openapi/jsonpointer/.travis.yml
@@ -1,8 +1,8 @@
after_success:
- bash <(curl -s https://codecov.io/bash)
go:
-- 1.11.x
-- 1.12.x
+- 1.14.x
+- 1.15.x
install:
- GO111MODULE=off go get -u gotest.tools/gotestsum
env:
diff --git a/constraint/vendor/github.com/go-openapi/jsonpointer/pointer.go b/constraint/vendor/github.com/go-openapi/jsonpointer/pointer.go
index b284eb77a..7df9853de 100644
--- a/constraint/vendor/github.com/go-openapi/jsonpointer/pointer.go
+++ b/constraint/vendor/github.com/go-openapi/jsonpointer/pointer.go
@@ -114,16 +114,16 @@ func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.Nam
rValue := reflect.Indirect(reflect.ValueOf(node))
kind := rValue.Kind()
- switch kind {
+ if rValue.Type().Implements(jsonPointableType) {
+ r, err := node.(JSONPointable).JSONLookup(decodedToken)
+ if err != nil {
+ return nil, kind, err
+ }
+ return r, kind, nil
+ }
+ switch kind {
case reflect.Struct:
- if rValue.Type().Implements(jsonPointableType) {
- r, err := node.(JSONPointable).JSONLookup(decodedToken)
- if err != nil {
- return nil, kind, err
- }
- return r, kind, nil
- }
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
if !ok {
return nil, kind, fmt.Errorf("object has no field %q", decodedToken)
@@ -161,17 +161,17 @@ func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.Nam
func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *swag.NameProvider) error {
rValue := reflect.Indirect(reflect.ValueOf(node))
- switch rValue.Kind() {
- case reflect.Struct:
- if ns, ok := node.(JSONSetable); ok { // pointer impl
- return ns.JSONSet(decodedToken, data)
- }
+ if ns, ok := node.(JSONSetable); ok { // pointer impl
+ return ns.JSONSet(decodedToken, data)
+ }
- if rValue.Type().Implements(jsonSetableType) {
- return node.(JSONSetable).JSONSet(decodedToken, data)
- }
+ if rValue.Type().Implements(jsonSetableType) {
+ return node.(JSONSetable).JSONSet(decodedToken, data)
+ }
+ switch rValue.Kind() {
+ case reflect.Struct:
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
if !ok {
return fmt.Errorf("object has no field %q", decodedToken)
@@ -270,22 +270,22 @@ func (p *Pointer) set(node, data interface{}, nameProvider *swag.NameProvider) e
rValue := reflect.Indirect(reflect.ValueOf(node))
kind := rValue.Kind()
- switch kind {
-
- case reflect.Struct:
- if rValue.Type().Implements(jsonPointableType) {
- r, err := node.(JSONPointable).JSONLookup(decodedToken)
- if err != nil {
- return err
- }
- fld := reflect.ValueOf(r)
- if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Ptr {
- node = fld.Addr().Interface()
- continue
- }
- node = r
+ if rValue.Type().Implements(jsonPointableType) {
+ r, err := node.(JSONPointable).JSONLookup(decodedToken)
+ if err != nil {
+ return err
+ }
+ fld := reflect.ValueOf(r)
+ if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Ptr {
+ node = fld.Addr().Interface()
continue
}
+ node = r
+ continue
+ }
+
+ switch kind {
+ case reflect.Struct:
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
if !ok {
return fmt.Errorf("object has no field %q", decodedToken)
diff --git a/constraint/vendor/github.com/go-openapi/jsonreference/.golangci.yml b/constraint/vendor/github.com/go-openapi/jsonreference/.golangci.yml
new file mode 100644
index 000000000..f9381aee5
--- /dev/null
+++ b/constraint/vendor/github.com/go-openapi/jsonreference/.golangci.yml
@@ -0,0 +1,41 @@
+linters-settings:
+ govet:
+ check-shadowing: true
+ golint:
+ min-confidence: 0
+ gocyclo:
+ min-complexity: 30
+ maligned:
+ suggest-new: true
+ dupl:
+ threshold: 100
+ goconst:
+ min-len: 2
+ min-occurrences: 4
+linters:
+ enable-all: true
+ disable:
+ - maligned
+ - lll
+ - gochecknoglobals
+ - godox
+ - gocognit
+ - whitespace
+ - wsl
+ - funlen
+ - gochecknoglobals
+ - gochecknoinits
+ - scopelint
+ - wrapcheck
+ - exhaustivestruct
+ - exhaustive
+ - nlreturn
+ - testpackage
+ - gci
+ - gofumpt
+ - goerr113
+ - gomnd
+ - tparallel
+ - nestif
+ - godot
+ - errorlint
diff --git a/constraint/vendor/github.com/go-openapi/jsonreference/.travis.yml b/constraint/vendor/github.com/go-openapi/jsonreference/.travis.yml
index 40b90757d..05482f4b9 100644
--- a/constraint/vendor/github.com/go-openapi/jsonreference/.travis.yml
+++ b/constraint/vendor/github.com/go-openapi/jsonreference/.travis.yml
@@ -1,10 +1,19 @@
after_success:
- bash <(curl -s https://codecov.io/bash)
go:
-- 1.11.x
-- 1.12.x
+- 1.14.x
+- 1.x
install:
-- GO111MODULE=off go get -u gotest.tools/gotestsum
+- go get gotest.tools/gotestsum
+jobs:
+ include:
+ # include linting job, but only for latest go version and amd64 arch
+ - go: 1.x
+ arch: amd64
+ install:
+ go get github.com/golangci/golangci-lint/cmd/golangci-lint
+ script:
+ - golangci-lint run --new-from-rev master
env:
- GO111MODULE=on
language: go
diff --git a/constraint/vendor/github.com/go-openapi/jsonreference/README.md b/constraint/vendor/github.com/go-openapi/jsonreference/README.md
index 66345f4c6..b94753aa5 100644
--- a/constraint/vendor/github.com/go-openapi/jsonreference/README.md
+++ b/constraint/vendor/github.com/go-openapi/jsonreference/README.md
@@ -4,7 +4,7 @@
An implementation of JSON Reference - Go language
## Status
-Work in progress ( 90% done )
+Feature complete. Stable API
## Dependencies
https://github.com/go-openapi/jsonpointer
diff --git a/constraint/vendor/github.com/go-openapi/jsonreference/go.mod b/constraint/vendor/github.com/go-openapi/jsonreference/go.mod
index aff1d0163..e6c2ec4d9 100644
--- a/constraint/vendor/github.com/go-openapi/jsonreference/go.mod
+++ b/constraint/vendor/github.com/go-openapi/jsonreference/go.mod
@@ -6,7 +6,7 @@ require (
github.com/go-openapi/jsonpointer v0.19.3
github.com/stretchr/testify v1.3.0
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 // indirect
- golang.org/x/text v0.3.2 // indirect
+ golang.org/x/text v0.3.3 // indirect
)
go 1.13
diff --git a/constraint/vendor/github.com/go-openapi/jsonreference/go.sum b/constraint/vendor/github.com/go-openapi/jsonreference/go.sum
index c7ceab580..b37f873e5 100644
--- a/constraint/vendor/github.com/go-openapi/jsonreference/go.sum
+++ b/constraint/vendor/github.com/go-openapi/jsonreference/go.sum
@@ -5,12 +5,8 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko
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/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0=
-github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
-github.com/go-openapi/swag v0.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE=
-github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
@@ -28,14 +24,12 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU=
-golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
diff --git a/constraint/vendor/github.com/go-openapi/spec/.golangci.yml b/constraint/vendor/github.com/go-openapi/spec/.golangci.yml
index 4e17ed497..835d55e74 100644
--- a/constraint/vendor/github.com/go-openapi/spec/.golangci.yml
+++ b/constraint/vendor/github.com/go-openapi/spec/.golangci.yml
@@ -26,3 +26,17 @@ linters:
- gocognit
- whitespace
- wsl
+ - wrapcheck
+ - testpackage
+ - nlreturn
+ - gomnd
+ - exhaustivestruct
+ - goerr113
+ - errorlint
+ - nestif
+ - godot
+ - gofumpt
+ - paralleltest
+ - tparallel
+ - thelper
+ - ifshort
diff --git a/constraint/vendor/github.com/go-openapi/spec/.travis.yml b/constraint/vendor/github.com/go-openapi/spec/.travis.yml
index aa26d8763..e8ceca446 100644
--- a/constraint/vendor/github.com/go-openapi/spec/.travis.yml
+++ b/constraint/vendor/github.com/go-openapi/spec/.travis.yml
@@ -1,12 +1,28 @@
after_success:
- bash <(curl -s https://codecov.io/bash)
go:
-- 1.11.x
-- 1.12.x
+- 1.14.x
+- 1.x
+arch:
+ - amd64
+jobs:
+ include:
+ # only run fast tests on ppc64le
+ - go: 1.x
+ arch: ppc64le
+ script:
+ - gotestsum -f short-verbose -- ./...
+
+ # include linting job, but only for latest go version and amd64 arch
+ - go: 1.x
+ arch: amd64
+ install:
+ go get github.com/golangci/golangci-lint/cmd/golangci-lint
+ script:
+ - golangci-lint run --new-from-rev master
+
install:
- GO111MODULE=off go get -u gotest.tools/gotestsum
-env:
-- GO111MODULE=on
language: go
notifications:
slack:
diff --git a/constraint/vendor/github.com/go-openapi/spec/README.md b/constraint/vendor/github.com/go-openapi/spec/README.md
index 6354742cb..18782c6da 100644
--- a/constraint/vendor/github.com/go-openapi/spec/README.md
+++ b/constraint/vendor/github.com/go-openapi/spec/README.md
@@ -1,10 +1,34 @@
-# OAI object model [![Build Status](https://travis-ci.org/go-openapi/spec.svg?branch=master)](https://travis-ci.org/go-openapi/spec) [![codecov](https://codecov.io/gh/go-openapi/spec/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/spec) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
+# OAI object model
+[![Build Status](https://travis-ci.org/go-openapi/spec.svg?branch=master)](https://travis-ci.org/go-openapi/spec)
+
+[![codecov](https://codecov.io/gh/go-openapi/spec/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/spec)
+[![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/spec/master/LICENSE)
-[![GoDoc](https://godoc.org/github.com/go-openapi/spec?status.svg)](http://godoc.org/github.com/go-openapi/spec)
-[![GolangCI](https://golangci.com/badges/github.com/go-openapi/spec.svg)](https://golangci.com)
+[![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/spec.svg)](https://pkg.go.dev/github.com/go-openapi/spec)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/spec)](https://goreportcard.com/report/github.com/go-openapi/spec)
The object model for OpenAPI specification documents.
-Currently supports Swagger 2.0.
+### FAQ
+
+* What does this do?
+
+> 1. This package knows how to marshal and unmarshal Swagger API specifications into a golang object model
+> 2. It knows how to resolve $ref and expand them to make a single root document
+
+* How does it play with the rest of the go-openapi packages ?
+
+> 1. This package is at the core of the go-openapi suite of packages and [code generator](https://github.com/go-swagger/go-swagger)
+> 2. There is a [spec loading package](https://github.com/go-openapi/loads) to fetch specs as JSON or YAML from local or remote locations
+> 3. There is a [spec validation package](https://github.com/go-openapi/validate) built on top of it
+> 4. There is a [spec analysis package](https://github.com/go-openapi/analysis) built on top of it, to analyze, flatten, fix and merge spec documents
+
+* Does this library support OpenAPI 3?
+
+> No.
+> This package currently only supports OpenAPI 2.0 (aka Swagger 2.0).
+> There is no plan to make it evolve toward supporting OpenAPI 3.x.
+> This [discussion thread](https://github.com/go-openapi/spec/issues/21) relates the full story.
+>
+> An early attempt to support Swagger 3 may be found at: https://github.com/go-openapi/spec3
diff --git a/constraint/vendor/github.com/go-openapi/spec/appveyor.yml b/constraint/vendor/github.com/go-openapi/spec/appveyor.yml
new file mode 100644
index 000000000..090359391
--- /dev/null
+++ b/constraint/vendor/github.com/go-openapi/spec/appveyor.yml
@@ -0,0 +1,32 @@
+version: "0.1.{build}"
+
+clone_folder: C:\go-openapi\spec
+shallow_clone: true # for startup speed
+pull_requests:
+ do_not_increment_build_number: true
+
+#skip_tags: true
+#skip_branch_with_pr: true
+
+# appveyor.yml
+build: off
+
+environment:
+ GOPATH: c:\gopath
+
+stack: go 1.15
+
+test_script:
+ - go test -v -timeout 20m ./...
+
+deploy: off
+
+notifications:
+ - provider: Slack
+ incoming_webhook: https://hooks.slack.com/services/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
+ auth_token:
+ secure: Sf7kZf7ZGbnwWUMpffHwMu5A0cHkLK2MYY32LNTPj4+/3qC3Ghl7+9v4TSLOqOlCwdRNjOGblAq7s+GDJed6/xgRQl1JtCi1klzZNrYX4q01pgTPvvGcwbBkIYgeMaPeIRcK9OZnud7sRXdttozgTOpytps2U6Js32ip7uj5mHSg2ub0FwoSJwlS6dbezZ8+eDhoha0F/guY99BEwx8Bd+zROrT2TFGsSGOFGN6wFc7moCqTHO/YkWib13a2QNXqOxCCVBy/lt76Wp+JkeFppjHlzs/2lP3EAk13RIUAaesdEUHvIHrzCyNJEd3/+KO2DzsWOYfpktd+KBCvgaYOsoo7ubdT3IROeAegZdCgo/6xgCEsmFc9ZcqCfN5yNx2A+BZ2Vwmpws+bQ1E1+B5HDzzaiLcYfG4X2O210QVGVDLWsv1jqD+uPYeHY2WRfh5ZsIUFvaqgUEnwHwrK44/8REAhQavt1QAj5uJpsRd7CkRVPWRNK+yIky+wgbVUFEchRNmS55E7QWf+W4+4QZkQi7vUTMc9nbTUu2Es9NfvfudOpM2wZbn98fjpb/qq/nRv6Bk+ca+7XD5/IgNLMbWp2ouDdzbiHLCOfDUiHiDJhLfFZx9Bwo7ZwfzeOlbrQX66bx7xRKYmOe4DLrXhNcpbsMa8qbfxlZRCmYbubB/Y8h4=
+ channel: bots
+ on_build_success: false
+ on_build_failure: true
+ on_build_status_changed: true
diff --git a/constraint/vendor/github.com/go-openapi/spec/bindata.go b/constraint/vendor/github.com/go-openapi/spec/bindata.go
index 66b1f3263..afc83850c 100644
--- a/constraint/vendor/github.com/go-openapi/spec/bindata.go
+++ b/constraint/vendor/github.com/go-openapi/spec/bindata.go
@@ -247,9 +247,9 @@ type bintree struct {
}
var _bintree = &bintree{nil, map[string]*bintree{
- "jsonschema-draft-04.json": &bintree{jsonschemaDraft04Json, map[string]*bintree{}},
- "v2": &bintree{nil, map[string]*bintree{
- "schema.json": &bintree{v2SchemaJson, map[string]*bintree{}},
+ "jsonschema-draft-04.json": {jsonschemaDraft04Json, map[string]*bintree{}},
+ "v2": {nil, map[string]*bintree{
+ "schema.json": {v2SchemaJson, map[string]*bintree{}},
}},
}}
diff --git a/constraint/vendor/github.com/go-openapi/spec/cache.go b/constraint/vendor/github.com/go-openapi/spec/cache.go
index 3fada0dae..122993b44 100644
--- a/constraint/vendor/github.com/go-openapi/spec/cache.go
+++ b/constraint/vendor/github.com/go-openapi/spec/cache.go
@@ -14,7 +14,9 @@
package spec
-import "sync"
+import (
+ "sync"
+)
// ResolutionCache a cache for resolving urls
type ResolutionCache interface {
@@ -27,12 +29,23 @@ type simpleCache struct {
store map[string]interface{}
}
+func (s *simpleCache) ShallowClone() ResolutionCache {
+ store := make(map[string]interface{}, len(s.store))
+ s.lock.RLock()
+ for k, v := range s.store {
+ store[k] = v
+ }
+ s.lock.RUnlock()
+
+ return &simpleCache{
+ store: store,
+ }
+}
+
// Get retrieves a cached URI
func (s *simpleCache) Get(uri string) (interface{}, bool) {
- debugLog("getting %q from resolution cache", uri)
s.lock.RLock()
v, ok := s.store[uri]
- debugLog("got %q from resolution cache: %t", uri, ok)
s.lock.RUnlock()
return v, ok
@@ -45,16 +58,41 @@ func (s *simpleCache) Set(uri string, data interface{}) {
s.lock.Unlock()
}
-var resCache ResolutionCache
+var (
+ // resCache is a package level cache for $ref resolution and expansion.
+ // It is initialized lazily by methods that have the need for it: no
+ // memory is allocated unless some expander methods are called.
+ //
+ // It is initialized with JSON schema and swagger schema,
+ // which do not mutate during normal operations.
+ //
+ // All subsequent utilizations of this cache are produced from a shallow
+ // clone of this initial version.
+ resCache *simpleCache
+ onceCache sync.Once
-func init() {
- resCache = initResolutionCache()
+ _ ResolutionCache = &simpleCache{}
+)
+
+// initResolutionCache initializes the URI resolution cache. To be wrapped in a sync.Once.Do call.
+func initResolutionCache() {
+ resCache = defaultResolutionCache()
}
-// initResolutionCache initializes the URI resolution cache
-func initResolutionCache() ResolutionCache {
+func defaultResolutionCache() *simpleCache {
return &simpleCache{store: map[string]interface{}{
"http://swagger.io/v2/schema.json": MustLoadSwagger20Schema(),
"http://json-schema.org/draft-04/schema": MustLoadJSONSchemaDraft04(),
}}
}
+
+func cacheOrDefault(cache ResolutionCache) ResolutionCache {
+ onceCache.Do(initResolutionCache)
+
+ if cache != nil {
+ return cache
+ }
+
+ // get a shallow clone of the base cache with swagger and json schema
+ return resCache.ShallowClone()
+}
diff --git a/constraint/vendor/github.com/go-openapi/spec/contact_info.go b/constraint/vendor/github.com/go-openapi/spec/contact_info.go
index f285970aa..2f7bb219b 100644
--- a/constraint/vendor/github.com/go-openapi/spec/contact_info.go
+++ b/constraint/vendor/github.com/go-openapi/spec/contact_info.go
@@ -14,11 +14,44 @@
package spec
+import (
+ "encoding/json"
+
+ "github.com/go-openapi/swag"
+)
+
// ContactInfo contact information for the exposed API.
//
// For more information: http://goo.gl/8us55a#contactObject
type ContactInfo struct {
+ ContactInfoProps
+ VendorExtensible
+}
+
+// ContactInfoProps hold the properties of a ContactInfo object
+type ContactInfoProps struct {
Name string `json:"name,omitempty"`
URL string `json:"url,omitempty"`
Email string `json:"email,omitempty"`
}
+
+// UnmarshalJSON hydrates ContactInfo from json
+func (c *ContactInfo) UnmarshalJSON(data []byte) error {
+ if err := json.Unmarshal(data, &c.ContactInfoProps); err != nil {
+ return err
+ }
+ return json.Unmarshal(data, &c.VendorExtensible)
+}
+
+// MarshalJSON produces ContactInfo as json
+func (c ContactInfo) MarshalJSON() ([]byte, error) {
+ b1, err := json.Marshal(c.ContactInfoProps)
+ if err != nil {
+ return nil, err
+ }
+ b2, err := json.Marshal(c.VendorExtensible)
+ if err != nil {
+ return nil, err
+ }
+ return swag.ConcatJSON(b1, b2), nil
+}
diff --git a/constraint/vendor/github.com/go-openapi/spec/debug.go b/constraint/vendor/github.com/go-openapi/spec/debug.go
index 389c528ff..fc889f6d0 100644
--- a/constraint/vendor/github.com/go-openapi/spec/debug.go
+++ b/constraint/vendor/github.com/go-openapi/spec/debug.go
@@ -18,14 +18,16 @@ import (
"fmt"
"log"
"os"
- "path/filepath"
+ "path"
"runtime"
)
+// Debug is true when the SWAGGER_DEBUG env var is not empty.
+//
+// It enables a more verbose logging of this package.
+var Debug = os.Getenv("SWAGGER_DEBUG") != ""
+
var (
- // Debug is true when the SWAGGER_DEBUG env var is not empty.
- // It enables a more verbose logging of this package.
- Debug = os.Getenv("SWAGGER_DEBUG") != ""
// specLogger is a debug logger for this package
specLogger *log.Logger
)
@@ -42,6 +44,6 @@ func debugLog(msg string, args ...interface{}) {
// A private, trivial trace logger, based on go-openapi/spec/expander.go:debugLog()
if Debug {
_, file1, pos1, _ := runtime.Caller(1)
- specLogger.Printf("%s:%d: %s", filepath.Base(file1), pos1, fmt.Sprintf(msg, args...))
+ specLogger.Printf("%s:%d: %s", path.Base(file1), pos1, fmt.Sprintf(msg, args...))
}
}
diff --git a/constraint/vendor/github.com/go-openapi/spec/errors.go b/constraint/vendor/github.com/go-openapi/spec/errors.go
new file mode 100644
index 000000000..6992c7ba7
--- /dev/null
+++ b/constraint/vendor/github.com/go-openapi/spec/errors.go
@@ -0,0 +1,19 @@
+package spec
+
+import "errors"
+
+// Error codes
+var (
+ // ErrUnknownTypeForReference indicates that a resolved reference was found in an unsupported container type
+ ErrUnknownTypeForReference = errors.New("unknown type for the resolved reference")
+
+ // ErrResolveRefNeedsAPointer indicates that a $ref target must be a valid JSON pointer
+ ErrResolveRefNeedsAPointer = errors.New("resolve ref: target needs to be a pointer")
+
+ // ErrDerefUnsupportedType indicates that a resolved reference was found in an unsupported container type.
+ // At the moment, $ref are supported only inside: schemas, parameters, responses, path items
+ ErrDerefUnsupportedType = errors.New("deref: unsupported type")
+
+ // ErrExpandUnsupportedType indicates that $ref expansion is attempted on some invalid type
+ ErrExpandUnsupportedType = errors.New("expand: unsupported type. Input should be of type *Parameter or *Response")
+)
diff --git a/constraint/vendor/github.com/go-openapi/spec/expander.go b/constraint/vendor/github.com/go-openapi/spec/expander.go
index 043720d7d..d4ea889d4 100644
--- a/constraint/vendor/github.com/go-openapi/spec/expander.go
+++ b/constraint/vendor/github.com/go-openapi/spec/expander.go
@@ -17,152 +17,51 @@ package spec
import (
"encoding/json"
"fmt"
- "strings"
)
-// ExpandOptions provides options for spec expand
-type ExpandOptions struct {
- RelativeBase string
- SkipSchemas bool
- ContinueOnError bool
- AbsoluteCircularRef bool
-}
-
-// ResolveRefWithBase resolves a reference against a context root with preservation of base path
-func ResolveRefWithBase(root interface{}, ref *Ref, opts *ExpandOptions) (*Schema, error) {
- resolver, err := defaultSchemaLoader(root, opts, nil, nil)
- if err != nil {
- return nil, err
- }
- specBasePath := ""
- if opts != nil && opts.RelativeBase != "" {
- specBasePath, _ = absPath(opts.RelativeBase)
- }
-
- result := new(Schema)
- if err := resolver.Resolve(ref, result, specBasePath); err != nil {
- return nil, err
- }
- return result, nil
-}
-
-// ResolveRef resolves a reference against a context root
-// ref is guaranteed to be in root (no need to go to external files)
-// ResolveRef is ONLY called from the code generation module
-func ResolveRef(root interface{}, ref *Ref) (*Schema, error) {
- res, _, err := ref.GetPointer().Get(root)
- if err != nil {
- panic(err)
- }
- switch sch := res.(type) {
- case Schema:
- return &sch, nil
- case *Schema:
- return sch, nil
- case map[string]interface{}:
- b, _ := json.Marshal(sch)
- newSch := new(Schema)
- _ = json.Unmarshal(b, newSch)
- return newSch, nil
- default:
- return nil, fmt.Errorf("unknown type for the resolved reference")
- }
-}
-
-// ResolveParameter resolves a parameter reference against a context root
-func ResolveParameter(root interface{}, ref Ref) (*Parameter, error) {
- return ResolveParameterWithBase(root, ref, nil)
-}
-
-// ResolveParameterWithBase resolves a parameter reference against a context root and base path
-func ResolveParameterWithBase(root interface{}, ref Ref, opts *ExpandOptions) (*Parameter, error) {
- resolver, err := defaultSchemaLoader(root, opts, nil, nil)
- if err != nil {
- return nil, err
- }
-
- result := new(Parameter)
- if err := resolver.Resolve(&ref, result, ""); err != nil {
- return nil, err
- }
- return result, nil
-}
-
-// ResolveResponse resolves response a reference against a context root
-func ResolveResponse(root interface{}, ref Ref) (*Response, error) {
- return ResolveResponseWithBase(root, ref, nil)
-}
-
-// ResolveResponseWithBase resolves response a reference against a context root and base path
-func ResolveResponseWithBase(root interface{}, ref Ref, opts *ExpandOptions) (*Response, error) {
- resolver, err := defaultSchemaLoader(root, opts, nil, nil)
- if err != nil {
- return nil, err
- }
-
- result := new(Response)
- if err := resolver.Resolve(&ref, result, ""); err != nil {
- return nil, err
- }
- return result, nil
-}
-
-// ResolveItems resolves parameter items reference against a context root and base path.
+// ExpandOptions provides options for the spec expander.
//
-// NOTE: stricly speaking, this construct is not supported by Swagger 2.0.
-// Similarly, $ref are forbidden in response headers.
-func ResolveItems(root interface{}, ref Ref, opts *ExpandOptions) (*Items, error) {
- resolver, err := defaultSchemaLoader(root, opts, nil, nil)
- if err != nil {
- return nil, err
- }
- basePath := ""
- if opts.RelativeBase != "" {
- basePath = opts.RelativeBase
- }
- result := new(Items)
- if err := resolver.Resolve(&ref, result, basePath); err != nil {
- return nil, err
- }
- return result, nil
+// RelativeBase is the path to the root document. This can be a remote URL or a path to a local file.
+//
+// If left empty, the root document is assumed to be located in the current working directory:
+// all relative $ref's will be resolved from there.
+//
+// PathLoader injects a document loading method. By default, this resolves to the function provided by the SpecLoader package variable.
+//
+type ExpandOptions struct {
+ RelativeBase string // the path to the root document to expand. This is a file, not a directory
+ SkipSchemas bool // do not expand schemas, just paths, parameters and responses
+ ContinueOnError bool // continue expanding even after and error is found
+ PathLoader func(string) (json.RawMessage, error) `json:"-"` // the document loading method that takes a path as input and yields a json document
+ AbsoluteCircularRef bool // circular $ref remaining after expansion remain absolute URLs
}
-// ResolvePathItem resolves response a path item against a context root and base path
-func ResolvePathItem(root interface{}, ref Ref, opts *ExpandOptions) (*PathItem, error) {
- resolver, err := defaultSchemaLoader(root, opts, nil, nil)
- if err != nil {
- return nil, err
- }
- basePath := ""
- if opts.RelativeBase != "" {
- basePath = opts.RelativeBase
- }
- result := new(PathItem)
- if err := resolver.Resolve(&ref, result, basePath); err != nil {
- return nil, err
+func optionsOrDefault(opts *ExpandOptions) *ExpandOptions {
+ if opts != nil {
+ clone := *opts // shallow clone to avoid internal changes to be propagated to the caller
+ if clone.RelativeBase != "" {
+ clone.RelativeBase = normalizeBase(clone.RelativeBase)
+ }
+ // if the relative base is empty, let the schema loader choose a pseudo root document
+ return &clone
}
- return result, nil
+ return &ExpandOptions{}
}
// ExpandSpec expands the references in a swagger spec
func ExpandSpec(spec *Swagger, options *ExpandOptions) error {
- resolver, err := defaultSchemaLoader(spec, options, nil, nil)
- // Just in case this ever returns an error.
- if resolver.shouldStopOnError(err) {
- return err
- }
+ options = optionsOrDefault(options)
+ resolver := defaultSchemaLoader(spec, options, nil, nil)
- // getting the base path of the spec to adjust all subsequent reference resolutions
- specBasePath := ""
- if options != nil && options.RelativeBase != "" {
- specBasePath, _ = absPath(options.RelativeBase)
- }
+ specBasePath := options.RelativeBase
- if options == nil || !options.SkipSchemas {
+ if !options.SkipSchemas {
for key, definition := range spec.Definitions {
- var def *Schema
- var err error
- if def, err = expandSchema(definition, []string{fmt.Sprintf("#/definitions/%s", key)}, resolver, specBasePath); resolver.shouldStopOnError(err) {
+ parentRefs := make([]string, 0, 10)
+ parentRefs = append(parentRefs, fmt.Sprintf("#/definitions/%s", key))
+
+ def, err := expandSchema(definition, parentRefs, resolver, specBasePath)
+ if resolver.shouldStopOnError(err) {
return err
}
if def != nil {
@@ -189,157 +88,136 @@ func ExpandSpec(spec *Swagger, options *ExpandOptions) error {
if spec.Paths != nil {
for key := range spec.Paths.Paths {
- path := spec.Paths.Paths[key]
- if err := expandPathItem(&path, resolver, specBasePath); resolver.shouldStopOnError(err) {
+ pth := spec.Paths.Paths[key]
+ if err := expandPathItem(&pth, resolver, specBasePath); resolver.shouldStopOnError(err) {
return err
}
- spec.Paths.Paths[key] = path
+ spec.Paths.Paths[key] = pth
}
}
return nil
}
-// baseForRoot loads in the cache the root document and produces a fake "root" base path entry
+const rootBase = ".root"
+
+// baseForRoot loads in the cache the root document and produces a fake ".root" base path entry
// for further $ref resolution
+//
+// Setting the cache is optional and this parameter may safely be left to nil.
func baseForRoot(root interface{}, cache ResolutionCache) string {
+ if root == nil {
+ return ""
+ }
+
// cache the root document to resolve $ref's
- const rootBase = "root"
- if root != nil {
- base, _ := absPath(rootBase)
- normalizedBase := normalizeAbsPath(base)
- debugLog("setting root doc in cache at: %s", normalizedBase)
- if cache == nil {
- cache = resCache
- }
- cache.Set(normalizedBase, root)
- return rootBase
- }
- return ""
+ normalizedBase := normalizeBase(rootBase)
+ cache.Set(normalizedBase, root)
+
+ return normalizedBase
}
-// ExpandSchema expands the refs in the schema object with reference to the root object
-// go-openapi/validate uses this function
-// notice that it is impossible to reference a json schema in a different file other than root
+// ExpandSchema expands the refs in the schema object with reference to the root object.
+//
+// go-openapi/validate uses this function.
+//
+// Notice that it is impossible to reference a json schema in a different document other than root
+// (use ExpandSchemaWithBasePath to resolve external references).
+//
+// Setting the cache is optional and this parameter may safely be left to nil.
func ExpandSchema(schema *Schema, root interface{}, cache ResolutionCache) error {
+ cache = cacheOrDefault(cache)
+ if root == nil {
+ root = schema
+ }
+
opts := &ExpandOptions{
// when a root is specified, cache the root as an in-memory document for $ref retrieval
RelativeBase: baseForRoot(root, cache),
SkipSchemas: false,
ContinueOnError: false,
- // when no base path is specified, remaining $ref (circular) are rendered with an absolute path
- AbsoluteCircularRef: true,
}
+
return ExpandSchemaWithBasePath(schema, cache, opts)
}
-// ExpandSchemaWithBasePath expands the refs in the schema object, base path configured through expand options
+// ExpandSchemaWithBasePath expands the refs in the schema object, base path configured through expand options.
+//
+// Setting the cache is optional and this parameter may safely be left to nil.
func ExpandSchemaWithBasePath(schema *Schema, cache ResolutionCache, opts *ExpandOptions) error {
if schema == nil {
return nil
}
- var basePath string
- if opts.RelativeBase != "" {
- basePath, _ = absPath(opts.RelativeBase)
- }
+ cache = cacheOrDefault(cache)
- resolver, err := defaultSchemaLoader(nil, opts, cache, nil)
+ opts = optionsOrDefault(opts)
+
+ resolver := defaultSchemaLoader(nil, opts, cache, nil)
+
+ parentRefs := make([]string, 0, 10)
+ s, err := expandSchema(*schema, parentRefs, resolver, opts.RelativeBase)
if err != nil {
return err
}
-
- refs := []string{""}
- var s *Schema
- if s, err = expandSchema(*schema, refs, resolver, basePath); err != nil {
- return err
+ if s != nil {
+ // guard for when continuing on error
+ *schema = *s
}
- *schema = *s
+
return nil
}
func expandItems(target Schema, parentRefs []string, resolver *schemaLoader, basePath string) (*Schema, error) {
- if target.Items != nil {
- if target.Items.Schema != nil {
- t, err := expandSchema(*target.Items.Schema, parentRefs, resolver, basePath)
- if err != nil {
- return nil, err
- }
- *target.Items.Schema = *t
+ if target.Items == nil {
+ return &target, nil
+ }
+
+ // array
+ if target.Items.Schema != nil {
+ t, err := expandSchema(*target.Items.Schema, parentRefs, resolver, basePath)
+ if err != nil {
+ return nil, err
}
- for i := range target.Items.Schemas {
- t, err := expandSchema(target.Items.Schemas[i], parentRefs, resolver, basePath)
- if err != nil {
- return nil, err
- }
- target.Items.Schemas[i] = *t
+ *target.Items.Schema = *t
+ }
+
+ // tuple
+ for i := range target.Items.Schemas {
+ t, err := expandSchema(target.Items.Schemas[i], parentRefs, resolver, basePath)
+ if err != nil {
+ return nil, err
}
+ target.Items.Schemas[i] = *t
}
+
return &target, nil
}
func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, basePath string) (*Schema, error) {
if target.Ref.String() == "" && target.Ref.IsRoot() {
- // normalizing is important
- newRef := normalizeFileRef(&target.Ref, basePath)
+ newRef := normalizeRef(&target.Ref, basePath)
target.Ref = *newRef
return &target, nil
-
}
// change the base path of resolution when an ID is encountered
// otherwise the basePath should inherit the parent's
- // important: ID can be relative path
if target.ID != "" {
- debugLog("schema has ID: %s", target.ID)
- // handling the case when id is a folder
- // remember that basePath has to be a file
- refPath := target.ID
- if strings.HasSuffix(target.ID, "/") {
- // path.Clean here would not work correctly if basepath is http
- refPath = fmt.Sprintf("%s%s", refPath, "placeholder.json")
- }
- basePath = normalizePaths(refPath, basePath)
+ basePath, _ = resolver.setSchemaID(target, target.ID, basePath)
}
- var t *Schema
- // if Ref is found, everything else doesn't matter
- // Ref also changes the resolution scope of children expandSchema
if target.Ref.String() != "" {
- // here the resolution scope is changed because a $ref was encountered
- normalizedRef := normalizeFileRef(&target.Ref, basePath)
- normalizedBasePath := normalizedRef.RemoteURI()
-
- if resolver.isCircular(normalizedRef, basePath, parentRefs...) {
- // this means there is a cycle in the recursion tree: return the Ref
- // - circular refs cannot be expanded. We leave them as ref.
- // - denormalization means that a new local file ref is set relative to the original basePath
- debugLog("shortcut circular ref: basePath: %s, normalizedPath: %s, normalized ref: %s",
- basePath, normalizedBasePath, normalizedRef.String())
- if !resolver.options.AbsoluteCircularRef {
- target.Ref = *denormalizeFileRef(normalizedRef, normalizedBasePath, resolver.context.basePath)
- } else {
- target.Ref = *normalizedRef
- }
- return &target, nil
- }
+ return expandSchemaRef(target, parentRefs, resolver, basePath)
+ }
- debugLog("basePath: %s: calling Resolve with target: %#v", basePath, target)
- if err := resolver.Resolve(&target.Ref, &t, basePath); resolver.shouldStopOnError(err) {
- return nil, err
+ for k := range target.Definitions {
+ tt, err := expandSchema(target.Definitions[k], parentRefs, resolver, basePath)
+ if resolver.shouldStopOnError(err) {
+ return &target, err
}
-
- if t != nil {
- parentRefs = append(parentRefs, normalizedRef.String())
- var err error
- transitiveResolver, err := resolver.transitiveResolver(basePath, target.Ref)
- if transitiveResolver.shouldStopOnError(err) {
- return nil, err
- }
-
- basePath = resolver.updateBasePath(transitiveResolver, normalizedBasePath)
-
- return expandSchema(*t, parentRefs, transitiveResolver, basePath)
+ if tt != nil {
+ target.Definitions[k] = *tt
}
}
@@ -356,15 +234,21 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
if resolver.shouldStopOnError(err) {
return &target, err
}
- target.AllOf[i] = *t
+ if t != nil {
+ target.AllOf[i] = *t
+ }
}
+
for i := range target.AnyOf {
t, err := expandSchema(target.AnyOf[i], parentRefs, resolver, basePath)
if resolver.shouldStopOnError(err) {
return &target, err
}
- target.AnyOf[i] = *t
+ if t != nil {
+ target.AnyOf[i] = *t
+ }
}
+
for i := range target.OneOf {
t, err := expandSchema(target.OneOf[i], parentRefs, resolver, basePath)
if resolver.shouldStopOnError(err) {
@@ -374,6 +258,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
target.OneOf[i] = *t
}
}
+
if target.Not != nil {
t, err := expandSchema(*target.Not, parentRefs, resolver, basePath)
if resolver.shouldStopOnError(err) {
@@ -383,6 +268,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
*target.Not = *t
}
}
+
for k := range target.Properties {
t, err := expandSchema(target.Properties[k], parentRefs, resolver, basePath)
if resolver.shouldStopOnError(err) {
@@ -392,6 +278,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
target.Properties[k] = *t
}
}
+
if target.AdditionalProperties != nil && target.AdditionalProperties.Schema != nil {
t, err := expandSchema(*target.AdditionalProperties.Schema, parentRefs, resolver, basePath)
if resolver.shouldStopOnError(err) {
@@ -401,6 +288,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
*target.AdditionalProperties.Schema = *t
}
}
+
for k := range target.PatternProperties {
t, err := expandSchema(target.PatternProperties[k], parentRefs, resolver, basePath)
if resolver.shouldStopOnError(err) {
@@ -410,6 +298,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
target.PatternProperties[k] = *t
}
}
+
for k := range target.Dependencies {
if target.Dependencies[k].Schema != nil {
t, err := expandSchema(*target.Dependencies[k].Schema, parentRefs, resolver, basePath)
@@ -421,6 +310,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
}
}
}
+
if target.AdditionalItems != nil && target.AdditionalItems.Schema != nil {
t, err := expandSchema(*target.AdditionalItems.Schema, parentRefs, resolver, basePath)
if resolver.shouldStopOnError(err) {
@@ -430,16 +320,48 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
*target.AdditionalItems.Schema = *t
}
}
- for k := range target.Definitions {
- t, err := expandSchema(target.Definitions[k], parentRefs, resolver, basePath)
- if resolver.shouldStopOnError(err) {
- return &target, err
- }
- if t != nil {
- target.Definitions[k] = *t
+ return &target, nil
+}
+
+func expandSchemaRef(target Schema, parentRefs []string, resolver *schemaLoader, basePath string) (*Schema, error) {
+ // if a Ref is found, all sibling fields are skipped
+ // Ref also changes the resolution scope of children expandSchema
+
+ // here the resolution scope is changed because a $ref was encountered
+ normalizedRef := normalizeRef(&target.Ref, basePath)
+ normalizedBasePath := normalizedRef.RemoteURI()
+
+ if resolver.isCircular(normalizedRef, basePath, parentRefs...) {
+ // this means there is a cycle in the recursion tree: return the Ref
+ // - circular refs cannot be expanded. We leave them as ref.
+ // - denormalization means that a new local file ref is set relative to the original basePath
+ debugLog("short circuit circular ref: basePath: %s, normalizedPath: %s, normalized ref: %s",
+ basePath, normalizedBasePath, normalizedRef.String())
+ if !resolver.options.AbsoluteCircularRef {
+ target.Ref = denormalizeRef(normalizedRef, resolver.context.basePath, resolver.context.rootID)
+ } else {
+ target.Ref = *normalizedRef
}
+ return &target, nil
}
- return &target, nil
+
+ var t *Schema
+ err := resolver.Resolve(&target.Ref, &t, basePath)
+ if resolver.shouldStopOnError(err) {
+ return nil, err
+ }
+
+ if t == nil {
+ // guard for when continuing on error
+ return &target, nil
+ }
+
+ parentRefs = append(parentRefs, normalizedRef.String())
+ transitiveResolver := resolver.transitiveResolver(basePath, target.Ref)
+
+ basePath = resolver.updateBasePath(transitiveResolver, normalizedBasePath)
+
+ return expandSchema(*t, parentRefs, transitiveResolver, basePath)
}
func expandPathItem(pathItem *PathItem, resolver *schemaLoader, basePath string) error {
@@ -447,25 +369,24 @@ func expandPathItem(pathItem *PathItem, resolver *schemaLoader, basePath string)
return nil
}
- parentRefs := []string{}
+ parentRefs := make([]string, 0, 10)
if err := resolver.deref(pathItem, parentRefs, basePath); resolver.shouldStopOnError(err) {
return err
}
+
if pathItem.Ref.String() != "" {
- transitiveResolver, err := resolver.transitiveResolver(basePath, pathItem.Ref)
- if transitiveResolver.shouldStopOnError(err) {
- return err
- }
+ transitiveResolver := resolver.transitiveResolver(basePath, pathItem.Ref)
basePath = transitiveResolver.updateBasePath(resolver, basePath)
resolver = transitiveResolver
}
- pathItem.Ref = Ref{}
- for idx := range pathItem.Parameters {
- if err := expandParameterOrResponse(&(pathItem.Parameters[idx]), resolver, basePath); resolver.shouldStopOnError(err) {
+ pathItem.Ref = Ref{}
+ for i := range pathItem.Parameters {
+ if err := expandParameterOrResponse(&(pathItem.Parameters[i]), resolver, basePath); resolver.shouldStopOnError(err) {
return err
}
}
+
ops := []*Operation{
pathItem.Get,
pathItem.Head,
@@ -480,6 +401,7 @@ func expandPathItem(pathItem *PathItem, resolver *schemaLoader, basePath string)
return err
}
}
+
return nil
}
@@ -496,71 +418,65 @@ func expandOperation(op *Operation, resolver *schemaLoader, basePath string) err
op.Parameters[i] = param
}
- if op.Responses != nil {
- responses := op.Responses
- if err := expandParameterOrResponse(responses.Default, resolver, basePath); resolver.shouldStopOnError(err) {
+ if op.Responses == nil {
+ return nil
+ }
+
+ responses := op.Responses
+ if err := expandParameterOrResponse(responses.Default, resolver, basePath); resolver.shouldStopOnError(err) {
+ return err
+ }
+
+ for code := range responses.StatusCodeResponses {
+ response := responses.StatusCodeResponses[code]
+ if err := expandParameterOrResponse(&response, resolver, basePath); resolver.shouldStopOnError(err) {
return err
}
- for code := range responses.StatusCodeResponses {
- response := responses.StatusCodeResponses[code]
- if err := expandParameterOrResponse(&response, resolver, basePath); resolver.shouldStopOnError(err) {
- return err
- }
- responses.StatusCodeResponses[code] = response
- }
+ responses.StatusCodeResponses[code] = response
}
+
return nil
}
// ExpandResponseWithRoot expands a response based on a root document, not a fetchable document
+//
+// Notice that it is impossible to reference a json schema in a different document other than root
+// (use ExpandResponse to resolve external references).
+//
+// Setting the cache is optional and this parameter may safely be left to nil.
func ExpandResponseWithRoot(response *Response, root interface{}, cache ResolutionCache) error {
+ cache = cacheOrDefault(cache)
opts := &ExpandOptions{
- RelativeBase: baseForRoot(root, cache),
- SkipSchemas: false,
- ContinueOnError: false,
- // when no base path is specified, remaining $ref (circular) are rendered with an absolute path
- AbsoluteCircularRef: true,
- }
- resolver, err := defaultSchemaLoader(root, opts, nil, nil)
- if err != nil {
- return err
+ RelativeBase: baseForRoot(root, cache),
}
+ resolver := defaultSchemaLoader(root, opts, cache, nil)
return expandParameterOrResponse(response, resolver, opts.RelativeBase)
}
// ExpandResponse expands a response based on a basepath
-// This is the exported version of expandResponse
-// all refs inside response will be resolved relative to basePath
+//
+// All refs inside response will be resolved relative to basePath
func ExpandResponse(response *Response, basePath string) error {
- var specBasePath string
- if basePath != "" {
- specBasePath, _ = absPath(basePath)
- }
- opts := &ExpandOptions{
- RelativeBase: specBasePath,
- }
- resolver, err := defaultSchemaLoader(nil, opts, nil, nil)
- if err != nil {
- return err
- }
+ opts := optionsOrDefault(&ExpandOptions{
+ RelativeBase: basePath,
+ })
+ resolver := defaultSchemaLoader(nil, opts, nil, nil)
return expandParameterOrResponse(response, resolver, opts.RelativeBase)
}
-// ExpandParameterWithRoot expands a parameter based on a root document, not a fetchable document
+// ExpandParameterWithRoot expands a parameter based on a root document, not a fetchable document.
+//
+// Notice that it is impossible to reference a json schema in a different document other than root
+// (use ExpandParameter to resolve external references).
func ExpandParameterWithRoot(parameter *Parameter, root interface{}, cache ResolutionCache) error {
+ cache = cacheOrDefault(cache)
+
opts := &ExpandOptions{
- RelativeBase: baseForRoot(root, cache),
- SkipSchemas: false,
- ContinueOnError: false,
- // when no base path is specified, remaining $ref (circular) are rendered with an absolute path
- AbsoluteCircularRef: true,
- }
- resolver, err := defaultSchemaLoader(root, opts, nil, nil)
- if err != nil {
- return err
+ RelativeBase: baseForRoot(root, cache),
}
+ resolver := defaultSchemaLoader(root, opts, cache, nil)
return expandParameterOrResponse(parameter, resolver, opts.RelativeBase)
}
@@ -569,24 +485,20 @@ func ExpandParameterWithRoot(parameter *Parameter, root interface{}, cache Resol
// This is the exported version of expandParameter
// all refs inside parameter will be resolved relative to basePath
func ExpandParameter(parameter *Parameter, basePath string) error {
- var specBasePath string
- if basePath != "" {
- specBasePath, _ = absPath(basePath)
- }
- opts := &ExpandOptions{
- RelativeBase: specBasePath,
- }
- resolver, err := defaultSchemaLoader(nil, opts, nil, nil)
- if err != nil {
- return err
- }
+ opts := optionsOrDefault(&ExpandOptions{
+ RelativeBase: basePath,
+ })
+ resolver := defaultSchemaLoader(nil, opts, nil, nil)
return expandParameterOrResponse(parameter, resolver, opts.RelativeBase)
}
func getRefAndSchema(input interface{}) (*Ref, *Schema, error) {
- var ref *Ref
- var sch *Schema
+ var (
+ ref *Ref
+ sch *Schema
+ )
+
switch refable := input.(type) {
case *Parameter:
if refable == nil {
@@ -601,8 +513,9 @@ func getRefAndSchema(input interface{}) (*Ref, *Schema, error) {
ref = &refable.Ref
sch = refable.Schema
default:
- return nil, nil, fmt.Errorf("expand: unsupported type %T. Input should be of type *Parameter or *Response", input)
+ return nil, nil, fmt.Errorf("unsupported type: %T: %w", input, ErrExpandUnsupportedType)
}
+
return ref, sch, nil
}
@@ -611,41 +524,71 @@ func expandParameterOrResponse(input interface{}, resolver *schemaLoader, basePa
if err != nil {
return err
}
+
if ref == nil {
return nil
}
- parentRefs := []string{}
- if err := resolver.deref(input, parentRefs, basePath); resolver.shouldStopOnError(err) {
+
+ parentRefs := make([]string, 0, 10)
+ if err = resolver.deref(input, parentRefs, basePath); resolver.shouldStopOnError(err) {
return err
}
+
ref, sch, _ := getRefAndSchema(input)
if ref.String() != "" {
- transitiveResolver, err := resolver.transitiveResolver(basePath, *ref)
- if transitiveResolver.shouldStopOnError(err) {
- return err
- }
+ transitiveResolver := resolver.transitiveResolver(basePath, *ref)
basePath = resolver.updateBasePath(transitiveResolver, basePath)
resolver = transitiveResolver
}
- if sch != nil && sch.Ref.String() != "" {
- // schema expanded to a $ref in another root
- var ern error
- sch.Ref, ern = NewRef(normalizePaths(sch.Ref.String(), ref.RemoteURI()))
+ if sch == nil {
+ // nothing to be expanded
+ if ref != nil {
+ *ref = Ref{}
+ }
+ return nil
+ }
+
+ if sch.Ref.String() != "" {
+ rebasedRef, ern := NewRef(normalizeURI(sch.Ref.String(), basePath))
if ern != nil {
return ern
}
+
+ switch {
+ case resolver.isCircular(&rebasedRef, basePath, parentRefs...):
+ // this is a circular $ref: stop expansion
+ if !resolver.options.AbsoluteCircularRef {
+ sch.Ref = denormalizeRef(&rebasedRef, resolver.context.basePath, resolver.context.rootID)
+ } else {
+ sch.Ref = rebasedRef
+ }
+ case !resolver.options.SkipSchemas:
+ // schema expanded to a $ref in another root
+ sch.Ref = rebasedRef
+ debugLog("rebased to: %s", sch.Ref.String())
+ default:
+ // skip schema expansion but rebase $ref to schema
+ sch.Ref = denormalizeRef(&rebasedRef, resolver.context.basePath, resolver.context.rootID)
+ }
}
+
if ref != nil {
*ref = Ref{}
}
- if !resolver.options.SkipSchemas && sch != nil {
+ // expand schema
+ if !resolver.options.SkipSchemas {
s, err := expandSchema(*sch, parentRefs, resolver, basePath)
if resolver.shouldStopOnError(err) {
return err
}
+ if s == nil {
+ // guard for when continuing on error
+ return nil
+ }
*sch = *s
}
+
return nil
}
diff --git a/constraint/vendor/github.com/go-openapi/spec/go.mod b/constraint/vendor/github.com/go-openapi/spec/go.mod
index 14e5f2dac..63d9e82e9 100644
--- a/constraint/vendor/github.com/go-openapi/spec/go.mod
+++ b/constraint/vendor/github.com/go-openapi/spec/go.mod
@@ -1,12 +1,13 @@
module github.com/go-openapi/spec
require (
- github.com/go-openapi/jsonpointer v0.19.3
- github.com/go-openapi/jsonreference v0.19.2
- github.com/go-openapi/swag v0.19.5
- github.com/stretchr/testify v1.3.0
- golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 // indirect
- gopkg.in/yaml.v2 v2.2.4
+ github.com/go-openapi/jsonpointer v0.19.5
+ github.com/go-openapi/jsonreference v0.19.5
+ github.com/go-openapi/swag v0.19.14
+ github.com/stretchr/testify v1.6.1
+ golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect
+ golang.org/x/text v0.3.5 // indirect
+ gopkg.in/yaml.v2 v2.4.0
)
go 1.13
diff --git a/constraint/vendor/github.com/go-openapi/spec/go.sum b/constraint/vendor/github.com/go-openapi/spec/go.sum
index c209ff971..9e86ed981 100644
--- a/constraint/vendor/github.com/go-openapi/spec/go.sum
+++ b/constraint/vendor/github.com/go-openapi/spec/go.sum
@@ -2,48 +2,64 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+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/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0=
-github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
-github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w=
-github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
-github.com/go-openapi/swag v0.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE=
-github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
-github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
+github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
+github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM=
+github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
-github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=
+github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
+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/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4=
+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.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
+github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU=
-golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
+golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
-gopkg.in/yaml.v2 v2.2.4/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 h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
+gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/constraint/vendor/github.com/go-openapi/spec/header.go b/constraint/vendor/github.com/go-openapi/spec/header.go
index 39efe452b..9dfd17b18 100644
--- a/constraint/vendor/github.com/go-openapi/spec/header.go
+++ b/constraint/vendor/github.com/go-openapi/spec/header.go
@@ -141,6 +141,12 @@ func (h *Header) AllowDuplicates() *Header {
return h
}
+// WithValidations is a fluent method to set header validations
+func (h *Header) WithValidations(val CommonValidations) *Header {
+ h.SetValidations(SchemaValidations{CommonValidations: val})
+ return h
+}
+
// MarshalJSON marshal this to JSON
func (h Header) MarshalJSON() ([]byte, error) {
b1, err := json.Marshal(h.CommonValidations)
diff --git a/constraint/vendor/github.com/go-openapi/spec/items.go b/constraint/vendor/github.com/go-openapi/spec/items.go
index 365d16315..e2afb2133 100644
--- a/constraint/vendor/github.com/go-openapi/spec/items.go
+++ b/constraint/vendor/github.com/go-openapi/spec/items.go
@@ -53,22 +53,6 @@ func (s *SimpleSchema) ItemsTypeName() string {
return s.Items.TypeName()
}
-// CommonValidations describe common JSON-schema validations
-type CommonValidations struct {
- Maximum *float64 `json:"maximum,omitempty"`
- ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"`
- Minimum *float64 `json:"minimum,omitempty"`
- ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"`
- MaxLength *int64 `json:"maxLength,omitempty"`
- MinLength *int64 `json:"minLength,omitempty"`
- Pattern string `json:"pattern,omitempty"`
- MaxItems *int64 `json:"maxItems,omitempty"`
- MinItems *int64 `json:"minItems,omitempty"`
- UniqueItems bool `json:"uniqueItems,omitempty"`
- MultipleOf *float64 `json:"multipleOf,omitempty"`
- Enum []interface{} `json:"enum,omitempty"`
-}
-
// Items a limited subset of JSON-Schema's items object.
// It is used by parameter definitions that are not located in "body".
//
@@ -180,6 +164,12 @@ func (i *Items) AllowDuplicates() *Items {
return i
}
+// WithValidations is a fluent method to set Items validations
+func (i *Items) WithValidations(val CommonValidations) *Items {
+ i.SetValidations(SchemaValidations{CommonValidations: val})
+ return i
+}
+
// UnmarshalJSON hydrates this items instance with the data from JSON
func (i *Items) UnmarshalJSON(data []byte) error {
var validations CommonValidations
diff --git a/constraint/vendor/github.com/go-openapi/spec/license.go b/constraint/vendor/github.com/go-openapi/spec/license.go
index f20961b4f..b42f80368 100644
--- a/constraint/vendor/github.com/go-openapi/spec/license.go
+++ b/constraint/vendor/github.com/go-openapi/spec/license.go
@@ -14,10 +14,43 @@
package spec
+import (
+ "encoding/json"
+
+ "github.com/go-openapi/swag"
+)
+
// License information for the exposed API.
//
// For more information: http://goo.gl/8us55a#licenseObject
type License struct {
+ LicenseProps
+ VendorExtensible
+}
+
+// LicenseProps holds the properties of a License object
+type LicenseProps struct {
Name string `json:"name,omitempty"`
URL string `json:"url,omitempty"`
}
+
+// UnmarshalJSON hydrates License from json
+func (l *License) UnmarshalJSON(data []byte) error {
+ if err := json.Unmarshal(data, &l.LicenseProps); err != nil {
+ return err
+ }
+ return json.Unmarshal(data, &l.VendorExtensible)
+}
+
+// MarshalJSON produces License as json
+func (l License) MarshalJSON() ([]byte, error) {
+ b1, err := json.Marshal(l.LicenseProps)
+ if err != nil {
+ return nil, err
+ }
+ b2, err := json.Marshal(l.VendorExtensible)
+ if err != nil {
+ return nil, err
+ }
+ return swag.ConcatJSON(b1, b2), nil
+}
diff --git a/constraint/vendor/github.com/go-openapi/spec/normalizer.go b/constraint/vendor/github.com/go-openapi/spec/normalizer.go
index b8957e7c0..d6c483971 100644
--- a/constraint/vendor/github.com/go-openapi/spec/normalizer.go
+++ b/constraint/vendor/github.com/go-openapi/spec/normalizer.go
@@ -15,138 +15,189 @@
package spec
import (
- "fmt"
"net/url"
- "os"
"path"
- "path/filepath"
"strings"
)
-// normalize absolute path for cache.
-// on Windows, drive letters should be converted to lower as scheme in net/url.URL
-func normalizeAbsPath(path string) string {
- u, err := url.Parse(path)
+const fileScheme = "file"
+
+// normalizeURI ensures that all $ref paths used internally by the expander are canonicalized.
+//
+// NOTE(windows): there is a tolerance over the strict URI format on windows.
+//
+// The normalizer accepts relative file URLs like 'Path\File.JSON' as well as absolute file URLs like
+// 'C:\Path\file.Yaml'.
+//
+// Both are canonicalized with a "file://" scheme, slashes and a lower-cased path:
+// 'file:///c:/path/file.yaml'
+//
+// URLs can be specified with a file scheme, like in 'file:///folder/file.json' or
+// 'file:///c:\folder\File.json'.
+//
+// URLs like file://C:\folder are considered invalid (i.e. there is no host 'c:\folder') and a "repair"
+// is attempted.
+//
+// The base path argument is assumed to be canonicalized (e.g. using normalizeBase()).
+func normalizeURI(refPath, base string) string {
+ refURL, err := url.Parse(refPath)
if err != nil {
- debugLog("normalize absolute path failed: %s", err)
- return path
+ specLogger.Printf("warning: invalid URI in $ref %q: %v", refPath, err)
+ refURL, refPath = repairURI(refPath)
}
- return u.String()
-}
-// base or refPath could be a file path or a URL
-// given a base absolute path and a ref path, return the absolute path of refPath
-// 1) if refPath is absolute, return it
-// 2) if refPath is relative, join it with basePath keeping the scheme, hosts, and ports if exists
-// base could be a directory or a full file path
-func normalizePaths(refPath, base string) string {
- refURL, _ := url.Parse(refPath)
- if path.IsAbs(refURL.Path) || filepath.IsAbs(refPath) {
- // refPath is actually absolute
- if refURL.Host != "" {
- return refPath
- }
- parts := strings.Split(refPath, "#")
- result := filepath.FromSlash(parts[0])
- if len(parts) == 2 {
- result += "#" + parts[1]
- }
- return result
+ fixWindowsURI(refURL, refPath) // noop on non-windows OS
+
+ refURL.Path = path.Clean(refURL.Path)
+ if refURL.Path == "." {
+ refURL.Path = ""
}
- // relative refPath
- baseURL, _ := url.Parse(base)
- if !strings.HasPrefix(refPath, "#") {
- // combining paths
- if baseURL.Host != "" {
- baseURL.Path = path.Join(path.Dir(baseURL.Path), refURL.Path)
- } else { // base is a file
- newBase := fmt.Sprintf("%s#%s", filepath.Join(filepath.Dir(base), filepath.FromSlash(refURL.Path)), refURL.Fragment)
- return newBase
- }
+ r := MustCreateRef(refURL.String())
+ if r.IsCanonical() {
+ return refURL.String()
+ }
+ baseURL, _ := url.Parse(base)
+ if path.IsAbs(refURL.Path) {
+ baseURL.Path = refURL.Path
+ } else if refURL.Path != "" {
+ baseURL.Path = path.Join(path.Dir(baseURL.Path), refURL.Path)
}
// copying fragment from ref to base
baseURL.Fragment = refURL.Fragment
+
return baseURL.String()
}
-// denormalizePaths returns to simplest notation on file $ref,
-// i.e. strips the absolute path and sets a path relative to the base path.
+// denormalizeRef returns the simplest notation for a normalized $ref, given the path of the original root document.
+//
+// When calling this, we assume that:
+// * $ref is a canonical URI
+// * originalRelativeBase is a canonical URI
+//
+// denormalizeRef is currently used when we rewrite a $ref after a circular $ref has been detected.
+// In this case, expansion stops and normally renders the internal canonical $ref.
+//
+// This internal $ref is eventually rebased to the original RelativeBase used for the expansion.
//
-// This is currently used when we rewrite ref after a circular ref has been detected
-func denormalizeFileRef(ref *Ref, relativeBase, originalRelativeBase string) *Ref {
- debugLog("denormalizeFileRef for: %s", ref.String())
+// There is a special case for schemas that are anchored with an "id":
+// in that case, the rebasing is performed // against the id only if this is an anchor for the initial root document.
+// All other intermediate "id"'s found along the way are ignored for the purpose of rebasing.
+//
+func denormalizeRef(ref *Ref, originalRelativeBase, id string) Ref {
+ debugLog("denormalizeRef called:\n$ref: %q\noriginal: %s\nroot ID:%s", ref.String(), originalRelativeBase, id)
if ref.String() == "" || ref.IsRoot() || ref.HasFragmentOnly {
- return ref
- }
- // strip relativeBase from URI
- relativeBaseURL, _ := url.Parse(relativeBase)
- relativeBaseURL.Fragment = ""
-
- if relativeBaseURL.IsAbs() && strings.HasPrefix(ref.String(), relativeBase) {
- // this should work for absolute URI (e.g. http://...): we have an exact match, just trim prefix
- r, _ := NewRef(strings.TrimPrefix(ref.String(), relativeBase))
- return &r
+ // short circuit: $ref to current doc
+ return *ref
}
- if relativeBaseURL.IsAbs() {
- // other absolute URL get unchanged (i.e. with a non-empty scheme)
- return ref
+ if id != "" {
+ idBaseURL, err := url.Parse(id)
+ if err == nil { // if the schema id is not usable as a URI, ignore it
+ if ref, ok := rebase(ref, idBaseURL, true); ok { // rebase, but keep references to root unchaged (do not want $ref: "")
+ // $ref relative to the ID of the schema in the root document
+ return ref
+ }
+ }
}
- // for relative file URIs:
originalRelativeBaseURL, _ := url.Parse(originalRelativeBase)
- originalRelativeBaseURL.Fragment = ""
- if strings.HasPrefix(ref.String(), originalRelativeBaseURL.String()) {
- // the resulting ref is in the expanded spec: return a local ref
- r, _ := NewRef(strings.TrimPrefix(ref.String(), originalRelativeBaseURL.String()))
- return &r
+
+ r, _ := rebase(ref, originalRelativeBaseURL, false)
+
+ return r
+}
+
+func rebase(ref *Ref, v *url.URL, notEqual bool) (Ref, bool) {
+ var newBase url.URL
+
+ u := ref.GetURL()
+
+ if u.Scheme != v.Scheme || u.Host != v.Host {
+ return *ref, false
}
- // check if we may set a relative path, considering the original base path for this spec.
- // Example:
- // spec is located at /mypath/spec.json
- // my normalized ref points to: /mypath/item.json#/target
- // expected result: item.json#/target
- parts := strings.Split(ref.String(), "#")
- relativePath, err := filepath.Rel(path.Dir(originalRelativeBaseURL.String()), parts[0])
- if err != nil {
- // there is no common ancestor (e.g. different drives on windows)
- // leaves the ref unchanged
- return ref
+ docPath := v.Path
+ v.Path = path.Dir(v.Path)
+
+ if v.Path == "." {
+ v.Path = ""
+ } else if !strings.HasSuffix(v.Path, "/") {
+ v.Path += "/"
}
- if len(parts) == 2 {
- relativePath += "#" + parts[1]
+
+ newBase.Fragment = u.Fragment
+
+ if strings.HasPrefix(u.Path, docPath) {
+ newBase.Path = strings.TrimPrefix(u.Path, docPath)
+ } else {
+ newBase.Path = strings.TrimPrefix(u.Path, v.Path)
+ }
+
+ if notEqual && newBase.Path == "" && newBase.Fragment == "" {
+ // do not want rebasing to end up in an empty $ref
+ return *ref, false
}
- r, _ := NewRef(relativePath)
- return &r
-}
-// relativeBase could be an ABSOLUTE file path or an ABSOLUTE URL
-func normalizeFileRef(ref *Ref, relativeBase string) *Ref {
- // This is important for when the reference is pointing to the root schema
- if ref.String() == "" {
- r, _ := NewRef(relativeBase)
- return &r
+ if path.IsAbs(newBase.Path) {
+ // whenever we end up with an absolute path, specify the scheme and host
+ newBase.Scheme = v.Scheme
+ newBase.Host = v.Host
}
- debugLog("normalizing %s against %s", ref.String(), relativeBase)
+ return MustCreateRef(newBase.String()), true
+}
- s := normalizePaths(ref.String(), relativeBase)
- r, _ := NewRef(s)
+// normalizeRef canonicalize a Ref, using a canonical relativeBase as its absolute anchor
+func normalizeRef(ref *Ref, relativeBase string) *Ref {
+ r := MustCreateRef(normalizeURI(ref.String(), relativeBase))
return &r
}
-// absPath returns the absolute path of a file
-func absPath(fname string) (string, error) {
- if strings.HasPrefix(fname, "http") {
- return fname, nil
+// normalizeBase performs a normalization of the input base path.
+//
+// This always yields a canonical URI (absolute), usable for the document cache.
+//
+// It ensures that all further internal work on basePath may safely assume
+// a non-empty, cross-platform, canonical URI (i.e. absolute).
+//
+// This normalization tolerates windows paths (e.g. C:\x\y\File.dat) and transform this
+// in a file:// URL with lower cased drive letter and path.
+//
+// See also: https://en.wikipedia.org/wiki/File_URI_scheme
+func normalizeBase(in string) string {
+ u, err := url.Parse(in)
+ if err != nil {
+ specLogger.Printf("warning: invalid URI in RelativeBase %q: %v", in, err)
+ u, in = repairURI(in)
+ }
+
+ u.Fragment = "" // any fragment in the base is irrelevant
+
+ fixWindowsURI(u, in) // noop on non-windows OS
+
+ u.Path = path.Clean(u.Path)
+ if u.Path == "." { // empty after Clean()
+ u.Path = ""
}
- if filepath.IsAbs(fname) {
- return fname, nil
+
+ if u.Scheme != "" {
+ if path.IsAbs(u.Path) || u.Scheme != fileScheme {
+ // this is absolute or explicitly not a local file: we're good
+ return u.String()
+ }
}
- wd, err := os.Getwd()
- return filepath.Join(wd, fname), err
+
+ // no scheme or file scheme with relative path: assume file and make it absolute
+ // enforce scheme file://... with absolute path.
+ //
+ // If the input path is relative, we anchor the path to the current working directory.
+ // NOTE: we may end up with a host component. Leave it unchanged: e.g. file://host/folder/file.json
+
+ u.Scheme = fileScheme
+ u.Path = absPath(u.Path) // platform-dependent
+ u.RawQuery = "" // any query component is irrelevant for a base
+ return u.String()
}
diff --git a/constraint/vendor/github.com/go-openapi/spec/normalizer_nonwindows.go b/constraint/vendor/github.com/go-openapi/spec/normalizer_nonwindows.go
new file mode 100644
index 000000000..c8a064534
--- /dev/null
+++ b/constraint/vendor/github.com/go-openapi/spec/normalizer_nonwindows.go
@@ -0,0 +1,43 @@
+// +build !windows
+
+// Copyright 2015 go-swagger maintainers
+//
+// 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 spec
+
+import (
+ "net/url"
+ "path/filepath"
+)
+
+// absPath makes a file path absolute and compatible with a URI path component.
+//
+// The parameter must be a path, not an URI.
+func absPath(in string) string {
+ anchored, err := filepath.Abs(in)
+ if err != nil {
+ specLogger.Printf("warning: could not resolve current working directory: %v", err)
+ return in
+ }
+ return anchored
+}
+
+func repairURI(in string) (*url.URL, string) {
+ u, _ := url.Parse("")
+ debugLog("repaired URI: original: %q, repaired: %q", in, "")
+ return u, ""
+}
+
+func fixWindowsURI(u *url.URL, in string) {
+}
diff --git a/constraint/vendor/github.com/go-openapi/spec/normalizer_windows.go b/constraint/vendor/github.com/go-openapi/spec/normalizer_windows.go
new file mode 100644
index 000000000..fe2d1ecd4
--- /dev/null
+++ b/constraint/vendor/github.com/go-openapi/spec/normalizer_windows.go
@@ -0,0 +1,154 @@
+// -build windows
+
+// Copyright 2015 go-swagger maintainers
+//
+// 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 spec
+
+import (
+ "net/url"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+)
+
+// absPath makes a file path absolute and compatible with a URI path component
+//
+// The parameter must be a path, not an URI.
+func absPath(in string) string {
+ // NOTE(windows): filepath.Abs exhibits a special behavior on windows for empty paths.
+ // See https://github.com/golang/go/issues/24441
+ if in == "" {
+ in = "."
+ }
+
+ anchored, err := filepath.Abs(in)
+ if err != nil {
+ specLogger.Printf("warning: could not resolve current working directory: %v", err)
+ return in
+ }
+
+ pth := strings.ReplaceAll(strings.ToLower(anchored), `\`, `/`)
+ if !strings.HasPrefix(pth, "/") {
+ pth = "/" + pth
+ }
+
+ return path.Clean(pth)
+}
+
+// repairURI tolerates invalid file URIs with common typos
+// such as 'file://E:\folder\file', that break the regular URL parser.
+//
+// Adopting the same defaults as for unixes (e.g. return an empty path) would
+// result into a counter-intuitive result for that case (e.g. E:\folder\file is
+// eventually resolved as the current directory). The repair will detect the missing "/".
+//
+// Note that this only works for the file scheme.
+func repairURI(in string) (*url.URL, string) {
+ const prefix = fileScheme + "://"
+ if !strings.HasPrefix(in, prefix) {
+ // giving up: resolve to empty path
+ u, _ := url.Parse("")
+
+ return u, ""
+ }
+
+ // attempt the repair, stripping the scheme should be sufficient
+ u, _ := url.Parse(strings.TrimPrefix(in, prefix))
+ debugLog("repaired URI: original: %q, repaired: %q", in, u.String())
+
+ return u, u.String()
+}
+
+// fixWindowsURI tolerates an absolute file path on windows such as C:\Base\File.yaml or \\host\share\Base\File.yaml
+// and makes it a canonical URI: file:///c:/base/file.yaml
+//
+// Catch 22 notes for Windows:
+//
+// * There may be a drive letter on windows (it is lower-cased)
+// * There may be a share UNC, e.g. \\server\folder\data.xml
+// * Paths are case insensitive
+// * Paths may already contain slashes
+// * Paths must be slashed
+//
+// NOTE: there is no escaping. "/" may be valid separators just like "\".
+// We don't use ToSlash() (which escapes everything) because windows now also
+// tolerates the use of "/". Hence, both C:\File.yaml and C:/File.yaml will work.
+func fixWindowsURI(u *url.URL, in string) {
+ drive := filepath.VolumeName(in)
+
+ if len(drive) > 0 {
+ if len(u.Scheme) == 1 && strings.EqualFold(u.Scheme, drive[:1]) { // a path with a drive letter
+ u.Scheme = fileScheme
+ u.Host = ""
+ u.Path = strings.Join([]string{drive, u.Opaque, u.Path}, `/`) // reconstruct the full path component (no fragment, no query)
+ } else if u.Host == "" && strings.HasPrefix(u.Path, drive) { // a path with a \\host volume
+ // NOTE: the special host@port syntax for UNC is not supported (yet)
+ u.Scheme = fileScheme
+
+ // this is a modified version of filepath.Dir() to apply on the VolumeName itself
+ i := len(drive) - 1
+ for i >= 0 && !os.IsPathSeparator(drive[i]) {
+ i--
+ }
+ host := drive[:i] // \\host\share => host
+
+ u.Path = strings.TrimPrefix(u.Path, host)
+ u.Host = strings.TrimPrefix(host, `\\`)
+ }
+
+ u.Opaque = ""
+ u.Path = strings.ReplaceAll(strings.ToLower(u.Path), `\`, `/`)
+
+ // ensure we form an absolute path
+ if !strings.HasPrefix(u.Path, "/") {
+ u.Path = "/" + u.Path
+ }
+
+ u.Path = path.Clean(u.Path)
+
+ return
+ }
+
+ if u.Scheme == fileScheme {
+ // Handle dodgy cases for file://{...} URIs on windows.
+ // A canonical URI should always be followed by an absolute path.
+ //
+ // Examples:
+ // * file:///folder/file => valid, unchanged
+ // * file:///c:\folder\file => slashed
+ // * file:///./folder/file => valid, cleaned to remove the dot
+ // * file:///.\folder\file => remapped to cwd
+ // * file:///. => dodgy, remapped to / (consistent with the behavior on unix)
+ // * file:///.. => dodgy, remapped to / (consistent with the behavior on unix)
+ if (!path.IsAbs(u.Path) && !filepath.IsAbs(u.Path)) || (strings.HasPrefix(u.Path, `/.`) && strings.Contains(u.Path, `\`)) {
+ // ensure we form an absolute path
+ u.Path, _ = filepath.Abs(strings.TrimLeft(u.Path, `/`))
+ if !strings.HasPrefix(u.Path, "/") {
+ u.Path = "/" + u.Path
+ }
+ }
+ u.Path = strings.ToLower(u.Path)
+ }
+
+ // NOTE: lower case normalization does not propagate to inner resources,
+ // generated when rebasing: when joining a relative URI with a file to an absolute base,
+ // only the base is currently lower-cased.
+ //
+ // For now, we assume this is good enough for most use cases
+ // and try not to generate too many differences
+ // between the output produced on different platforms.
+ u.Path = path.Clean(strings.ReplaceAll(u.Path, `\`, `/`))
+}
diff --git a/constraint/vendor/github.com/go-openapi/spec/operation.go b/constraint/vendor/github.com/go-openapi/spec/operation.go
index b1ebd5994..995ce6acb 100644
--- a/constraint/vendor/github.com/go-openapi/spec/operation.go
+++ b/constraint/vendor/github.com/go-openapi/spec/operation.go
@@ -25,7 +25,6 @@ import (
)
func init() {
- //gob.Register(map[string][]interface{}{})
gob.Register(map[string]interface{}{})
gob.Register([]interface{}{})
}
diff --git a/constraint/vendor/github.com/go-openapi/spec/parameter.go b/constraint/vendor/github.com/go-openapi/spec/parameter.go
index cecdff545..2b2b89b67 100644
--- a/constraint/vendor/github.com/go-openapi/spec/parameter.go
+++ b/constraint/vendor/github.com/go-openapi/spec/parameter.go
@@ -39,8 +39,7 @@ func PathParam(name string) *Parameter {
// BodyParam creates a body parameter
func BodyParam(name string, schema *Schema) *Parameter {
- return &Parameter{ParamProps: ParamProps{Name: name, In: "body", Schema: schema},
- SimpleSchema: SimpleSchema{Type: "object"}}
+ return &Parameter{ParamProps: ParamProps{Name: name, In: "body", Schema: schema}}
}
// FormDataParam creates a body parameter
@@ -58,7 +57,7 @@ func FileParam(name string) *Parameter {
func SimpleArrayParam(name, tpe, fmt string) *Parameter {
return &Parameter{ParamProps: ParamProps{Name: name},
SimpleSchema: SimpleSchema{Type: jsonArray, CollectionFormat: "csv",
- Items: &Items{SimpleSchema: SimpleSchema{Type: "string", Format: fmt}}}}
+ Items: &Items{SimpleSchema: SimpleSchema{Type: tpe, Format: fmt}}}}
}
// ParamRef creates a parameter that's a json reference
@@ -278,6 +277,12 @@ func (p *Parameter) AllowDuplicates() *Parameter {
return p
}
+// WithValidations is a fluent method to set parameter validations
+func (p *Parameter) WithValidations(val CommonValidations) *Parameter {
+ p.SetValidations(SchemaValidations{CommonValidations: val})
+ return p
+}
+
// UnmarshalJSON hydrates this items instance with the data from JSON
func (p *Parameter) UnmarshalJSON(data []byte) error {
if err := json.Unmarshal(data, &p.CommonValidations); err != nil {
diff --git a/constraint/vendor/github.com/go-openapi/spec/properties.go b/constraint/vendor/github.com/go-openapi/spec/properties.go
new file mode 100644
index 000000000..2af13787a
--- /dev/null
+++ b/constraint/vendor/github.com/go-openapi/spec/properties.go
@@ -0,0 +1,91 @@
+package spec
+
+import (
+ "bytes"
+ "encoding/json"
+ "reflect"
+ "sort"
+)
+
+// OrderSchemaItem holds a named schema (e.g. from a property of an object)
+type OrderSchemaItem struct {
+ Name string
+ Schema
+}
+
+// OrderSchemaItems is a sortable slice of named schemas.
+// The ordering is defined by the x-order schema extension.
+type OrderSchemaItems []OrderSchemaItem
+
+// MarshalJSON produces a json object with keys defined by the name schemas
+// of the OrderSchemaItems slice, keeping the original order of the slice.
+func (items OrderSchemaItems) MarshalJSON() ([]byte, error) {
+ buf := bytes.NewBuffer(nil)
+ buf.WriteString("{")
+ for i := range items {
+ if i > 0 {
+ buf.WriteString(",")
+ }
+ buf.WriteString("\"")
+ buf.WriteString(items[i].Name)
+ buf.WriteString("\":")
+ bs, err := json.Marshal(&items[i].Schema)
+ if err != nil {
+ return nil, err
+ }
+ buf.Write(bs)
+ }
+ buf.WriteString("}")
+ return buf.Bytes(), nil
+}
+
+func (items OrderSchemaItems) Len() int { return len(items) }
+func (items OrderSchemaItems) Swap(i, j int) { items[i], items[j] = items[j], items[i] }
+func (items OrderSchemaItems) Less(i, j int) (ret bool) {
+ ii, oki := items[i].Extensions.GetString("x-order")
+ ij, okj := items[j].Extensions.GetString("x-order")
+ if oki {
+ if okj {
+ defer func() {
+ if err := recover(); err != nil {
+ defer func() {
+ if err = recover(); err != nil {
+ ret = items[i].Name < items[j].Name
+ }
+ }()
+ ret = reflect.ValueOf(ii).String() < reflect.ValueOf(ij).String()
+ }
+ }()
+ return reflect.ValueOf(ii).Int() < reflect.ValueOf(ij).Int()
+ }
+ return true
+ } else if okj {
+ return false
+ }
+ return items[i].Name < items[j].Name
+}
+
+// SchemaProperties is a map representing the properties of a Schema object.
+// It knows how to transform its keys into an ordered slice.
+type SchemaProperties map[string]Schema
+
+// ToOrderedSchemaItems transforms the map of properties into a sortable slice
+func (properties SchemaProperties) ToOrderedSchemaItems() OrderSchemaItems {
+ items := make(OrderSchemaItems, 0, len(properties))
+ for k, v := range properties {
+ items = append(items, OrderSchemaItem{
+ Name: k,
+ Schema: v,
+ })
+ }
+ sort.Sort(items)
+ return items
+}
+
+// MarshalJSON produces properties as json, keeping their order.
+func (properties SchemaProperties) MarshalJSON() ([]byte, error) {
+ if properties == nil {
+ return []byte("null"), nil
+ }
+ return json.Marshal(properties.ToOrderedSchemaItems())
+}
diff --git a/constraint/vendor/github.com/go-openapi/spec/ref.go b/constraint/vendor/github.com/go-openapi/spec/ref.go
index 1f31a9ead..b0ef9bd9c 100644
--- a/constraint/vendor/github.com/go-openapi/spec/ref.go
+++ b/constraint/vendor/github.com/go-openapi/spec/ref.go
@@ -48,7 +48,7 @@ type Ref struct {
// RemoteURI gets the remote uri part of the ref
func (r *Ref) RemoteURI() string {
if r.String() == "" {
- return r.String()
+ return ""
}
u := *r.GetURL()
@@ -68,7 +68,7 @@ func (r *Ref) IsValidURI(basepaths ...string) bool {
}
if r.HasFullURL {
- //#nosec
+ //nolint:noctx,gosec
rr, err := http.Get(v)
if err != nil {
return false
diff --git a/constraint/vendor/github.com/go-openapi/spec/resolver.go b/constraint/vendor/github.com/go-openapi/spec/resolver.go
new file mode 100644
index 000000000..47d1ee13f
--- /dev/null
+++ b/constraint/vendor/github.com/go-openapi/spec/resolver.go
@@ -0,0 +1,127 @@
+package spec
+
+import (
+ "fmt"
+
+ "github.com/go-openapi/swag"
+)
+
+func resolveAnyWithBase(root interface{}, ref *Ref, result interface{}, options *ExpandOptions) error {
+ options = optionsOrDefault(options)
+ resolver := defaultSchemaLoader(root, options, nil, nil)
+
+ if err := resolver.Resolve(ref, result, options.RelativeBase); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// ResolveRefWithBase resolves a reference against a context root with preservation of base path
+func ResolveRefWithBase(root interface{}, ref *Ref, options *ExpandOptions) (*Schema, error) {
+ result := new(Schema)
+
+ if err := resolveAnyWithBase(root, ref, result, options); err != nil {
+ return nil, err
+ }
+
+ return result, nil
+}
+
+// ResolveRef resolves a reference for a schema against a context root
+// ref is guaranteed to be in root (no need to go to external files)
+//
+// ResolveRef is ONLY called from the code generation module
+func ResolveRef(root interface{}, ref *Ref) (*Schema, error) {
+ res, _, err := ref.GetPointer().Get(root)
+ if err != nil {
+ return nil, err
+ }
+
+ switch sch := res.(type) {
+ case Schema:
+ return &sch, nil
+ case *Schema:
+ return sch, nil
+ case map[string]interface{}:
+ newSch := new(Schema)
+ if err = swag.DynamicJSONToStruct(sch, newSch); err != nil {
+ return nil, err
+ }
+ return newSch, nil
+ default:
+ return nil, fmt.Errorf("type: %T: %w", sch, ErrUnknownTypeForReference)
+ }
+}
+
+// ResolveParameterWithBase resolves a parameter reference against a context root and base path
+func ResolveParameterWithBase(root interface{}, ref Ref, options *ExpandOptions) (*Parameter, error) {
+ result := new(Parameter)
+
+ if err := resolveAnyWithBase(root, &ref, result, options); err != nil {
+ return nil, err
+ }
+
+ return result, nil
+}
+
+// ResolveParameter resolves a parameter reference against a context root
+func ResolveParameter(root interface{}, ref Ref) (*Parameter, error) {
+ return ResolveParameterWithBase(root, ref, nil)
+}
+
+// ResolveResponseWithBase resolves response a reference against a context root and base path
+func ResolveResponseWithBase(root interface{}, ref Ref, options *ExpandOptions) (*Response, error) {
+ result := new(Response)
+
+ err := resolveAnyWithBase(root, &ref, result, options)
+ if err != nil {
+ return nil, err
+ }
+
+ return result, nil
+}
+
+// ResolveResponse resolves response a reference against a context root
+func ResolveResponse(root interface{}, ref Ref) (*Response, error) {
+ return ResolveResponseWithBase(root, ref, nil)
+}
+
+// ResolvePathItemWithBase resolves response a path item against a context root and base path
+func ResolvePathItemWithBase(root interface{}, ref Ref, options *ExpandOptions) (*PathItem, error) {
+ result := new(PathItem)
+
+ if err := resolveAnyWithBase(root, &ref, result, options); err != nil {
+ return nil, err
+ }
+
+ return result, nil
+}
+
+// ResolvePathItem resolves response a path item against a context root and base path
+//
+// Deprecated: use ResolvePathItemWithBase instead
+func ResolvePathItem(root interface{}, ref Ref, options *ExpandOptions) (*PathItem, error) {
+ return ResolvePathItemWithBase(root, ref, options)
+}
+
+// ResolveItemsWithBase resolves parameter items reference against a context root and base path.
+//
+// NOTE: stricly speaking, this construct is not supported by Swagger 2.0.
+// Similarly, $ref are forbidden in response headers.
+func ResolveItemsWithBase(root interface{}, ref Ref, options *ExpandOptions) (*Items, error) {
+ result := new(Items)
+
+ if err := resolveAnyWithBase(root, &ref, result, options); err != nil {
+ return nil, err
+ }
+
+ return result, nil
+}
+
+// ResolveItems resolves parameter items reference against a context root and base path.
+//
+// Deprecated: use ResolveItemsWithBase instead
+func ResolveItems(root interface{}, ref Ref, options *ExpandOptions) (*Items, error) {
+ return ResolveItemsWithBase(root, ref, options)
+}
diff --git a/constraint/vendor/github.com/go-openapi/spec/response.go b/constraint/vendor/github.com/go-openapi/spec/response.go
index 27729c1d9..0340b60d8 100644
--- a/constraint/vendor/github.com/go-openapi/spec/response.go
+++ b/constraint/vendor/github.com/go-openapi/spec/response.go
@@ -23,7 +23,7 @@ import (
// ResponseProps properties specific to a response
type ResponseProps struct {
- Description string `json:"description,omitempty"`
+ Description string `json:"description"`
Schema *Schema `json:"schema,omitempty"`
Headers map[string]Header `json:"headers,omitempty"`
Examples map[string]interface{} `json:"examples,omitempty"`
@@ -63,10 +63,31 @@ func (r *Response) UnmarshalJSON(data []byte) error {
// MarshalJSON converts this items object to JSON
func (r Response) MarshalJSON() ([]byte, error) {
- b1, err := json.Marshal(r.ResponseProps)
+ var (
+ b1 []byte
+ err error
+ )
+
+ if r.Ref.String() == "" {
+ // when there is no $ref, empty description is rendered as an empty string
+ b1, err = json.Marshal(r.ResponseProps)
+ } else {
+ // when there is $ref inside the schema, description should be omitempty-ied
+ b1, err = json.Marshal(struct {
+ Description string `json:"description,omitempty"`
+ Schema *Schema `json:"schema,omitempty"`
+ Headers map[string]Header `json:"headers,omitempty"`
+ Examples map[string]interface{} `json:"examples,omitempty"`
+ }{
+ Description: r.ResponseProps.Description,
+ Schema: r.ResponseProps.Schema,
+ Examples: r.ResponseProps.Examples,
+ })
+ }
if err != nil {
return nil, err
}
+
b2, err := json.Marshal(r.Refable)
if err != nil {
return nil, err
diff --git a/constraint/vendor/github.com/go-openapi/spec/schema.go b/constraint/vendor/github.com/go-openapi/spec/schema.go
index 37858ece9..a8d0f737a 100644
--- a/constraint/vendor/github.com/go-openapi/spec/schema.go
+++ b/constraint/vendor/github.com/go-openapi/spec/schema.go
@@ -158,41 +158,41 @@ func (r *SchemaURL) fromMap(v map[string]interface{}) error {
// SchemaProps describes a JSON schema (draft 4)
type SchemaProps struct {
- ID string `json:"id,omitempty"`
- Ref Ref `json:"-"`
- Schema SchemaURL `json:"-"`
- Description string `json:"description,omitempty"`
- Type StringOrArray `json:"type,omitempty"`
- Nullable bool `json:"nullable,omitempty"`
- Format string `json:"format,omitempty"`
- Title string `json:"title,omitempty"`
- Default interface{} `json:"default,omitempty"`
- Maximum *float64 `json:"maximum,omitempty"`
- ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"`
- Minimum *float64 `json:"minimum,omitempty"`
- ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"`
- MaxLength *int64 `json:"maxLength,omitempty"`
- MinLength *int64 `json:"minLength,omitempty"`
- Pattern string `json:"pattern,omitempty"`
- MaxItems *int64 `json:"maxItems,omitempty"`
- MinItems *int64 `json:"minItems,omitempty"`
- UniqueItems bool `json:"uniqueItems,omitempty"`
- MultipleOf *float64 `json:"multipleOf,omitempty"`
- Enum []interface{} `json:"enum,omitempty"`
- MaxProperties *int64 `json:"maxProperties,omitempty"`
- MinProperties *int64 `json:"minProperties,omitempty"`
- Required []string `json:"required,omitempty"`
- Items *SchemaOrArray `json:"items,omitempty"`
- AllOf []Schema `json:"allOf,omitempty"`
- OneOf []Schema `json:"oneOf,omitempty"`
- AnyOf []Schema `json:"anyOf,omitempty"`
- Not *Schema `json:"not,omitempty"`
- Properties map[string]Schema `json:"properties,omitempty"`
- AdditionalProperties *SchemaOrBool `json:"additionalProperties,omitempty"`
- PatternProperties map[string]Schema `json:"patternProperties,omitempty"`
- Dependencies Dependencies `json:"dependencies,omitempty"`
- AdditionalItems *SchemaOrBool `json:"additionalItems,omitempty"`
- Definitions Definitions `json:"definitions,omitempty"`
+ ID string `json:"id,omitempty"`
+ Ref Ref `json:"-"`
+ Schema SchemaURL `json:"-"`
+ Description string `json:"description,omitempty"`
+ Type StringOrArray `json:"type,omitempty"`
+ Nullable bool `json:"nullable,omitempty"`
+ Format string `json:"format,omitempty"`
+ Title string `json:"title,omitempty"`
+ Default interface{} `json:"default,omitempty"`
+ Maximum *float64 `json:"maximum,omitempty"`
+ ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"`
+ Minimum *float64 `json:"minimum,omitempty"`
+ ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"`
+ MaxLength *int64 `json:"maxLength,omitempty"`
+ MinLength *int64 `json:"minLength,omitempty"`
+ Pattern string `json:"pattern,omitempty"`
+ MaxItems *int64 `json:"maxItems,omitempty"`
+ MinItems *int64 `json:"minItems,omitempty"`
+ UniqueItems bool `json:"uniqueItems,omitempty"`
+ MultipleOf *float64 `json:"multipleOf,omitempty"`
+ Enum []interface{} `json:"enum,omitempty"`
+ MaxProperties *int64 `json:"maxProperties,omitempty"`
+ MinProperties *int64 `json:"minProperties,omitempty"`
+ Required []string `json:"required,omitempty"`
+ Items *SchemaOrArray `json:"items,omitempty"`
+ AllOf []Schema `json:"allOf,omitempty"`
+ OneOf []Schema `json:"oneOf,omitempty"`
+ AnyOf []Schema `json:"anyOf,omitempty"`
+ Not *Schema `json:"not,omitempty"`
+ Properties SchemaProperties `json:"properties,omitempty"`
+ AdditionalProperties *SchemaOrBool `json:"additionalProperties,omitempty"`
+ PatternProperties SchemaProperties `json:"patternProperties,omitempty"`
+ Dependencies Dependencies `json:"dependencies,omitempty"`
+ AdditionalItems *SchemaOrBool `json:"additionalItems,omitempty"`
+ Definitions Definitions `json:"definitions,omitempty"`
}
// SwaggerSchemaProps are additional properties supported by swagger schemas, but not JSON-schema (draft 4)
@@ -513,6 +513,56 @@ func (s *Schema) AsUnwrappedXML() *Schema {
return s
}
+// SetValidations defines all schema validations.
+//
+// NOTE: Required, ReadOnly, AllOf, AnyOf, OneOf and Not are not considered.
+func (s *Schema) SetValidations(val SchemaValidations) {
+ s.Maximum = val.Maximum
+ s.ExclusiveMaximum = val.ExclusiveMaximum
+ s.Minimum = val.Minimum
+ s.ExclusiveMinimum = val.ExclusiveMinimum
+ s.MaxLength = val.MaxLength
+ s.MinLength = val.MinLength
+ s.Pattern = val.Pattern
+ s.MaxItems = val.MaxItems
+ s.MinItems = val.MinItems
+ s.UniqueItems = val.UniqueItems
+ s.MultipleOf = val.MultipleOf
+ s.Enum = val.Enum
+ s.MinProperties = val.MinProperties
+ s.MaxProperties = val.MaxProperties
+ s.PatternProperties = val.PatternProperties
+}
+
+// WithValidations is a fluent method to set schema validations
+func (s *Schema) WithValidations(val SchemaValidations) *Schema {
+ s.SetValidations(val)
+ return s
+}
+
+// Validations returns a clone of the validations for this schema
+func (s Schema) Validations() SchemaValidations {
+ return SchemaValidations{
+ CommonValidations: CommonValidations{
+ Maximum: s.Maximum,
+ ExclusiveMaximum: s.ExclusiveMaximum,
+ Minimum: s.Minimum,
+ ExclusiveMinimum: s.ExclusiveMinimum,
+ MaxLength: s.MaxLength,
+ MinLength: s.MinLength,
+ Pattern: s.Pattern,
+ MaxItems: s.MaxItems,
+ MinItems: s.MinItems,
+ UniqueItems: s.UniqueItems,
+ MultipleOf: s.MultipleOf,
+ Enum: s.Enum,
+ },
+ MinProperties: s.MinProperties,
+ MaxProperties: s.MaxProperties,
+ PatternProperties: s.PatternProperties,
+ }
+}
+
// MarshalJSON marshal this to JSON
func (s Schema) MarshalJSON() ([]byte, error) {
b1, err := json.Marshal(s.SchemaProps)
diff --git a/constraint/vendor/github.com/go-openapi/spec/schema_loader.go b/constraint/vendor/github.com/go-openapi/spec/schema_loader.go
index 961d47757..0059b99ae 100644
--- a/constraint/vendor/github.com/go-openapi/spec/schema_loader.go
+++ b/constraint/vendor/github.com/go-openapi/spec/schema_loader.go
@@ -25,35 +25,50 @@ import (
"github.com/go-openapi/swag"
)
-// PathLoader function to use when loading remote refs
-var PathLoader func(string) (json.RawMessage, error)
-
-func init() {
- PathLoader = func(path string) (json.RawMessage, error) {
- data, err := swag.LoadFromFileOrHTTP(path)
- if err != nil {
- return nil, err
- }
- return json.RawMessage(data), nil
+// PathLoader is a function to use when loading remote refs.
+//
+// This is a package level default. It may be overridden or bypassed by
+// specifying the loader in ExpandOptions.
+//
+// NOTE: if you are using the go-openapi/loads package, it will override
+// this value with its own default (a loader to retrieve YAML documents as
+// well as JSON ones).
+var PathLoader = func(pth string) (json.RawMessage, error) {
+ data, err := swag.LoadFromFileOrHTTP(pth)
+ if err != nil {
+ return nil, err
}
+ return json.RawMessage(data), nil
}
// resolverContext allows to share a context during spec processing.
// At the moment, it just holds the index of circular references found.
type resolverContext struct {
- // circulars holds all visited circular references, which allows shortcuts.
- // NOTE: this is not just a performance improvement: it is required to figure out
- // circular references which participate several cycles.
+ // circulars holds all visited circular references, to shortcircuit $ref resolution.
+ //
// This structure is privately instantiated and needs not be locked against
// concurrent access, unless we chose to implement a parallel spec walking.
circulars map[string]bool
basePath string
+ loadDoc func(string) (json.RawMessage, error)
+ rootID string
}
-func newResolverContext(originalBasePath string) *resolverContext {
+func newResolverContext(options *ExpandOptions) *resolverContext {
+ expandOptions := optionsOrDefault(options)
+
+ // path loader may be overridden by options
+ var loader func(string) (json.RawMessage, error)
+ if expandOptions.PathLoader == nil {
+ loader = PathLoader
+ } else {
+ loader = expandOptions.PathLoader
+ }
+
return &resolverContext{
circulars: make(map[string]bool),
- basePath: originalBasePath, // keep the root base path in context
+ basePath: expandOptions.RelativeBase, // keep the root base path in context
+ loadDoc: loader,
}
}
@@ -62,21 +77,20 @@ type schemaLoader struct {
options *ExpandOptions
cache ResolutionCache
context *resolverContext
- loadDoc func(string) (json.RawMessage, error)
}
-func (r *schemaLoader) transitiveResolver(basePath string, ref Ref) (*schemaLoader, error) {
+func (r *schemaLoader) transitiveResolver(basePath string, ref Ref) *schemaLoader {
if ref.IsRoot() || ref.HasFragmentOnly {
- return r, nil
+ return r
}
- baseRef, _ := NewRef(basePath)
- currentRef := normalizeFileRef(&ref, basePath)
+ baseRef := MustCreateRef(basePath)
+ currentRef := normalizeRef(&ref, basePath)
if strings.HasPrefix(currentRef.String(), baseRef.String()) {
- return r, nil
+ return r
}
- // Set a new root to resolve against
+ // set a new root against which to resolve
rootURL := currentRef.GetURL()
rootURL.Fragment = ""
root, _ := r.cache.Get(rootURL.String())
@@ -85,35 +99,36 @@ func (r *schemaLoader) transitiveResolver(basePath string, ref Ref) (*schemaLoad
// traversing multiple documents
newOptions := r.options
newOptions.RelativeBase = rootURL.String()
- debugLog("setting new root: %s", newOptions.RelativeBase)
+
return defaultSchemaLoader(root, newOptions, r.cache, r.context)
}
func (r *schemaLoader) updateBasePath(transitive *schemaLoader, basePath string) string {
if transitive != r {
- debugLog("got a new resolver")
if transitive.options != nil && transitive.options.RelativeBase != "" {
- basePath, _ = absPath(transitive.options.RelativeBase)
- debugLog("new basePath = %s", basePath)
+ return normalizeBase(transitive.options.RelativeBase)
}
}
+
return basePath
}
func (r *schemaLoader) resolveRef(ref *Ref, target interface{}, basePath string) error {
tgt := reflect.ValueOf(target)
if tgt.Kind() != reflect.Ptr {
- return fmt.Errorf("resolve ref: target needs to be a pointer")
+ return ErrResolveRefNeedsAPointer
}
- refURL := ref.GetURL()
- if refURL == nil {
+ if ref.GetURL() == nil {
return nil
}
- var res interface{}
- var data interface{}
- var err error
+ var (
+ res interface{}
+ data interface{}
+ err error
+ )
+
// Resolve against the root if it isn't nil, and if ref is pointing at the root, or has a fragment only which means
// it is pointing somewhere in the root.
root := r.root
@@ -122,12 +137,11 @@ func (r *schemaLoader) resolveRef(ref *Ref, target interface{}, basePath string)
root, _, _, _ = r.load(baseRef.GetURL())
}
}
+
if (ref.IsRoot() || ref.HasFragmentOnly) && root != nil {
data = root
} else {
- baseRef := normalizeFileRef(ref, basePath)
- debugLog("current ref is: %s", ref.String())
- debugLog("current ref normalized file: %s", baseRef.String())
+ baseRef := normalizeRef(ref, basePath)
data, _, _, err = r.load(baseRef.GetURL())
if err != nil {
return err
@@ -149,45 +163,54 @@ func (r *schemaLoader) load(refURL *url.URL) (interface{}, url.URL, bool, error)
toFetch := *refURL
toFetch.Fragment = ""
- normalized := normalizeAbsPath(toFetch.String())
+ var err error
+ pth := toFetch.String()
+ normalized := normalizeBase(pth)
+ debugLog("loading doc from: %s", normalized)
data, fromCache := r.cache.Get(normalized)
- if !fromCache {
- b, err := r.loadDoc(normalized)
- if err != nil {
- debugLog("unable to load the document: %v", err)
- return nil, url.URL{}, false, err
- }
+ if fromCache {
+ return data, toFetch, fromCache, nil
+ }
- if err := json.Unmarshal(b, &data); err != nil {
- return nil, url.URL{}, false, err
- }
- r.cache.Set(normalized, data)
+ b, err := r.context.loadDoc(normalized)
+ if err != nil {
+ return nil, url.URL{}, false, err
}
- return data, toFetch, fromCache, nil
+ var doc interface{}
+ if err := json.Unmarshal(b, &doc); err != nil {
+ return nil, url.URL{}, false, err
+ }
+ r.cache.Set(normalized, doc)
+
+ return doc, toFetch, fromCache, nil
}
// isCircular detects cycles in sequences of $ref.
+//
// It relies on a private context (which needs not be locked).
func (r *schemaLoader) isCircular(ref *Ref, basePath string, parentRefs ...string) (foundCycle bool) {
- normalizedRef := normalizePaths(ref.String(), basePath)
+ normalizedRef := normalizeURI(ref.String(), basePath)
if _, ok := r.context.circulars[normalizedRef]; ok {
// circular $ref has been already detected in another explored cycle
foundCycle = true
return
}
- foundCycle = swag.ContainsStringsCI(parentRefs, normalizedRef)
+ foundCycle = swag.ContainsStrings(parentRefs, normalizedRef) // normalized windows url's are lower cased
if foundCycle {
r.context.circulars[normalizedRef] = true
}
return
}
-// Resolve resolves a reference against basePath and stores the result in target
-// Resolve is not in charge of following references, it only resolves ref by following its URL
-// if the schema that ref is referring to has more refs in it. Resolve doesn't resolve them
-// if basePath is an empty string, ref is resolved against the root schema stored in the schemaLoader struct
+// Resolve resolves a reference against basePath and stores the result in target.
+//
+// Resolve is not in charge of following references: it only resolves ref by following its URL.
+//
+// If the schema the ref is referring to holds nested refs, Resolve doesn't resolve them.
+//
+// If basePath is an empty string, ref is resolved against the root schema stored in the schemaLoader struct
func (r *schemaLoader) Resolve(ref *Ref, target interface{}, basePath string) error {
return r.resolveRef(ref, target, basePath)
}
@@ -204,30 +227,32 @@ func (r *schemaLoader) deref(input interface{}, parentRefs []string, basePath st
case *PathItem:
ref = &refable.Ref
default:
- return fmt.Errorf("deref: unsupported type %T", input)
+ return fmt.Errorf("unsupported type: %T: %w", input, ErrDerefUnsupportedType)
}
curRef := ref.String()
- if curRef != "" {
- normalizedRef := normalizeFileRef(ref, basePath)
- normalizedBasePath := normalizedRef.RemoteURI()
+ if curRef == "" {
+ return nil
+ }
- if r.isCircular(normalizedRef, basePath, parentRefs...) {
- return nil
- }
+ normalizedRef := normalizeRef(ref, basePath)
+ normalizedBasePath := normalizedRef.RemoteURI()
- if err := r.resolveRef(ref, input, basePath); r.shouldStopOnError(err) {
- return err
- }
+ if r.isCircular(normalizedRef, basePath, parentRefs...) {
+ return nil
+ }
- // NOTE(fredbi): removed basePath check => needs more testing
- if ref.String() != "" && ref.String() != curRef {
- parentRefs = append(parentRefs, normalizedRef.String())
- return r.deref(input, parentRefs, normalizedBasePath)
- }
+ if err := r.resolveRef(ref, input, basePath); r.shouldStopOnError(err) {
+ return err
}
- return nil
+ if ref.String() == "" || ref.String() == curRef {
+ // done with rereferencing
+ return nil
+ }
+
+ parentRefs = append(parentRefs, normalizedRef.String())
+ return r.deref(input, parentRefs, normalizedBasePath)
}
func (r *schemaLoader) shouldStopOnError(err error) bool {
@@ -242,30 +267,65 @@ func (r *schemaLoader) shouldStopOnError(err error) bool {
return false
}
+func (r *schemaLoader) setSchemaID(target interface{}, id, basePath string) (string, string) {
+ debugLog("schema has ID: %s", id)
+
+ // handling the case when id is a folder
+ // remember that basePath has to point to a file
+ var refPath string
+ if strings.HasSuffix(id, "/") {
+ // ensure this is detected as a file, not a folder
+ refPath = fmt.Sprintf("%s%s", id, "placeholder.json")
+ } else {
+ refPath = id
+ }
+
+ // updates the current base path
+ // * important: ID can be a relative path
+ // * registers target to be fetchable from the new base proposed by this id
+ newBasePath := normalizeURI(refPath, basePath)
+
+ // store found IDs for possible future reuse in $ref
+ r.cache.Set(newBasePath, target)
+
+ // the root document has an ID: all $ref relative to that ID may
+ // be rebased relative to the root document
+ if basePath == r.context.basePath {
+ debugLog("root document is a schema with ID: %s (normalized as:%s)", id, newBasePath)
+ r.context.rootID = newBasePath
+ }
+
+ return newBasePath, refPath
+}
+
func defaultSchemaLoader(
root interface{},
expandOptions *ExpandOptions,
cache ResolutionCache,
- context *resolverContext) (*schemaLoader, error) {
+ context *resolverContext) *schemaLoader {
- if cache == nil {
- cache = resCache
- }
if expandOptions == nil {
expandOptions = &ExpandOptions{}
}
- absBase, _ := absPath(expandOptions.RelativeBase)
+
+ cache = cacheOrDefault(cache)
+
+ if expandOptions.RelativeBase == "" {
+ // if no relative base is provided, assume the root document
+ // contains all $ref, or at least, that the relative documents
+ // may be resolved from the current working directory.
+ expandOptions.RelativeBase = baseForRoot(root, cache)
+ }
+ debugLog("effective expander options: %#v", expandOptions)
+
if context == nil {
- context = newResolverContext(absBase)
+ context = newResolverContext(expandOptions)
}
+
return &schemaLoader{
root: root,
options: expandOptions,
cache: cache,
context: context,
- loadDoc: func(path string) (json.RawMessage, error) {
- debugLog("fetching document at %q", path)
- return PathLoader(path)
- },
- }, nil
+ }
}
diff --git a/constraint/vendor/github.com/go-openapi/spec/security_scheme.go b/constraint/vendor/github.com/go-openapi/spec/security_scheme.go
index fe353842a..9d0bdae90 100644
--- a/constraint/vendor/github.com/go-openapi/spec/security_scheme.go
+++ b/constraint/vendor/github.com/go-openapi/spec/security_scheme.go
@@ -82,12 +82,12 @@ func OAuth2AccessToken(authorizationURL, tokenURL string) *SecurityScheme {
type SecuritySchemeProps struct {
Description string `json:"description,omitempty"`
Type string `json:"type"`
- Name string `json:"name,omitempty"` // api key
- In string `json:"in,omitempty"` // api key
- Flow string `json:"flow,omitempty"` // oauth2
- AuthorizationURL string `json:"authorizationUrl,omitempty"` // oauth2
- TokenURL string `json:"tokenUrl,omitempty"` // oauth2
- Scopes map[string]string `json:"scopes,omitempty"` // oauth2
+ Name string `json:"name,omitempty"` // api key
+ In string `json:"in,omitempty"` // api key
+ Flow string `json:"flow,omitempty"` // oauth2
+ AuthorizationURL string `json:"authorizationUrl"` // oauth2
+ TokenURL string `json:"tokenUrl,omitempty"` // oauth2
+ Scopes map[string]string `json:"scopes,omitempty"` // oauth2
}
// AddScope adds a scope to this security scheme
@@ -120,10 +120,40 @@ func (s SecurityScheme) JSONLookup(token string) (interface{}, error) {
// MarshalJSON marshal this to JSON
func (s SecurityScheme) MarshalJSON() ([]byte, error) {
- b1, err := json.Marshal(s.SecuritySchemeProps)
+ var (
+ b1 []byte
+ err error
+ )
+
+ if s.Type == oauth2 && (s.Flow == "implicit" || s.Flow == "accessCode") {
+ // when oauth2 for implicit or accessCode flows, empty AuthorizationURL is added as empty string
+ b1, err = json.Marshal(s.SecuritySchemeProps)
+ } else {
+ // when not oauth2, empty AuthorizationURL should be omitted
+ b1, err = json.Marshal(struct {
+ Description string `json:"description,omitempty"`
+ Type string `json:"type"`
+ Name string `json:"name,omitempty"` // api key
+ In string `json:"in,omitempty"` // api key
+ Flow string `json:"flow,omitempty"` // oauth2
+ AuthorizationURL string `json:"authorizationUrl,omitempty"` // oauth2
+ TokenURL string `json:"tokenUrl,omitempty"` // oauth2
+ Scopes map[string]string `json:"scopes,omitempty"` // oauth2
+ }{
+ Description: s.Description,
+ Type: s.Type,
+ Name: s.Name,
+ In: s.In,
+ Flow: s.Flow,
+ AuthorizationURL: s.AuthorizationURL,
+ TokenURL: s.TokenURL,
+ Scopes: s.Scopes,
+ })
+ }
if err != nil {
return nil, err
}
+
b2, err := json.Marshal(s.VendorExtensible)
if err != nil {
return nil, err
diff --git a/constraint/vendor/github.com/go-openapi/spec/spec.go b/constraint/vendor/github.com/go-openapi/spec/spec.go
index 0bb045bc0..7d38b6e62 100644
--- a/constraint/vendor/github.com/go-openapi/spec/spec.go
+++ b/constraint/vendor/github.com/go-openapi/spec/spec.go
@@ -14,7 +14,9 @@
package spec
-import "encoding/json"
+import (
+ "encoding/json"
+)
//go:generate curl -L --progress -o ./schemas/v2/schema.json http://swagger.io/v2/schema.json
//go:generate curl -L --progress -o ./schemas/jsonschema-draft-04.json http://json-schema.org/draft-04/schema
@@ -28,16 +30,6 @@ const (
JSONSchemaURL = "http://json-schema.org/draft-04/schema#"
)
-var (
- jsonSchema *Schema
- swaggerSchema *Schema
-)
-
-func init() {
- jsonSchema = MustLoadJSONSchemaDraft04()
- swaggerSchema = MustLoadSwagger20Schema()
-}
-
// MustLoadJSONSchemaDraft04 panics when Swagger20Schema returns an error
func MustLoadJSONSchemaDraft04() *Schema {
d, e := JSONSchemaDraft04()
diff --git a/constraint/vendor/github.com/go-openapi/spec/unused.go b/constraint/vendor/github.com/go-openapi/spec/unused.go
deleted file mode 100644
index aa12b56f6..000000000
--- a/constraint/vendor/github.com/go-openapi/spec/unused.go
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2015 go-swagger maintainers
-//
-// 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 spec
-
-/*
-
-import (
- "net/url"
- "os"
- "path"
- "path/filepath"
-
- "github.com/go-openapi/jsonpointer"
-)
-
- // Some currently unused functions and definitions that
- // used to be part of the expander.
-
- // Moved here for the record and possible future reuse
-
-var (
- idPtr, _ = jsonpointer.New("/id")
- refPtr, _ = jsonpointer.New("/$ref")
-)
-
-func idFromNode(node interface{}) (*Ref, error) {
- if idValue, _, err := idPtr.Get(node); err == nil {
- if refStr, ok := idValue.(string); ok && refStr != "" {
- idRef, err := NewRef(refStr)
- if err != nil {
- return nil, err
- }
- return &idRef, nil
- }
- }
- return nil, nil
-}
-
-func nextRef(startingNode interface{}, startingRef *Ref, ptr *jsonpointer.Pointer) *Ref {
- if startingRef == nil {
- return nil
- }
-
- if ptr == nil {
- return startingRef
- }
-
- ret := startingRef
- var idRef *Ref
- node := startingNode
-
- for _, tok := range ptr.DecodedTokens() {
- node, _, _ = jsonpointer.GetForToken(node, tok)
- if node == nil {
- break
- }
-
- idRef, _ = idFromNode(node)
- if idRef != nil {
- nw, err := ret.Inherits(*idRef)
- if err != nil {
- break
- }
- ret = nw
- }
-
- refRef, _, _ := refPtr.Get(node)
- if refRef != nil {
- var rf Ref
- switch value := refRef.(type) {
- case string:
- rf, _ = NewRef(value)
- }
- nw, err := ret.Inherits(rf)
- if err != nil {
- break
- }
- nwURL := nw.GetURL()
- if nwURL.Scheme == "file" || (nwURL.Scheme == "" && nwURL.Host == "") {
- nwpt := filepath.ToSlash(nwURL.Path)
- if filepath.IsAbs(nwpt) {
- _, err := os.Stat(nwpt)
- if err != nil {
- nwURL.Path = filepath.Join(".", nwpt)
- }
- }
- }
-
- ret = nw
- }
-
- }
-
- return ret
-}
-
-// basePathFromSchemaID returns a new basePath based on an existing basePath and a schema ID
-func basePathFromSchemaID(oldBasePath, id string) string {
- u, err := url.Parse(oldBasePath)
- if err != nil {
- panic(err)
- }
- uid, err := url.Parse(id)
- if err != nil {
- panic(err)
- }
-
- if path.IsAbs(uid.Path) {
- return id
- }
- u.Path = path.Join(path.Dir(u.Path), uid.Path)
- return u.String()
-}
-*/
-
-// type ExtraSchemaProps map[string]interface{}
-
-// // JSONSchema represents a structure that is a json schema draft 04
-// type JSONSchema struct {
-// SchemaProps
-// ExtraSchemaProps
-// }
-
-// // MarshalJSON marshal this to JSON
-// func (s JSONSchema) MarshalJSON() ([]byte, error) {
-// b1, err := json.Marshal(s.SchemaProps)
-// if err != nil {
-// return nil, err
-// }
-// b2, err := s.Ref.MarshalJSON()
-// if err != nil {
-// return nil, err
-// }
-// b3, err := s.Schema.MarshalJSON()
-// if err != nil {
-// return nil, err
-// }
-// b4, err := json.Marshal(s.ExtraSchemaProps)
-// if err != nil {
-// return nil, err
-// }
-// return swag.ConcatJSON(b1, b2, b3, b4), nil
-// }
-
-// // UnmarshalJSON marshal this from JSON
-// func (s *JSONSchema) UnmarshalJSON(data []byte) error {
-// var sch JSONSchema
-// if err := json.Unmarshal(data, &sch.SchemaProps); err != nil {
-// return err
-// }
-// if err := json.Unmarshal(data, &sch.Ref); err != nil {
-// return err
-// }
-// if err := json.Unmarshal(data, &sch.Schema); err != nil {
-// return err
-// }
-// if err := json.Unmarshal(data, &sch.ExtraSchemaProps); err != nil {
-// return err
-// }
-// *s = sch
-// return nil
-// }
diff --git a/constraint/vendor/github.com/go-openapi/spec/validations.go b/constraint/vendor/github.com/go-openapi/spec/validations.go
new file mode 100644
index 000000000..6360a8ea7
--- /dev/null
+++ b/constraint/vendor/github.com/go-openapi/spec/validations.go
@@ -0,0 +1,215 @@
+package spec
+
+// CommonValidations describe common JSON-schema validations
+type CommonValidations struct {
+ Maximum *float64 `json:"maximum,omitempty"`
+ ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"`
+ Minimum *float64 `json:"minimum,omitempty"`
+ ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"`
+ MaxLength *int64 `json:"maxLength,omitempty"`
+ MinLength *int64 `json:"minLength,omitempty"`
+ Pattern string `json:"pattern,omitempty"`
+ MaxItems *int64 `json:"maxItems,omitempty"`
+ MinItems *int64 `json:"minItems,omitempty"`
+ UniqueItems bool `json:"uniqueItems,omitempty"`
+ MultipleOf *float64 `json:"multipleOf,omitempty"`
+ Enum []interface{} `json:"enum,omitempty"`
+}
+
+// SetValidations defines all validations for a simple schema.
+//
+// NOTE: the input is the larger set of validations available for schemas.
+// For simple schemas, MinProperties and MaxProperties are ignored.
+func (v *CommonValidations) SetValidations(val SchemaValidations) {
+ v.Maximum = val.Maximum
+ v.ExclusiveMaximum = val.ExclusiveMaximum
+ v.Minimum = val.Minimum
+ v.ExclusiveMinimum = val.ExclusiveMinimum
+ v.MaxLength = val.MaxLength
+ v.MinLength = val.MinLength
+ v.Pattern = val.Pattern
+ v.MaxItems = val.MaxItems
+ v.MinItems = val.MinItems
+ v.UniqueItems = val.UniqueItems
+ v.MultipleOf = val.MultipleOf
+ v.Enum = val.Enum
+}
+
+type clearedValidation struct {
+ Validation string
+ Value interface{}
+}
+
+type clearedValidations []clearedValidation
+
+func (c clearedValidations) apply(cbs []func(string, interface{})) {
+ for _, cb := range cbs {
+ for _, cleared := range c {
+ cb(cleared.Validation, cleared.Value)
+ }
+ }
+}
+
+// ClearNumberValidations clears all number validations.
+//
+// Some callbacks may be set by the caller to capture changed values.
+func (v *CommonValidations) ClearNumberValidations(cbs ...func(string, interface{})) {
+ done := make(clearedValidations, 0, 5)
+ defer func() {
+ done.apply(cbs)
+ }()
+
+ if v.Minimum != nil {
+ done = append(done, clearedValidation{Validation: "minimum", Value: v.Minimum})
+ v.Minimum = nil
+ }
+ if v.Maximum != nil {
+ done = append(done, clearedValidation{Validation: "maximum", Value: v.Maximum})
+ v.Maximum = nil
+ }
+ if v.ExclusiveMaximum {
+ done = append(done, clearedValidation{Validation: "exclusiveMaximum", Value: v.ExclusiveMaximum})
+ v.ExclusiveMaximum = false
+ }
+ if v.ExclusiveMinimum {
+ done = append(done, clearedValidation{Validation: "exclusiveMinimum", Value: v.ExclusiveMinimum})
+ v.ExclusiveMinimum = false
+ }
+ if v.MultipleOf != nil {
+ done = append(done, clearedValidation{Validation: "multipleOf", Value: v.MultipleOf})
+ v.MultipleOf = nil
+ }
+}
+
+// ClearStringValidations clears all string validations.
+//
+// Some callbacks may be set by the caller to capture changed values.
+func (v *CommonValidations) ClearStringValidations(cbs ...func(string, interface{})) {
+ done := make(clearedValidations, 0, 3)
+ defer func() {
+ done.apply(cbs)
+ }()
+
+ if v.Pattern != "" {
+ done = append(done, clearedValidation{Validation: "pattern", Value: v.Pattern})
+ v.Pattern = ""
+ }
+ if v.MinLength != nil {
+ done = append(done, clearedValidation{Validation: "minLength", Value: v.MinLength})
+ v.MinLength = nil
+ }
+ if v.MaxLength != nil {
+ done = append(done, clearedValidation{Validation: "maxLength", Value: v.MaxLength})
+ v.MaxLength = nil
+ }
+}
+
+// ClearArrayValidations clears all array validations.
+//
+// Some callbacks may be set by the caller to capture changed values.
+func (v *CommonValidations) ClearArrayValidations(cbs ...func(string, interface{})) {
+ done := make(clearedValidations, 0, 3)
+ defer func() {
+ done.apply(cbs)
+ }()
+
+ if v.MaxItems != nil {
+ done = append(done, clearedValidation{Validation: "maxItems", Value: v.MaxItems})
+ v.MaxItems = nil
+ }
+ if v.MinItems != nil {
+ done = append(done, clearedValidation{Validation: "minItems", Value: v.MinItems})
+ v.MinItems = nil
+ }
+ if v.UniqueItems {
+ done = append(done, clearedValidation{Validation: "uniqueItems", Value: v.UniqueItems})
+ v.UniqueItems = false
+ }
+}
+
+// Validations returns a clone of the validations for a simple schema.
+//
+// NOTE: in the context of simple schema objects, MinProperties, MaxProperties
+// and PatternProperties remain unset.
+func (v CommonValidations) Validations() SchemaValidations {
+ return SchemaValidations{
+ CommonValidations: v,
+ }
+}
+
+// HasNumberValidations indicates if the validations are for numbers or integers
+func (v CommonValidations) HasNumberValidations() bool {
+ return v.Maximum != nil || v.Minimum != nil || v.MultipleOf != nil
+}
+
+// HasStringValidations indicates if the validations are for strings
+func (v CommonValidations) HasStringValidations() bool {
+ return v.MaxLength != nil || v.MinLength != nil || v.Pattern != ""
+}
+
+// HasArrayValidations indicates if the validations are for arrays
+func (v CommonValidations) HasArrayValidations() bool {
+ return v.MaxItems != nil || v.MinItems != nil || v.UniqueItems
+}
+
+// HasEnum indicates if the validation includes some enum constraint
+func (v CommonValidations) HasEnum() bool {
+ return len(v.Enum) > 0
+}
+
+// SchemaValidations describes the validation properties of a schema
+//
+// NOTE: at this moment, this is not embedded in SchemaProps because this would induce a breaking change
+// in the exported members: all initializers using litterals would fail.
+type SchemaValidations struct {
+ CommonValidations
+
+ PatternProperties SchemaProperties `json:"patternProperties,omitempty"`
+ MaxProperties *int64 `json:"maxProperties,omitempty"`
+ MinProperties *int64 `json:"minProperties,omitempty"`
+}
+
+// HasObjectValidations indicates if the validations are for objects
+func (v SchemaValidations) HasObjectValidations() bool {
+ return v.MaxProperties != nil || v.MinProperties != nil || v.PatternProperties != nil
+}
+
+// SetValidations for schema validations
+func (v *SchemaValidations) SetValidations(val SchemaValidations) {
+ v.CommonValidations.SetValidations(val)
+ v.PatternProperties = val.PatternProperties
+ v.MaxProperties = val.MaxProperties
+ v.MinProperties = val.MinProperties
+}
+
+// Validations for a schema
+func (v SchemaValidations) Validations() SchemaValidations {
+ val := v.CommonValidations.Validations()
+ val.PatternProperties = v.PatternProperties
+ val.MinProperties = v.MinProperties
+ val.MaxProperties = v.MaxProperties
+ return val
+}
+
+// ClearObjectValidations returns a clone of the validations with all object validations cleared.
+//
+// Some callbacks may be set by the caller to capture changed values.
+func (v *SchemaValidations) ClearObjectValidations(cbs ...func(string, interface{})) {
+ done := make(clearedValidations, 0, 3)
+ defer func() {
+ done.apply(cbs)
+ }()
+
+ if v.MaxProperties != nil {
+ done = append(done, clearedValidation{Validation: "maxProperties", Value: v.MaxProperties})
+ v.MaxProperties = nil
+ }
+ if v.MinProperties != nil {
+ done = append(done, clearedValidation{Validation: "minProperties", Value: v.MinProperties})
+ v.MinProperties = nil
+ }
+ if v.PatternProperties != nil {
+ done = append(done, clearedValidation{Validation: "patternProperties", Value: v.PatternProperties})
+ v.PatternProperties = nil
+ }
+}
diff --git a/constraint/vendor/github.com/go-openapi/swag/.golangci.yml b/constraint/vendor/github.com/go-openapi/swag/.golangci.yml
index 625c3d6af..842ac1c09 100644
--- a/constraint/vendor/github.com/go-openapi/swag/.golangci.yml
+++ b/constraint/vendor/github.com/go-openapi/swag/.golangci.yml
@@ -20,3 +20,22 @@ linters:
- lll
- gochecknoinits
- gochecknoglobals
+ - nlreturn
+ - testpackage
+ - wrapcheck
+ - gomnd
+ - exhaustive
+ - exhaustivestruct
+ - goerr113
+ - wsl
+ - whitespace
+ - gofumpt
+ - godot
+ - nestif
+ - godox
+ - funlen
+ - gci
+ - gocognit
+ - paralleltest
+ - thelper
+ - ifshort
diff --git a/constraint/vendor/github.com/go-openapi/swag/.travis.yml b/constraint/vendor/github.com/go-openapi/swag/.travis.yml
index aa26d8763..fc25a8872 100644
--- a/constraint/vendor/github.com/go-openapi/swag/.travis.yml
+++ b/constraint/vendor/github.com/go-openapi/swag/.travis.yml
@@ -1,12 +1,34 @@
after_success:
- bash <(curl -s https://codecov.io/bash)
go:
-- 1.11.x
-- 1.12.x
+- 1.14.x
+- 1.x
+arch:
+- amd64
+jobs:
+ include:
+ # include arch ppc, but only for latest go version - skip testing for race
+ - go: 1.x
+ arch: ppc64le
+ install: ~
+ script:
+ - go test -v
+
+ #- go: 1.x
+ # arch: arm
+ # install: ~
+ # script:
+ # - go test -v
+
+ # include linting job, but only for latest go version and amd64 arch
+ - go: 1.x
+ arch: amd64
+ install:
+ go get github.com/golangci/golangci-lint/cmd/golangci-lint
+ script:
+ - golangci-lint run --new-from-rev master
install:
- GO111MODULE=off go get -u gotest.tools/gotestsum
-env:
-- GO111MODULE=on
language: go
notifications:
slack:
diff --git a/constraint/vendor/github.com/go-openapi/swag/README.md b/constraint/vendor/github.com/go-openapi/swag/README.md
index eb60ae80a..217f6fa50 100644
--- a/constraint/vendor/github.com/go-openapi/swag/README.md
+++ b/constraint/vendor/github.com/go-openapi/swag/README.md
@@ -2,7 +2,6 @@
[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/swag/master/LICENSE)
[![GoDoc](https://godoc.org/github.com/go-openapi/swag?status.svg)](http://godoc.org/github.com/go-openapi/swag)
-[![GolangCI](https://golangci.com/badges/github.com/go-openapi/swag.svg)](https://golangci.com)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/swag)](https://goreportcard.com/report/github.com/go-openapi/swag)
Contains a bunch of helper functions for go-openapi and go-swagger projects.
diff --git a/constraint/vendor/github.com/go-openapi/swag/convert.go b/constraint/vendor/github.com/go-openapi/swag/convert.go
index 7da35c316..fc085aeb8 100644
--- a/constraint/vendor/github.com/go-openapi/swag/convert.go
+++ b/constraint/vendor/github.com/go-openapi/swag/convert.go
@@ -88,7 +88,7 @@ func ConvertFloat64(str string) (float64, error) {
return strconv.ParseFloat(str, 64)
}
-// ConvertInt8 turn a string into int8 boolean
+// ConvertInt8 turn a string into an int8
func ConvertInt8(str string) (int8, error) {
i, err := strconv.ParseInt(str, 10, 8)
if err != nil {
@@ -97,7 +97,7 @@ func ConvertInt8(str string) (int8, error) {
return int8(i), nil
}
-// ConvertInt16 turn a string into a int16
+// ConvertInt16 turn a string into an int16
func ConvertInt16(str string) (int16, error) {
i, err := strconv.ParseInt(str, 10, 16)
if err != nil {
@@ -106,7 +106,7 @@ func ConvertInt16(str string) (int16, error) {
return int16(i), nil
}
-// ConvertInt32 turn a string into a int32
+// ConvertInt32 turn a string into an int32
func ConvertInt32(str string) (int32, error) {
i, err := strconv.ParseInt(str, 10, 32)
if err != nil {
@@ -115,12 +115,12 @@ func ConvertInt32(str string) (int32, error) {
return int32(i), nil
}
-// ConvertInt64 turn a string into a int64
+// ConvertInt64 turn a string into an int64
func ConvertInt64(str string) (int64, error) {
return strconv.ParseInt(str, 10, 64)
}
-// ConvertUint8 turn a string into a uint8
+// ConvertUint8 turn a string into an uint8
func ConvertUint8(str string) (uint8, error) {
i, err := strconv.ParseUint(str, 10, 8)
if err != nil {
@@ -129,7 +129,7 @@ func ConvertUint8(str string) (uint8, error) {
return uint8(i), nil
}
-// ConvertUint16 turn a string into a uint16
+// ConvertUint16 turn a string into an uint16
func ConvertUint16(str string) (uint16, error) {
i, err := strconv.ParseUint(str, 10, 16)
if err != nil {
@@ -138,7 +138,7 @@ func ConvertUint16(str string) (uint16, error) {
return uint16(i), nil
}
-// ConvertUint32 turn a string into a uint32
+// ConvertUint32 turn a string into an uint32
func ConvertUint32(str string) (uint32, error) {
i, err := strconv.ParseUint(str, 10, 32)
if err != nil {
@@ -147,7 +147,7 @@ func ConvertUint32(str string) (uint32, error) {
return uint32(i), nil
}
-// ConvertUint64 turn a string into a uint64
+// ConvertUint64 turn a string into an uint64
func ConvertUint64(str string) (uint64, error) {
return strconv.ParseUint(str, 10, 64)
}
diff --git a/constraint/vendor/github.com/go-openapi/swag/convert_types.go b/constraint/vendor/github.com/go-openapi/swag/convert_types.go
index c95e4e78b..c49cc473a 100644
--- a/constraint/vendor/github.com/go-openapi/swag/convert_types.go
+++ b/constraint/vendor/github.com/go-openapi/swag/convert_types.go
@@ -181,12 +181,12 @@ func IntValueMap(src map[string]*int) map[string]int {
return dst
}
-// Int32 returns a pointer to of the int64 value passed in.
+// Int32 returns a pointer to of the int32 value passed in.
func Int32(v int32) *int32 {
return &v
}
-// Int32Value returns the value of the int64 pointer passed in or
+// Int32Value returns the value of the int32 pointer passed in or
// 0 if the pointer is nil.
func Int32Value(v *int32) int32 {
if v != nil {
@@ -195,7 +195,7 @@ func Int32Value(v *int32) int32 {
return 0
}
-// Int32Slice converts a slice of int64 values into a slice of
+// Int32Slice converts a slice of int32 values into a slice of
// int32 pointers
func Int32Slice(src []int32) []*int32 {
dst := make([]*int32, len(src))
@@ -299,13 +299,80 @@ func Int64ValueMap(src map[string]*int64) map[string]int64 {
return dst
}
-// Uint returns a pouinter to of the uint value passed in.
+// Uint16 returns a pointer to of the uint16 value passed in.
+func Uint16(v uint16) *uint16 {
+ return &v
+}
+
+// Uint16Value returns the value of the uint16 pointer passed in or
+// 0 if the pointer is nil.
+func Uint16Value(v *uint16) uint16 {
+ if v != nil {
+ return *v
+ }
+
+ return 0
+}
+
+// Uint16Slice converts a slice of uint16 values into a slice of
+// uint16 pointers
+func Uint16Slice(src []uint16) []*uint16 {
+ dst := make([]*uint16, len(src))
+ for i := 0; i < len(src); i++ {
+ dst[i] = &(src[i])
+ }
+
+ return dst
+}
+
+// Uint16ValueSlice converts a slice of uint16 pointers into a slice of
+// uint16 values
+func Uint16ValueSlice(src []*uint16) []uint16 {
+ dst := make([]uint16, len(src))
+
+ for i := 0; i < len(src); i++ {
+ if src[i] != nil {
+ dst[i] = *(src[i])
+ }
+ }
+
+ return dst
+}
+
+// Uint16Map converts a string map of uint16 values into a string
+// map of uint16 pointers
+func Uint16Map(src map[string]uint16) map[string]*uint16 {
+ dst := make(map[string]*uint16)
+
+ for k, val := range src {
+ v := val
+ dst[k] = &v
+ }
+
+ return dst
+}
+
+// Uint16ValueMap converts a string map of uint16 pointers into a string
+// map of uint16 values
+func Uint16ValueMap(src map[string]*uint16) map[string]uint16 {
+ dst := make(map[string]uint16)
+
+ for k, val := range src {
+ if val != nil {
+ dst[k] = *val
+ }
+ }
+
+ return dst
+}
+
+// Uint returns a pointer to of the uint value passed in.
func Uint(v uint) *uint {
return &v
}
-// UintValue returns the value of the uint pouinter passed in or
-// 0 if the pouinter is nil.
+// UintValue returns the value of the uint pointer passed in or
+// 0 if the pointer is nil.
func UintValue(v *uint) uint {
if v != nil {
return *v
@@ -313,8 +380,8 @@ func UintValue(v *uint) uint {
return 0
}
-// UintSlice converts a slice of uint values uinto a slice of
-// uint pouinters
+// UintSlice converts a slice of uint values into a slice of
+// uint pointers
func UintSlice(src []uint) []*uint {
dst := make([]*uint, len(src))
for i := 0; i < len(src); i++ {
@@ -323,7 +390,7 @@ func UintSlice(src []uint) []*uint {
return dst
}
-// UintValueSlice converts a slice of uint pouinters uinto a slice of
+// UintValueSlice converts a slice of uint pointers into a slice of
// uint values
func UintValueSlice(src []*uint) []uint {
dst := make([]uint, len(src))
@@ -335,8 +402,8 @@ func UintValueSlice(src []*uint) []uint {
return dst
}
-// UintMap converts a string map of uint values uinto a string
-// map of uint pouinters
+// UintMap converts a string map of uint values into a string
+// map of uint pointers
func UintMap(src map[string]uint) map[string]*uint {
dst := make(map[string]*uint)
for k, val := range src {
@@ -346,7 +413,7 @@ func UintMap(src map[string]uint) map[string]*uint {
return dst
}
-// UintValueMap converts a string map of uint pouinters uinto a string
+// UintValueMap converts a string map of uint pointers into a string
// map of uint values
func UintValueMap(src map[string]*uint) map[string]uint {
dst := make(map[string]uint)
@@ -358,13 +425,13 @@ func UintValueMap(src map[string]*uint) map[string]uint {
return dst
}
-// Uint32 returns a pouinter to of the uint64 value passed in.
+// Uint32 returns a pointer to of the uint32 value passed in.
func Uint32(v uint32) *uint32 {
return &v
}
-// Uint32Value returns the value of the uint64 pouinter passed in or
-// 0 if the pouinter is nil.
+// Uint32Value returns the value of the uint32 pointer passed in or
+// 0 if the pointer is nil.
func Uint32Value(v *uint32) uint32 {
if v != nil {
return *v
@@ -372,8 +439,8 @@ func Uint32Value(v *uint32) uint32 {
return 0
}
-// Uint32Slice converts a slice of uint64 values uinto a slice of
-// uint32 pouinters
+// Uint32Slice converts a slice of uint32 values into a slice of
+// uint32 pointers
func Uint32Slice(src []uint32) []*uint32 {
dst := make([]*uint32, len(src))
for i := 0; i < len(src); i++ {
@@ -382,7 +449,7 @@ func Uint32Slice(src []uint32) []*uint32 {
return dst
}
-// Uint32ValueSlice converts a slice of uint32 pouinters uinto a slice of
+// Uint32ValueSlice converts a slice of uint32 pointers into a slice of
// uint32 values
func Uint32ValueSlice(src []*uint32) []uint32 {
dst := make([]uint32, len(src))
@@ -394,8 +461,8 @@ func Uint32ValueSlice(src []*uint32) []uint32 {
return dst
}
-// Uint32Map converts a string map of uint32 values uinto a string
-// map of uint32 pouinters
+// Uint32Map converts a string map of uint32 values into a string
+// map of uint32 pointers
func Uint32Map(src map[string]uint32) map[string]*uint32 {
dst := make(map[string]*uint32)
for k, val := range src {
@@ -405,7 +472,7 @@ func Uint32Map(src map[string]uint32) map[string]*uint32 {
return dst
}
-// Uint32ValueMap converts a string map of uint32 pouinters uinto a string
+// Uint32ValueMap converts a string map of uint32 pointers into a string
// map of uint32 values
func Uint32ValueMap(src map[string]*uint32) map[string]uint32 {
dst := make(map[string]uint32)
@@ -417,13 +484,13 @@ func Uint32ValueMap(src map[string]*uint32) map[string]uint32 {
return dst
}
-// Uint64 returns a pouinter to of the uint64 value passed in.
+// Uint64 returns a pointer to of the uint64 value passed in.
func Uint64(v uint64) *uint64 {
return &v
}
-// Uint64Value returns the value of the uint64 pouinter passed in or
-// 0 if the pouinter is nil.
+// Uint64Value returns the value of the uint64 pointer passed in or
+// 0 if the pointer is nil.
func Uint64Value(v *uint64) uint64 {
if v != nil {
return *v
@@ -431,8 +498,8 @@ func Uint64Value(v *uint64) uint64 {
return 0
}
-// Uint64Slice converts a slice of uint64 values uinto a slice of
-// uint64 pouinters
+// Uint64Slice converts a slice of uint64 values into a slice of
+// uint64 pointers
func Uint64Slice(src []uint64) []*uint64 {
dst := make([]*uint64, len(src))
for i := 0; i < len(src); i++ {
@@ -441,7 +508,7 @@ func Uint64Slice(src []uint64) []*uint64 {
return dst
}
-// Uint64ValueSlice converts a slice of uint64 pouinters uinto a slice of
+// Uint64ValueSlice converts a slice of uint64 pointers into a slice of
// uint64 values
func Uint64ValueSlice(src []*uint64) []uint64 {
dst := make([]uint64, len(src))
@@ -453,8 +520,8 @@ func Uint64ValueSlice(src []*uint64) []uint64 {
return dst
}
-// Uint64Map converts a string map of uint64 values uinto a string
-// map of uint64 pouinters
+// Uint64Map converts a string map of uint64 values into a string
+// map of uint64 pointers
func Uint64Map(src map[string]uint64) map[string]*uint64 {
dst := make(map[string]*uint64)
for k, val := range src {
@@ -464,7 +531,7 @@ func Uint64Map(src map[string]uint64) map[string]*uint64 {
return dst
}
-// Uint64ValueMap converts a string map of uint64 pouinters uinto a string
+// Uint64ValueMap converts a string map of uint64 pointers into a string
// map of uint64 values
func Uint64ValueMap(src map[string]*uint64) map[string]uint64 {
dst := make(map[string]uint64)
@@ -476,6 +543,74 @@ func Uint64ValueMap(src map[string]*uint64) map[string]uint64 {
return dst
}
+// Float32 returns a pointer to of the float32 value passed in.
+func Float32(v float32) *float32 {
+ return &v
+}
+
+// Float32Value returns the value of the float32 pointer passed in or
+// 0 if the pointer is nil.
+func Float32Value(v *float32) float32 {
+ if v != nil {
+ return *v
+ }
+
+ return 0
+}
+
+// Float32Slice converts a slice of float32 values into a slice of
+// float32 pointers
+func Float32Slice(src []float32) []*float32 {
+ dst := make([]*float32, len(src))
+
+ for i := 0; i < len(src); i++ {
+ dst[i] = &(src[i])
+ }
+
+ return dst
+}
+
+// Float32ValueSlice converts a slice of float32 pointers into a slice of
+// float32 values
+func Float32ValueSlice(src []*float32) []float32 {
+ dst := make([]float32, len(src))
+
+ for i := 0; i < len(src); i++ {
+ if src[i] != nil {
+ dst[i] = *(src[i])
+ }
+ }
+
+ return dst
+}
+
+// Float32Map converts a string map of float32 values into a string
+// map of float32 pointers
+func Float32Map(src map[string]float32) map[string]*float32 {
+ dst := make(map[string]*float32)
+
+ for k, val := range src {
+ v := val
+ dst[k] = &v
+ }
+
+ return dst
+}
+
+// Float32ValueMap converts a string map of float32 pointers into a string
+// map of float32 values
+func Float32ValueMap(src map[string]*float32) map[string]float32 {
+ dst := make(map[string]float32)
+
+ for k, val := range src {
+ if val != nil {
+ dst[k] = *val
+ }
+ }
+
+ return dst
+}
+
// Float64 returns a pointer to of the float64 value passed in.
func Float64(v float64) *float64 {
return &v
diff --git a/constraint/vendor/github.com/go-openapi/swag/go.mod b/constraint/vendor/github.com/go-openapi/swag/go.mod
index 15bbb0822..fb29b65b2 100644
--- a/constraint/vendor/github.com/go-openapi/swag/go.mod
+++ b/constraint/vendor/github.com/go-openapi/swag/go.mod
@@ -2,13 +2,17 @@ module github.com/go-openapi/swag
require (
github.com/davecgh/go-spew v1.1.1 // indirect
- github.com/kr/pretty v0.1.0 // indirect
- github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63
- github.com/stretchr/testify v1.3.0
- gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
- gopkg.in/yaml.v2 v2.2.2
+ github.com/kr/text v0.2.0 // indirect
+ github.com/mailru/easyjson v0.7.6
+ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
+ github.com/stretchr/testify v1.6.1
+ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
+ gopkg.in/yaml.v2 v2.4.0
+ gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
)
replace github.com/golang/lint => golang.org/x/lint v0.0.0-20190409202823-959b441ac422
replace sourcegraph.com/sourcegraph/go-diff => github.com/sourcegraph/go-diff v0.5.1
+
+go 1.11
diff --git a/constraint/vendor/github.com/go-openapi/swag/go.sum b/constraint/vendor/github.com/go-openapi/swag/go.sum
index 33469f54a..a45da809a 100644
--- a/constraint/vendor/github.com/go-openapi/swag/go.sum
+++ b/constraint/vendor/github.com/go-openapi/swag/go.sum
@@ -1,20 +1,29 @@
+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/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
-github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+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/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4=
-github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+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.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
+github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
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/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+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 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
+gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/constraint/vendor/github.com/go-openapi/swag/json.go b/constraint/vendor/github.com/go-openapi/swag/json.go
index edf93d84c..7e9902ca3 100644
--- a/constraint/vendor/github.com/go-openapi/swag/json.go
+++ b/constraint/vendor/github.com/go-openapi/swag/json.go
@@ -51,7 +51,7 @@ type ejUnmarshaler interface {
UnmarshalEasyJSON(w *jlexer.Lexer)
}
-// WriteJSON writes json data, prefers finding an appropriate interface to short-circuit the marshaller
+// WriteJSON writes json data, prefers finding an appropriate interface to short-circuit the marshaler
// so it takes the fastest option available.
func WriteJSON(data interface{}) ([]byte, error) {
if d, ok := data.(ejMarshaler); ok {
@@ -65,8 +65,8 @@ func WriteJSON(data interface{}) ([]byte, error) {
return json.Marshal(data)
}
-// ReadJSON reads json data, prefers finding an appropriate interface to short-circuit the unmarshaller
-// so it takes the fastes option available
+// ReadJSON reads json data, prefers finding an appropriate interface to short-circuit the unmarshaler
+// so it takes the fastest option available
func ReadJSON(data []byte, value interface{}) error {
trimmedData := bytes.Trim(data, "\x00")
if d, ok := value.(ejUnmarshaler); ok {
@@ -189,7 +189,7 @@ func FromDynamicJSON(data, target interface{}) error {
return json.Unmarshal(b, target)
}
-// NameProvider represents an object capabale of translating from go property names
+// NameProvider represents an object capable of translating from go property names
// to json property names
// This type is thread-safe.
type NameProvider struct {
diff --git a/constraint/vendor/github.com/go-openapi/swag/loading.go b/constraint/vendor/github.com/go-openapi/swag/loading.go
index 70f4fb361..9a6040972 100644
--- a/constraint/vendor/github.com/go-openapi/swag/loading.go
+++ b/constraint/vendor/github.com/go-openapi/swag/loading.go
@@ -19,7 +19,9 @@ import (
"io/ioutil"
"log"
"net/http"
+ "net/url"
"path/filepath"
+ "runtime"
"strings"
"time"
)
@@ -27,6 +29,15 @@ import (
// LoadHTTPTimeout the default timeout for load requests
var LoadHTTPTimeout = 30 * time.Second
+// LoadHTTPBasicAuthUsername the username to use when load requests require basic auth
+var LoadHTTPBasicAuthUsername = ""
+
+// LoadHTTPBasicAuthPassword the password to use when load requests require basic auth
+var LoadHTTPBasicAuthPassword = ""
+
+// LoadHTTPCustomHeaders an optional collection of custom HTTP headers for load requests
+var LoadHTTPCustomHeaders = map[string]string{}
+
// LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in
func LoadFromFileOrHTTP(path string) ([]byte, error) {
return LoadStrategy(path, ioutil.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path)
@@ -48,6 +59,26 @@ func LoadStrategy(path string, local, remote func(string) ([]byte, error)) func(
if err != nil {
return nil, err
}
+
+ if strings.HasPrefix(pth, `file://`) {
+ if runtime.GOOS == "windows" {
+ // support for canonical file URIs on windows.
+ // Zero tolerance here for dodgy URIs.
+ u, _ := url.Parse(upth)
+ if u.Host != "" {
+ // assume UNC name (volume share)
+ // file://host/share/folder\... ==> \\host\share\path\folder
+ // NOTE: UNC port not yet supported
+ upth = strings.Join([]string{`\`, u.Host, u.Path}, `\`)
+ } else {
+ // file:///c:/folder/... ==> just remove the leading slash
+ upth = strings.TrimPrefix(upth, `file:///`)
+ }
+ } else {
+ upth = strings.TrimPrefix(upth, `file://`)
+ }
+ }
+
return local(filepath.FromSlash(upth))
}
}
@@ -55,10 +86,19 @@ func LoadStrategy(path string, local, remote func(string) ([]byte, error)) func(
func loadHTTPBytes(timeout time.Duration) func(path string) ([]byte, error) {
return func(path string) ([]byte, error) {
client := &http.Client{Timeout: timeout}
- req, err := http.NewRequest("GET", path, nil)
+ req, err := http.NewRequest("GET", path, nil) // nolint: noctx
if err != nil {
return nil, err
}
+
+ if LoadHTTPBasicAuthUsername != "" && LoadHTTPBasicAuthPassword != "" {
+ req.SetBasicAuth(LoadHTTPBasicAuthUsername, LoadHTTPBasicAuthPassword)
+ }
+
+ for key, val := range LoadHTTPCustomHeaders {
+ req.Header.Set(key, val)
+ }
+
resp, err := client.Do(req)
defer func() {
if resp != nil {
diff --git a/constraint/vendor/github.com/go-openapi/swag/util.go b/constraint/vendor/github.com/go-openapi/swag/util.go
index 9eac16afb..193702f2c 100644
--- a/constraint/vendor/github.com/go-openapi/swag/util.go
+++ b/constraint/vendor/github.com/go-openapi/swag/util.go
@@ -31,7 +31,7 @@ var isInitialism func(string) bool
// GoNamePrefixFunc sets an optional rule to prefix go names
// which do not start with a letter.
//
-// e.g. to help converting "123" into "{prefix}123"
+// e.g. to help convert "123" into "{prefix}123"
//
// The default is to prefix with "X"
var GoNamePrefixFunc func(string) string
@@ -91,7 +91,7 @@ func init() {
}
const (
- //collectionFormatComma = "csv"
+ // collectionFormatComma = "csv"
collectionFormatSpace = "ssv"
collectionFormatTab = "tsv"
collectionFormatPipe = "pipes"
@@ -370,7 +370,7 @@ func IsZero(data interface{}) bool {
// AddInitialisms add additional initialisms
func AddInitialisms(words ...string) {
for _, word := range words {
- //commonInitialisms[upper(word)] = true
+ // commonInitialisms[upper(word)] = true
commonInitialisms.add(upper(word))
}
// sort again
diff --git a/constraint/vendor/github.com/gogo/protobuf/proto/text_parser.go b/constraint/vendor/github.com/gogo/protobuf/proto/text_parser.go
index f85c0cc81..1ce0be2fa 100644
--- a/constraint/vendor/github.com/gogo/protobuf/proto/text_parser.go
+++ b/constraint/vendor/github.com/gogo/protobuf/proto/text_parser.go
@@ -318,7 +318,7 @@ func unescape(s string) (ch string, tail string, err error) {
if i > utf8.MaxRune {
return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss)
}
- return string(rune(i)), s, nil
+ return string(i), s, nil
}
return "", "", fmt.Errorf(`unknown escape \%c`, r)
}
diff --git a/constraint/vendor/github.com/golang/glog/README b/constraint/vendor/github.com/golang/glog/README
deleted file mode 100644
index 387b4eb68..000000000
--- a/constraint/vendor/github.com/golang/glog/README
+++ /dev/null
@@ -1,44 +0,0 @@
-glog
-====
-
-Leveled execution logs for Go.
-
-This is an efficient pure Go implementation of leveled logs in the
-manner of the open source C++ package
- https://github.com/google/glog
-
-By binding methods to booleans it is possible to use the log package
-without paying the expense of evaluating the arguments to the log.
-Through the -vmodule flag, the package also provides fine-grained
-control over logging at the file level.
-
-The comment from glog.go introduces the ideas:
-
- Package glog implements logging analogous to the Google-internal
- C++ INFO/ERROR/V setup. It provides functions Info, Warning,
- Error, Fatal, plus formatting variants such as Infof. It
- also provides V-style logging controlled by the -v and
- -vmodule=file=2 flags.
-
- Basic examples:
-
- glog.Info("Prepare to repel boarders")
-
- glog.Fatalf("Initialization failed: %s", err)
-
- See the documentation for the V function for an explanation
- of these examples:
-
- if glog.V(2) {
- glog.Info("Starting transaction...")
- }
-
- glog.V(2).Infoln("Processed", nItems, "elements")
-
-
-The repository contains an open source version of the log package
-used inside Google. The master copy of the source lives inside
-Google, not here. The code in this repo is for export only and is not itself
-under development. Feature requests will be ignored.
-
-Send bug reports to golang-nuts@googlegroups.com.
diff --git a/constraint/vendor/github.com/golang/glog/README.md b/constraint/vendor/github.com/golang/glog/README.md
new file mode 100644
index 000000000..a4f73883b
--- /dev/null
+++ b/constraint/vendor/github.com/golang/glog/README.md
@@ -0,0 +1,36 @@
+# glog
+
+[![PkgGoDev](https://pkg.go.dev/badge/github.com/golang/glog)](https://pkg.go.dev/github.com/golang/glog)
+
+Leveled execution logs for Go.
+
+This is an efficient pure Go implementation of leveled logs in the
+manner of the open source C++ package [_glog_](https://github.com/google/glog).
+
+By binding methods to booleans it is possible to use the log package without paying the expense of evaluating the arguments to the log. Through the `-vmodule` flag, the package also provides fine-grained
+control over logging at the file level.
+
+The comment from `glog.go` introduces the ideas:
+
+Package _glog_ implements logging analogous to the Google-internal C++ INFO/ERROR/V setup. It provides the functions Info, Warning, Error, Fatal, plus formatting variants such as Infof. It also provides V-style loggingcontrolled by the `-v` and `-vmodule=file=2` flags.
+
+Basic examples:
+
+```go
+glog.Info("Prepare to repel boarders")
+
+glog.Fatalf("Initialization failed: %s", err)
+```
+
+See the documentation for the V function for an explanation of these examples:
+
+```go
+if glog.V(2) {
+ glog.Info("Starting transaction...")
+}
+glog.V(2).Infoln("Processed", nItems, "elements")
+```
+
+The repository contains an open source version of the log package used inside Google. The master copy of the source lives inside Google, not here. The code in this repo is for export only and is not itself under development. Feature requests will be ignored.
+
+Send bug reports to golang-nuts@googlegroups.com.
diff --git a/constraint/vendor/github.com/golang/protobuf/proto/registry.go b/constraint/vendor/github.com/golang/protobuf/proto/registry.go
index 1e7ff6420..066b4323b 100644
--- a/constraint/vendor/github.com/golang/protobuf/proto/registry.go
+++ b/constraint/vendor/github.com/golang/protobuf/proto/registry.go
@@ -13,6 +13,7 @@ import (
"strings"
"sync"
+ "google.golang.org/protobuf/reflect/protodesc"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
"google.golang.org/protobuf/runtime/protoimpl"
@@ -62,14 +63,7 @@ func FileDescriptor(s filePath) fileDescGZIP {
// Find the descriptor in the v2 registry.
var b []byte
if fd, _ := protoregistry.GlobalFiles.FindFileByPath(s); fd != nil {
- if fd, ok := fd.(interface{ ProtoLegacyRawDesc() []byte }); ok {
- b = fd.ProtoLegacyRawDesc()
- } else {
- // TODO: Use protodesc.ToFileDescriptorProto to construct
- // a descriptorpb.FileDescriptorProto and marshal it.
- // However, doing so causes the proto package to have a dependency
- // on descriptorpb, leading to cyclic dependency issues.
- }
+ b, _ = Marshal(protodesc.ToFileDescriptorProto(fd))
}
// Locally cache the raw descriptor form for the file.
diff --git a/constraint/vendor/github.com/golang/protobuf/ptypes/any.go b/constraint/vendor/github.com/golang/protobuf/ptypes/any.go
index e729dcff1..85f9f5736 100644
--- a/constraint/vendor/github.com/golang/protobuf/ptypes/any.go
+++ b/constraint/vendor/github.com/golang/protobuf/ptypes/any.go
@@ -19,6 +19,8 @@ const urlPrefix = "type.googleapis.com/"
// AnyMessageName returns the message name contained in an anypb.Any message.
// Most type assertions should use the Is function instead.
+//
+// Deprecated: Call the any.MessageName method instead.
func AnyMessageName(any *anypb.Any) (string, error) {
name, err := anyMessageName(any)
return string(name), err
@@ -38,6 +40,8 @@ func anyMessageName(any *anypb.Any) (protoreflect.FullName, error) {
}
// MarshalAny marshals the given message m into an anypb.Any message.
+//
+// Deprecated: Call the anypb.New function instead.
func MarshalAny(m proto.Message) (*anypb.Any, error) {
switch dm := m.(type) {
case DynamicAny:
@@ -58,6 +62,9 @@ func MarshalAny(m proto.Message) (*anypb.Any, error) {
// Empty returns a new message of the type specified in an anypb.Any message.
// It returns protoregistry.NotFound if the corresponding message type could not
// be resolved in the global registry.
+//
+// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead
+// to resolve the message name and create a new instance of it.
func Empty(any *anypb.Any) (proto.Message, error) {
name, err := anyMessageName(any)
if err != nil {
@@ -76,6 +83,8 @@ func Empty(any *anypb.Any) (proto.Message, error) {
//
// The target message m may be a *DynamicAny message. If the underlying message
// type could not be resolved, then this returns protoregistry.NotFound.
+//
+// Deprecated: Call the any.UnmarshalTo method instead.
func UnmarshalAny(any *anypb.Any, m proto.Message) error {
if dm, ok := m.(*DynamicAny); ok {
if dm.Message == nil {
@@ -100,6 +109,8 @@ func UnmarshalAny(any *anypb.Any, m proto.Message) error {
}
// Is reports whether the Any message contains a message of the specified type.
+//
+// Deprecated: Call the any.MessageIs method instead.
func Is(any *anypb.Any, m proto.Message) bool {
if any == nil || m == nil {
return false
@@ -119,6 +130,9 @@ func Is(any *anypb.Any, m proto.Message) bool {
// var x ptypes.DynamicAny
// if err := ptypes.UnmarshalAny(a, &x); err != nil { ... }
// fmt.Printf("unmarshaled message: %v", x.Message)
+//
+// Deprecated: Use the any.UnmarshalNew method instead to unmarshal
+// the any message contents into a new instance of the underlying message.
type DynamicAny struct{ proto.Message }
func (m DynamicAny) String() string {
diff --git a/constraint/vendor/github.com/golang/protobuf/ptypes/doc.go b/constraint/vendor/github.com/golang/protobuf/ptypes/doc.go
index fb9edd5c6..d3c33259d 100644
--- a/constraint/vendor/github.com/golang/protobuf/ptypes/doc.go
+++ b/constraint/vendor/github.com/golang/protobuf/ptypes/doc.go
@@ -3,4 +3,8 @@
// license that can be found in the LICENSE file.
// Package ptypes provides functionality for interacting with well-known types.
+//
+// Deprecated: Well-known types have specialized functionality directly
+// injected into the generated packages for each message type.
+// See the deprecation notice for each function for the suggested alternative.
package ptypes
diff --git a/constraint/vendor/github.com/golang/protobuf/ptypes/duration.go b/constraint/vendor/github.com/golang/protobuf/ptypes/duration.go
index 6110ae8a4..b2b55dd85 100644
--- a/constraint/vendor/github.com/golang/protobuf/ptypes/duration.go
+++ b/constraint/vendor/github.com/golang/protobuf/ptypes/duration.go
@@ -21,6 +21,8 @@ const (
// Duration converts a durationpb.Duration to a time.Duration.
// Duration returns an error if dur is invalid or overflows a time.Duration.
+//
+// Deprecated: Call the dur.AsDuration and dur.CheckValid methods instead.
func Duration(dur *durationpb.Duration) (time.Duration, error) {
if err := validateDuration(dur); err != nil {
return 0, err
@@ -39,6 +41,8 @@ func Duration(dur *durationpb.Duration) (time.Duration, error) {
}
// DurationProto converts a time.Duration to a durationpb.Duration.
+//
+// Deprecated: Call the durationpb.New function instead.
func DurationProto(d time.Duration) *durationpb.Duration {
nanos := d.Nanoseconds()
secs := nanos / 1e9
diff --git a/constraint/vendor/github.com/golang/protobuf/ptypes/timestamp.go b/constraint/vendor/github.com/golang/protobuf/ptypes/timestamp.go
index 026d0d491..8368a3f70 100644
--- a/constraint/vendor/github.com/golang/protobuf/ptypes/timestamp.go
+++ b/constraint/vendor/github.com/golang/protobuf/ptypes/timestamp.go
@@ -33,6 +33,8 @@ const (
//
// A nil Timestamp returns an error. The first return value in that case is
// undefined.
+//
+// Deprecated: Call the ts.AsTime and ts.CheckValid methods instead.
func Timestamp(ts *timestamppb.Timestamp) (time.Time, error) {
// Don't return the zero value on error, because corresponds to a valid
// timestamp. Instead return whatever time.Unix gives us.
@@ -46,6 +48,8 @@ func Timestamp(ts *timestamppb.Timestamp) (time.Time, error) {
}
// TimestampNow returns a google.protobuf.Timestamp for the current time.
+//
+// Deprecated: Call the timestamppb.Now function instead.
func TimestampNow() *timestamppb.Timestamp {
ts, err := TimestampProto(time.Now())
if err != nil {
@@ -56,6 +60,8 @@ func TimestampNow() *timestamppb.Timestamp {
// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
// It returns an error if the resulting Timestamp is invalid.
+//
+// Deprecated: Call the timestamppb.New function instead.
func TimestampProto(t time.Time) (*timestamppb.Timestamp, error) {
ts := ×tamppb.Timestamp{
Seconds: t.Unix(),
@@ -69,6 +75,9 @@ func TimestampProto(t time.Time) (*timestamppb.Timestamp, error) {
// TimestampString returns the RFC 3339 string for valid Timestamps.
// For invalid Timestamps, it returns an error message in parentheses.
+//
+// Deprecated: Call the ts.AsTime method instead,
+// followed by a call to the Format method on the time.Time value.
func TimestampString(ts *timestamppb.Timestamp) string {
t, err := Timestamp(ts)
if err != nil {
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/compare.go b/constraint/vendor/github.com/google/go-cmp/cmp/compare.go
index 665618684..86d0903b8 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/compare.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/compare.go
@@ -1,6 +1,6 @@
// Copyright 2017, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
// Package cmp determines equality of values.
//
@@ -100,8 +100,8 @@ func Equal(x, y interface{}, opts ...Option) bool {
// same input values and options.
//
// The output is displayed as a literal in pseudo-Go syntax.
-// At the start of each line, a "-" prefix indicates an element removed from y,
-// a "+" prefix to indicates an element added to y, and the lack of a prefix
+// At the start of each line, a "-" prefix indicates an element removed from x,
+// a "+" prefix to indicates an element added from y, and the lack of a prefix
// indicates an element common to both x and y. If possible, the output
// uses fmt.Stringer.String or error.Error methods to produce more humanly
// readable outputs. In such cases, the string is prefixed with either an
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/export_panic.go b/constraint/vendor/github.com/google/go-cmp/cmp/export_panic.go
index dfa5d2137..5ff0b4218 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/export_panic.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/export_panic.go
@@ -1,6 +1,6 @@
// Copyright 2017, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
// +build purego
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/export_unsafe.go b/constraint/vendor/github.com/google/go-cmp/cmp/export_unsafe.go
index 351f1a34b..21eb54858 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/export_unsafe.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/export_unsafe.go
@@ -1,6 +1,6 @@
// Copyright 2017, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
// +build !purego
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go b/constraint/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go
index fe98dcc67..1daaaacc5 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go
@@ -1,6 +1,6 @@
// Copyright 2017, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
// +build !cmp_debug
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go b/constraint/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go
index 597b6ae56..4b91dbcac 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go
@@ -1,6 +1,6 @@
// Copyright 2017, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
// +build cmp_debug
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go b/constraint/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go
index 730e223ee..bc196b16c 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go
@@ -1,6 +1,6 @@
// Copyright 2017, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
// Package diff implements an algorithm for producing edit-scripts.
// The edit-script is a sequence of operations needed to transform one list
@@ -119,7 +119,7 @@ func (r Result) Similar() bool {
return r.NumSame+1 >= r.NumDiff
}
-var randInt = rand.New(rand.NewSource(time.Now().Unix())).Intn(2)
+var randBool = rand.New(rand.NewSource(time.Now().Unix())).Intn(2) == 0
// Difference reports whether two lists of lengths nx and ny are equal
// given the definition of equality provided as f.
@@ -168,17 +168,6 @@ func Difference(nx, ny int, f EqualFunc) (es EditScript) {
// A vertical edge is equivalent to inserting a symbol from list Y.
// A diagonal edge is equivalent to a matching symbol between both X and Y.
- // To ensure flexibility in changing the algorithm in the future,
- // introduce some degree of deliberate instability.
- // This is achieved by fiddling the zigzag iterator to start searching
- // the graph starting from the bottom-right versus than the top-left.
- // The result may differ depending on the starting search location,
- // but still produces a valid edit script.
- zigzagInit := randInt // either 0 or 1
- if flags.Deterministic {
- zigzagInit = 0
- }
-
// Invariants:
// • 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx
// • 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny
@@ -197,6 +186,11 @@ func Difference(nx, ny int, f EqualFunc) (es EditScript) {
// approximately the square-root of the search budget.
searchBudget := 4 * (nx + ny) // O(n)
+ // Running the tests with the "cmp_debug" build tag prints a visualization
+ // of the algorithm running in real-time. This is educational for
+ // understanding how the algorithm works. See debug_enable.go.
+ f = debug.Begin(nx, ny, f, &fwdPath.es, &revPath.es)
+
// The algorithm below is a greedy, meet-in-the-middle algorithm for
// computing sub-optimal edit-scripts between two lists.
//
@@ -214,22 +208,28 @@ func Difference(nx, ny int, f EqualFunc) (es EditScript) {
// frontier towards the opposite corner.
// • This algorithm terminates when either the X coordinates or the
// Y coordinates of the forward and reverse frontier points ever intersect.
- //
+
// This algorithm is correct even if searching only in the forward direction
// or in the reverse direction. We do both because it is commonly observed
// that two lists commonly differ because elements were added to the front
// or end of the other list.
//
- // Running the tests with the "cmp_debug" build tag prints a visualization
- // of the algorithm running in real-time. This is educational for
- // understanding how the algorithm works. See debug_enable.go.
- f = debug.Begin(nx, ny, f, &fwdPath.es, &revPath.es)
- for {
+ // Non-deterministically start with either the forward or reverse direction
+ // to introduce some deliberate instability so that we have the flexibility
+ // to change this algorithm in the future.
+ if flags.Deterministic || randBool {
+ goto forwardSearch
+ } else {
+ goto reverseSearch
+ }
+
+forwardSearch:
+ {
// Forward search from the beginning.
if fwdFrontier.X >= revFrontier.X || fwdFrontier.Y >= revFrontier.Y || searchBudget == 0 {
- break
+ goto finishSearch
}
- for stop1, stop2, i := false, false, zigzagInit; !(stop1 && stop2) && searchBudget > 0; i++ {
+ for stop1, stop2, i := false, false, 0; !(stop1 && stop2) && searchBudget > 0; i++ {
// Search in a diagonal pattern for a match.
z := zigzag(i)
p := point{fwdFrontier.X + z, fwdFrontier.Y - z}
@@ -262,10 +262,14 @@ func Difference(nx, ny int, f EqualFunc) (es EditScript) {
} else {
fwdFrontier.Y++
}
+ goto reverseSearch
+ }
+reverseSearch:
+ {
// Reverse search from the end.
if fwdFrontier.X >= revFrontier.X || fwdFrontier.Y >= revFrontier.Y || searchBudget == 0 {
- break
+ goto finishSearch
}
for stop1, stop2, i := false, false, 0; !(stop1 && stop2) && searchBudget > 0; i++ {
// Search in a diagonal pattern for a match.
@@ -300,8 +304,10 @@ func Difference(nx, ny int, f EqualFunc) (es EditScript) {
} else {
revFrontier.Y--
}
+ goto forwardSearch
}
+finishSearch:
// Join the forward and reverse paths and then append the reverse path.
fwdPath.connect(revPath.point, f)
for i := len(revPath.es) - 1; i >= 0; i-- {
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/internal/flags/flags.go b/constraint/vendor/github.com/google/go-cmp/cmp/internal/flags/flags.go
index a9e7fc0b5..d8e459c9b 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/internal/flags/flags.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/internal/flags/flags.go
@@ -1,6 +1,6 @@
// Copyright 2019, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
package flags
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go b/constraint/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go
index 01aed0a15..82d1d7fbf 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go
@@ -1,6 +1,6 @@
// Copyright 2019, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
// +build !go1.10
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go b/constraint/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go
index c0b667f58..8646f0529 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go
@@ -1,6 +1,6 @@
// Copyright 2019, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
// +build go1.10
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/internal/function/func.go b/constraint/vendor/github.com/google/go-cmp/cmp/internal/function/func.go
index ace1dbe86..d127d4362 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/internal/function/func.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/internal/function/func.go
@@ -1,6 +1,6 @@
// Copyright 2017, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
// Package function provides functionality for identifying function types.
package function
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/name.go b/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/name.go
index 8228e7d51..b6c12cefb 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/name.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/name.go
@@ -1,6 +1,6 @@
// Copyright 2020, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
package value
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go b/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go
index e9e384a1c..44f4a5afd 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go
@@ -1,6 +1,6 @@
// Copyright 2018, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
// +build purego
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go b/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go
index b50c17ec7..a605953d4 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go
@@ -1,6 +1,6 @@
// Copyright 2018, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
// +build !purego
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go b/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go
index 24fbae6e3..98533b036 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go
@@ -1,6 +1,6 @@
// Copyright 2017, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
package value
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go b/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go
index 06a8ffd03..9147a2997 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go
@@ -1,6 +1,6 @@
// Copyright 2017, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
package value
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/options.go b/constraint/vendor/github.com/google/go-cmp/cmp/options.go
index 4b0407a7f..e57b9eb53 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/options.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/options.go
@@ -1,6 +1,6 @@
// Copyright 2017, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
package cmp
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/path.go b/constraint/vendor/github.com/google/go-cmp/cmp/path.go
index 603dbb002..f01eff318 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/path.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/path.go
@@ -1,6 +1,6 @@
// Copyright 2017, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
package cmp
@@ -315,7 +315,7 @@ func (tf Transform) Option() Option { return tf.trans }
// pops the address from the stack. Thus, when traversing into a pointer from
// reflect.Ptr, reflect.Slice element, or reflect.Map, we can detect cycles
// by checking whether the pointer has already been visited. The cycle detection
-// uses a seperate stack for the x and y values.
+// uses a separate stack for the x and y values.
//
// If a cycle is detected we need to determine whether the two pointers
// should be considered equal. The definition of equality chosen by Equal
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/report.go b/constraint/vendor/github.com/google/go-cmp/cmp/report.go
index aafcb3635..f43cd12eb 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/report.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/report.go
@@ -1,6 +1,6 @@
// Copyright 2017, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
package cmp
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/report_compare.go b/constraint/vendor/github.com/google/go-cmp/cmp/report_compare.go
index 9e2180964..104bb3053 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/report_compare.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/report_compare.go
@@ -1,6 +1,6 @@
// Copyright 2019, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
package cmp
@@ -79,7 +79,7 @@ func (opts formatOptions) verbosity() uint {
}
}
-const maxVerbosityPreset = 3
+const maxVerbosityPreset = 6
// verbosityPreset modifies the verbosity settings given an index
// between 0 and maxVerbosityPreset, inclusive.
@@ -100,7 +100,7 @@ func verbosityPreset(opts formatOptions, i int) formatOptions {
func (opts formatOptions) FormatDiff(v *valueNode, ptrs *pointerReferences) (out textNode) {
if opts.DiffMode == diffIdentical {
opts = opts.WithVerbosity(1)
- } else {
+ } else if opts.verbosity() < 3 {
opts = opts.WithVerbosity(3)
}
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/report_references.go b/constraint/vendor/github.com/google/go-cmp/cmp/report_references.go
index d620c2c20..be31b33a9 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/report_references.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/report_references.go
@@ -1,6 +1,6 @@
// Copyright 2020, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
package cmp
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/report_reflect.go b/constraint/vendor/github.com/google/go-cmp/cmp/report_reflect.go
index 786f67126..33f03577f 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/report_reflect.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/report_reflect.go
@@ -1,6 +1,6 @@
// Copyright 2019, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
package cmp
@@ -351,6 +351,8 @@ func formatMapKey(v reflect.Value, disambiguate bool, ptrs *pointerReferences) s
opts.PrintAddresses = disambiguate
opts.AvoidStringer = disambiguate
opts.QualifiedNames = disambiguate
+ opts.VerbosityLevel = maxVerbosityPreset
+ opts.LimitVerbosity = true
s := opts.FormatValue(v, reflect.Map, ptrs).String()
return strings.TrimSpace(s)
}
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/report_slices.go b/constraint/vendor/github.com/google/go-cmp/cmp/report_slices.go
index 35315dad3..2ad3bc85b 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/report_slices.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/report_slices.go
@@ -1,12 +1,13 @@
// Copyright 2019, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
package cmp
import (
"bytes"
"fmt"
+ "math"
"reflect"
"strconv"
"strings"
@@ -26,8 +27,6 @@ func (opts formatOptions) CanFormatDiffSlice(v *valueNode) bool {
return false // No differences detected
case !v.ValueX.IsValid() || !v.ValueY.IsValid():
return false // Both values must be valid
- case v.Type.Kind() == reflect.Slice && (v.ValueX.Len() == 0 || v.ValueY.Len() == 0):
- return false // Both slice values have to be non-empty
case v.NumIgnored > 0:
return false // Some ignore option was used
case v.NumTransformed > 0:
@@ -45,7 +44,16 @@ func (opts formatOptions) CanFormatDiffSlice(v *valueNode) bool {
return false
}
- switch t := v.Type; t.Kind() {
+ // Check whether this is an interface with the same concrete types.
+ t := v.Type
+ vx, vy := v.ValueX, v.ValueY
+ if t.Kind() == reflect.Interface && !vx.IsNil() && !vy.IsNil() && vx.Elem().Type() == vy.Elem().Type() {
+ vx, vy = vx.Elem(), vy.Elem()
+ t = vx.Type()
+ }
+
+ // Check whether we provide specialized diffing for this type.
+ switch t.Kind() {
case reflect.String:
case reflect.Array, reflect.Slice:
// Only slices of primitive types have specialized handling.
@@ -57,6 +65,11 @@ func (opts formatOptions) CanFormatDiffSlice(v *valueNode) bool {
return false
}
+ // Both slice values have to be non-empty.
+ if t.Kind() == reflect.Slice && (vx.Len() == 0 || vy.Len() == 0) {
+ return false
+ }
+
// If a sufficient number of elements already differ,
// use specialized formatting even if length requirement is not met.
if v.NumDiff > v.NumSame {
@@ -68,7 +81,7 @@ func (opts formatOptions) CanFormatDiffSlice(v *valueNode) bool {
// Use specialized string diffing for longer slices or strings.
const minLength = 64
- return v.ValueX.Len() >= minLength && v.ValueY.Len() >= minLength
+ return vx.Len() >= minLength && vy.Len() >= minLength
}
// FormatDiffSlice prints a diff for the slices (or strings) represented by v.
@@ -77,17 +90,23 @@ func (opts formatOptions) CanFormatDiffSlice(v *valueNode) bool {
func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
assert(opts.DiffMode == diffUnknown)
t, vx, vy := v.Type, v.ValueX, v.ValueY
+ if t.Kind() == reflect.Interface {
+ vx, vy = vx.Elem(), vy.Elem()
+ t = vx.Type()
+ opts = opts.WithTypeMode(emitType)
+ }
// Auto-detect the type of the data.
- var isLinedText, isText, isBinary bool
var sx, sy string
+ var ssx, ssy []string
+ var isString, isMostlyText, isPureLinedText, isBinary bool
switch {
case t.Kind() == reflect.String:
sx, sy = vx.String(), vy.String()
- isText = true // Initial estimate, verify later
+ isString = true
case t.Kind() == reflect.Slice && t.Elem() == reflect.TypeOf(byte(0)):
sx, sy = string(vx.Bytes()), string(vy.Bytes())
- isBinary = true // Initial estimate, verify later
+ isString = true
case t.Kind() == reflect.Array:
// Arrays need to be addressable for slice operations to work.
vx2, vy2 := reflect.New(t).Elem(), reflect.New(t).Elem()
@@ -95,13 +114,12 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
vy2.Set(vy)
vx, vy = vx2, vy2
}
- if isText || isBinary {
- var numLines, lastLineIdx, maxLineLen int
- isBinary = !utf8.ValidString(sx) || !utf8.ValidString(sy)
+ if isString {
+ var numTotalRunes, numValidRunes, numLines, lastLineIdx, maxLineLen int
for i, r := range sx + sy {
- if !(unicode.IsPrint(r) || unicode.IsSpace(r)) || r == utf8.RuneError {
- isBinary = true
- break
+ numTotalRunes++
+ if (unicode.IsPrint(r) || unicode.IsSpace(r)) && r != utf8.RuneError {
+ numValidRunes++
}
if r == '\n' {
if maxLineLen < i-lastLineIdx {
@@ -111,8 +129,26 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
numLines++
}
}
- isText = !isBinary
- isLinedText = isText && numLines >= 4 && maxLineLen <= 1024
+ isPureText := numValidRunes == numTotalRunes
+ isMostlyText = float64(numValidRunes) > math.Floor(0.90*float64(numTotalRunes))
+ isPureLinedText = isPureText && numLines >= 4 && maxLineLen <= 1024
+ isBinary = !isMostlyText
+
+ // Avoid diffing by lines if it produces a significantly more complex
+ // edit script than diffing by bytes.
+ if isPureLinedText {
+ ssx = strings.Split(sx, "\n")
+ ssy = strings.Split(sy, "\n")
+ esLines := diff.Difference(len(ssx), len(ssy), func(ix, iy int) diff.Result {
+ return diff.BoolResult(ssx[ix] == ssy[iy])
+ })
+ esBytes := diff.Difference(len(sx), len(sy), func(ix, iy int) diff.Result {
+ return diff.BoolResult(sx[ix] == sy[iy])
+ })
+ efficiencyLines := float64(esLines.Dist()) / float64(len(esLines))
+ efficiencyBytes := float64(esBytes.Dist()) / float64(len(esBytes))
+ isPureLinedText = efficiencyLines < 4*efficiencyBytes
+ }
}
// Format the string into printable records.
@@ -121,9 +157,7 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
switch {
// If the text appears to be multi-lined text,
// then perform differencing across individual lines.
- case isLinedText:
- ssx := strings.Split(sx, "\n")
- ssy := strings.Split(sy, "\n")
+ case isPureLinedText:
list = opts.formatDiffSlice(
reflect.ValueOf(ssx), reflect.ValueOf(ssy), 1, "line",
func(v reflect.Value, d diffMode) textRecord {
@@ -212,7 +246,7 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
// If the text appears to be single-lined text,
// then perform differencing in approximately fixed-sized chunks.
// The output is printed as quoted strings.
- case isText:
+ case isMostlyText:
list = opts.formatDiffSlice(
reflect.ValueOf(sx), reflect.ValueOf(sy), 64, "byte",
func(v reflect.Value, d diffMode) textRecord {
@@ -220,7 +254,6 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
return textRecord{Diff: d, Value: textLine(s)}
},
)
- delim = ""
// If the text appears to be binary data,
// then perform differencing in approximately fixed-sized chunks.
@@ -282,7 +315,7 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
// Wrap the output with appropriate type information.
var out textNode = &textWrap{Prefix: "{", Value: list, Suffix: "}"}
- if !isText {
+ if !isMostlyText {
// The "{...}" byte-sequence literal is not valid Go syntax for strings.
// Emit the type for extra clarity (e.g. "string{...}").
if t.Kind() == reflect.String {
@@ -321,8 +354,11 @@ func (opts formatOptions) formatDiffSlice(
vx, vy reflect.Value, chunkSize int, name string,
makeRec func(reflect.Value, diffMode) textRecord,
) (list textList) {
- es := diff.Difference(vx.Len(), vy.Len(), func(ix int, iy int) diff.Result {
- return diff.BoolResult(vx.Index(ix).Interface() == vy.Index(iy).Interface())
+ eq := func(ix, iy int) bool {
+ return vx.Index(ix).Interface() == vy.Index(iy).Interface()
+ }
+ es := diff.Difference(vx.Len(), vy.Len(), func(ix, iy int) diff.Result {
+ return diff.BoolResult(eq(ix, iy))
})
appendChunks := func(v reflect.Value, d diffMode) int {
@@ -347,6 +383,7 @@ func (opts formatOptions) formatDiffSlice(
groups := coalesceAdjacentEdits(name, es)
groups = coalesceInterveningIdentical(groups, chunkSize/4)
+ groups = cleanupSurroundingIdentical(groups, eq)
maxGroup := diffStats{Name: name}
for i, ds := range groups {
if maxLen >= 0 && numDiffs >= maxLen {
@@ -399,25 +436,36 @@ func (opts formatOptions) formatDiffSlice(
// coalesceAdjacentEdits coalesces the list of edits into groups of adjacent
// equal or unequal counts.
+//
+// Example:
+//
+// Input: "..XXY...Y"
+// Output: [
+// {NumIdentical: 2},
+// {NumRemoved: 2, NumInserted 1},
+// {NumIdentical: 3},
+// {NumInserted: 1},
+// ]
+//
func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats) {
- var prevCase int // Arbitrary index into which case last occurred
- lastStats := func(i int) *diffStats {
- if prevCase != i {
+ var prevMode byte
+ lastStats := func(mode byte) *diffStats {
+ if prevMode != mode {
groups = append(groups, diffStats{Name: name})
- prevCase = i
+ prevMode = mode
}
return &groups[len(groups)-1]
}
for _, e := range es {
switch e {
case diff.Identity:
- lastStats(1).NumIdentical++
+ lastStats('=').NumIdentical++
case diff.UniqueX:
- lastStats(2).NumRemoved++
+ lastStats('!').NumRemoved++
case diff.UniqueY:
- lastStats(2).NumInserted++
+ lastStats('!').NumInserted++
case diff.Modified:
- lastStats(2).NumModified++
+ lastStats('!').NumModified++
}
}
return groups
@@ -427,6 +475,35 @@ func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats)
// equal groups into adjacent unequal groups that currently result in a
// dual inserted/removed printout. This acts as a high-pass filter to smooth
// out high-frequency changes within the windowSize.
+//
+// Example:
+//
+// WindowSize: 16,
+// Input: [
+// {NumIdentical: 61}, // group 0
+// {NumRemoved: 3, NumInserted: 1}, // group 1
+// {NumIdentical: 6}, // ├── coalesce
+// {NumInserted: 2}, // ├── coalesce
+// {NumIdentical: 1}, // ├── coalesce
+// {NumRemoved: 9}, // └── coalesce
+// {NumIdentical: 64}, // group 2
+// {NumRemoved: 3, NumInserted: 1}, // group 3
+// {NumIdentical: 6}, // ├── coalesce
+// {NumInserted: 2}, // ├── coalesce
+// {NumIdentical: 1}, // ├── coalesce
+// {NumRemoved: 7}, // ├── coalesce
+// {NumIdentical: 1}, // ├── coalesce
+// {NumRemoved: 2}, // └── coalesce
+// {NumIdentical: 63}, // group 4
+// ]
+// Output: [
+// {NumIdentical: 61},
+// {NumIdentical: 7, NumRemoved: 12, NumInserted: 3},
+// {NumIdentical: 64},
+// {NumIdentical: 8, NumRemoved: 12, NumInserted: 3},
+// {NumIdentical: 63},
+// ]
+//
func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStats {
groups, groupsOrig := groups[:0], groups
for i, ds := range groupsOrig {
@@ -446,3 +523,91 @@ func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStat
}
return groups
}
+
+// cleanupSurroundingIdentical scans through all unequal groups, and
+// moves any leading sequence of equal elements to the preceding equal group and
+// moves and trailing sequence of equal elements to the succeeding equal group.
+//
+// This is necessary since coalesceInterveningIdentical may coalesce edit groups
+// together such that leading/trailing spans of equal elements becomes possible.
+// Note that this can occur even with an optimal diffing algorithm.
+//
+// Example:
+//
+// Input: [
+// {NumIdentical: 61},
+// {NumIdentical: 1 , NumRemoved: 11, NumInserted: 2}, // assume 3 leading identical elements
+// {NumIdentical: 67},
+// {NumIdentical: 7, NumRemoved: 12, NumInserted: 3}, // assume 10 trailing identical elements
+// {NumIdentical: 54},
+// ]
+// Output: [
+// {NumIdentical: 64}, // incremented by 3
+// {NumRemoved: 9},
+// {NumIdentical: 67},
+// {NumRemoved: 9},
+// {NumIdentical: 64}, // incremented by 10
+// ]
+//
+func cleanupSurroundingIdentical(groups []diffStats, eq func(i, j int) bool) []diffStats {
+ var ix, iy int // indexes into sequence x and y
+ for i, ds := range groups {
+ // Handle equal group.
+ if ds.NumDiff() == 0 {
+ ix += ds.NumIdentical
+ iy += ds.NumIdentical
+ continue
+ }
+
+ // Handle unequal group.
+ nx := ds.NumIdentical + ds.NumRemoved + ds.NumModified
+ ny := ds.NumIdentical + ds.NumInserted + ds.NumModified
+ var numLeadingIdentical, numTrailingIdentical int
+ for i := 0; i < nx && i < ny && eq(ix+i, iy+i); i++ {
+ numLeadingIdentical++
+ }
+ for i := 0; i < nx && i < ny && eq(ix+nx-1-i, iy+ny-1-i); i++ {
+ numTrailingIdentical++
+ }
+ if numIdentical := numLeadingIdentical + numTrailingIdentical; numIdentical > 0 {
+ if numLeadingIdentical > 0 {
+ // Remove leading identical span from this group and
+ // insert it into the preceding group.
+ if i-1 >= 0 {
+ groups[i-1].NumIdentical += numLeadingIdentical
+ } else {
+ // No preceding group exists, so prepend a new group,
+ // but do so after we finish iterating over all groups.
+ defer func() {
+ groups = append([]diffStats{{Name: groups[0].Name, NumIdentical: numLeadingIdentical}}, groups...)
+ }()
+ }
+ // Increment indexes since the preceding group would have handled this.
+ ix += numLeadingIdentical
+ iy += numLeadingIdentical
+ }
+ if numTrailingIdentical > 0 {
+ // Remove trailing identical span from this group and
+ // insert it into the succeeding group.
+ if i+1 < len(groups) {
+ groups[i+1].NumIdentical += numTrailingIdentical
+ } else {
+ // No succeeding group exists, so append a new group,
+ // but do so after we finish iterating over all groups.
+ defer func() {
+ groups = append(groups, diffStats{Name: groups[len(groups)-1].Name, NumIdentical: numTrailingIdentical})
+ }()
+ }
+ // Do not increment indexes since the succeeding group will handle this.
+ }
+
+ // Update this group since some identical elements were removed.
+ nx -= numIdentical
+ ny -= numIdentical
+ groups[i] = diffStats{Name: ds.Name, NumRemoved: nx, NumInserted: ny}
+ }
+ ix += nx
+ iy += ny
+ }
+ return groups
+}
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/report_text.go b/constraint/vendor/github.com/google/go-cmp/cmp/report_text.go
index 8b12c05cd..0fd46d7ff 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/report_text.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/report_text.go
@@ -1,6 +1,6 @@
// Copyright 2019, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
package cmp
diff --git a/constraint/vendor/github.com/google/go-cmp/cmp/report_value.go b/constraint/vendor/github.com/google/go-cmp/cmp/report_value.go
index 83031a7f5..668d470fd 100644
--- a/constraint/vendor/github.com/google/go-cmp/cmp/report_value.go
+++ b/constraint/vendor/github.com/google/go-cmp/cmp/report_value.go
@@ -1,6 +1,6 @@
// Copyright 2019, The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
+// license that can be found in the LICENSE file.
package cmp
diff --git a/constraint/vendor/github.com/google/gofuzz/.travis.yml b/constraint/vendor/github.com/google/gofuzz/.travis.yml
index f8684d99f..061d72ae0 100644
--- a/constraint/vendor/github.com/google/gofuzz/.travis.yml
+++ b/constraint/vendor/github.com/google/gofuzz/.travis.yml
@@ -1,13 +1,10 @@
language: go
go:
- - 1.4
- - 1.3
- - 1.2
- - tip
-
-install:
- - if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
+ - 1.11.x
+ - 1.12.x
+ - 1.13.x
+ - master
script:
- go test -cover
diff --git a/constraint/vendor/github.com/google/gofuzz/CONTRIBUTING.md b/constraint/vendor/github.com/google/gofuzz/CONTRIBUTING.md
index 51cf5cd1a..97c1b34fd 100644
--- a/constraint/vendor/github.com/google/gofuzz/CONTRIBUTING.md
+++ b/constraint/vendor/github.com/google/gofuzz/CONTRIBUTING.md
@@ -1,7 +1,7 @@
# How to contribute #
We'd love to accept your patches and contributions to this project. There are
-a just a few small guidelines you need to follow.
+just a few small guidelines you need to follow.
## Contributor License Agreement ##
diff --git a/constraint/vendor/github.com/google/gofuzz/README.md b/constraint/vendor/github.com/google/gofuzz/README.md
index 386c2a457..b503aae7d 100644
--- a/constraint/vendor/github.com/google/gofuzz/README.md
+++ b/constraint/vendor/github.com/google/gofuzz/README.md
@@ -68,4 +68,22 @@ f.Fuzz(&myObject) // Type will correspond to whether A or B info is set.
See more examples in ```example_test.go```.
+You can use this library for easier [go-fuzz](https://github.com/dvyukov/go-fuzz)ing.
+go-fuzz provides the user a byte-slice, which should be converted to different inputs
+for the tested function. This library can help convert the byte slice. Consider for
+example a fuzz test for a the function `mypackage.MyFunc` that takes an int arguments:
+```go
+// +build gofuzz
+package mypackage
+
+import fuzz "github.com/google/gofuzz"
+
+func Fuzz(data []byte) int {
+ var i int
+ fuzz.NewFromGoFuzz(data).Fuzz(&i)
+ MyFunc(i)
+ return 0
+}
+```
+
Happy testing!
diff --git a/constraint/vendor/github.com/google/gofuzz/bytesource/bytesource.go b/constraint/vendor/github.com/google/gofuzz/bytesource/bytesource.go
new file mode 100644
index 000000000..5bb365949
--- /dev/null
+++ b/constraint/vendor/github.com/google/gofuzz/bytesource/bytesource.go
@@ -0,0 +1,81 @@
+/*
+Copyright 2014 Google Inc. 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.
+*/
+
+// Package bytesource provides a rand.Source64 that is determined by a slice of bytes.
+package bytesource
+
+import (
+ "bytes"
+ "encoding/binary"
+ "io"
+ "math/rand"
+)
+
+// ByteSource implements rand.Source64 determined by a slice of bytes. The random numbers are
+// generated from each 8 bytes in the slice, until the last bytes are consumed, from which a
+// fallback pseudo random source is created in case more random numbers are required.
+// It also exposes a `bytes.Reader` API, which lets callers consume the bytes directly.
+type ByteSource struct {
+ *bytes.Reader
+ fallback rand.Source
+}
+
+// New returns a new ByteSource from a given slice of bytes.
+func New(input []byte) *ByteSource {
+ s := &ByteSource{
+ Reader: bytes.NewReader(input),
+ fallback: rand.NewSource(0),
+ }
+ if len(input) > 0 {
+ s.fallback = rand.NewSource(int64(s.consumeUint64()))
+ }
+ return s
+}
+
+func (s *ByteSource) Uint64() uint64 {
+ // Return from input if it was not exhausted.
+ if s.Len() > 0 {
+ return s.consumeUint64()
+ }
+
+ // Input was exhausted, return random number from fallback (in this case fallback should not be
+ // nil). Try first having a Uint64 output (Should work in current rand implementation),
+ // otherwise return a conversion of Int63.
+ if s64, ok := s.fallback.(rand.Source64); ok {
+ return s64.Uint64()
+ }
+ return uint64(s.fallback.Int63())
+}
+
+func (s *ByteSource) Int63() int64 {
+ return int64(s.Uint64() >> 1)
+}
+
+func (s *ByteSource) Seed(seed int64) {
+ s.fallback = rand.NewSource(seed)
+ s.Reader = bytes.NewReader(nil)
+}
+
+// consumeUint64 reads 8 bytes from the input and convert them to a uint64. It assumes that the the
+// bytes reader is not empty.
+func (s *ByteSource) consumeUint64() uint64 {
+ var bytes [8]byte
+ _, err := s.Read(bytes[:])
+ if err != nil && err != io.EOF {
+ panic("failed reading source") // Should not happen.
+ }
+ return binary.BigEndian.Uint64(bytes[:])
+}
diff --git a/constraint/vendor/github.com/google/gofuzz/fuzz.go b/constraint/vendor/github.com/google/gofuzz/fuzz.go
index da0a5f938..761520a8c 100644
--- a/constraint/vendor/github.com/google/gofuzz/fuzz.go
+++ b/constraint/vendor/github.com/google/gofuzz/fuzz.go
@@ -22,6 +22,9 @@ import (
"reflect"
"regexp"
"time"
+
+ "github.com/google/gofuzz/bytesource"
+ "strings"
)
// fuzzFuncMap is a map from a type to a fuzzFunc that handles that type.
@@ -61,6 +64,34 @@ func NewWithSeed(seed int64) *Fuzzer {
return f
}
+// NewFromGoFuzz is a helper function that enables using gofuzz (this
+// project) with go-fuzz (https://github.com/dvyukov/go-fuzz) for continuous
+// fuzzing. Essentially, it enables translating the fuzzing bytes from
+// go-fuzz to any Go object using this library.
+//
+// This implementation promises a constant translation from a given slice of
+// bytes to the fuzzed objects. This promise will remain over future
+// versions of Go and of this library.
+//
+// Note: the returned Fuzzer should not be shared between multiple goroutines,
+// as its deterministic output will no longer be available.
+//
+// Example: use go-fuzz to test the function `MyFunc(int)` in the package
+// `mypackage`. Add the file: "mypacakge_fuzz.go" with the content:
+//
+// // +build gofuzz
+// package mypacakge
+// import fuzz "github.com/google/gofuzz"
+// func Fuzz(data []byte) int {
+// var i int
+// fuzz.NewFromGoFuzz(data).Fuzz(&i)
+// MyFunc(i)
+// return 0
+// }
+func NewFromGoFuzz(data []byte) *Fuzzer {
+ return New().RandSource(bytesource.New(data))
+}
+
// Funcs adds each entry in fuzzFuncs as a custom fuzzing function.
//
// Each entry in fuzzFuncs must be a function taking two parameters.
@@ -141,7 +172,7 @@ func (f *Fuzzer) genElementCount() int {
}
func (f *Fuzzer) genShouldFill() bool {
- return f.r.Float64() > f.nilChance
+ return f.r.Float64() >= f.nilChance
}
// MaxDepth sets the maximum number of recursive fuzz calls that will be made
@@ -240,6 +271,7 @@ func (fc *fuzzerContext) doFuzz(v reflect.Value, flags uint64) {
fn(v, fc.fuzzer.r)
return
}
+
switch v.Kind() {
case reflect.Map:
if fc.fuzzer.genShouldFill() {
@@ -450,10 +482,10 @@ var fillFuncMap = map[reflect.Kind]func(reflect.Value, *rand.Rand){
v.SetFloat(r.Float64())
},
reflect.Complex64: func(v reflect.Value, r *rand.Rand) {
- panic("unimplemented")
+ v.SetComplex(complex128(complex(r.Float32(), r.Float32())))
},
reflect.Complex128: func(v reflect.Value, r *rand.Rand) {
- panic("unimplemented")
+ v.SetComplex(complex(r.Float64(), r.Float64()))
},
reflect.String: func(v reflect.Value, r *rand.Rand) {
v.SetString(randString(r))
@@ -465,38 +497,105 @@ var fillFuncMap = map[reflect.Kind]func(reflect.Value, *rand.Rand){
// randBool returns true or false randomly.
func randBool(r *rand.Rand) bool {
- if r.Int()&1 == 1 {
- return true
- }
- return false
+ return r.Int31()&(1<<30) == 0
+}
+
+type int63nPicker interface {
+ Int63n(int64) int64
}
-type charRange struct {
- first, last rune
+// UnicodeRange describes a sequential range of unicode characters.
+// Last must be numerically greater than First.
+type UnicodeRange struct {
+ First, Last rune
}
+// UnicodeRanges describes an arbitrary number of sequential ranges of unicode characters.
+// To be useful, each range must have at least one character (First <= Last) and
+// there must be at least one range.
+type UnicodeRanges []UnicodeRange
+
// choose returns a random unicode character from the given range, using the
// given randomness source.
-func (r *charRange) choose(rand *rand.Rand) rune {
- count := int64(r.last - r.first)
- return r.first + rune(rand.Int63n(count))
+func (ur UnicodeRange) choose(r int63nPicker) rune {
+ count := int64(ur.Last - ur.First + 1)
+ return ur.First + rune(r.Int63n(count))
+}
+
+// CustomStringFuzzFunc constructs a FuzzFunc which produces random strings.
+// Each character is selected from the range ur. If there are no characters
+// in the range (cr.Last < cr.First), this will panic.
+func (ur UnicodeRange) CustomStringFuzzFunc() func(s *string, c Continue) {
+ ur.check()
+ return func(s *string, c Continue) {
+ *s = ur.randString(c.Rand)
+ }
}
-var unicodeRanges = []charRange{
+// check is a function that used to check whether the first of ur(UnicodeRange)
+// is greater than the last one.
+func (ur UnicodeRange) check() {
+ if ur.Last < ur.First {
+ panic("The last encoding must be greater than the first one.")
+ }
+}
+
+// randString of UnicodeRange makes a random string up to 20 characters long.
+// Each character is selected form ur(UnicodeRange).
+func (ur UnicodeRange) randString(r *rand.Rand) string {
+ n := r.Intn(20)
+ sb := strings.Builder{}
+ sb.Grow(n)
+ for i := 0; i < n; i++ {
+ sb.WriteRune(ur.choose(r))
+ }
+ return sb.String()
+}
+
+// defaultUnicodeRanges sets a default unicode range when user do not set
+// CustomStringFuzzFunc() but wants fuzz string.
+var defaultUnicodeRanges = UnicodeRanges{
{' ', '~'}, // ASCII characters
{'\u00a0', '\u02af'}, // Multi-byte encoded characters
{'\u4e00', '\u9fff'}, // Common CJK (even longer encodings)
}
+// CustomStringFuzzFunc constructs a FuzzFunc which produces random strings.
+// Each character is selected from one of the ranges of ur(UnicodeRanges).
+// Each range has an equal probability of being chosen. If there are no ranges,
+// or a selected range has no characters (.Last < .First), this will panic.
+// Do not modify any of the ranges in ur after calling this function.
+func (ur UnicodeRanges) CustomStringFuzzFunc() func(s *string, c Continue) {
+ // Check unicode ranges slice is empty.
+ if len(ur) == 0 {
+ panic("UnicodeRanges is empty.")
+ }
+ // if not empty, each range should be checked.
+ for i := range ur {
+ ur[i].check()
+ }
+ return func(s *string, c Continue) {
+ *s = ur.randString(c.Rand)
+ }
+}
+
+// randString of UnicodeRanges makes a random string up to 20 characters long.
+// Each character is selected form one of the ranges of ur(UnicodeRanges),
+// and each range has an equal probability of being chosen.
+func (ur UnicodeRanges) randString(r *rand.Rand) string {
+ n := r.Intn(20)
+ sb := strings.Builder{}
+ sb.Grow(n)
+ for i := 0; i < n; i++ {
+ sb.WriteRune(ur[r.Intn(len(ur))].choose(r))
+ }
+ return sb.String()
+}
+
// randString makes a random string up to 20 characters long. The returned string
// may include a variety of (valid) UTF-8 encodings.
func randString(r *rand.Rand) string {
- n := r.Intn(20)
- runes := make([]rune, n)
- for i := range runes {
- runes[i] = unicodeRanges[r.Intn(len(unicodeRanges))].choose(r)
- }
- return string(runes)
+ return defaultUnicodeRanges.randString(r)
}
// randUint64 makes random 64 bit numbers.
diff --git a/constraint/vendor/github.com/imdario/mergo/.travis.yml b/constraint/vendor/github.com/imdario/mergo/.travis.yml
index dad29725f..d324c43ba 100644
--- a/constraint/vendor/github.com/imdario/mergo/.travis.yml
+++ b/constraint/vendor/github.com/imdario/mergo/.travis.yml
@@ -1,4 +1,7 @@
language: go
+arch:
+ - amd64
+ - ppc64le
install:
- go get -t
- go get golang.org/x/tools/cmd/cover
diff --git a/constraint/vendor/github.com/imdario/mergo/README.md b/constraint/vendor/github.com/imdario/mergo/README.md
index 075b4d78e..aa8cbd7ce 100644
--- a/constraint/vendor/github.com/imdario/mergo/README.md
+++ b/constraint/vendor/github.com/imdario/mergo/README.md
@@ -1,14 +1,5 @@
# Mergo
-A helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements.
-
-Mergo merges same-type structs and maps by setting default values in zero-value fields. Mergo won't merge unexported (private) fields. It will do recursively any exported one. It also won't merge structs inside maps (because they are not addressable using Go reflection).
-
-Also a lovely [comune](http://en.wikipedia.org/wiki/Mergo) (municipality) in the Province of Ancona in the Italian region of Marche.
-
-## Status
-
-It is ready for production use. [It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, etc](https://github.com/imdario/mergo#mergo-in-the-wild).
[![GoDoc][3]][4]
[![GitHub release][5]][6]
@@ -16,7 +7,9 @@ It is ready for production use. [It is used in several projects by Docker, Googl
[![Build Status][1]][2]
[![Coverage Status][9]][10]
[![Sourcegraph][11]][12]
-[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fimdario%2Fmergo.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_shield)
+[![FOSSA Status][13]][14]
+
+[![GoCenter Kudos][15]][16]
[1]: https://travis-ci.org/imdario/mergo.png
[2]: https://travis-ci.org/imdario/mergo
@@ -30,6 +23,20 @@ It is ready for production use. [It is used in several projects by Docker, Googl
[10]: https://coveralls.io/github/imdario/mergo?branch=master
[11]: https://sourcegraph.com/github.com/imdario/mergo/-/badge.svg
[12]: https://sourcegraph.com/github.com/imdario/mergo?badge
+[13]: https://app.fossa.io/api/projects/git%2Bgithub.com%2Fimdario%2Fmergo.svg?type=shield
+[14]: https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_shield
+[15]: https://search.gocenter.io/api/ui/badge/github.com%2Fimdario%2Fmergo
+[16]: https://search.gocenter.io/github.com/imdario/mergo
+
+A helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements.
+
+Mergo merges same-type structs and maps by setting default values in zero-value fields. Mergo won't merge unexported (private) fields. It will do recursively any exported one. It also won't merge structs inside maps (because they are not addressable using Go reflection).
+
+Also a lovely [comune](http://en.wikipedia.org/wiki/Mergo) (municipality) in the Province of Ancona in the Italian region of Marche.
+
+## Status
+
+It is ready for production use. [It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, etc](https://github.com/imdario/mergo#mergo-in-the-wild).
### Important note
@@ -90,7 +97,7 @@ If Mergo is useful to you, consider buying me a coffee, a beer, or making a mont
- [mantasmatelis/whooplist-server](https://github.com/mantasmatelis/whooplist-server)
- [jnuthong/item_search](https://github.com/jnuthong/item_search)
- [bukalapak/snowboard](https://github.com/bukalapak/snowboard)
-- [janoszen/containerssh](https://github.com/janoszen/containerssh)
+- [containerssh/containerssh](https://github.com/containerssh/containerssh)
## Install
diff --git a/constraint/vendor/github.com/imdario/mergo/merge.go b/constraint/vendor/github.com/imdario/mergo/merge.go
index 11a8c156d..8c2a8fcd9 100644
--- a/constraint/vendor/github.com/imdario/mergo/merge.go
+++ b/constraint/vendor/github.com/imdario/mergo/merge.go
@@ -95,13 +95,18 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
}
}
} else {
- if (isReflectNil(dst) || overwrite) && (!isEmptyValue(src) || overwriteWithEmptySrc) {
+ if dst.CanSet() && (isReflectNil(dst) || overwrite) && (!isEmptyValue(src) || overwriteWithEmptySrc) {
dst.Set(src)
}
}
case reflect.Map:
if dst.IsNil() && !src.IsNil() {
- dst.Set(reflect.MakeMap(dst.Type()))
+ if dst.CanSet() {
+ dst.Set(reflect.MakeMap(dst.Type()))
+ } else {
+ dst = src
+ return
+ }
}
if src.Kind() != reflect.Map {
@@ -271,11 +276,6 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
}
default:
mustSet := (isEmptyValue(dst) || overwrite) && (!isEmptyValue(src) || overwriteWithEmptySrc)
- v := fmt.Sprintf("%v", src)
- if v == "TestIssue106" {
- fmt.Println(mustSet)
- fmt.Println(dst.CanSet())
- }
if mustSet {
if dst.CanSet() {
dst.Set(src)
diff --git a/constraint/vendor/github.com/josharian/intern/README.md b/constraint/vendor/github.com/josharian/intern/README.md
new file mode 100644
index 000000000..ffc44b219
--- /dev/null
+++ b/constraint/vendor/github.com/josharian/intern/README.md
@@ -0,0 +1,5 @@
+Docs: https://godoc.org/github.com/josharian/intern
+
+See also [Go issue 5160](https://golang.org/issue/5160).
+
+License: MIT
diff --git a/constraint/vendor/github.com/josharian/intern/go.mod b/constraint/vendor/github.com/josharian/intern/go.mod
new file mode 100644
index 000000000..f2262ff0d
--- /dev/null
+++ b/constraint/vendor/github.com/josharian/intern/go.mod
@@ -0,0 +1,3 @@
+module github.com/josharian/intern
+
+go 1.5
diff --git a/constraint/vendor/github.com/josharian/intern/intern.go b/constraint/vendor/github.com/josharian/intern/intern.go
new file mode 100644
index 000000000..7acb1fe90
--- /dev/null
+++ b/constraint/vendor/github.com/josharian/intern/intern.go
@@ -0,0 +1,44 @@
+// Package intern interns strings.
+// Interning is best effort only.
+// Interned strings may be removed automatically
+// at any time without notification.
+// All functions may be called concurrently
+// with themselves and each other.
+package intern
+
+import "sync"
+
+var (
+ pool sync.Pool = sync.Pool{
+ New: func() interface{} {
+ return make(map[string]string)
+ },
+ }
+)
+
+// String returns s, interned.
+func String(s string) string {
+ m := pool.Get().(map[string]string)
+ c, ok := m[s]
+ if ok {
+ pool.Put(m)
+ return c
+ }
+ m[s] = s
+ pool.Put(m)
+ return s
+}
+
+// Bytes returns b converted to a string, interned.
+func Bytes(b []byte) string {
+ m := pool.Get().(map[string]string)
+ c, ok := m[string(b)]
+ if ok {
+ pool.Put(m)
+ return c
+ }
+ s := string(b)
+ m[s] = s
+ pool.Put(m)
+ return s
+}
diff --git a/constraint/vendor/github.com/josharian/intern/license.md b/constraint/vendor/github.com/josharian/intern/license.md
new file mode 100644
index 000000000..353d3055f
--- /dev/null
+++ b/constraint/vendor/github.com/josharian/intern/license.md
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Josh Bleecher Snyder
+
+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/constraint/vendor/github.com/json-iterator/go/go.sum b/constraint/vendor/github.com/json-iterator/go/go.sum
index d778b5a14..be00a6df9 100644
--- a/constraint/vendor/github.com/json-iterator/go/go.sum
+++ b/constraint/vendor/github.com/json-iterator/go/go.sum
@@ -9,6 +9,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLD
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
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/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
diff --git a/constraint/vendor/github.com/json-iterator/go/iter_float.go b/constraint/vendor/github.com/json-iterator/go/iter_float.go
index b9754638e..8a3d8b6fb 100644
--- a/constraint/vendor/github.com/json-iterator/go/iter_float.go
+++ b/constraint/vendor/github.com/json-iterator/go/iter_float.go
@@ -288,6 +288,9 @@ non_decimal_loop:
return iter.readFloat64SlowPath()
}
value = (value << 3) + (value << 1) + uint64(ind)
+ if value > maxFloat64 {
+ return iter.readFloat64SlowPath()
+ }
}
}
return iter.readFloat64SlowPath()
diff --git a/constraint/vendor/github.com/json-iterator/go/iter_int.go b/constraint/vendor/github.com/json-iterator/go/iter_int.go
index 214232035..d786a89fe 100644
--- a/constraint/vendor/github.com/json-iterator/go/iter_int.go
+++ b/constraint/vendor/github.com/json-iterator/go/iter_int.go
@@ -9,6 +9,7 @@ var intDigits []int8
const uint32SafeToMultiply10 = uint32(0xffffffff)/10 - 1
const uint64SafeToMultiple10 = uint64(0xffffffffffffffff)/10 - 1
+const maxFloat64 = 1<<53 - 1
func init() {
intDigits = make([]int8, 256)
@@ -339,7 +340,7 @@ func (iter *Iterator) readUint64(c byte) (ret uint64) {
}
func (iter *Iterator) assertInteger() {
- if iter.head < len(iter.buf) && iter.buf[iter.head] == '.' {
+ if iter.head < iter.tail && iter.buf[iter.head] == '.' {
iter.ReportError("assertInteger", "can not decode float as int")
}
}
diff --git a/constraint/vendor/github.com/json-iterator/go/reflect.go b/constraint/vendor/github.com/json-iterator/go/reflect.go
index 74974ba74..39acb320a 100644
--- a/constraint/vendor/github.com/json-iterator/go/reflect.go
+++ b/constraint/vendor/github.com/json-iterator/go/reflect.go
@@ -65,7 +65,7 @@ func (iter *Iterator) ReadVal(obj interface{}) {
decoder := iter.cfg.getDecoderFromCache(cacheKey)
if decoder == nil {
typ := reflect2.TypeOf(obj)
- if typ.Kind() != reflect.Ptr {
+ if typ == nil || typ.Kind() != reflect.Ptr {
iter.ReportError("ReadVal", "can only unmarshal into pointer")
return
}
diff --git a/constraint/vendor/github.com/json-iterator/go/reflect_json_raw_message.go b/constraint/vendor/github.com/json-iterator/go/reflect_json_raw_message.go
index f2619936c..eba434f2f 100644
--- a/constraint/vendor/github.com/json-iterator/go/reflect_json_raw_message.go
+++ b/constraint/vendor/github.com/json-iterator/go/reflect_json_raw_message.go
@@ -33,11 +33,19 @@ type jsonRawMessageCodec struct {
}
func (codec *jsonRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
- *((*json.RawMessage)(ptr)) = json.RawMessage(iter.SkipAndReturnBytes())
+ if iter.ReadNil() {
+ *((*json.RawMessage)(ptr)) = nil
+ } else {
+ *((*json.RawMessage)(ptr)) = iter.SkipAndReturnBytes()
+ }
}
func (codec *jsonRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
- stream.WriteRaw(string(*((*json.RawMessage)(ptr))))
+ if *((*json.RawMessage)(ptr)) == nil {
+ stream.WriteNil()
+ } else {
+ stream.WriteRaw(string(*((*json.RawMessage)(ptr))))
+ }
}
func (codec *jsonRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
@@ -48,11 +56,19 @@ type jsoniterRawMessageCodec struct {
}
func (codec *jsoniterRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
- *((*RawMessage)(ptr)) = RawMessage(iter.SkipAndReturnBytes())
+ if iter.ReadNil() {
+ *((*RawMessage)(ptr)) = nil
+ } else {
+ *((*RawMessage)(ptr)) = iter.SkipAndReturnBytes()
+ }
}
func (codec *jsoniterRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
- stream.WriteRaw(string(*((*RawMessage)(ptr))))
+ if *((*RawMessage)(ptr)) == nil {
+ stream.WriteNil()
+ } else {
+ stream.WriteRaw(string(*((*RawMessage)(ptr))))
+ }
}
func (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
diff --git a/constraint/vendor/github.com/json-iterator/go/reflect_struct_decoder.go b/constraint/vendor/github.com/json-iterator/go/reflect_struct_decoder.go
index d7eb0eb5c..92ae912dc 100644
--- a/constraint/vendor/github.com/json-iterator/go/reflect_struct_decoder.go
+++ b/constraint/vendor/github.com/json-iterator/go/reflect_struct_decoder.go
@@ -1075,6 +1075,11 @@ type stringModeNumberDecoder struct {
}
func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+ if iter.WhatIsNext() == NilValue {
+ decoder.elemDecoder.Decode(ptr, iter)
+ return
+ }
+
c := iter.nextToken()
if c != '"' {
iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c}))
diff --git a/constraint/vendor/github.com/mailru/easyjson/buffer/pool.go b/constraint/vendor/github.com/mailru/easyjson/buffer/pool.go
index 07fb4bc1f..598a54af9 100644
--- a/constraint/vendor/github.com/mailru/easyjson/buffer/pool.go
+++ b/constraint/vendor/github.com/mailru/easyjson/buffer/pool.go
@@ -4,6 +4,7 @@ package buffer
import (
"io"
+ "net"
"sync"
)
@@ -52,14 +53,12 @@ func putBuf(buf []byte) {
// getBuf gets a chunk from reuse pool or creates a new one if reuse failed.
func getBuf(size int) []byte {
- if size < config.PooledSize {
- return make([]byte, 0, size)
- }
-
- if c := buffers[size]; c != nil {
- v := c.Get()
- if v != nil {
- return v.([]byte)
+ if size >= config.PooledSize {
+ if c := buffers[size]; c != nil {
+ v := c.Get()
+ if v != nil {
+ return v.([]byte)
+ }
}
}
return make([]byte, 0, size)
@@ -78,9 +77,12 @@ type Buffer struct {
// EnsureSpace makes sure that the current chunk contains at least s free bytes,
// possibly creating a new chunk.
func (b *Buffer) EnsureSpace(s int) {
- if cap(b.Buf)-len(b.Buf) >= s {
- return
+ if cap(b.Buf)-len(b.Buf) < s {
+ b.ensureSpaceSlow(s)
}
+}
+
+func (b *Buffer) ensureSpaceSlow(s int) {
l := len(b.Buf)
if l > 0 {
if cap(b.toPool) != cap(b.Buf) {
@@ -105,18 +107,22 @@ func (b *Buffer) EnsureSpace(s int) {
// AppendByte appends a single byte to buffer.
func (b *Buffer) AppendByte(data byte) {
- if cap(b.Buf) == len(b.Buf) { // EnsureSpace won't be inlined.
- b.EnsureSpace(1)
- }
+ b.EnsureSpace(1)
b.Buf = append(b.Buf, data)
}
// AppendBytes appends a byte slice to buffer.
func (b *Buffer) AppendBytes(data []byte) {
+ if len(data) <= cap(b.Buf)-len(b.Buf) {
+ b.Buf = append(b.Buf, data...) // fast path
+ } else {
+ b.appendBytesSlow(data)
+ }
+}
+
+func (b *Buffer) appendBytesSlow(data []byte) {
for len(data) > 0 {
- if cap(b.Buf) == len(b.Buf) { // EnsureSpace won't be inlined.
- b.EnsureSpace(1)
- }
+ b.EnsureSpace(1)
sz := cap(b.Buf) - len(b.Buf)
if sz > len(data) {
@@ -128,12 +134,18 @@ func (b *Buffer) AppendBytes(data []byte) {
}
}
-// AppendBytes appends a string to buffer.
+// AppendString appends a string to buffer.
func (b *Buffer) AppendString(data string) {
+ if len(data) <= cap(b.Buf)-len(b.Buf) {
+ b.Buf = append(b.Buf, data...) // fast path
+ } else {
+ b.appendStringSlow(data)
+ }
+}
+
+func (b *Buffer) appendStringSlow(data string) {
for len(data) > 0 {
- if cap(b.Buf) == len(b.Buf) { // EnsureSpace won't be inlined.
- b.EnsureSpace(1)
- }
+ b.EnsureSpace(1)
sz := cap(b.Buf) - len(b.Buf)
if sz > len(data) {
@@ -156,18 +168,14 @@ func (b *Buffer) Size() int {
// DumpTo outputs the contents of a buffer to a writer and resets the buffer.
func (b *Buffer) DumpTo(w io.Writer) (written int, err error) {
- var n int
- for _, buf := range b.bufs {
- if err == nil {
- n, err = w.Write(buf)
- written += n
- }
- putBuf(buf)
+ bufs := net.Buffers(b.bufs)
+ if len(b.Buf) > 0 {
+ bufs = append(bufs, b.Buf)
}
+ n, err := bufs.WriteTo(w)
- if err == nil {
- n, err = w.Write(b.Buf)
- written += n
+ for _, buf := range b.bufs {
+ putBuf(buf)
}
putBuf(b.toPool)
@@ -175,7 +183,7 @@ func (b *Buffer) DumpTo(w io.Writer) (written int, err error) {
b.Buf = nil
b.toPool = nil
- return
+ return int(n), err
}
// BuildBytes creates a single byte slice with all the contents of the buffer. Data is
@@ -192,7 +200,7 @@ func (b *Buffer) BuildBytes(reuse ...[]byte) []byte {
var ret []byte
size := b.Size()
- // If we got a buffer as argument and it is big enought, reuse it.
+ // If we got a buffer as argument and it is big enough, reuse it.
if len(reuse) == 1 && cap(reuse[0]) >= size {
ret = reuse[0][:0]
} else {
diff --git a/constraint/vendor/github.com/mailru/easyjson/jlexer/lexer.go b/constraint/vendor/github.com/mailru/easyjson/jlexer/lexer.go
index ddd376b84..b5f5e2613 100644
--- a/constraint/vendor/github.com/mailru/easyjson/jlexer/lexer.go
+++ b/constraint/vendor/github.com/mailru/easyjson/jlexer/lexer.go
@@ -5,6 +5,7 @@
package jlexer
import (
+ "bytes"
"encoding/base64"
"encoding/json"
"errors"
@@ -14,6 +15,8 @@ import (
"unicode"
"unicode/utf16"
"unicode/utf8"
+
+ "github.com/josharian/intern"
)
// tokenKind determines type of a token.
@@ -32,9 +35,10 @@ const (
type token struct {
kind tokenKind // Type of a token.
- boolValue bool // Value if a boolean literal token.
- byteValue []byte // Raw value of a token.
- delimValue byte
+ boolValue bool // Value if a boolean literal token.
+ byteValueCloned bool // true if byteValue was allocated and does not refer to original json body
+ byteValue []byte // Raw value of a token.
+ delimValue byte
}
// Lexer is a JSON lexer: it iterates over JSON tokens in a byte slice.
@@ -240,23 +244,65 @@ func (r *Lexer) fetchNumber() {
// findStringLen tries to scan into the string literal for ending quote char to determine required size.
// The size will be exact if no escapes are present and may be inexact if there are escaped chars.
-func findStringLen(data []byte) (isValid, hasEscapes bool, length int) {
- delta := 0
-
- for i := 0; i < len(data); i++ {
- switch data[i] {
- case '\\':
- i++
- delta++
- if i < len(data) && data[i] == 'u' {
- delta++
- }
- case '"':
- return true, (delta > 0), (i - delta)
+func findStringLen(data []byte) (isValid bool, length int) {
+ for {
+ idx := bytes.IndexByte(data, '"')
+ if idx == -1 {
+ return false, len(data)
+ }
+ if idx == 0 || (idx > 0 && data[idx-1] != '\\') {
+ return true, length + idx
+ }
+
+ // count \\\\\\\ sequences. even number of slashes means quote is not really escaped
+ cnt := 1
+ for idx-cnt-1 >= 0 && data[idx-cnt-1] == '\\' {
+ cnt++
+ }
+ if cnt%2 == 0 {
+ return true, length + idx
+ }
+
+ length += idx + 1
+ data = data[idx+1:]
+ }
+}
+
+// unescapeStringToken performs unescaping of string token.
+// if no escaping is needed, original string is returned, otherwise - a new one allocated
+func (r *Lexer) unescapeStringToken() (err error) {
+ data := r.token.byteValue
+ var unescapedData []byte
+
+ for {
+ i := bytes.IndexByte(data, '\\')
+ if i == -1 {
+ break
+ }
+
+ escapedRune, escapedBytes, err := decodeEscape(data[i:])
+ if err != nil {
+ r.errParse(err.Error())
+ return err
+ }
+
+ if unescapedData == nil {
+ unescapedData = make([]byte, 0, len(r.token.byteValue))
}
+
+ var d [4]byte
+ s := utf8.EncodeRune(d[:], escapedRune)
+ unescapedData = append(unescapedData, data[:i]...)
+ unescapedData = append(unescapedData, d[:s]...)
+
+ data = data[i+escapedBytes:]
}
- return false, false, len(data)
+ if unescapedData != nil {
+ r.token.byteValue = append(unescapedData, data...)
+ r.token.byteValueCloned = true
+ }
+ return
}
// getu4 decodes \uXXXX from the beginning of s, returning the hex value,
@@ -286,36 +332,30 @@ func getu4(s []byte) rune {
return val
}
-// processEscape processes a single escape sequence and returns number of bytes processed.
-func (r *Lexer) processEscape(data []byte) (int, error) {
+// decodeEscape processes a single escape sequence and returns number of bytes processed.
+func decodeEscape(data []byte) (decoded rune, bytesProcessed int, err error) {
if len(data) < 2 {
- return 0, fmt.Errorf("syntax error at %v", string(data))
+ return 0, 0, errors.New("incorrect escape symbol \\ at the end of token")
}
c := data[1]
switch c {
case '"', '/', '\\':
- r.token.byteValue = append(r.token.byteValue, c)
- return 2, nil
+ return rune(c), 2, nil
case 'b':
- r.token.byteValue = append(r.token.byteValue, '\b')
- return 2, nil
+ return '\b', 2, nil
case 'f':
- r.token.byteValue = append(r.token.byteValue, '\f')
- return 2, nil
+ return '\f', 2, nil
case 'n':
- r.token.byteValue = append(r.token.byteValue, '\n')
- return 2, nil
+ return '\n', 2, nil
case 'r':
- r.token.byteValue = append(r.token.byteValue, '\r')
- return 2, nil
+ return '\r', 2, nil
case 't':
- r.token.byteValue = append(r.token.byteValue, '\t')
- return 2, nil
+ return '\t', 2, nil
case 'u':
rr := getu4(data)
if rr < 0 {
- return 0, errors.New("syntax error")
+ return 0, 0, errors.New("incorrectly escaped \\uXXXX sequence")
}
read := 6
@@ -328,13 +368,10 @@ func (r *Lexer) processEscape(data []byte) (int, error) {
rr = unicode.ReplacementChar
}
}
- var d [4]byte
- s := utf8.EncodeRune(d[:], rr)
- r.token.byteValue = append(r.token.byteValue, d[:s]...)
- return read, nil
+ return rr, read, nil
}
- return 0, errors.New("syntax error")
+ return 0, 0, errors.New("incorrectly escaped bytes")
}
// fetchString scans a string literal token.
@@ -342,43 +379,14 @@ func (r *Lexer) fetchString() {
r.pos++
data := r.Data[r.pos:]
- isValid, hasEscapes, length := findStringLen(data)
+ isValid, length := findStringLen(data)
if !isValid {
r.pos += length
r.errParse("unterminated string literal")
return
}
- if !hasEscapes {
- r.token.byteValue = data[:length]
- r.pos += length + 1
- return
- }
-
- r.token.byteValue = make([]byte, 0, length)
- p := 0
- for i := 0; i < len(data); {
- switch data[i] {
- case '"':
- r.pos += i + 1
- r.token.byteValue = append(r.token.byteValue, data[p:i]...)
- i++
- return
-
- case '\\':
- r.token.byteValue = append(r.token.byteValue, data[p:i]...)
- off, err := r.processEscape(data[i:])
- if err != nil {
- r.errParse(err.Error())
- return
- }
- i += off
- p = i
-
- default:
- i++
- }
- }
- r.errParse("unterminated string literal")
+ r.token.byteValue = data[:length]
+ r.pos += length + 1 // skip closing '"' as well
}
// scanToken scans the next token if no token is currently available in the lexer.
@@ -393,6 +401,7 @@ func (r *Lexer) scanToken() {
// consume resets the current token to allow scanning the next one.
func (r *Lexer) consume() {
r.token.kind = tokenUndef
+ r.token.byteValueCloned = false
r.token.delimValue = 0
}
@@ -520,6 +529,7 @@ func (r *Lexer) Skip() {
func (r *Lexer) SkipRecursive() {
r.scanToken()
var start, end byte
+ startPos := r.start
switch r.token.delimValue {
case '{':
@@ -545,6 +555,14 @@ func (r *Lexer) SkipRecursive() {
level--
if level == 0 {
r.pos += i + 1
+ if !json.Valid(r.Data[startPos:r.pos]) {
+ r.pos = len(r.Data)
+ r.fatalError = &LexerError{
+ Reason: "skipped array/object json value is invalid",
+ Offset: r.pos,
+ Data: string(r.Data[r.pos:]),
+ }
+ }
return
}
case c == '\\' && inQuotes:
@@ -602,7 +620,7 @@ func (r *Lexer) Consumed() {
}
}
-func (r *Lexer) unsafeString() (string, []byte) {
+func (r *Lexer) unsafeString(skipUnescape bool) (string, []byte) {
if r.token.kind == tokenUndef && r.Ok() {
r.FetchToken()
}
@@ -610,6 +628,13 @@ func (r *Lexer) unsafeString() (string, []byte) {
r.errInvalidToken("string")
return "", nil
}
+ if !skipUnescape {
+ if err := r.unescapeStringToken(); err != nil {
+ r.errInvalidToken("string")
+ return "", nil
+ }
+ }
+
bytes := r.token.byteValue
ret := bytesToStr(r.token.byteValue)
r.consume()
@@ -621,13 +646,19 @@ func (r *Lexer) unsafeString() (string, []byte) {
// Warning: returned string may point to the input buffer, so the string should not outlive
// the input buffer. Intended pattern of usage is as an argument to a switch statement.
func (r *Lexer) UnsafeString() string {
- ret, _ := r.unsafeString()
+ ret, _ := r.unsafeString(false)
return ret
}
// UnsafeBytes returns the byte slice if the token is a string literal.
func (r *Lexer) UnsafeBytes() []byte {
- _, ret := r.unsafeString()
+ _, ret := r.unsafeString(false)
+ return ret
+}
+
+// UnsafeFieldName returns current member name string token
+func (r *Lexer) UnsafeFieldName(skipUnescape bool) string {
+ ret, _ := r.unsafeString(skipUnescape)
return ret
}
@@ -640,7 +671,34 @@ func (r *Lexer) String() string {
r.errInvalidToken("string")
return ""
}
- ret := string(r.token.byteValue)
+ if err := r.unescapeStringToken(); err != nil {
+ r.errInvalidToken("string")
+ return ""
+ }
+ var ret string
+ if r.token.byteValueCloned {
+ ret = bytesToStr(r.token.byteValue)
+ } else {
+ ret = string(r.token.byteValue)
+ }
+ r.consume()
+ return ret
+}
+
+// StringIntern reads a string literal, and performs string interning on it.
+func (r *Lexer) StringIntern() string {
+ if r.token.kind == tokenUndef && r.Ok() {
+ r.FetchToken()
+ }
+ if !r.Ok() || r.token.kind != tokenString {
+ r.errInvalidToken("string")
+ return ""
+ }
+ if err := r.unescapeStringToken(); err != nil {
+ r.errInvalidToken("string")
+ return ""
+ }
+ ret := intern.Bytes(r.token.byteValue)
r.consume()
return ret
}
@@ -654,6 +712,10 @@ func (r *Lexer) Bytes() []byte {
r.errInvalidToken("string")
return nil
}
+ if err := r.unescapeStringToken(); err != nil {
+ r.errInvalidToken("string")
+ return nil
+ }
ret := make([]byte, base64.StdEncoding.DecodedLen(len(r.token.byteValue)))
n, err := base64.StdEncoding.Decode(ret, r.token.byteValue)
if err != nil {
@@ -839,7 +901,7 @@ func (r *Lexer) Int() int {
}
func (r *Lexer) Uint8Str() uint8 {
- s, b := r.unsafeString()
+ s, b := r.unsafeString(false)
if !r.Ok() {
return 0
}
@@ -856,7 +918,7 @@ func (r *Lexer) Uint8Str() uint8 {
}
func (r *Lexer) Uint16Str() uint16 {
- s, b := r.unsafeString()
+ s, b := r.unsafeString(false)
if !r.Ok() {
return 0
}
@@ -873,7 +935,7 @@ func (r *Lexer) Uint16Str() uint16 {
}
func (r *Lexer) Uint32Str() uint32 {
- s, b := r.unsafeString()
+ s, b := r.unsafeString(false)
if !r.Ok() {
return 0
}
@@ -890,7 +952,7 @@ func (r *Lexer) Uint32Str() uint32 {
}
func (r *Lexer) Uint64Str() uint64 {
- s, b := r.unsafeString()
+ s, b := r.unsafeString(false)
if !r.Ok() {
return 0
}
@@ -915,7 +977,7 @@ func (r *Lexer) UintptrStr() uintptr {
}
func (r *Lexer) Int8Str() int8 {
- s, b := r.unsafeString()
+ s, b := r.unsafeString(false)
if !r.Ok() {
return 0
}
@@ -932,7 +994,7 @@ func (r *Lexer) Int8Str() int8 {
}
func (r *Lexer) Int16Str() int16 {
- s, b := r.unsafeString()
+ s, b := r.unsafeString(false)
if !r.Ok() {
return 0
}
@@ -949,7 +1011,7 @@ func (r *Lexer) Int16Str() int16 {
}
func (r *Lexer) Int32Str() int32 {
- s, b := r.unsafeString()
+ s, b := r.unsafeString(false)
if !r.Ok() {
return 0
}
@@ -966,7 +1028,7 @@ func (r *Lexer) Int32Str() int32 {
}
func (r *Lexer) Int64Str() int64 {
- s, b := r.unsafeString()
+ s, b := r.unsafeString(false)
if !r.Ok() {
return 0
}
@@ -1004,7 +1066,7 @@ func (r *Lexer) Float32() float32 {
}
func (r *Lexer) Float32Str() float32 {
- s, b := r.unsafeString()
+ s, b := r.unsafeString(false)
if !r.Ok() {
return 0
}
@@ -1037,7 +1099,7 @@ func (r *Lexer) Float64() float64 {
}
func (r *Lexer) Float64Str() float64 {
- s, b := r.unsafeString()
+ s, b := r.unsafeString(false)
if !r.Ok() {
return 0
}
diff --git a/constraint/vendor/github.com/mailru/easyjson/jwriter/writer.go b/constraint/vendor/github.com/mailru/easyjson/jwriter/writer.go
index b9ed7ccaa..2c5b20105 100644
--- a/constraint/vendor/github.com/mailru/easyjson/jwriter/writer.go
+++ b/constraint/vendor/github.com/mailru/easyjson/jwriter/writer.go
@@ -270,16 +270,25 @@ func (w *Writer) Bool(v bool) {
const chars = "0123456789abcdef"
-func isNotEscapedSingleChar(c byte, escapeHTML bool) bool {
- // Note: might make sense to use a table if there are more chars to escape. With 4 chars
- // it benchmarks the same.
- if escapeHTML {
- return c != '<' && c != '>' && c != '&' && c != '\\' && c != '"' && c >= 0x20 && c < utf8.RuneSelf
- } else {
- return c != '\\' && c != '"' && c >= 0x20 && c < utf8.RuneSelf
+func getTable(falseValues ...int) [128]bool {
+ table := [128]bool{}
+
+ for i := 0; i < 128; i++ {
+ table[i] = true
+ }
+
+ for _, v := range falseValues {
+ table[v] = false
}
+
+ return table
}
+var (
+ htmlEscapeTable = getTable(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, '"', '&', '<', '>', '\\')
+ htmlNoEscapeTable = getTable(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, '"', '\\')
+)
+
func (w *Writer) String(s string) {
w.Buffer.AppendByte('"')
@@ -288,15 +297,21 @@ func (w *Writer) String(s string) {
p := 0 // last non-escape symbol
+ escapeTable := &htmlEscapeTable
+ if w.NoEscapeHTML {
+ escapeTable = &htmlNoEscapeTable
+ }
+
for i := 0; i < len(s); {
c := s[i]
- if isNotEscapedSingleChar(c, !w.NoEscapeHTML) {
- // single-width character, no escaping is required
- i++
- continue
- } else if c < utf8.RuneSelf {
- // single-with character, need to escape
+ if c < utf8.RuneSelf {
+ if escapeTable[c] {
+ // single-width character, no escaping is required
+ i++
+ continue
+ }
+
w.Buffer.AppendString(s[p:i])
switch c {
case '\t':
diff --git a/constraint/vendor/github.com/mitchellh/mapstructure/.travis.yml b/constraint/vendor/github.com/mitchellh/mapstructure/.travis.yml
deleted file mode 100644
index 1689c7d73..000000000
--- a/constraint/vendor/github.com/mitchellh/mapstructure/.travis.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-language: go
-
-go:
- - "1.11.x"
- - tip
-
-script:
- - go test
diff --git a/constraint/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md b/constraint/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
index 3b3cb723f..1955f2878 100644
--- a/constraint/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
+++ b/constraint/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
@@ -1,3 +1,55 @@
+## 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
diff --git a/constraint/vendor/github.com/mitchellh/mapstructure/decode_hooks.go b/constraint/vendor/github.com/mitchellh/mapstructure/decode_hooks.go
index 1f0abc65a..92e6f76ff 100644
--- a/constraint/vendor/github.com/mitchellh/mapstructure/decode_hooks.go
+++ b/constraint/vendor/github.com/mitchellh/mapstructure/decode_hooks.go
@@ -1,6 +1,7 @@
package mapstructure
import (
+ "encoding"
"errors"
"fmt"
"net"
@@ -16,10 +17,11 @@ 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}
+ potential := []interface{}{f1, f2, f3}
v := reflect.ValueOf(h)
vt := v.Type()
@@ -38,13 +40,15 @@ func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc {
// that took reflect.Kind instead of reflect.Type.
func DecodeHookExec(
raw DecodeHookFunc,
- from reflect.Type, to reflect.Type,
- data interface{}) (interface{}, error) {
+ from reflect.Value, to reflect.Value) (interface{}, error) {
+
switch f := typedDecodeHook(raw).(type) {
case DecodeHookFuncType:
- return f(from, to, data)
+ return f(from.Type(), to.Type(), from.Interface())
case DecodeHookFuncKind:
- return f(from.Kind(), to.Kind(), data)
+ return f(from.Kind(), to.Kind(), from.Interface())
+ case DecodeHookFuncValue:
+ return f(from, to)
default:
return nil, errors.New("invalid decode hook signature")
}
@@ -56,22 +60,16 @@ func DecodeHookExec(
// The composed funcs are called in order, with the result of the
// previous transformation.
func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc {
- return func(
- f reflect.Type,
- t reflect.Type,
- data interface{}) (interface{}, error) {
+ 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, f, t, data)
+ data, err = DecodeHookExec(f1, newFrom, t)
if err != nil {
return nil, err
}
-
- // Modify the from kind to be correct with the new data
- f = nil
- if val := reflect.ValueOf(data); val.IsValid() {
- f = val.Type()
- }
+ newFrom = reflect.ValueOf(data)
}
return data, nil
@@ -215,3 +213,44 @@ func WeaklyTypedHook(
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/constraint/vendor/github.com/mitchellh/mapstructure/go.mod b/constraint/vendor/github.com/mitchellh/mapstructure/go.mod
index d2a712562..a03ae9730 100644
--- a/constraint/vendor/github.com/mitchellh/mapstructure/go.mod
+++ b/constraint/vendor/github.com/mitchellh/mapstructure/go.mod
@@ -1 +1,3 @@
module github.com/mitchellh/mapstructure
+
+go 1.14
diff --git a/constraint/vendor/github.com/mitchellh/mapstructure/mapstructure.go b/constraint/vendor/github.com/mitchellh/mapstructure/mapstructure.go
index 256ee63fb..3643901f5 100644
--- a/constraint/vendor/github.com/mitchellh/mapstructure/mapstructure.go
+++ b/constraint/vendor/github.com/mitchellh/mapstructure/mapstructure.go
@@ -1,10 +1,161 @@
-// Package mapstructure exposes functionality to convert an arbitrary
-// map[string]interface{} into a native Go structure.
+// 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 (
@@ -21,10 +172,11 @@ import (
// data transformations. See "DecodeHook" in the DecoderConfig
// struct.
//
-// The type should be DecodeHookFuncType or DecodeHookFuncKind.
-// Either is accepted. 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 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,
@@ -40,15 +192,22 @@ type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface
// 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 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.
+ // 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
@@ -80,6 +239,14 @@ type DecoderConfig struct {
//
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
@@ -261,9 +428,7 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e
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.Type(), outVal.Type(), input)
+ input, err = DecodeHookExec(d.config.DecodeHook, inputVal, outVal)
if err != nil {
return fmt.Errorf("error decoding '%s': %s", name, err)
}
@@ -271,6 +436,7 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e
var err error
outputKind := getKind(outVal)
+ addMetaKey := true
switch outputKind {
case reflect.Bool:
err = d.decodeBool(name, input, outVal)
@@ -289,7 +455,7 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e
case reflect.Map:
err = d.decodeMap(name, input, outVal)
case reflect.Ptr:
- err = d.decodePtr(name, input, outVal)
+ addMetaKey, err = d.decodePtr(name, input, outVal)
case reflect.Slice:
err = d.decodeSlice(name, input, outVal)
case reflect.Array:
@@ -303,7 +469,7 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e
// If we reached here, then we successfully decoded SOMETHING, so
// mark the key as used if we're tracking metainput.
- if d.config.Metadata != nil && name != "" {
+ if addMetaKey && d.config.Metadata != nil && name != "" {
d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
}
@@ -314,7 +480,34 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e
// value to "data" of that type.
func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error {
if val.IsValid() && val.Elem().IsValid() {
- return d.decode(name, data, val.Elem())
+ 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)
@@ -386,8 +579,8 @@ func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value)
if !converted {
return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s'",
- name, val.Type(), dataVal.Type())
+ "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
+ name, val.Type(), dataVal.Type(), data)
}
return nil
@@ -412,7 +605,12 @@ func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) er
val.SetInt(0)
}
case dataKind == reflect.String && d.config.WeaklyTypedInput:
- i, err := strconv.ParseInt(dataVal.String(), 0, val.Type().Bits())
+ str := dataVal.String()
+ if str == "" {
+ str = "0"
+ }
+
+ i, err := strconv.ParseInt(str, 0, val.Type().Bits())
if err == nil {
val.SetInt(i)
} else {
@@ -428,8 +626,8 @@ func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) er
val.SetInt(i)
default:
return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s'",
- name, val.Type(), dataVal.Type())
+ "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
+ name, val.Type(), dataVal.Type(), data)
}
return nil
@@ -438,6 +636,7 @@ func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) er
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:
@@ -463,16 +662,33 @@ func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) e
val.SetUint(0)
}
case dataKind == reflect.String && d.config.WeaklyTypedInput:
- i, err := strconv.ParseUint(dataVal.String(), 0, val.Type().Bits())
+ 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'",
- name, val.Type(), dataVal.Type())
+ "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
+ name, val.Type(), dataVal.Type(), data)
}
return nil
@@ -502,8 +718,8 @@ func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) e
}
default:
return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s'",
- name, val.Type(), dataVal.Type())
+ "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
+ name, val.Type(), dataVal.Type(), data)
}
return nil
@@ -528,7 +744,12 @@ func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value)
val.SetFloat(0)
}
case dataKind == reflect.String && d.config.WeaklyTypedInput:
- f, err := strconv.ParseFloat(dataVal.String(), val.Type().Bits())
+ str := dataVal.String()
+ if str == "" {
+ str = "0"
+ }
+
+ f, err := strconv.ParseFloat(str, val.Type().Bits())
if err == nil {
val.SetFloat(f)
} else {
@@ -544,8 +765,8 @@ func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value)
val.SetFloat(i)
default:
return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s'",
- name, val.Type(), dataVal.Type())
+ "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
+ name, val.Type(), dataVal.Type(), data)
}
return nil
@@ -596,7 +817,7 @@ func (d *Decoder) decodeMapFromSlice(name string, dataVal reflect.Value, val ref
for i := 0; i < dataVal.Len(); i++ {
err := d.decode(
- fmt.Sprintf("%s[%d]", name, i),
+ name+"["+strconv.Itoa(i)+"]",
dataVal.Index(i).Interface(), val)
if err != nil {
return err
@@ -629,7 +850,7 @@ func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val refle
}
for _, k := range dataVal.MapKeys() {
- fieldName := fmt.Sprintf("%s[%s]", name, k)
+ fieldName := name + "[" + k.String() + "]"
// First decode the key into the proper type
currentKey := reflect.Indirect(reflect.New(valKeyType))
@@ -678,27 +899,40 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
}
tagValue := f.Tag.Get(d.config.TagName)
- tagParts := strings.Split(tagValue, ",")
+ 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
- keyName := f.Name
- if tagParts[0] != "" {
- if tagParts[0] == "-" {
+ 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
}
- keyName = tagParts[0]
- }
- // If "squash" is specified in the tag, we squash the field down.
- squash := false
- for _, tag := range tagParts[1:] {
- if tag == "squash" {
- squash = true
- break
+ // 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())
+ }
}
- }
- if squash && 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() {
@@ -713,11 +947,22 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
mType := reflect.MapOf(vKeyType, vElemType)
vMap := reflect.MakeMap(mType)
- err := d.decode(keyName, x.Interface(), vMap)
+ // 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))
@@ -738,7 +983,7 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
return nil
}
-func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) error {
+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
@@ -759,7 +1004,7 @@ func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) er
val.Set(nilValue)
}
- return nil
+ return true, nil
}
// Create an element of the concrete (non pointer) type and decode
@@ -773,16 +1018,16 @@ func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) er
}
if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {
- return err
+ return false, err
}
val.Set(realVal)
} else {
if err := d.decode(name, data, reflect.Indirect(val)); err != nil {
- return err
+ return false, err
}
}
- return nil
+ return false, nil
}
func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error {
@@ -791,8 +1036,8 @@ func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) e
dataVal := reflect.Indirect(reflect.ValueOf(data))
if val.Type() != dataVal.Type() {
return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s'",
- name, val.Type(), dataVal.Type())
+ "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
+ name, val.Type(), dataVal.Type(), data)
}
val.Set(dataVal)
return nil
@@ -805,8 +1050,8 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
valElemType := valType.Elem()
sliceType := reflect.SliceOf(valElemType)
- valSlice := val
- if valSlice.IsNil() || d.config.ZeroFields {
+ // 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
@@ -833,18 +1078,17 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
}
}
- // Check input type
- if dataValKind != reflect.Array && dataValKind != reflect.Slice {
- return fmt.Errorf(
- "'%s': source data must be an array or slice, got %s", name, dataValKind)
-
- }
+ return fmt.Errorf(
+ "'%s': source data must be an array or slice, got %s", name, dataValKind)
+ }
- // If the input value is empty, then don't allocate since non-nil != nil
- if dataVal.Len() == 0 {
- return nil
- }
+ // 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())
}
@@ -859,7 +1103,7 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
}
currentField := valSlice.Index(i)
- fieldName := fmt.Sprintf("%s[%d]", name, i)
+ fieldName := name + "[" + strconv.Itoa(i) + "]"
if err := d.decode(fieldName, currentData, currentField); err != nil {
errors = appendErrors(errors, err)
}
@@ -926,7 +1170,7 @@ func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value)
currentData := dataVal.Index(i).Interface()
currentField := valArray.Index(i)
- fieldName := fmt.Sprintf("%s[%d]", name, i)
+ fieldName := name + "[" + strconv.Itoa(i) + "]"
if err := d.decode(fieldName, currentData, currentField); err != nil {
errors = appendErrors(errors, err)
}
@@ -962,13 +1206,23 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
// 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.
- m := make(map[string]interface{})
- mval := reflect.Indirect(reflect.ValueOf(&m))
- if err := d.decodeMapFromStruct(name, dataVal, mval, mval); err != nil {
+
+ // 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, mval, val)
+ result := d.decodeStructFromMap(name, reflect.Indirect(addrVal), val)
return result
default:
@@ -1005,6 +1259,11 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
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]
@@ -1014,30 +1273,47 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
for i := 0; i < structType.NumField(); i++ {
fieldType := structType.Field(i)
- fieldKind := fieldType.Type.Kind()
+ 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 := false
+ 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 fieldKind != reflect.Struct {
+ if fieldVal.Kind() != reflect.Struct {
errors = appendErrors(errors,
- fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind))
+ fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldVal.Kind()))
} else {
- structs = append(structs, structVal.FieldByName(fieldType.Name))
+ structs = append(structs, fieldVal)
}
continue
}
- // Normal struct field, store it away
- fields = append(fields, field{fieldType, structVal.Field(i)})
+ // Build our field
+ if remain {
+ remainField = &field{fieldType, fieldVal}
+ } else {
+ // Normal struct field, store it away
+ fields = append(fields, field{fieldType, fieldVal})
+ }
}
}
@@ -1078,9 +1354,6 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
}
}
- // Delete the key we're using from the unused map so we stop tracking
- delete(dataValKeysUnused, rawMapKey.Interface())
-
if !fieldValue.IsValid() {
// This should never happen
panic("field is not valid")
@@ -1092,10 +1365,13 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
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 = fmt.Sprintf("%s.%s", name, fieldName)
+ fieldName = name + "." + fieldName
}
if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil {
@@ -1103,6 +1379,25 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
}
}
+ // 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 {
@@ -1123,7 +1418,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
for rawKey := range dataValKeysUnused {
key := rawKey.(string)
if name != "" {
- key = fmt.Sprintf("%s.%s", name, key)
+ key = name + "." + key
}
d.config.Metadata.Unused = append(d.config.Metadata.Unused, key)
@@ -1133,6 +1428,24 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
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()
diff --git a/constraint/vendor/github.com/onsi/gomega/.travis.yml b/constraint/vendor/github.com/onsi/gomega/.travis.yml
index 072fdd2db..348e3014c 100644
--- a/constraint/vendor/github.com/onsi/gomega/.travis.yml
+++ b/constraint/vendor/github.com/onsi/gomega/.travis.yml
@@ -1,8 +1,11 @@
language: go
+arch:
+ - amd64
+ - ppc64le
go:
- - 1.13.x
- 1.14.x
+ - 1.15.x
- gotip
env:
diff --git a/constraint/vendor/github.com/onsi/gomega/CHANGELOG.md b/constraint/vendor/github.com/onsi/gomega/CHANGELOG.md
index 0b6c2fb61..16095fa3c 100644
--- a/constraint/vendor/github.com/onsi/gomega/CHANGELOG.md
+++ b/constraint/vendor/github.com/onsi/gomega/CHANGELOG.md
@@ -1,3 +1,22 @@
+## 1.10.5
+
+### Fixes
+- fix: collections matchers should display type of expectation (#408) [6b4eb5a]
+- fix(ContainElements): consistently flatten expected values [073b880]
+- fix(ConsistOf): consistently flatten expected values [7266efe]
+
+## 1.10.4
+
+### Fixes
+- update golang net library to more recent version without vulnerability (#406) [817a8b9]
+- Correct spelling: alloted -> allotted (#403) [0bae715]
+- fix a panic in MessageWithDiff with long message (#402) [ea06b9b]
+
+## 1.10.3
+
+### Fixes
+- updates golang/x/net to fix vulnerability detected by snyk (#394) [c479356]
+
## 1.10.2
### Fixes
diff --git a/constraint/vendor/github.com/onsi/gomega/format/format.go b/constraint/vendor/github.com/onsi/gomega/format/format.go
index fae25adce..e59d7d75b 100644
--- a/constraint/vendor/github.com/onsi/gomega/format/format.go
+++ b/constraint/vendor/github.com/onsi/gomega/format/format.go
@@ -105,7 +105,13 @@ func MessageWithDiff(actual, message, expected string) string {
tabLength := 4
spaceFromMessageToActual := tabLength + len(": ") - len(message)
- padding := strings.Repeat(" ", spaceFromMessageToActual+spacesBeforeFormattedMismatch) + "|"
+
+ paddingCount := spaceFromMessageToActual + spacesBeforeFormattedMismatch
+ if paddingCount < 0 {
+ return Message(formattedActual, message, formattedExpected)
+ }
+
+ padding := strings.Repeat(" ", paddingCount) + "|"
return Message(formattedActual, message+padding, formattedExpected)
}
diff --git a/constraint/vendor/github.com/onsi/gomega/gbytes/io_wrappers.go b/constraint/vendor/github.com/onsi/gomega/gbytes/io_wrappers.go
index 3caed8769..a41ad6232 100644
--- a/constraint/vendor/github.com/onsi/gomega/gbytes/io_wrappers.go
+++ b/constraint/vendor/github.com/onsi/gomega/gbytes/io_wrappers.go
@@ -9,17 +9,17 @@ import (
// ErrTimeout is returned by TimeoutCloser, TimeoutReader, and TimeoutWriter when the underlying Closer/Reader/Writer does not return within the specified timeout
var ErrTimeout = errors.New("timeout occurred")
-// TimeoutCloser returns an io.Closer that wraps the passed-in io.Closer. If the underlying Closer fails to close within the alloted timeout ErrTimeout is returned.
+// TimeoutCloser returns an io.Closer that wraps the passed-in io.Closer. If the underlying Closer fails to close within the allotted timeout ErrTimeout is returned.
func TimeoutCloser(c io.Closer, timeout time.Duration) io.Closer {
return timeoutReaderWriterCloser{c: c, d: timeout}
}
-// TimeoutReader returns an io.Reader that wraps the passed-in io.Reader. If the underlying Reader fails to read within the alloted timeout ErrTimeout is returned.
+// TimeoutReader returns an io.Reader that wraps the passed-in io.Reader. If the underlying Reader fails to read within the allotted timeout ErrTimeout is returned.
func TimeoutReader(r io.Reader, timeout time.Duration) io.Reader {
return timeoutReaderWriterCloser{r: r, d: timeout}
}
-// TimeoutWriter returns an io.Writer that wraps the passed-in io.Writer. If the underlying Writer fails to write within the alloted timeout ErrTimeout is returned.
+// TimeoutWriter returns an io.Writer that wraps the passed-in io.Writer. If the underlying Writer fails to write within the allotted timeout ErrTimeout is returned.
func TimeoutWriter(w io.Writer, timeout time.Duration) io.Writer {
return timeoutReaderWriterCloser{w: w, d: timeout}
}
diff --git a/constraint/vendor/github.com/onsi/gomega/go.mod b/constraint/vendor/github.com/onsi/gomega/go.mod
index 778935141..6f853a579 100644
--- a/constraint/vendor/github.com/onsi/gomega/go.mod
+++ b/constraint/vendor/github.com/onsi/gomega/go.mod
@@ -1,9 +1,10 @@
module github.com/onsi/gomega
+go 1.14
+
require (
github.com/golang/protobuf v1.4.2
github.com/onsi/ginkgo v1.12.1
- golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7
- golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
+ golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb
gopkg.in/yaml.v2 v2.3.0
)
diff --git a/constraint/vendor/github.com/onsi/gomega/go.sum b/constraint/vendor/github.com/onsi/gomega/go.sum
index 610b09bee..54eeacd2b 100644
--- a/constraint/vendor/github.com/onsi/gomega/go.sum
+++ b/constraint/vendor/github.com/onsi/gomega/go.sum
@@ -23,22 +23,28 @@ github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0=
-golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
+golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
diff --git a/constraint/vendor/github.com/onsi/gomega/gomega_dsl.go b/constraint/vendor/github.com/onsi/gomega/gomega_dsl.go
index b416d20cc..1bc5288b8 100644
--- a/constraint/vendor/github.com/onsi/gomega/gomega_dsl.go
+++ b/constraint/vendor/github.com/onsi/gomega/gomega_dsl.go
@@ -24,7 +24,7 @@ import (
"github.com/onsi/gomega/types"
)
-const GOMEGA_VERSION = "1.10.2"
+const GOMEGA_VERSION = "1.10.5"
const nilFailHandlerPanic = `You are trying to make an assertion, but Gomega's fail handler is nil.
If you're using Ginkgo then you probably forgot to put your assertion in an It().
diff --git a/constraint/vendor/github.com/onsi/gomega/matchers/consist_of.go b/constraint/vendor/github.com/onsi/gomega/matchers/consist_of.go
index e453b22d1..e8ef0dee1 100644
--- a/constraint/vendor/github.com/onsi/gomega/matchers/consist_of.go
+++ b/constraint/vendor/github.com/onsi/gomega/matchers/consist_of.go
@@ -57,17 +57,21 @@ func equalMatchersToElements(matchers []interface{}) (elements []interface{}) {
return
}
-func matchers(expectedElems []interface{}) (matchers []interface{}) {
- elems := expectedElems
- if len(expectedElems) == 1 && isArrayOrSlice(expectedElems[0]) {
- elems = []interface{}{}
- value := reflect.ValueOf(expectedElems[0])
- for i := 0; i < value.Len(); i++ {
- elems = append(elems, value.Index(i).Interface())
- }
+func flatten(elems []interface{}) []interface{} {
+ if len(elems) != 1 || !isArrayOrSlice(elems[0]) {
+ return elems
}
- for _, e := range elems {
+ value := reflect.ValueOf(elems[0])
+ flattened := make([]interface{}, value.Len())
+ for i := 0; i < value.Len(); i++ {
+ flattened[i] = value.Index(i).Interface()
+ }
+ return flattened
+}
+
+func matchers(expectedElems []interface{}) (matchers []interface{}) {
+ for _, e := range flatten(expectedElems) {
matcher, isMatcher := e.(omegaMatcher)
if !isMatcher {
matcher = &EqualMatcher{Expected: e}
@@ -77,6 +81,29 @@ func matchers(expectedElems []interface{}) (matchers []interface{}) {
return
}
+func presentable(elems []interface{}) interface{} {
+ elems = flatten(elems)
+
+ if len(elems) == 0 {
+ return []interface{}{}
+ }
+
+ sv := reflect.ValueOf(elems)
+ tt := sv.Index(0).Elem().Type()
+ for i := 1; i < sv.Len(); i++ {
+ if sv.Index(i).Elem().Type() != tt {
+ return elems
+ }
+ }
+
+ ss := reflect.MakeSlice(reflect.SliceOf(tt), sv.Len(), sv.Len())
+ for i := 0; i < sv.Len(); i++ {
+ ss.Index(i).Set(sv.Index(i).Elem())
+ }
+
+ return ss.Interface()
+}
+
func valuesOf(actual interface{}) []interface{} {
value := reflect.ValueOf(actual)
values := []interface{}{}
@@ -95,11 +122,11 @@ func valuesOf(actual interface{}) []interface{} {
}
func (matcher *ConsistOfMatcher) FailureMessage(actual interface{}) (message string) {
- message = format.Message(actual, "to consist of", matcher.Elements)
+ message = format.Message(actual, "to consist of", presentable(matcher.Elements))
message = appendMissingElements(message, matcher.missingElements)
if len(matcher.extraElements) > 0 {
message = fmt.Sprintf("%s\nthe extra elements were\n%s", message,
- format.Object(matcher.extraElements, 1))
+ format.Object(presentable(matcher.extraElements), 1))
}
return
}
@@ -109,9 +136,9 @@ func appendMissingElements(message string, missingElements []interface{}) string
return message
}
return fmt.Sprintf("%s\nthe missing elements were\n%s", message,
- format.Object(missingElements, 1))
+ format.Object(presentable(missingElements), 1))
}
func (matcher *ConsistOfMatcher) NegatedFailureMessage(actual interface{}) (message string) {
- return format.Message(actual, "not to consist of", matcher.Elements)
+ return format.Message(actual, "not to consist of", presentable(matcher.Elements))
}
diff --git a/constraint/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go b/constraint/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go
index 19a9e78f8..946cd8bea 100644
--- a/constraint/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go
+++ b/constraint/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go
@@ -35,10 +35,10 @@ func (matcher *ContainElementsMatcher) Match(actual interface{}) (success bool,
}
func (matcher *ContainElementsMatcher) FailureMessage(actual interface{}) (message string) {
- message = format.Message(actual, "to contain elements", matcher.Elements)
+ message = format.Message(actual, "to contain elements", presentable(matcher.Elements))
return appendMissingElements(message, matcher.missingElements)
}
func (matcher *ContainElementsMatcher) NegatedFailureMessage(actual interface{}) (message string) {
- return format.Message(actual, "not to contain elements", matcher.Elements)
+ return format.Message(actual, "not to contain elements", presentable(matcher.Elements))
}
diff --git a/constraint/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go b/constraint/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go
index 4e09239ff..c8993a86d 100644
--- a/constraint/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go
+++ b/constraint/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go
@@ -1,11 +1,11 @@
package matchers
import (
+ "errors"
"fmt"
"reflect"
"github.com/onsi/gomega/format"
- "golang.org/x/xerrors"
)
type MatchErrorMatcher struct {
@@ -25,7 +25,7 @@ func (matcher *MatchErrorMatcher) Match(actual interface{}) (success bool, err e
expected := matcher.Expected
if isError(expected) {
- return reflect.DeepEqual(actualErr, expected) || xerrors.Is(actualErr, expected.(error)), nil
+ return reflect.DeepEqual(actualErr, expected) || errors.Is(actualErr, expected.(error)), nil
}
if isString(expected) {
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/ast/builtins.go b/constraint/vendor/github.com/open-policy-agent/opa/ast/builtins.go
index 2c91456c2..5ddde37ba 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/ast/builtins.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/ast/builtins.go
@@ -46,6 +46,8 @@ var DefaultBuiltins = [...]*Builtin{
Minus,
Multiply,
Divide,
+ Ceil,
+ Floor,
Round,
Abs,
Rem,
@@ -128,10 +130,12 @@ var DefaultBuiltins = [...]*Builtin{
// Encoding
JSONMarshal,
JSONUnmarshal,
+ JSONIsValid,
Base64Encode,
Base64Decode,
Base64IsValid,
Base64UrlEncode,
+ Base64UrlEncodeNoPad,
Base64UrlDecode,
URLQueryDecode,
URLQueryEncode,
@@ -139,6 +143,9 @@ var DefaultBuiltins = [...]*Builtin{
URLQueryDecodeObject,
YAMLMarshal,
YAMLUnmarshal,
+ YAMLIsValid,
+ HexEncode,
+ HexDecode,
// Object Manipulation
ObjectUnion,
@@ -149,6 +156,7 @@ var DefaultBuiltins = [...]*Builtin{
// JSON Object Manipulation
JSONFilter,
JSONRemove,
+ JSONPatch,
// Tokens
JWTDecode,
@@ -177,6 +185,7 @@ var DefaultBuiltins = [...]*Builtin{
Clock,
Weekday,
AddDate,
+ Diff,
// Crypto
CryptoX509ParseCertificates,
@@ -390,7 +399,7 @@ var Divide = &Builtin{
),
}
-// Round rounds the number up to the nearest integer.
+// Round rounds the number to the nearest integer.
var Round = &Builtin{
Name: "round",
Decl: types.NewFunction(
@@ -399,6 +408,24 @@ var Round = &Builtin{
),
}
+// Ceil rounds the number up to the nearest integer.
+var Ceil = &Builtin{
+ Name: "ceil",
+ Decl: types.NewFunction(
+ types.Args(types.N),
+ types.N,
+ ),
+}
+
+// Floor rounds the number down to the nearest integer.
+var Floor = &Builtin{
+ Name: "floor",
+ Decl: types.NewFunction(
+ types.Args(types.N),
+ types.N,
+ ),
+}
+
// Abs returns the number without its sign.
var Abs = &Builtin{
Name: "abs",
@@ -1075,6 +1102,15 @@ var JSONUnmarshal = &Builtin{
),
}
+// JSONIsValid verifies the input string is a valid JSON document.
+var JSONIsValid = &Builtin{
+ Name: "json.is_valid",
+ Decl: types.NewFunction(
+ types.Args(types.S),
+ types.B,
+ ),
+}
+
// JSONFilter filters the JSON object
var JSONFilter = &Builtin{
Name: "json.filter",
@@ -1145,6 +1181,27 @@ var JSONRemove = &Builtin{
),
}
+// JSONPatch patches a JSON object according to RFC6902
+var JSONPatch = &Builtin{
+ Name: "json.patch",
+ Decl: types.NewFunction(
+ types.Args(
+ types.A,
+ types.NewArray(
+ nil,
+ types.NewObject(
+ []*types.StaticProperty{
+ {Key: "op", Value: types.S},
+ {Key: "path", Value: types.A},
+ },
+ types.NewDynamicProperty(types.A, types.A),
+ ),
+ ),
+ ),
+ types.A,
+ ),
+}
+
// ObjectGet returns takes an object and returns a value under its key if
// present, otherwise it returns the default.
var ObjectGet = &Builtin{
@@ -1251,6 +1308,15 @@ var Base64UrlEncode = &Builtin{
),
}
+// Base64UrlEncodeNoPad serializes the input string into base64url encoding without padding.
+var Base64UrlEncodeNoPad = &Builtin{
+ Name: "base64url.encode_no_pad",
+ Decl: types.NewFunction(
+ types.Args(types.S),
+ types.S,
+ ),
+}
+
// Base64UrlDecode deserializes the base64url encoded input string.
var Base64UrlDecode = &Builtin{
Name: "base64url.decode",
@@ -1324,6 +1390,33 @@ var YAMLUnmarshal = &Builtin{
),
}
+// YAMLIsValid verifies the input string is a valid YAML document.
+var YAMLIsValid = &Builtin{
+ Name: "yaml.is_valid",
+ Decl: types.NewFunction(
+ types.Args(types.S),
+ types.B,
+ ),
+}
+
+// HexEncode serializes the input string into hex encoding.
+var HexEncode = &Builtin{
+ Name: "hex.encode",
+ Decl: types.NewFunction(
+ types.Args(types.S),
+ types.S,
+ ),
+}
+
+// HexDecode deserializes the hex encoded input string.
+var HexDecode = &Builtin{
+ Name: "hex.decode",
+ Decl: types.NewFunction(
+ types.Args(types.S),
+ types.S,
+ ),
+}
+
/**
* Tokens
*/
@@ -1629,6 +1722,24 @@ var AddDate = &Builtin{
),
}
+// Diff returns the difference [years, months, days, hours, minutes, seconds] between two unix timestamps in nanoseconds
+var Diff = &Builtin{
+ Name: "time.diff",
+ Decl: types.NewFunction(
+ types.Args(
+ types.NewAny(
+ types.N,
+ types.NewArray([]types.Type{types.N, types.S}, nil),
+ ),
+ types.NewAny(
+ types.N,
+ types.NewArray([]types.Type{types.N, types.S}, nil),
+ ),
+ ),
+ types.NewArray([]types.Type{types.N, types.N, types.N, types.N, types.N, types.N}, nil),
+ ),
+}
+
/**
* Crypto.
*/
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/ast/capabilities.go b/constraint/vendor/github.com/open-policy-agent/opa/ast/capabilities.go
index 50765b616..c7eec63f9 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/ast/capabilities.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/ast/capabilities.go
@@ -8,26 +8,33 @@ import (
"io"
"sort"
+ "github.com/open-policy-agent/opa/internal/wasm/sdk/opa/capabilities"
"github.com/open-policy-agent/opa/util"
)
// Capabilities defines a structure containing data that describes the capablilities
// or features supported by a particular version of OPA.
type Capabilities struct {
- Builtins []*Builtin `json:"builtins"` // builtins is a set of built-in functions that are supported.
+ Builtins []*Builtin `json:"builtins"` // builtins is a set of built-in functions that are supported.
+ WasmABIVersions []WasmABIVersion `json:"wasm_abi_versions"`
+}
+
+// WasmABIVersion captures the Wasm ABI version. Its `Minor` version is indicating
+// backwards-compatible changes.
+type WasmABIVersion struct {
+ Version int `json:"version"`
+ Minor int `json:"minor_version"`
}
// CapabilitiesForThisVersion returns the capabilities of this version of OPA.
func CapabilitiesForThisVersion() *Capabilities {
+ f := &Capabilities{}
- f := &Capabilities{
- Builtins: []*Builtin{},
- }
-
- for _, bi := range Builtins {
- f.Builtins = append(f.Builtins, bi)
+ for _, vers := range capabilities.ABIVersions() {
+ f.WasmABIVersions = append(f.WasmABIVersions, WasmABIVersion{Version: vers[0], Minor: vers[1]})
}
+ f.Builtins = append(f.Builtins, Builtins...)
sort.Slice(f.Builtins, func(i, j int) bool {
return f.Builtins[i].Name < f.Builtins[j].Name
})
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/ast/check.go b/constraint/vendor/github.com/open-policy-agent/opa/ast/check.go
index b77a291a2..0a3a22f15 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/ast/check.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/ast/check.go
@@ -27,6 +27,8 @@ type typeChecker struct {
errs Errors
exprCheckers map[string]exprChecker
varRewriter rewriteVars
+ ss *SchemaSet
+ input types.Type
}
// newTypeChecker returns a new typeChecker object that has no errors.
@@ -38,23 +40,57 @@ func newTypeChecker() *typeChecker {
return tc
}
+func (tc *typeChecker) newEnv(exist *TypeEnv) *TypeEnv {
+ if exist != nil {
+ return exist.wrap()
+ }
+ env := newTypeEnv(tc.copy)
+ if tc.input != nil {
+ env.tree.Put(InputRootRef, tc.input)
+ }
+ return env
+}
+
+func (tc *typeChecker) copy() *typeChecker {
+ return newTypeChecker().
+ WithVarRewriter(tc.varRewriter).
+ WithSchemaSet(tc.ss).
+ WithInputType(tc.input)
+}
+
+func (tc *typeChecker) WithSchemaSet(ss *SchemaSet) *typeChecker {
+ tc.ss = ss
+ return tc
+}
+
func (tc *typeChecker) WithVarRewriter(f rewriteVars) *typeChecker {
tc.varRewriter = f
return tc
}
+func (tc *typeChecker) WithInputType(tpe types.Type) *typeChecker {
+ tc.input = tpe
+ return tc
+}
+
+// Env returns a type environment for the specified built-ins with any other
+// global types configured on the checker. In practice, this is the default
+// environment that other statements will be checked against.
+func (tc *typeChecker) Env(builtins map[string]*Builtin) *TypeEnv {
+ env := tc.newEnv(nil)
+ for _, bi := range builtins {
+ env.tree.Put(bi.Ref(), bi.Decl)
+ }
+ return env
+}
+
// CheckBody runs type checking on the body and returns a TypeEnv if no errors
// are found. The resulting TypeEnv wraps the provided one. The resulting
// TypeEnv will be able to resolve types of vars contained in the body.
func (tc *typeChecker) CheckBody(env *TypeEnv, body Body) (*TypeEnv, Errors) {
errors := []*Error{}
-
- if env == nil {
- env = NewTypeEnv()
- } else {
- env = env.wrap()
- }
+ env = tc.newEnv(env)
WalkExprs(body, func(expr *Expr) bool {
@@ -94,13 +130,17 @@ func (tc *typeChecker) CheckBody(env *TypeEnv, body Body) (*TypeEnv, Errors) {
// are found. The resulting TypeEnv wraps the provided one. The resulting
// TypeEnv will be able to resolve types of refs that refer to rules.
func (tc *typeChecker) CheckTypes(env *TypeEnv, sorted []util.T) (*TypeEnv, Errors) {
- if env == nil {
- env = NewTypeEnv()
- } else {
- env = env.wrap()
+ env = tc.newEnv(env)
+ var as *annotationSet
+ if tc.ss != nil {
+ var errs Errors
+ as, errs = buildAnnotationSet(sorted)
+ if len(errs) > 0 {
+ return env, errs
+ }
}
for _, s := range sorted {
- tc.checkRule(env, s.(*Rule))
+ tc.checkRule(env, as, s.(*Rule))
}
tc.errs.Sort()
return env, tc.errs
@@ -111,19 +151,19 @@ func (tc *typeChecker) checkClosures(env *TypeEnv, expr *Expr) Errors {
WalkClosures(expr, func(x interface{}) bool {
switch x := x.(type) {
case *ArrayComprehension:
- _, errs := newTypeChecker().WithVarRewriter(tc.varRewriter).CheckBody(env, x.Body)
+ _, errs := tc.copy().CheckBody(env, x.Body)
if len(errs) > 0 {
result = errs
return true
}
case *SetComprehension:
- _, errs := newTypeChecker().WithVarRewriter(tc.varRewriter).CheckBody(env, x.Body)
+ _, errs := tc.copy().CheckBody(env, x.Body)
if len(errs) > 0 {
result = errs
return true
}
case *ObjectComprehension:
- _, errs := newTypeChecker().WithVarRewriter(tc.varRewriter).CheckBody(env, x.Body)
+ _, errs := tc.copy().CheckBody(env, x.Body)
if len(errs) > 0 {
result = errs
return true
@@ -134,84 +174,96 @@ func (tc *typeChecker) checkClosures(env *TypeEnv, expr *Expr) Errors {
return result
}
-func (tc *typeChecker) checkLanguageBuiltins(env *TypeEnv, builtins map[string]*Builtin) *TypeEnv {
- if env == nil {
- env = NewTypeEnv()
- } else {
- env = env.wrap()
- }
- for _, bi := range builtins {
- env.tree.Put(bi.Ref(), bi.Decl)
- }
- return env
-}
+func (tc *typeChecker) checkRule(env *TypeEnv, as *annotationSet, rule *Rule) {
-func (tc *typeChecker) checkRule(env *TypeEnv, rule *Rule) {
+ env = env.wrap()
- cpy, err := tc.CheckBody(env, rule.Body)
-
- if len(err) == 0 {
+ if schemaAnnots := getRuleAnnotation(as, rule); schemaAnnots != nil {
+ for _, schemaAnnot := range schemaAnnots {
+ ref, refType, err := processAnnotation(tc.ss, schemaAnnot, rule)
+ if err != nil {
+ tc.err([]*Error{err})
+ continue
+ }
+ prefixRef, t := getPrefix(env, ref)
+ if t == nil || len(prefixRef) == len(ref) {
+ env.tree.Put(ref, refType)
+ } else {
+ newType, err := override(ref[len(prefixRef):], t, refType, rule)
+ if err != nil {
+ tc.err([]*Error{err})
+ continue
+ }
+ env.tree.Put(prefixRef, newType)
+ }
+ }
+ }
- path := rule.Path()
- var tpe types.Type
+ cpy, err := tc.CheckBody(env, rule.Body)
+ env = env.next
+ path := rule.Path()
+
+ if len(err) > 0 {
+ // if the rule/function contains an error, add it to the type env so
+ // that expressions that refer to this rule/function do not encounter
+ // type errors.
+ env.tree.Put(path, types.A)
+ return
+ }
- if len(rule.Head.Args) > 0 {
+ var tpe types.Type
- // If args are not referred to in body, infer as any.
- WalkVars(rule.Head.Args, func(v Var) bool {
- if cpy.Get(v) == nil {
- cpy.tree.PutOne(v, types.A)
- }
- return false
- })
+ if len(rule.Head.Args) > 0 {
- // Construct function type.
- args := make([]types.Type, len(rule.Head.Args))
- for i := 0; i < len(rule.Head.Args); i++ {
- args[i] = cpy.Get(rule.Head.Args[i])
+ // If args are not referred to in body, infer as any.
+ WalkVars(rule.Head.Args, func(v Var) bool {
+ if cpy.Get(v) == nil {
+ cpy.tree.PutOne(v, types.A)
}
+ return false
+ })
- f := types.NewFunction(args, cpy.Get(rule.Head.Value))
+ // Construct function type.
+ args := make([]types.Type, len(rule.Head.Args))
+ for i := 0; i < len(rule.Head.Args); i++ {
+ args[i] = cpy.Get(rule.Head.Args[i])
+ }
- // Union with existing.
- exist := env.tree.Get(path)
- tpe = types.Or(exist, f)
+ f := types.NewFunction(args, cpy.Get(rule.Head.Value))
- } else {
- switch rule.Head.DocKind() {
- case CompleteDoc:
- typeV := cpy.Get(rule.Head.Value)
- if typeV != nil {
- exist := env.tree.Get(path)
- tpe = types.Or(typeV, exist)
- }
- case PartialObjectDoc:
- typeK := cpy.Get(rule.Head.Key)
- typeV := cpy.Get(rule.Head.Value)
- if typeK != nil && typeV != nil {
- exist := env.tree.Get(path)
- typeV = types.Or(types.Values(exist), typeV)
- typeK = types.Or(types.Keys(exist), typeK)
- tpe = types.NewObject(nil, types.NewDynamicProperty(typeK, typeV))
- }
- case PartialSetDoc:
- typeK := cpy.Get(rule.Head.Key)
- if typeK != nil {
- exist := env.tree.Get(path)
- typeK = types.Or(types.Keys(exist), typeK)
- tpe = types.NewSet(typeK)
- }
+ // Union with existing.
+ exist := env.tree.Get(path)
+ tpe = types.Or(exist, f)
+
+ } else {
+ switch rule.Head.DocKind() {
+ case CompleteDoc:
+ typeV := cpy.Get(rule.Head.Value)
+ if typeV != nil {
+ exist := env.tree.Get(path)
+ tpe = types.Or(typeV, exist)
+ }
+ case PartialObjectDoc:
+ typeK := cpy.Get(rule.Head.Key)
+ typeV := cpy.Get(rule.Head.Value)
+ if typeK != nil && typeV != nil {
+ exist := env.tree.Get(path)
+ typeV = types.Or(types.Values(exist), typeV)
+ typeK = types.Or(types.Keys(exist), typeK)
+ tpe = types.NewObject(nil, types.NewDynamicProperty(typeK, typeV))
+ }
+ case PartialSetDoc:
+ typeK := cpy.Get(rule.Head.Key)
+ if typeK != nil {
+ exist := env.tree.Get(path)
+ typeK = types.Or(types.Keys(exist), typeK)
+ tpe = types.NewSet(typeK)
}
}
+ }
- if tpe != nil {
- env.tree.Put(path, tpe)
- }
- } else {
- // if the rule/function contains an error, add it to the type env
- // so that expressions that refer to this rule/function
- // do not encounter type errors
- env.tree.Put(rule.Path(), types.A)
+ if tpe != nil {
+ env.tree.Put(path, tpe)
}
}
@@ -327,24 +379,24 @@ func unify2(env *TypeEnv, a *Term, typeA types.Type, b *Term, typeB types.Type)
switch a.Value.(type) {
case *Array:
- return unify2Array(env, a, typeA, b, typeB)
+ return unify2Array(env, a, b)
case *object:
- return unify2Object(env, a, typeA, b, typeB)
+ return unify2Object(env, a, b)
case Var:
switch b.Value.(type) {
case Var:
return unify1(env, a, types.A, false) && unify1(env, b, env.Get(a), false)
case *Array:
- return unify2Array(env, b, typeB, a, typeA)
+ return unify2Array(env, b, a)
case *object:
- return unify2Object(env, b, typeB, a, typeA)
+ return unify2Object(env, b, a)
}
}
return false
}
-func unify2Array(env *TypeEnv, a *Term, typeA types.Type, b *Term, typeB types.Type) bool {
+func unify2Array(env *TypeEnv, a *Term, b *Term) bool {
arr := a.Value.(*Array)
switch bv := b.Value.(type) {
case *Array:
@@ -362,7 +414,7 @@ func unify2Array(env *TypeEnv, a *Term, typeA types.Type, b *Term, typeB types.T
return false
}
-func unify2Object(env *TypeEnv, a *Term, typeA types.Type, b *Term, typeB types.Type) bool {
+func unify2Object(env *TypeEnv, a *Term, b *Term) bool {
obj := a.Value.(Object)
switch bv := b.Value.(type) {
case *object:
@@ -630,7 +682,7 @@ func (rc *refChecker) checkRef(curr *TypeEnv, node *typeTreeNode, ref Ref, idx i
// potentially refers to data for which no type information exists,
// checking should never fail.
node.Children().Iter(func(_, child util.T) bool {
- rc.checkRef(curr, child.(*typeTreeNode), ref, idx+1)
+ _ = rc.checkRef(curr, child.(*typeTreeNode), ref, idx+1) // ignore error
return false
})
@@ -990,3 +1042,298 @@ func getArgTypes(env *TypeEnv, args []*Term) []types.Type {
}
return pre
}
+
+// getPrefix returns the shortest prefix of ref that exists in env
+func getPrefix(env *TypeEnv, ref Ref) (Ref, types.Type) {
+ if len(ref) == 1 {
+ t := env.Get(ref)
+ if t != nil {
+ return ref, t
+ }
+ }
+ for i := 1; i < len(ref); i++ {
+ t := env.Get(ref[:i])
+ if t != nil {
+ return ref[:i], t
+ }
+ }
+ return nil, nil
+}
+
+// override takes a type t and returns a type obtained from t where the path represented by ref within it has type o (overriding the original type of that path)
+func override(ref Ref, t types.Type, o types.Type, rule *Rule) (types.Type, *Error) {
+ var newStaticProps []*types.StaticProperty
+ obj, ok := t.(*types.Object)
+ if !ok {
+ newType, err := getObjectType(ref, o, rule, types.NewDynamicProperty(types.A, types.A))
+ if err != nil {
+ return nil, err
+ }
+ return newType, nil
+ }
+ found := false
+ if ok {
+ staticProps := obj.StaticProperties()
+ for _, prop := range staticProps {
+ valueCopy := prop.Value
+ key, err := InterfaceToValue(prop.Key)
+ if err != nil {
+ return nil, NewError(TypeErr, rule.Location, "unexpected error in override: %s", err.Error())
+ }
+ if len(ref) > 0 && ref[0].Value.Compare(key) == 0 {
+ found = true
+ if len(ref) == 1 {
+ valueCopy = o
+ } else {
+ newVal, err := override(ref[1:], valueCopy, o, rule)
+ if err != nil {
+ return nil, err
+ }
+ valueCopy = newVal
+ }
+ }
+ newStaticProps = append(newStaticProps, types.NewStaticProperty(prop.Key, valueCopy))
+ }
+ }
+
+ // ref[0] is not a top-level key in staticProps, so it must be added
+ if !found {
+ newType, err := getObjectType(ref, o, rule, obj.DynamicProperties())
+ if err != nil {
+ return nil, err
+ }
+ newStaticProps = append(newStaticProps, newType.StaticProperties()...)
+ }
+ return types.NewObject(newStaticProps, obj.DynamicProperties()), nil
+}
+
+func getKeys(ref Ref, rule *Rule) ([]interface{}, *Error) {
+ keys := []interface{}{}
+ for _, refElem := range ref {
+ key, err := JSON(refElem.Value)
+ if err != nil {
+ return nil, NewError(TypeErr, rule.Location, "error getting key from value: %s", err.Error())
+ }
+ keys = append(keys, key)
+ }
+ return keys, nil
+}
+
+func getObjectTypeRec(keys []interface{}, o types.Type, d *types.DynamicProperty) *types.Object {
+ if len(keys) == 1 {
+ staticProps := []*types.StaticProperty{types.NewStaticProperty(keys[0], o)}
+ return types.NewObject(staticProps, d)
+ }
+
+ staticProps := []*types.StaticProperty{types.NewStaticProperty(keys[0], getObjectTypeRec(keys[1:], o, d))}
+ return types.NewObject(staticProps, d)
+}
+
+func getObjectType(ref Ref, o types.Type, rule *Rule, d *types.DynamicProperty) (*types.Object, *Error) {
+ keys, err := getKeys(ref, rule)
+ if err != nil {
+ return nil, err
+ }
+ return getObjectTypeRec(keys, o, d), nil
+}
+
+func getRuleAnnotation(as *annotationSet, rule *Rule) (result []*SchemaAnnotation) {
+
+ for _, x := range as.GetSubpackagesScope(rule.Module.Package.Path) {
+ result = append(result, x.Schemas...)
+ }
+
+ if x := as.GetPackageScope(rule.Module.Package); x != nil {
+ result = append(result, x.Schemas...)
+ }
+
+ if x := as.GetDocumentScope(rule.Path()); x != nil {
+ result = append(result, x.Schemas...)
+ }
+
+ for _, x := range as.GetRuleScope(rule) {
+ result = append(result, x.Schemas...)
+ }
+
+ return result
+}
+
+func processAnnotation(ss *SchemaSet, annot *SchemaAnnotation, rule *Rule) (Ref, types.Type, *Error) {
+
+ var schema interface{}
+
+ if annot.Schema != nil {
+ schema = ss.Get(annot.Schema)
+ if schema == nil {
+ return nil, nil, NewError(TypeErr, rule.Location, "undefined schema: %v", annot.Schema)
+ }
+ } else if annot.Definition != nil {
+ schema = *annot.Definition
+ }
+
+ tpe, err := loadSchema(schema)
+ if err != nil {
+ return nil, nil, NewError(TypeErr, rule.Location, err.Error())
+ }
+
+ return annot.Path, tpe, nil
+}
+
+func errAnnotationRedeclared(a *Annotations, other *Location) *Error {
+ return NewError(TypeErr, a.Location, "%v annotation redeclared: %v", a.Scope, other)
+}
+
+type annotationSet struct {
+ byRule map[*Rule][]*Annotations
+ byPackage map[*Package]*Annotations
+ byPath *annotationTreeNode
+}
+
+func buildAnnotationSet(rules []util.T) (*annotationSet, Errors) {
+ as := newAnnotationSet()
+ processed := map[*Module]struct{}{}
+ var errs Errors
+ for _, x := range rules {
+ module := x.(*Rule).Module
+ if _, ok := processed[module]; ok {
+ continue
+ }
+ processed[module] = struct{}{}
+ for _, a := range module.Annotations {
+ if err := as.Add(a); err != nil {
+ errs = append(errs, err)
+ }
+ }
+ }
+ if len(errs) > 0 {
+ return nil, errs
+ }
+ return as, nil
+}
+
+func newAnnotationSet() *annotationSet {
+ return &annotationSet{
+ byRule: map[*Rule][]*Annotations{},
+ byPackage: map[*Package]*Annotations{},
+ byPath: newAnnotationTree(),
+ }
+}
+
+func (as *annotationSet) Add(a *Annotations) *Error {
+ switch a.Scope {
+ case annotationScopeRule:
+ rule := a.node.(*Rule)
+ as.byRule[rule] = append(as.byRule[rule], a)
+ case annotationScopePackage:
+ pkg := a.node.(*Package)
+ if exist, ok := as.byPackage[pkg]; ok {
+ return errAnnotationRedeclared(a, exist.Location)
+ }
+ as.byPackage[pkg] = a
+ case annotationScopeDocument:
+ rule := a.node.(*Rule)
+ path := rule.Path()
+ x := as.byPath.Get(path)
+ if x != nil {
+ return errAnnotationRedeclared(a, x.Value.Location)
+ }
+ as.byPath.Insert(path, a)
+ case annotationScopeSubpackages:
+ pkg := a.node.(*Package)
+ x := as.byPath.Get(pkg.Path)
+ if x != nil {
+ return errAnnotationRedeclared(a, x.Value.Location)
+ }
+ as.byPath.Insert(pkg.Path, a)
+ }
+ return nil
+}
+
+func (as *annotationSet) GetRuleScope(r *Rule) []*Annotations {
+ if as == nil {
+ return nil
+ }
+ return as.byRule[r]
+}
+
+func (as *annotationSet) GetSubpackagesScope(path Ref) []*Annotations {
+ if as == nil {
+ return nil
+ }
+ return as.byPath.Ancestors(path)
+}
+
+func (as *annotationSet) GetDocumentScope(path Ref) *Annotations {
+ if as == nil {
+ return nil
+ }
+ if node := as.byPath.Get(path); node != nil {
+ return node.Value
+ }
+ return nil
+}
+
+func (as *annotationSet) GetPackageScope(pkg *Package) *Annotations {
+ if as == nil {
+ return nil
+ }
+ return as.byPackage[pkg]
+}
+
+type annotationTreeNode struct {
+ Value *Annotations
+ Children map[Value]*annotationTreeNode // we assume key elements are hashable (vars and strings only!)
+}
+
+func newAnnotationTree() *annotationTreeNode {
+ return &annotationTreeNode{
+ Value: nil,
+ Children: map[Value]*annotationTreeNode{},
+ }
+}
+
+func (t *annotationTreeNode) Insert(path Ref, value *Annotations) {
+ node := t
+ for _, k := range path {
+ child, ok := node.Children[k.Value]
+ if !ok {
+ child = newAnnotationTree()
+ node.Children[k.Value] = child
+ }
+ node = child
+ }
+ node.Value = value
+}
+
+func (t *annotationTreeNode) Get(path Ref) *annotationTreeNode {
+ node := t
+ for _, k := range path {
+ if node == nil {
+ return nil
+ }
+ child, ok := node.Children[k.Value]
+ if !ok {
+ return nil
+ }
+ node = child
+ }
+ return node
+}
+
+func (t *annotationTreeNode) Ancestors(path Ref) (result []*Annotations) {
+ node := t
+ for _, k := range path {
+ if node == nil {
+ return result
+ }
+ child, ok := node.Children[k.Value]
+ if !ok {
+ return result
+ }
+ if child.Value != nil {
+ result = append(result, child.Value)
+ }
+ node = child
+ }
+ return result
+}
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/ast/compare.go b/constraint/vendor/github.com/open-policy-agent/opa/ast/compare.go
index 627ca2407..bdffeb06d 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/ast/compare.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/ast/compare.go
@@ -97,14 +97,48 @@ func Compare(a, b interface{}) int {
}
}
- bigA, ok := new(big.Float).SetString(string(a))
+ // We use big.Rat for comparing big numbers.
+ // It replaces big.Float due to following reason:
+ // big.Float comes with a default precision of 64, and setting a
+ // larger precision results in more memory being allocated
+ // (regardless of the actual number we are parsing with SetString).
+ //
+ // Note: If we're so close to zero that big.Float says we are zero, do
+ // *not* big.Rat).SetString on the original string it'll potentially
+ // take very long.
+ var bigA, bigB *big.Rat
+ fa, ok := new(big.Float).SetString(string(a))
if !ok {
panic("illegal value")
}
- bigB, ok := new(big.Float).SetString(string(b.(Number)))
+ if fa.IsInt() {
+ if i, _ := fa.Int64(); i == 0 {
+ bigA = new(big.Rat).SetInt64(0)
+ }
+ }
+ if bigA == nil {
+ bigA, ok = new(big.Rat).SetString(string(a))
+ if !ok {
+ panic("illegal value")
+ }
+ }
+
+ fb, ok := new(big.Float).SetString(string(b.(Number)))
if !ok {
panic("illegal value")
}
+ if fb.IsInt() {
+ if i, _ := fb.Int64(); i == 0 {
+ bigB = new(big.Rat).SetInt64(0)
+ }
+ }
+ if bigB == nil {
+ bigB, ok = new(big.Rat).SetString(string(b.(Number)))
+ if !ok {
+ panic("illegal value")
+ }
+ }
+
return bigA.Cmp(bigB)
case String:
b := b.(String)
@@ -187,6 +221,9 @@ func Compare(a, b interface{}) int {
case *Package:
b := b.(*Package)
return a.Compare(b)
+ case *Annotations:
+ b := b.(*Annotations)
+ return a.Compare(b)
case *Module:
b := b.(*Module)
return a.Compare(b)
@@ -246,6 +283,8 @@ func sortOrder(x interface{}) int {
return 1001
case *Package:
return 1002
+ case *Annotations:
+ return 1003
case *Module:
return 10000
}
@@ -271,6 +310,25 @@ func importsCompare(a, b []*Import) int {
return 0
}
+func annotationsCompare(a, b []*Annotations) int {
+ minLen := len(a)
+ if len(b) < minLen {
+ minLen = len(b)
+ }
+ for i := 0; i < minLen; i++ {
+ if cmp := a[i].Compare(b[i]); cmp != 0 {
+ return cmp
+ }
+ }
+ if len(a) < len(b) {
+ return -1
+ }
+ if len(b) < len(a) {
+ return 1
+ }
+ return 0
+}
+
func rulesCompare(a, b []*Rule) int {
minLen := len(a)
if len(b) < minLen {
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/ast/compile.go b/constraint/vendor/github.com/open-policy-agent/opa/ast/compile.go
index 2089e9b58..6fbc26a0c 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/ast/compile.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/ast/compile.go
@@ -6,11 +6,15 @@ package ast
import (
"fmt"
+ "io"
"sort"
"strconv"
"strings"
+ "github.com/open-policy-agent/opa/internal/debug"
+ "github.com/open-policy-agent/opa/internal/gojsonschema"
"github.com/open-policy-agent/opa/metrics"
+ "github.com/open-policy-agent/opa/types"
"github.com/open-policy-agent/opa/util"
)
@@ -101,6 +105,9 @@ type Compiler struct {
unsafeBuiltinsMap map[string]struct{} // user-supplied set of unsafe built-ins functions to block (deprecated: use capabilities)
comprehensionIndices map[*Term]*ComprehensionIndex // comprehension key index
initialized bool // indicates if init() has been called
+ debug debug.Debug // emits debug information produced during compilation
+ schemaSet *SchemaSet // user-supplied schemas for input and data documents
+ inputType types.Type // global input type retrieved from schema set
}
// CompilerStage defines the interface for stages in the compiler.
@@ -207,14 +214,11 @@ type QueryCompilerStageDefinition struct {
Stage QueryCompilerStage
}
-const compileStageMetricPrefex = "ast_compile_stage_"
-
// NewCompiler returns a new empty compiler.
func NewCompiler() *Compiler {
c := &Compiler{
Modules: map[string]*Module{},
- TypeEnv: NewTypeEnv(),
RewrittenVars: map[Var]Var{},
ruleIndices: util.NewHashMap(func(a, b util.T) bool {
r1, r2 := a.(Ref), b.(Ref)
@@ -226,6 +230,7 @@ func NewCompiler() *Compiler {
after: map[string][]CompilerStageDefinition{},
unsafeBuiltinsMap: map[string]struct{}{},
comprehensionIndices: map[*Term]*ComprehensionIndex{},
+ debug: debug.Discard(),
}
c.ModuleTree = NewModuleTree(nil)
@@ -308,6 +313,15 @@ func (c *Compiler) WithCapabilities(capabilities *Capabilities) *Compiler {
return c
}
+// WithDebug sets where debug messages are written to. Passing `nil` has no
+// effect.
+func (c *Compiler) WithDebug(sink io.Writer) *Compiler {
+ if sink != nil {
+ c.debug = debug.New(sink)
+ }
+ return c
+}
+
// WithBuiltins is deprecated. Use WithCapabilities instead.
func (c *Compiler) WithBuiltins(builtins map[string]*Builtin) *Compiler {
c.customBuiltins = make(map[string]*Builtin)
@@ -351,6 +365,12 @@ func (c *Compiler) Compile(modules map[string]*Module) {
c.compile()
}
+// WithSchemas sets a schemaSet to the compiler
+func (c *Compiler) WithSchemas(schemas *SchemaSet) *Compiler {
+ c.schemaSet = schemas
+ return c
+}
+
// Failed returns true if a compilation error has been encountered.
func (c *Compiler) Failed() bool {
return len(c.Errors) > 0
@@ -606,6 +626,14 @@ func (c *Compiler) RuleIndex(path Ref) RuleIndex {
return r.(RuleIndex)
}
+// PassesTypeCheck determines whether the given body passes type checking
+func (c *Compiler) PassesTypeCheck(body Body) bool {
+ checker := newTypeChecker().WithSchemaSet(c.schemaSet).WithInputType(c.inputType)
+ env := c.TypeEnv
+ _, errs := checker.CheckBody(env, body)
+ return len(errs) == 0
+}
+
// ModuleLoader defines the interface that callers can implement to enable lazy
// loading of modules during compilation.
type ModuleLoader func(resolved map[string]*Module) (parsed map[string]*Module, err error)
@@ -652,7 +680,7 @@ func (c *Compiler) buildComprehensionIndices() {
WalkRules(c.Modules[name], func(r *Rule) bool {
candidates := r.Head.Args.Vars()
candidates.Update(ReservedVars)
- n := buildComprehensionIndices(c.GetArity, candidates, r.Body, c.comprehensionIndices)
+ n := buildComprehensionIndices(c.debug, c.GetArity, candidates, c.RewrittenVars, r.Body, c.comprehensionIndices)
c.counterAdd(compileStageComprehensionIndexBuild, n)
return false
})
@@ -791,13 +819,13 @@ func (c *Compiler) checkSafetyRuleBodies() {
WalkRules(m, func(r *Rule) bool {
safe := ReservedVars.Copy()
safe.Update(r.Head.Args.Vars())
- r.Body = c.checkBodySafety(safe, m, r.Body)
+ r.Body = c.checkBodySafety(safe, r.Body)
return false
})
}
}
-func (c *Compiler) checkBodySafety(safe VarSet, m *Module, b Body) Body {
+func (c *Compiler) checkBodySafety(safe VarSet, b Body) Body {
reordered, unsafe := reorderBodyForSafety(c.builtins, c.GetArity, safe, b)
if errs := safetyErrorSlice(unsafe); len(errs) > 0 {
for _, err := range errs {
@@ -836,12 +864,93 @@ func (c *Compiler) checkSafetyRuleHeads() {
}
}
+func compileSchema(goSchema interface{}) (*gojsonschema.Schema, error) {
+ var refLoader gojsonschema.JSONLoader
+ sl := gojsonschema.NewSchemaLoader()
+
+ if goSchema != nil {
+ refLoader = gojsonschema.NewGoLoader(goSchema)
+ } else {
+ return nil, fmt.Errorf("no schema as input to compile")
+ }
+ schemasCompiled, err := sl.Compile(refLoader)
+ if err != nil {
+ return nil, fmt.Errorf("unable to compile the schema due to: %w", err)
+ }
+ return schemasCompiled, nil
+}
+
+func parseSchema(schema interface{}) (types.Type, error) {
+ subSchema, ok := schema.(*gojsonschema.SubSchema)
+ if !ok {
+ return nil, fmt.Errorf("unexpected schema type %v", subSchema)
+ }
+
+ // Handle referenced schemas, returns directly when a $ref is found
+ if subSchema.RefSchema != nil {
+ return parseSchema(subSchema.RefSchema)
+ }
+
+ if subSchema.Types.IsTyped() {
+ if subSchema.Types.Contains("boolean") {
+ return types.B, nil
+
+ } else if subSchema.Types.Contains("string") {
+ return types.S, nil
+
+ } else if subSchema.Types.Contains("integer") || subSchema.Types.Contains("number") {
+ return types.N, nil
+
+ } else if subSchema.Types.Contains("object") {
+ if len(subSchema.PropertiesChildren) > 0 {
+ staticProps := make([]*types.StaticProperty, 0, len(subSchema.PropertiesChildren))
+ for _, pSchema := range subSchema.PropertiesChildren {
+ newtype, err := parseSchema(pSchema)
+ if err != nil {
+ return nil, fmt.Errorf("unexpected schema type %v: %w", pSchema, err)
+ }
+ staticProps = append(staticProps, types.NewStaticProperty(pSchema.Property, newtype))
+ }
+ return types.NewObject(staticProps, nil), nil
+ }
+ return types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)), nil
+
+ } else if subSchema.Types.Contains("array") {
+ if len(subSchema.ItemsChildren) > 0 {
+ if subSchema.ItemsChildrenIsSingleSchema {
+ iSchema := subSchema.ItemsChildren[0]
+ newtype, err := parseSchema(iSchema)
+ if err != nil {
+ return nil, fmt.Errorf("unexpected schema type %v", iSchema)
+ }
+ return types.NewArray(nil, newtype), nil
+ }
+ newTypes := make([]types.Type, 0, len(subSchema.ItemsChildren))
+ for i := 0; i != len(subSchema.ItemsChildren); i++ {
+ iSchema := subSchema.ItemsChildren[i]
+ newtype, err := parseSchema(iSchema)
+ if err != nil {
+ return nil, fmt.Errorf("unexpected schema type %v", iSchema)
+ }
+ newTypes = append(newTypes, newtype)
+ }
+ return types.NewArray(newTypes, nil), nil
+ }
+ return types.NewArray(nil, types.A), nil
+ }
+ }
+ return types.A, nil
+}
+
// checkTypes runs the type checker on all rules. The type checker builds a
// TypeEnv that is stored on the compiler.
func (c *Compiler) checkTypes() {
// Recursion is caught in earlier step, so this cannot fail.
sorted, _ := c.Graph.Sort()
- checker := newTypeChecker().WithVarRewriter(rewriteVarsInRef(c.RewrittenVars))
+ checker := newTypeChecker().
+ WithSchemaSet(c.schemaSet).
+ WithInputType(c.inputType).
+ WithVarRewriter(rewriteVarsInRef(c.RewrittenVars))
env, errs := checker.CheckTypes(c.TypeEnv, sorted)
for _, err := range errs {
c.err(err)
@@ -916,8 +1025,23 @@ func (c *Compiler) init() {
c.builtins[name] = bi
}
- tc := newTypeChecker()
- c.TypeEnv = tc.checkLanguageBuiltins(nil, c.builtins)
+ // Load the global input schema if one was provided.
+ if c.schemaSet != nil {
+ if schema := c.schemaSet.Get(SchemaRootRef); schema != nil {
+ tpe, err := loadSchema(schema)
+ if err != nil {
+ c.err(NewError(TypeErr, nil, err.Error()))
+ } else {
+ c.inputType = tpe
+ }
+ }
+ }
+
+ c.TypeEnv = newTypeChecker().
+ WithSchemaSet(c.schemaSet).
+ WithInputType(c.inputType).
+ Env(c.builtins)
+
c.initialized = true
}
@@ -1021,7 +1145,7 @@ func (c *Compiler) rewriteComprehensionTerms() {
f := newEqualityFactory(c.localvargen)
for _, name := range c.sorted {
mod := c.Modules[name]
- rewriteComprehensionTerms(f, mod)
+ _, _ = rewriteComprehensionTerms(f, mod) // ignore error
}
}
@@ -1316,7 +1440,7 @@ func (c *Compiler) rewriteWithModifiers() {
return body, nil
})
- Transform(t, mod)
+ _, _ = Transform(t, mod) // ignore error
}
}
@@ -1454,15 +1578,23 @@ func (qc *queryCompiler) resolveRefs(qctx *QueryContext, body Body) (Body, error
var globals map[Var]Ref
- if qctx != nil && qctx.Package != nil {
- var ruleExports []Var
- rules := qc.compiler.getExports()
- if exist, ok := rules.Get(qctx.Package.Path); ok {
- ruleExports = exist.([]Var)
- }
+ if qctx != nil {
+ pkg := qctx.Package
+ // Query compiler ought to generate a package if one was not provided and one or more imports were provided.
+ // The generated package name could even be an empty string to avoid conflicts (it doesn't have to be valid syntactically)
+ if pkg == nil && len(qctx.Imports) > 0 {
+ pkg = &Package{Path: RefTerm(VarTerm("")).Value.(Ref)}
+ }
+ if pkg != nil {
+ var ruleExports []Var
+ rules := qc.compiler.getExports()
+ if exist, ok := rules.Get(pkg.Path); ok {
+ ruleExports = exist.([]Var)
+ }
- globals = getGlobals(qctx.Package, ruleExports, qc.qctx.Imports)
- qctx.Imports = nil
+ globals = getGlobals(qctx.Package, ruleExports, qctx.Imports)
+ qctx.Imports = nil
+ }
}
ignore := &declaredVarStack{declaredVars(body)}
@@ -1526,11 +1658,15 @@ func (qc *queryCompiler) checkSafety(_ *QueryContext, body Body) (Body, error) {
func (qc *queryCompiler) checkTypes(qctx *QueryContext, body Body) (Body, error) {
var errs Errors
- checker := newTypeChecker().WithVarRewriter(rewriteVarsInRef(qc.rewritten, qc.compiler.RewrittenVars))
+ checker := newTypeChecker().
+ WithSchemaSet(qc.compiler.schemaSet).
+ WithInputType(qc.compiler.inputType).
+ WithVarRewriter(rewriteVarsInRef(qc.rewritten, qc.compiler.RewrittenVars))
qc.typeEnv, errs = checker.CheckBody(qc.compiler.TypeEnv, body)
if len(errs) > 0 {
return nil, errs
}
+
return body, nil
}
@@ -1560,7 +1696,7 @@ func (qc *queryCompiler) rewriteWithModifiers(qctx *QueryContext, body Body) (Bo
func (qc *queryCompiler) buildComprehensionIndices(qctx *QueryContext, body Body) (Body, error) {
// NOTE(tsandall): The query compiler does not have a metrics object so we
// cannot record index metrics currently.
- _ = buildComprehensionIndices(qc.compiler.GetArity, ReservedVars, body, qc.comprehensionIndices)
+ _ = buildComprehensionIndices(qc.compiler.debug, qc.compiler.GetArity, ReservedVars, qc.RewrittenVars(), body, qc.comprehensionIndices)
return body, nil
}
@@ -1581,11 +1717,13 @@ func (ci *ComprehensionIndex) String() string {
return fmt.Sprintf("", NewArray(ci.Keys...))
}
-func buildComprehensionIndices(arity func(Ref) int, candidates VarSet, node interface{}, result map[*Term]*ComprehensionIndex) (n uint64) {
+func buildComprehensionIndices(dbg debug.Debug, arity func(Ref) int, candidates VarSet, rwVars map[Var]Var, node interface{}, result map[*Term]*ComprehensionIndex) uint64 {
+ var n uint64
WalkBodies(node, func(b Body) bool {
cpy := candidates.Copy()
for _, expr := range b {
- if index := getComprehensionIndex(arity, cpy, expr); index != nil {
+ index := getComprehensionIndex(dbg, arity, cpy, rwVars, expr)
+ if index != nil {
result[index.Term] = index
n++
}
@@ -1598,11 +1736,13 @@ func buildComprehensionIndices(arity func(Ref) int, candidates VarSet, node inte
return n
}
-func getComprehensionIndex(arity func(Ref) int, candidates VarSet, expr *Expr) *ComprehensionIndex {
+func getComprehensionIndex(dbg debug.Debug, arity func(Ref) int, candidates VarSet, rwVars map[Var]Var, expr *Expr) *ComprehensionIndex {
// Ignore everything except = expressions. Extract
// the comprehension term from the expression.
if !expr.IsEquality() || expr.Negated || len(expr.With) > 0 {
+ // No debug message, these are assumed to be known hinderances
+ // to comprehension indexing.
return nil
}
@@ -1617,6 +1757,7 @@ func getComprehensionIndex(arity func(Ref) int, candidates VarSet, expr *Expr) *
}
if term == nil {
+ // no debug for this, it's the ordinary "nothing to do here" case
return nil
}
@@ -1653,6 +1794,7 @@ func getComprehensionIndex(arity func(Ref) int, candidates VarSet, expr *Expr) *
unsafe := body.Vars(SafetyCheckVisitorParams).Diff(outputs).Diff(ReservedVars)
if len(unsafe) > 0 {
+ dbg.Printf("%s: comprehension index: unsafe vars: %v", expr.Location, unsafe)
return nil
}
@@ -1662,6 +1804,7 @@ func getComprehensionIndex(arity func(Ref) int, candidates VarSet, expr *Expr) *
regressionVis := newComprehensionIndexRegressionCheckVisitor(candidates)
regressionVis.Walk(body)
if regressionVis.worse {
+ dbg.Printf("%s: comprehension index: output vars intersect candidates", expr.Location)
return nil
}
@@ -1671,6 +1814,7 @@ func getComprehensionIndex(arity func(Ref) int, candidates VarSet, expr *Expr) *
nestedVis := newComprehensionIndexNestedCandidateVisitor(candidates)
nestedVis.Walk(body)
if nestedVis.found {
+ dbg.Printf("%s: comprehension index: nested comprehensions close over candidates", expr.Location)
return nil
}
@@ -1680,6 +1824,7 @@ func getComprehensionIndex(arity func(Ref) int, candidates VarSet, expr *Expr) *
// empty, there is no indexing to do.
indexVars := candidates.Intersect(outputs)
if len(indexVars) == 0 {
+ dbg.Printf("%s: comprehension index: no index vars", expr.Location)
return nil
}
@@ -1693,6 +1838,15 @@ func getComprehensionIndex(arity func(Ref) int, candidates VarSet, expr *Expr) *
return result[i].Value.Compare(result[j].Value) < 0
})
+ debugRes := make([]*Term, len(result))
+ for i, r := range result {
+ if o, ok := rwVars[r.Value.(Var)]; ok {
+ debugRes[i] = NewTerm(o)
+ } else {
+ debugRes[i] = r
+ }
+ }
+ dbg.Printf("%s: comprehension index: built with keys: %v", expr.Location, debugRes)
return &ComprehensionIndex{Term: term, Keys: result}
}
@@ -1702,7 +1856,7 @@ type comprehensionIndexRegressionCheckVisitor struct {
worse bool
}
-// TOOD(tsandall): Improve this so that users can either supply this list explicitly
+// TODO(tsandall): Improve this so that users can either supply this list explicitly
// or the information is maintained on the built-in function declaration. What we really
// need to know is whether the built-in function allows callers to push down output
// values or not. It's unlikely that anything outside of OPA does this today so this
@@ -1753,7 +1907,6 @@ func (vis *comprehensionIndexRegressionCheckVisitor) assertEmptyIntersection(vs
type comprehensionIndexNestedCandidateVisitor struct {
candidates VarSet
- nested bool
found bool
}
@@ -1996,7 +2149,7 @@ func (g *Graph) Sort() (sorted []util.T, ok bool) {
return g.sorted, true
}
- sort := &graphSort{
+ sorter := &graphSort{
sorted: make([]util.T, 0, len(g.nodes)),
deps: g.Dependencies,
marked: map[util.T]struct{}{},
@@ -2004,12 +2157,12 @@ func (g *Graph) Sort() (sorted []util.T, ok bool) {
}
for node := range g.nodes {
- if !sort.Visit(node) {
+ if !sorter.Visit(node) {
return nil, false
}
}
- g.sorted = sort.sorted
+ g.sorted = sorter.sorted
return g.sorted, true
}
@@ -2917,15 +3070,16 @@ func rewriteComprehensionTerms(f *equalityFactory, node interface{}) (interface{
func rewriteEquals(x interface{}) {
doubleEq := Equal.Ref()
unifyOp := Equality.Ref()
- WalkExprs(x, func(x *Expr) bool {
- if x.IsCall() {
+ t := NewGenericTransformer(func(x interface{}) (interface{}, error) {
+ if x, ok := x.(*Expr); ok && x.IsCall() {
operator := x.Operator()
if operator.Equal(doubleEq) && len(x.Operands()) == 2 {
x.SetOperator(NewTerm(unifyOp))
}
}
- return false
+ return x, nil
})
+ _, _ = Transform(t, x) // ignore error
}
// rewriteDynamics will rewrite the body so that dynamic terms (i.e., refs and
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/ast/env.go b/constraint/vendor/github.com/open-policy-agent/opa/ast/env.go
index ab4f0e688..60006baaf 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/ast/env.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/ast/env.go
@@ -11,14 +11,17 @@ import (
// TypeEnv contains type info for static analysis such as type checking.
type TypeEnv struct {
- tree *typeTreeNode
- next *TypeEnv
+ tree *typeTreeNode
+ next *TypeEnv
+ newChecker func() *typeChecker
}
-// NewTypeEnv returns an empty TypeEnv.
-func NewTypeEnv() *TypeEnv {
+// newTypeEnv returns an empty TypeEnv. The constructor is not exported because
+// type environments should only be created by the type checker.
+func newTypeEnv(f func() *typeChecker) *TypeEnv {
return &TypeEnv{
- tree: newTypeTree(),
+ tree: newTypeTree(),
+ newChecker: f,
}
}
@@ -94,22 +97,19 @@ func (env *TypeEnv) Get(x interface{}) types.Type {
// Comprehensions.
case *ArrayComprehension:
- checker := newTypeChecker()
- cpy, errs := checker.CheckBody(env, x.Body)
+ cpy, errs := env.newChecker().CheckBody(env, x.Body)
if len(errs) == 0 {
return types.NewArray(nil, cpy.Get(x.Term))
}
return nil
case *ObjectComprehension:
- checker := newTypeChecker()
- cpy, errs := checker.CheckBody(env, x.Body)
+ cpy, errs := env.newChecker().CheckBody(env, x.Body)
if len(errs) == 0 {
return types.NewObject(nil, types.NewDynamicProperty(cpy.Get(x.Key), cpy.Get(x.Value)))
}
return nil
case *SetComprehension:
- checker := newTypeChecker()
- cpy, errs := checker.CheckBody(env, x.Body)
+ cpy, errs := env.newChecker().CheckBody(env, x.Body)
if len(errs) == 0 {
return types.NewSet(cpy.Get(x.Term))
}
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/ast/errors.go b/constraint/vendor/github.com/open-policy-agent/opa/ast/errors.go
index 76a084214..11348b3d7 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/ast/errors.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/ast/errors.go
@@ -24,9 +24,9 @@ func (e Errors) Error() string {
return fmt.Sprintf("1 error occurred: %v", e[0].Error())
}
- s := []string{}
- for _, err := range e {
- s = append(s, err.Error())
+ s := make([]string, len(e))
+ for i, err := range e {
+ s[i] = err.Error()
}
return fmt.Sprintf("%d errors occurred:\n%s", len(e), strings.Join(s, "\n"))
@@ -124,7 +124,6 @@ func NewError(code string, loc *Location, f string, a ...interface{}) *Error {
var (
errPartialRuleAssignOperator = fmt.Errorf("partial rules must use = operator (not := operator)")
- errElseAssignOperator = fmt.Errorf("else keyword cannot be used on rule declared with := operator")
errFunctionAssignOperator = fmt.Errorf("functions must use = operator (not := operator)")
)
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/ast/index.go b/constraint/vendor/github.com/open-policy-agent/opa/ast/index.go
index 3e9a9fc92..a54e378a5 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/ast/index.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/ast/index.go
@@ -6,7 +6,6 @@ package ast
import (
"fmt"
- "io"
"sort"
"strings"
@@ -17,18 +16,18 @@ import (
type RuleIndex interface {
// Build tries to construct an index for the given rules. If the index was
- // constructed, ok is true, otherwise false.
- Build(rules []*Rule) (ok bool)
+ // constructed, it returns true, otherwise false.
+ Build(rules []*Rule) bool
// Lookup searches the index for rules that will match the provided
// resolver. If the resolver returns an error, it is returned via err.
- Lookup(resolver ValueResolver) (result *IndexResult, err error)
+ Lookup(resolver ValueResolver) (*IndexResult, error)
// AllRules traverses the index and returns all rules that will match
// the provided resolver without any optimizations (effectively with
// indexing disabled). If the resolver returns an error, it is returned
// via err.
- AllRules(resolver ValueResolver) (result *IndexResult, err error)
+ AllRules(resolver ValueResolver) (*IndexResult, error)
}
// IndexResult contains the result of an index lookup.
@@ -421,7 +420,7 @@ func (node *trieNode) String() string {
flags = append(flags, fmt.Sprintf("array:%p", node.array))
}
if len(node.scalars) > 0 {
- buf := []string{}
+ buf := make([]string, 0, len(node.scalars))
for k, v := range node.scalars {
buf = append(buf, fmt.Sprintf("scalar(%v):%p", k, v))
}
@@ -432,7 +431,7 @@ func (node *trieNode) String() string {
flags = append(flags, fmt.Sprintf("%d rule(s)", len(node.rules)))
}
if len(node.mappers) > 0 {
- flags = append(flags, "mapper(s)")
+ flags = append(flags, fmt.Sprintf("%d mapper(s)", len(node.mappers)))
}
return strings.Join(flags, " ")
}
@@ -575,7 +574,10 @@ func (node *trieNode) traverse(resolver ValueResolver, tr *trieTraversalResult)
}
if node.undefined != nil {
- node.undefined.Traverse(resolver, tr)
+ err = node.undefined.Traverse(resolver, tr)
+ if err != nil {
+ return err
+ }
}
if v == nil {
@@ -583,11 +585,14 @@ func (node *trieNode) traverse(resolver ValueResolver, tr *trieTraversalResult)
}
if node.any != nil {
- node.any.Traverse(resolver, tr)
+ err = node.any.Traverse(resolver, tr)
+ if err != nil {
+ return err
+ }
}
- if len(node.mappers) == 0 {
- return node.traverseValue(resolver, tr, v)
+ if err := node.traverseValue(resolver, tr, v); err != nil {
+ return err
}
for i := range node.mappers {
@@ -632,7 +637,10 @@ func (node *trieNode) traverseArray(resolver ValueResolver, tr *trieTraversalRes
}
if node.any != nil {
- node.any.traverseArray(resolver, tr, arr.Slice(1, -1))
+ err := node.any.traverseArray(resolver, tr, arr.Slice(1, -1))
+ if err != nil {
+ return err
+ }
}
child, ok := node.scalars[head]
@@ -674,18 +682,6 @@ func (node *trieNode) traverseUnknown(resolver ValueResolver, tr *trieTraversalR
return nil
}
-type triePrinter struct {
- depth int
- w io.Writer
-}
-
-func (p triePrinter) Do(x interface{}) trieWalker {
- padding := strings.Repeat(" ", p.depth)
- fmt.Fprintf(p.w, "%v%v\n", padding, x)
- p.depth++
- return p
-}
-
func eqOperandsToRefAndValue(isVirtual func(Ref) bool, a, b *Term) (Ref, Value, bool) {
ref, ok := a.Value.(Ref)
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/ast/internal/scanner/scanner.go b/constraint/vendor/github.com/open-policy-agent/opa/ast/internal/scanner/scanner.go
index 8223e59e6..cb4bd3a59 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/ast/internal/scanner/scanner.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/ast/internal/scanner/scanner.go
@@ -19,14 +19,13 @@ const bom = 0xFEFF
// Scanner is used to tokenize an input stream of
// Rego source code.
type Scanner struct {
- offset int
- row int
- col int
- bs []byte
- curr rune
- width int
- errors []Error
- filename string
+ offset int
+ row int
+ col int
+ bs []byte
+ curr rune
+ width int
+ errors []Error
}
// Error represents a scanner error.
@@ -347,13 +346,6 @@ func (s *Scanner) next() {
}
}
-func (s *Scanner) peek(i int) rune {
- if s.offset+i < len(s.bs) {
- return rune(s.bs[s.offset+i])
- }
- return 0
-}
-
func (s *Scanner) literalStart() int {
// The current offset is at the first character past the literal delimiter (#, ", `, etc.)
// Need to subtract width of first character (plus one for the delimiter).
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/ast/parser.go b/constraint/vendor/github.com/open-policy-agent/opa/ast/parser.go
index 58bb0f02f..146a41bd1 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/ast/parser.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/ast/parser.go
@@ -5,10 +5,17 @@
package ast
import (
+ "bytes"
"encoding/json"
"fmt"
"io"
"math/big"
+ "regexp"
+ "strconv"
+ "strings"
+
+ "github.com/pkg/errors"
+ "gopkg.in/yaml.v2"
"github.com/open-policy-agent/opa/ast/internal/scanner"
"github.com/open-policy-agent/opa/ast/internal/tokens"
@@ -52,13 +59,20 @@ func (s *state) Text(offset, end int) []byte {
// Parser is used to parse Rego statements.
type Parser struct {
- r io.Reader
- s *state
+ r io.Reader
+ s *state
+ po ParserOptions
+}
+
+// ParserOptions defines the options for parsing Rego statements.
+type ParserOptions struct {
+ ProcessAnnotation bool
}
// NewParser creates and initializes a Parser.
func NewParser() *Parser {
- p := &Parser{s: &state{}}
+ p := &Parser{s: &state{},
+ po: ParserOptions{}}
return p
}
@@ -76,6 +90,21 @@ func (p *Parser) WithReader(r io.Reader) *Parser {
return p
}
+// WithProcessAnnotation enables or disables the processing of
+// annotations by the Parser
+func (p *Parser) WithProcessAnnotation(processAnnotation bool) *Parser {
+ p.po.ProcessAnnotation = processAnnotation
+ return p
+}
+
+const (
+ annotationScopePackage = "package"
+ annotationScopeImport = "import"
+ annotationScopeRule = "rule"
+ annotationScopeDocument = "document"
+ annotationScopeSubpackages = "subpackages"
+)
+
// Parse will read the Rego source and parse statements and
// comments as they are found. Any errors encountered while
// parsing will be accumulated and returned as a list of Errors.
@@ -138,7 +167,7 @@ func (p *Parser) Parse() ([]Statement, []*Comment, Errors) {
}
p.restore(s)
- s = p.save()
+ p.save() // no need to save return value to s
if body := p.parseQuery(true, tokens.EOF); body != nil {
stmts = append(stmts, body)
@@ -148,9 +177,45 @@ func (p *Parser) Parse() ([]Statement, []*Comment, Errors) {
break
}
+ if p.po.ProcessAnnotation {
+ stmts = p.parseAnnotations(stmts)
+ }
+
return stmts, p.s.comments, p.s.errors
}
+func (p *Parser) parseAnnotations(stmts []Statement) []Statement {
+
+ var hint = []byte("METADATA")
+ var curr *metadataParser
+ var blocks []*metadataParser
+
+ for i := 0; i < len(p.s.comments); i++ {
+ if curr != nil {
+ if p.s.comments[i].Location.Row == p.s.comments[i-1].Location.Row+1 && p.s.comments[i].Location.Col == 1 {
+ curr.Append(p.s.comments[i])
+ continue
+ }
+ curr = nil
+ }
+ if bytes.HasPrefix(bytes.TrimSpace(p.s.comments[i].Text), hint) {
+ curr = newMetadataParser(p.s.comments[i].Location)
+ blocks = append(blocks, curr)
+ }
+ }
+
+ for _, b := range blocks {
+ a, err := b.Parse()
+ if err != nil {
+ p.error(b.loc, err.Error())
+ } else {
+ stmts = append(stmts, a)
+ }
+ }
+
+ return stmts
+}
+
func (p *Parser) parsePackage() *Package {
var pkg Package
@@ -867,11 +932,19 @@ func (p *Parser) parseNumber() *Term {
}
}
+ // Check for multiple leading 0's, parsed by math/big.Float.Parse as decimal 0:
+ // https://golang.org/pkg/math/big/#Float.Parse
+ if ((len(prefix) != 0 && prefix[0] == '-') || len(prefix) == 0) &&
+ len(p.s.lit) > 1 && p.s.lit[0] == '0' && p.s.lit[1] == '0' {
+ p.illegal("expected number")
+ return nil
+ }
+
// Ensure that the number is valid
s := prefix + p.s.lit
f, ok := new(big.Float).SetString(s)
if !ok {
- p.illegal("expected number")
+ p.illegal("invalid float")
return nil
}
@@ -883,7 +956,7 @@ func (p *Parser) parseNumber() *Term {
//
// The limit is arbitrary.
exp := f.MantExp(nil)
- if exp > 1e5 || exp < -1e5 {
+ if exp > 1e5 || exp < -1e5 || f.IsInf() { // +/- inf, exp is 0
p.error(p.s.Loc(), "number too big")
return nil
}
@@ -1468,7 +1541,7 @@ func (p *Parser) setLoc(term *Term, loc *location.Location, offset, end int) *Te
func (p *Parser) validateDefaultRuleValue(rule *Rule) bool {
if rule.Head.Value == nil {
- p.error(rule.Loc(), fmt.Sprintf("illegal default rule (must have a value)"))
+ p.error(rule.Loc(), "illegal default rule (must have a value)")
return false
}
@@ -1488,3 +1561,145 @@ func (p *Parser) validateDefaultRuleValue(rule *Rule) bool {
vis.Walk(rule.Head.Value.Value)
return valid
}
+
+type rawAnnotation struct {
+ Scope string `json:"scope"`
+ Schemas []rawSchemaAnnotation `json:"schemas"`
+}
+
+type rawSchemaAnnotation map[string]interface{}
+
+type metadataParser struct {
+ buf *bytes.Buffer
+ comments []*Comment
+ loc *location.Location
+}
+
+func newMetadataParser(loc *Location) *metadataParser {
+ return &metadataParser{loc: loc, buf: bytes.NewBuffer(nil)}
+}
+
+func (b *metadataParser) Append(c *Comment) {
+ b.buf.Write(bytes.TrimPrefix(c.Text, []byte(" ")))
+ b.buf.WriteByte('\n')
+ b.comments = append(b.comments, c)
+}
+
+var yamlLineErrRegex = regexp.MustCompile(`^yaml: line ([[:digit:]]+):`)
+
+func (b *metadataParser) Parse() (*Annotations, error) {
+
+ var raw rawAnnotation
+
+ if len(bytes.TrimSpace(b.buf.Bytes())) == 0 {
+ return nil, fmt.Errorf("expected METADATA block, found whitespace")
+ }
+
+ if err := yaml.Unmarshal(b.buf.Bytes(), &raw); err != nil {
+ match := yamlLineErrRegex.FindStringSubmatch(err.Error())
+ if len(match) == 2 {
+ n, err2 := strconv.Atoi(match[1])
+ if err2 == nil {
+ index := n - 1 // line numbering is 1-based so subtract one from row
+ if index >= len(b.comments) {
+ b.loc = b.comments[len(b.comments)-1].Location
+ } else {
+ b.loc = b.comments[index].Location
+ }
+ }
+ }
+ return nil, err
+ }
+
+ var result Annotations
+ result.Scope = raw.Scope
+
+ for _, pair := range raw.Schemas {
+ var k string
+ var v interface{}
+ for k, v = range pair {
+ }
+
+ var a SchemaAnnotation
+ var err error
+
+ a.Path, err = ParseRef(k)
+ if err != nil {
+ return nil, fmt.Errorf("invalid document reference")
+ }
+
+ switch v := v.(type) {
+ case string:
+ a.Schema, err = parseSchemaRef(v)
+ if err != nil {
+ return nil, err
+ }
+ case map[interface{}]interface{}:
+ w, err := convertYAMLMapKeyTypes(v, nil)
+ if err != nil {
+ return nil, errors.Wrap(err, "invalid schema definition")
+ }
+ a.Definition = &w
+ default:
+ return nil, fmt.Errorf("invalid schema declaration for path %q", k)
+ }
+
+ result.Schemas = append(result.Schemas, &a)
+ }
+
+ result.Location = b.loc
+ return &result, nil
+}
+
+var errInvalidSchemaRef = fmt.Errorf("invalid schema reference")
+
+// NOTE(tsandall): 'schema' is not registered as a root because it's not
+// supported by the compiler or evaluator today. Once we fix that, we can remove
+// this function.
+func parseSchemaRef(s string) (Ref, error) {
+
+ term, err := ParseTerm(s)
+ if err == nil {
+ switch v := term.Value.(type) {
+ case Var:
+ if term.Equal(SchemaRootDocument) {
+ return SchemaRootRef.Copy(), nil
+ }
+ case Ref:
+ if v.HasPrefix(SchemaRootRef) {
+ return v, nil
+ }
+ }
+ }
+
+ return nil, errInvalidSchemaRef
+}
+
+func convertYAMLMapKeyTypes(x interface{}, path []string) (interface{}, error) {
+ var err error
+ switch x := x.(type) {
+ case map[interface{}]interface{}:
+ result := make(map[string]interface{}, len(x))
+ for k, v := range x {
+ str, ok := k.(string)
+ if !ok {
+ return nil, fmt.Errorf("invalid map key type(s): %v", strings.Join(path, "/"))
+ }
+ result[str], err = convertYAMLMapKeyTypes(v, append(path, str))
+ if err != nil {
+ return nil, err
+ }
+ }
+ return result, nil
+ case []interface{}:
+ for i := range x {
+ x[i], err = convertYAMLMapKeyTypes(x[i], append(path, fmt.Sprintf("%d", i)))
+ if err != nil {
+ return nil, err
+ }
+ }
+ return x, nil
+ default:
+ return x, nil
+ }
+}
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/ast/parser_ext.go b/constraint/vendor/github.com/open-policy-agent/opa/ast/parser_ext.go
index 644169a48..8d8c2809d 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/ast/parser_ext.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/ast/parser_ext.go
@@ -418,7 +418,14 @@ func ParseImports(input string) ([]*Import, error) {
// For details on Module objects and their fields, see policy.go.
// Empty input will return nil, nil.
func ParseModule(filename, input string) (*Module, error) {
- stmts, comments, err := ParseStatements(filename, input)
+ return ParseModuleWithOpts(filename, input, ParserOptions{})
+}
+
+// ParseModuleWithOpts returns a parsed Module object, and has an additional input ParserOptions
+// For details on Module objects and their fields, see policy.go.
+// Empty input will return nil, nil.
+func ParseModuleWithOpts(filename, input string, popts ParserOptions) (*Module, error) {
+ stmts, comments, err := ParseStatementsWithOpts(filename, input, popts)
if err != nil {
return nil, err
}
@@ -540,40 +547,27 @@ func ParseStatement(input string) (Statement, error) {
return stmts[0], nil
}
-type commentKey struct {
- File string
- Row int
- Col int
+// ParseStatements is deprecated. Use ParseStatementWithOpts instead.
+func ParseStatements(filename, input string) ([]Statement, []*Comment, error) {
+ return ParseStatementsWithOpts(filename, input, ParserOptions{})
}
-func (a commentKey) Compare(other commentKey) int {
- if a.File < other.File {
- return -1
- } else if a.File > other.File {
- return 1
- } else if a.Row < other.Row {
- return -1
- } else if a.Row > other.Row {
- return 1
- } else if a.Col < other.Col {
- return -1
- } else if a.Col > other.Col {
- return 1
- }
- return 0
-}
+// ParseStatementsWithOpts returns a slice of parsed statements. This is the
+// default return value from the parser.
+func ParseStatementsWithOpts(filename, input string, popts ParserOptions) ([]Statement, []*Comment, error) {
-// ParseStatements returns a slice of parsed statements.
-// This is the default return value from the parser.
-func ParseStatements(filename, input string) ([]Statement, []*Comment, error) {
+ parser := NewParser().WithFilename(filename).WithReader(bytes.NewBufferString(input))
- stmts, comment, errs := NewParser().WithFilename(filename).WithReader(bytes.NewBufferString(input)).Parse()
+ if popts.ProcessAnnotation {
+ parser.WithProcessAnnotation(popts.ProcessAnnotation)
+ }
+ stmts, comments, errs := parser.Parse()
if len(errs) > 0 {
return nil, nil, errs
}
- return stmts, comment, nil
+ return stmts, comments, nil
}
func parseModule(filename string, stmts []Statement, comments []*Comment) (*Module, error) {
@@ -597,7 +591,7 @@ func parseModule(filename string, stmts []Statement, comments []*Comment) (*Modu
// The comments slice only holds comments that were not their own statements.
mod.Comments = append(mod.Comments, comments...)
- for _, stmt := range stmts[1:] {
+ for i, stmt := range stmts[1:] {
switch stmt := stmt.(type) {
case *Import:
mod.Imports = append(mod.Imports, stmt)
@@ -610,20 +604,87 @@ func parseModule(filename string, stmts []Statement, comments []*Comment) (*Modu
errs = append(errs, NewError(ParseErr, stmt[0].Location, err.Error()))
} else {
mod.Rules = append(mod.Rules, rule)
+
+ // NOTE(tsandall): the statement should now be interpreted as a
+ // rule so update the statement list. This is important for the
+ // logic below that associates annotations with statements.
+ stmts[i+1] = rule
}
case *Package:
errs = append(errs, NewError(ParseErr, stmt.Loc(), "unexpected package"))
- case *Comment: // Ignore comments, they're handled above.
+ case *Annotations:
+ mod.Annotations = append(mod.Annotations, stmt)
+ case *Comment:
+ // Ignore comments, they're handled above.
default:
panic("illegal value") // Indicates grammar is out-of-sync with code.
}
}
- if len(errs) == 0 {
- return mod, nil
+ if len(errs) > 0 {
+ return nil, errs
+ }
+
+ // Find first non-annotation statement following each annotation and attach
+ // the annotation to that statement.
+ for _, a := range mod.Annotations {
+ for _, stmt := range stmts {
+ _, ok := stmt.(*Annotations)
+ if !ok {
+ if stmt.Loc().Row > a.Location.Row {
+ a.node = stmt
+ break
+ }
+ }
+ }
+
+ if a.Scope == "" {
+ switch a.node.(type) {
+ case *Rule:
+ a.Scope = annotationScopeRule
+ case *Package:
+ a.Scope = annotationScopePackage
+ case *Import:
+ a.Scope = annotationScopeImport
+ }
+ }
+
+ if err := validateAnnotationScopeAttachment(a); err != nil {
+ errs = append(errs, err)
+ }
+ }
+
+ if len(errs) > 0 {
+ return nil, errs
+ }
+
+ return mod, nil
+}
+
+func validateAnnotationScopeAttachment(a *Annotations) *Error {
+
+ switch a.Scope {
+ case annotationScopeRule, annotationScopeDocument:
+ if _, ok := a.node.(*Rule); ok {
+ return nil
+ }
+ return newScopeAttachmentErr(a, "rule")
+ case annotationScopePackage, annotationScopeSubpackages:
+ if _, ok := a.node.(*Package); ok {
+ return nil
+ }
+ return newScopeAttachmentErr(a, "package")
}
- return nil, errs
+ return NewError(ParseErr, a.Loc(), "invalid annotation scope '%v'", a.Scope)
+}
+
+func newScopeAttachmentErr(a *Annotations, want string) *Error {
+ var have string
+ if a.node != nil {
+ have = fmt.Sprintf(" (have %v)", TypeName(a.node))
+ }
+ return NewError(ParseErr, a.Loc(), "annotation scope '%v' must be applied to %v%v", a.Scope, want, have)
}
func setRuleModule(rule *Rule, module *Module) {
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/ast/policy.go b/constraint/vendor/github.com/open-policy-agent/opa/ast/policy.go
index 563411d43..d175594e7 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/ast/policy.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/ast/policy.go
@@ -20,7 +20,6 @@ import (
// subsequent lookups. If the hash seeds are out of sync, lookups will fail.
var hashSeed = rand.New(rand.NewSource(time.Now().UnixNano()))
var hashSeed0 = (uint64(hashSeed.Uint32()) << 32) | uint64(hashSeed.Uint32())
-var hashSeed1 = (uint64(hashSeed.Uint32()) << 32) | uint64(hashSeed.Uint32())
// DefaultRootDocument is the default root document.
//
@@ -31,8 +30,14 @@ var DefaultRootDocument = VarTerm("data")
// InputRootDocument names the document containing query arguments.
var InputRootDocument = VarTerm("input")
+// SchemaRootDocument names the document containing external data schemas.
+var SchemaRootDocument = VarTerm("schema")
+
// RootDocumentNames contains the names of top-level documents that can be
// referred to in modules and queries.
+//
+// Note, the schema document is not currently implemented in the evaluator so it
+// is not registered as a root document name (yet).
var RootDocumentNames = NewSet(
DefaultRootDocument,
InputRootDocument,
@@ -48,6 +53,13 @@ var DefaultRootRef = Ref{DefaultRootDocument}
// All refs to query arguments are prefixed with this ref.
var InputRootRef = Ref{InputRootDocument}
+// SchemaRootRef is a reference to the root of the schema document.
+//
+// All refs to schema documents are prefixed with this ref. Note, the schema
+// document is not currently implemented in the evaluator so it is not
+// registered as a root document ref (yet).
+var SchemaRootRef = Ref{SchemaRootDocument}
+
// RootDocumentRefs contains the prefixes of top-level documents that all
// non-local references start with.
var RootDocumentRefs = NewSet(
@@ -118,10 +130,11 @@ type (
// within a namespace (defined by the package) and optional
// dependencies on external documents (defined by imports).
Module struct {
- Package *Package `json:"package"`
- Imports []*Import `json:"imports,omitempty"`
- Rules []*Rule `json:"rules,omitempty"`
- Comments []*Comment `json:"comments,omitempty"`
+ Package *Package `json:"package"`
+ Imports []*Import `json:"imports,omitempty"`
+ Annotations []*Annotations `json:"annotations,omitempty"`
+ Rules []*Rule `json:"rules,omitempty"`
+ Comments []*Comment `json:"comments,omitempty"`
}
// Comment contains the raw text from the comment in the definition.
@@ -130,6 +143,21 @@ type (
Location *Location
}
+ // Annotations represents metadata attached to other AST nodes such as rules.
+ Annotations struct {
+ Location *Location `json:"-"`
+ Scope string `json:"scope"`
+ Schemas []*SchemaAnnotation `json:"schemas,omitempty"`
+ node Node
+ }
+
+ // SchemaAnnotation contains a schema declaration for the document identified by the path.
+ SchemaAnnotation struct {
+ Path Ref `json:"path"`
+ Schema Ref `json:"schema,omitempty"`
+ Definition *interface{} `json:"definition,omitempty"`
+ }
+
// Package represents the namespace of the documents produced
// by rules inside the module.
Package struct {
@@ -180,12 +208,12 @@ type (
// Expr represents a single expression contained inside the body of a rule.
Expr struct {
+ With []*With `json:"with,omitempty"`
+ Terms interface{} `json:"terms"`
Location *Location `json:"-"`
- Generated bool `json:"generated,omitempty"`
Index int `json:"index"`
+ Generated bool `json:"generated,omitempty"`
Negated bool `json:"negated,omitempty"`
- Terms interface{} `json:"terms"`
- With []*With `json:"with,omitempty"`
}
// SomeDecl represents a variable declaration statement. The symbols are variables.
@@ -202,6 +230,122 @@ type (
}
)
+func (s *Annotations) String() string {
+ bs, _ := json.Marshal(s)
+ return string(bs)
+}
+
+// Loc returns the location of this annotation.
+func (s *Annotations) Loc() *Location {
+ return s.Location
+}
+
+// SetLoc updates the location of this annotation.
+func (s *Annotations) SetLoc(l *Location) {
+ s.Location = l
+}
+
+// Compare returns an integer indicating if s is less than, equal to, or greater
+// than other.
+func (s *Annotations) Compare(other *Annotations) int {
+
+ if cmp := scopeCompare(s.Scope, other.Scope); cmp != 0 {
+ return cmp
+ }
+
+ max := len(s.Schemas)
+ if len(other.Schemas) < max {
+ max = len(other.Schemas)
+ }
+
+ for i := 0; i < max; i++ {
+ if cmp := s.Schemas[i].Compare(other.Schemas[i]); cmp != 0 {
+ return cmp
+ }
+ }
+
+ if len(s.Schemas) > len(other.Schemas) {
+ return 1
+ } else if len(s.Schemas) < len(other.Schemas) {
+ return -1
+ }
+
+ return 0
+}
+
+// Copy returns a deep copy of s.
+func (s *Annotations) Copy(node Node) *Annotations {
+ cpy := *s
+ cpy.Schemas = make([]*SchemaAnnotation, len(s.Schemas))
+ for i := range cpy.Schemas {
+ cpy.Schemas[i] = s.Schemas[i].Copy()
+ }
+ cpy.node = node
+ return &cpy
+}
+
+// Copy returns a deep copy of s.
+func (s *SchemaAnnotation) Copy() *SchemaAnnotation {
+ cpy := *s
+ return &cpy
+}
+
+// Compare returns an integer indicating if s is less than, equal to, or greater
+// than other.
+func (s *SchemaAnnotation) Compare(other *SchemaAnnotation) int {
+
+ if cmp := s.Path.Compare(other.Path); cmp != 0 {
+ return cmp
+ }
+
+ if cmp := s.Schema.Compare(other.Schema); cmp != 0 {
+ return cmp
+ }
+
+ if s.Definition != nil && other.Definition == nil {
+ return -1
+ } else if s.Definition == nil && other.Definition != nil {
+ return 1
+ } else if s.Definition != nil && other.Definition != nil {
+ return util.Compare(*s.Definition, *other.Definition)
+ }
+
+ return 0
+}
+
+func (s *SchemaAnnotation) String() string {
+ bs, _ := json.Marshal(s)
+ return string(bs)
+}
+
+func scopeCompare(s1, s2 string) int {
+
+ o1 := scopeOrder(s1)
+ o2 := scopeOrder(s2)
+
+ if o2 < o1 {
+ return 1
+ } else if o2 > o1 {
+ return -1
+ }
+
+ if s1 < s2 {
+ return -1
+ } else if s2 < s1 {
+ return 1
+ }
+
+ return 0
+}
+
+func scopeOrder(s string) int {
+ switch s {
+ case annotationScopeRule:
+ return 1
+ }
+ return 0
+}
+
// Compare returns an integer indicating whether mod is less than, equal to,
// or greater than other.
func (mod *Module) Compare(other *Module) int {
@@ -219,6 +363,9 @@ func (mod *Module) Compare(other *Module) int {
if cmp := importsCompare(mod.Imports, other.Imports); cmp != 0 {
return cmp
}
+ if cmp := annotationsCompare(mod.Annotations, other.Annotations); cmp != 0 {
+ return cmp
+ }
return rulesCompare(mod.Rules, other.Rules)
}
@@ -226,14 +373,39 @@ func (mod *Module) Compare(other *Module) int {
func (mod *Module) Copy() *Module {
cpy := *mod
cpy.Rules = make([]*Rule, len(mod.Rules))
+
+ var nodes map[Node]Node
+
+ if len(mod.Annotations) > 0 {
+ nodes = make(map[Node]Node)
+ }
+
for i := range mod.Rules {
cpy.Rules[i] = mod.Rules[i].Copy()
+ cpy.Rules[i].Module = &cpy
+ if nodes != nil {
+ nodes[mod.Rules[i]] = cpy.Rules[i]
+ }
}
+
cpy.Imports = make([]*Import, len(mod.Imports))
for i := range mod.Imports {
cpy.Imports[i] = mod.Imports[i].Copy()
+ if nodes != nil {
+ nodes[mod.Imports[i]] = cpy.Imports[i]
+ }
}
+
cpy.Package = mod.Package.Copy()
+ if nodes != nil {
+ nodes[mod.Package] = cpy.Package
+ }
+
+ cpy.Annotations = make([]*Annotations, len(mod.Annotations))
+ for i := range mod.Annotations {
+ cpy.Annotations[i] = mod.Annotations[i].Copy(nodes[mod.Annotations[i].node])
+ }
+
return &cpy
}
@@ -243,17 +415,36 @@ func (mod *Module) Equal(other *Module) bool {
}
func (mod *Module) String() string {
+ byNode := map[Node][]*Annotations{}
+ for _, a := range mod.Annotations {
+ byNode[a.node] = append(byNode[a.node], a)
+ }
+
+ appendAnnotationStrings := func(buf []string, node Node) []string {
+ if as, ok := byNode[node]; ok {
+ for i := range as {
+ buf = append(buf, "# METADATA")
+ buf = append(buf, "# "+as[i].String())
+ }
+ }
+ return buf
+ }
+
buf := []string{}
+ buf = appendAnnotationStrings(buf, mod.Package)
buf = append(buf, mod.Package.String())
+
if len(mod.Imports) > 0 {
buf = append(buf, "")
for _, imp := range mod.Imports {
+ buf = appendAnnotationStrings(buf, imp)
buf = append(buf, imp.String())
}
}
if len(mod.Rules) > 0 {
buf = append(buf, "")
for _, rule := range mod.Rules {
+ buf = appendAnnotationStrings(buf, rule)
buf = append(buf, rule.String())
}
}
@@ -1374,12 +1565,6 @@ func (rs RuleSet) String() string {
return "{" + strings.Join(buf, ", ") + "}"
}
-type ruleSlice []*Rule
-
-func (s ruleSlice) Less(i, j int) bool { return Compare(s[i], s[j]) < 0 }
-func (s ruleSlice) Swap(i, j int) { x := s[i]; s[i] = s[j]; s[j] = x }
-func (s ruleSlice) Len() int { return len(s) }
-
// Returns true if the equality or assignment expression referred to by expr
// has a valid number of arguments.
func validEqAssignArgCount(expr *Expr) bool {
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/ast/schema.go b/constraint/vendor/github.com/open-policy-agent/opa/ast/schema.go
new file mode 100644
index 000000000..1feea3570
--- /dev/null
+++ b/constraint/vendor/github.com/open-policy-agent/opa/ast/schema.go
@@ -0,0 +1,63 @@
+// Copyright 2021 The OPA Authors. All rights reserved.
+// Use of this source code is governed by an Apache2
+// license that can be found in the LICENSE file.
+
+package ast
+
+import (
+ "fmt"
+
+ "github.com/open-policy-agent/opa/types"
+ "github.com/open-policy-agent/opa/util"
+)
+
+// SchemaSet holds a map from a path to a schema.
+type SchemaSet struct {
+ m *util.HashMap
+}
+
+// NewSchemaSet returns an empty SchemaSet.
+func NewSchemaSet() *SchemaSet {
+
+ eqFunc := func(a, b util.T) bool {
+ return a.(Ref).Equal(b.(Ref))
+ }
+
+ hashFunc := func(x util.T) int { return x.(Ref).Hash() }
+
+ return &SchemaSet{
+ m: util.NewHashMap(eqFunc, hashFunc),
+ }
+}
+
+// Put inserts a raw schema into the set.
+func (ss *SchemaSet) Put(path Ref, raw interface{}) {
+ ss.m.Put(path, raw)
+}
+
+// Get returns the raw schema identified by the path.
+func (ss *SchemaSet) Get(path Ref) interface{} {
+ if ss == nil {
+ return nil
+ }
+ x, ok := ss.m.Get(path)
+ if !ok {
+ return nil
+ }
+ return x
+}
+
+func loadSchema(raw interface{}) (types.Type, error) {
+
+ jsonSchema, err := compileSchema(raw)
+ if err != nil {
+ return nil, fmt.Errorf("compile failed: %s", err.Error())
+ }
+
+ tpe, err := parseSchema(jsonSchema.RootSchema)
+ if err != nil {
+ return nil, fmt.Errorf("error when type checking %v", err)
+ }
+
+ return tpe, nil
+}
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/ast/term.go b/constraint/vendor/github.com/open-policy-agent/opa/ast/term.go
index 98adc391a..a97a24cff 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/ast/term.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/ast/term.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by an Apache2
// license that can be found in the LICENSE file.
+// nolint: deadcode // Public API.
package ast
import (
@@ -159,6 +160,10 @@ func (illegalResolver) Resolve(ref Ref) (interface{}, error) {
// value should not contain any values that require evaluation (e.g., vars,
// comprehensions, etc.)
func ValueToInterface(v Value, resolver Resolver) (interface{}, error) {
+ return valueToInterface(v, resolver, JSONOpt{})
+}
+
+func valueToInterface(v Value, resolver Resolver, opt JSONOpt) (interface{}, error) {
switch v := v.(type) {
case Null:
return nil, nil
@@ -171,7 +176,7 @@ func ValueToInterface(v Value, resolver Resolver) (interface{}, error) {
case *Array:
buf := []interface{}{}
for i := 0; i < v.Len(); i++ {
- x1, err := ValueToInterface(v.Elem(i).Value, resolver)
+ x1, err := valueToInterface(v.Elem(i).Value, resolver, opt)
if err != nil {
return nil, err
}
@@ -181,7 +186,7 @@ func ValueToInterface(v Value, resolver Resolver) (interface{}, error) {
case *object:
buf := make(map[string]interface{}, v.Len())
err := v.Iter(func(k, v *Term) error {
- ki, err := ValueToInterface(k.Value, resolver)
+ ki, err := valueToInterface(k.Value, resolver, opt)
if err != nil {
return err
}
@@ -194,7 +199,7 @@ func ValueToInterface(v Value, resolver Resolver) (interface{}, error) {
}
str = strings.TrimSpace(buf.String())
}
- vi, err := ValueToInterface(v.Value, resolver)
+ vi, err := valueToInterface(v.Value, resolver, opt)
if err != nil {
return err
}
@@ -207,14 +212,20 @@ func ValueToInterface(v Value, resolver Resolver) (interface{}, error) {
return buf, nil
case Set:
buf := []interface{}{}
- err := v.Iter(func(x *Term) error {
- x1, err := ValueToInterface(x.Value, resolver)
+ iter := func(x *Term) error {
+ x1, err := valueToInterface(x.Value, resolver, opt)
if err != nil {
return err
}
buf = append(buf, x1)
return nil
- })
+ }
+ var err error
+ if opt.SortSets {
+ err = v.Sorted().Iter(iter)
+ } else {
+ err = v.Iter(iter)
+ }
if err != nil {
return nil, err
}
@@ -229,7 +240,30 @@ func ValueToInterface(v Value, resolver Resolver) (interface{}, error) {
// JSON returns the JSON representation of v. The value must not contain any
// refs or terms that require evaluation (e.g., vars, comprehensions, etc.)
func JSON(v Value) (interface{}, error) {
- return ValueToInterface(v, illegalResolver{})
+ return JSONWithOpt(v, JSONOpt{})
+}
+
+// JSONOpt defines parameters for AST to JSON conversion.
+type JSONOpt struct {
+ SortSets bool // sort sets before serializing (this makes conversion more expensive)
+}
+
+// JSONWithOpt returns the JSON representation of v. The value must not contain any
+// refs or terms that require evaluation (e.g., vars, comprehensions, etc.)
+func JSONWithOpt(v Value, opt JSONOpt) (interface{}, error) {
+ return valueToInterface(v, illegalResolver{}, opt)
+}
+
+// MustJSON returns the JSON representation of v. The value must not contain any
+// refs or terms that require evaluation (e.g., vars, comprehensions, etc.) If
+// the conversion fails, this function will panic. This function is mostly for
+// test purposes.
+func MustJSON(v Value) interface{} {
+ r, err := JSON(v)
+ if err != nil {
+ panic(err)
+ }
+ return r
}
// MustInterfaceToValue converts a native Go value x to a Value. If the
@@ -855,9 +889,8 @@ func (ref Ref) Insert(x *Term, pos int) Ref {
// other will be converted to a string.
func (ref Ref) Extend(other Ref) Ref {
dst := make(Ref, len(ref)+len(other))
- for i := range ref {
- dst[i] = ref[i]
- }
+ copy(dst, ref)
+
head := other[0].Copy()
head.Value = String(head.Value.(Var))
offset := len(ref)
@@ -874,9 +907,8 @@ func (ref Ref) Concat(terms []*Term) Ref {
return ref
}
cpy := make(Ref, len(ref)+len(terms))
- for i := range ref {
- cpy[i] = ref[i]
- }
+ copy(cpy, ref)
+
for i := range terms {
cpy[len(ref)+i] = terms[i]
}
@@ -1200,10 +1232,10 @@ func (arr *Array) Until(f func(*Term) bool) bool {
// Foreach calls f on each element in arr.
func (arr *Array) Foreach(f func(*Term)) {
- arr.Iter(func(t *Term) error {
+ _ = arr.Iter(func(t *Term) error {
f(t)
return nil
- })
+ }) // ignore error
}
// Append appends a term to arr, returning the appended array.
@@ -1248,9 +1280,10 @@ func newset(n int) *set {
keys = make([]*Term, 0, n)
}
return &set{
- elems: make(map[int]*Term, n),
- keys: keys,
- hash: 0,
+ elems: make(map[int]*Term, n),
+ keys: keys,
+ hash: 0,
+ ground: true,
}
}
@@ -1263,9 +1296,10 @@ func SetTerm(t ...*Term) *Term {
}
type set struct {
- elems map[int]*Term
- keys []*Term
- hash int
+ elems map[int]*Term
+ keys []*Term
+ hash int
+ ground bool
}
// Copy returns a deep copy of s.
@@ -1275,14 +1309,13 @@ func (s *set) Copy() Set {
cpy.Add(x.Copy())
})
cpy.hash = s.hash
+ cpy.ground = s.ground
return cpy
}
// IsGround returns true if all terms in s are ground.
func (s *set) IsGround() bool {
- return !s.Until(func(x *Term) bool {
- return !x.IsGround()
- })
+ return s.ground
}
// Hash returns a hash code for s.
@@ -1409,10 +1442,10 @@ func (s *set) Until(f func(*Term) bool) bool {
// Foreach calls f on each element in s.
func (s *set) Foreach(f func(*Term)) {
- s.Iter(func(t *Term) error {
+ _ = s.Iter(func(t *Term) error {
f(t)
return nil
- })
+ }) // ignore error
}
// Map returns a new Set obtained by applying f to each value in s.
@@ -1482,6 +1515,10 @@ func (s *set) Slice() []*Term {
func (s *set) insert(x *Term) {
hash := x.Hash()
+ // This `equal` utility is duplicated and manually inlined a number of
+ // time in this file. Inlining it avoids heap allocations, so it makes
+ // a big performance difference: some operations like lookup become twice
+ // as slow without it.
var equal func(v Value) bool
switch x := x.Value.(type) {
@@ -1501,17 +1538,50 @@ func (s *set) insert(x *Term) {
break
}
- a, ok := new(big.Float).SetString(string(x))
+ // We use big.Rat for comparing big numbers.
+ // It replaces big.Float due to following reason:
+ // big.Float comes with a default precision of 64, and setting a
+ // larger precision results in more memory being allocated
+ // (regardless of the actual number we are parsing with SetString).
+ //
+ // Note: If we're so close to zero that big.Float says we are zero, do
+ // *not* big.Rat).SetString on the original string it'll potentially
+ // take very long.
+ var a *big.Rat
+ fa, ok := new(big.Float).SetString(string(x))
if !ok {
panic("illegal value")
}
+ if fa.IsInt() {
+ if i, _ := fa.Int64(); i == 0 {
+ a = new(big.Rat).SetInt64(0)
+ }
+ }
+ if a == nil {
+ a, ok = new(big.Rat).SetString(string(x))
+ if !ok {
+ panic("illegal value")
+ }
+ }
equal = func(b Value) bool {
- if b, ok := b.(Number); ok {
- b, ok := new(big.Float).SetString(string(b))
+ if bNum, ok := b.(Number); ok {
+ var b *big.Rat
+ fb, ok := new(big.Float).SetString(string(bNum))
if !ok {
panic("illegal value")
}
+ if fb.IsInt() {
+ if i, _ := fb.Int64(); i == 0 {
+ b = new(big.Rat).SetInt64(0)
+ }
+ }
+ if b == nil {
+ b, ok = new(big.Rat).SetString(string(bNum))
+ if !ok {
+ panic("illegal value")
+ }
+ }
return a.Cmp(b) == 0
}
@@ -1534,10 +1604,15 @@ func (s *set) insert(x *Term) {
s.elems[hash] = x
s.keys = append(s.keys, x)
s.hash = 0
+ s.ground = s.ground && x.IsGround()
}
func (s *set) get(x *Term) *Term {
hash := x.Hash()
+ // This `equal` utility is duplicated and manually inlined a number of
+ // time in this file. Inlining it avoids heap allocations, so it makes
+ // a big performance difference: some operations like lookup become twice
+ // as slow without it.
var equal func(v Value) bool
switch x := x.Value.(type) {
@@ -1557,23 +1632,57 @@ func (s *set) get(x *Term) *Term {
break
}
- a, ok := new(big.Float).SetString(string(x))
+ // We use big.Rat for comparing big numbers.
+ // It replaces big.Float due to following reason:
+ // big.Float comes with a default precision of 64, and setting a
+ // larger precision results in more memory being allocated
+ // (regardless of the actual number we are parsing with SetString).
+ //
+ // Note: If we're so close to zero that big.Float says we are zero, do
+ // *not* big.Rat).SetString on the original string it'll potentially
+ // take very long.
+ var a *big.Rat
+ fa, ok := new(big.Float).SetString(string(x))
if !ok {
panic("illegal value")
}
+ if fa.IsInt() {
+ if i, _ := fa.Int64(); i == 0 {
+ a = new(big.Rat).SetInt64(0)
+ }
+ }
+ if a == nil {
+ a, ok = new(big.Rat).SetString(string(x))
+ if !ok {
+ panic("illegal value")
+ }
+ }
equal = func(b Value) bool {
- if b, ok := b.(Number); ok {
- b, ok := new(big.Float).SetString(string(b))
+ if bNum, ok := b.(Number); ok {
+ var b *big.Rat
+ fb, ok := new(big.Float).SetString(string(bNum))
if !ok {
panic("illegal value")
}
+ if fb.IsInt() {
+ if i, _ := fb.Int64(); i == 0 {
+ b = new(big.Rat).SetInt64(0)
+ }
+ }
+ if b == nil {
+ b, ok = new(big.Rat).SetString(string(bNum))
+ if !ok {
+ panic("illegal value")
+ }
+ }
return a.Cmp(b) == 0
}
-
return false
+
}
+
default:
equal = func(y Value) bool { return Compare(x, y) == 0 }
}
@@ -1792,8 +1901,9 @@ func (obj *object) Iter(f func(*Term, *Term) error) error {
return nil
}
-// Until calls f for each key-value pair in the object. If f returns true,
-// iteration stops.
+// Until calls f for each key-value pair in the object. If f returns
+// true, iteration stops and Until returns true. Otherwise, return
+// false.
func (obj *object) Until(f func(*Term, *Term) bool) bool {
err := obj.Iter(func(k, v *Term) error {
if f(k, v) {
@@ -1806,10 +1916,10 @@ func (obj *object) Until(f func(*Term, *Term) bool) bool {
// Foreach calls f for each key-value pair in the object.
func (obj *object) Foreach(f func(*Term, *Term)) {
- obj.Iter(func(k, v *Term) error {
+ _ = obj.Iter(func(k, v *Term) error {
f(k, v)
return nil
- })
+ }) // ignore error
}
// Map returns a new Object constructed by mapping each element in the object
@@ -1937,6 +2047,10 @@ func (obj object) String() string {
func (obj *object) get(k *Term) *objectElem {
hash := k.Hash()
+ // This `equal` utility is duplicated and manually inlined a number of
+ // time in this file. Inlining it avoids heap allocations, so it makes
+ // a big performance difference: some operations like lookup become twice
+ // as slow without it.
var equal func(v Value) bool
switch x := k.Value.(type) {
@@ -1956,17 +2070,50 @@ func (obj *object) get(k *Term) *objectElem {
break
}
- a, ok := new(big.Float).SetString(string(x))
+ // We use big.Rat for comparing big numbers.
+ // It replaces big.Float due to following reason:
+ // big.Float comes with a default precision of 64, and setting a
+ // larger precision results in more memory being allocated
+ // (regardless of the actual number we are parsing with SetString).
+ //
+ // Note: If we're so close to zero that big.Float says we are zero, do
+ // *not* big.Rat).SetString on the original string it'll potentially
+ // take very long.
+ var a *big.Rat
+ fa, ok := new(big.Float).SetString(string(x))
if !ok {
panic("illegal value")
}
+ if fa.IsInt() {
+ if i, _ := fa.Int64(); i == 0 {
+ a = new(big.Rat).SetInt64(0)
+ }
+ }
+ if a == nil {
+ a, ok = new(big.Rat).SetString(string(x))
+ if !ok {
+ panic("illegal value")
+ }
+ }
equal = func(b Value) bool {
- if b, ok := b.(Number); ok {
- b, ok := new(big.Float).SetString(string(b))
+ if bNum, ok := b.(Number); ok {
+ var b *big.Rat
+ fb, ok := new(big.Float).SetString(string(bNum))
if !ok {
panic("illegal value")
}
+ if fb.IsInt() {
+ if i, _ := fb.Int64(); i == 0 {
+ b = new(big.Rat).SetInt64(0)
+ }
+ }
+ if b == nil {
+ b, ok = new(big.Rat).SetString(string(bNum))
+ if !ok {
+ panic("illegal value")
+ }
+ }
return a.Cmp(b) == 0
}
@@ -1988,6 +2135,10 @@ func (obj *object) get(k *Term) *objectElem {
func (obj *object) insert(k, v *Term) {
hash := k.Hash()
head := obj.elems[hash]
+ // This `equal` utility is duplicated and manually inlined a number of
+ // time in this file. Inlining it avoids heap allocations, so it makes
+ // a big performance difference: some operations like lookup become twice
+ // as slow without it.
var equal func(v Value) bool
switch x := k.Value.(type) {
@@ -2007,17 +2158,50 @@ func (obj *object) insert(k, v *Term) {
break
}
- a, ok := new(big.Float).SetString(string(x))
+ // We use big.Rat for comparing big numbers.
+ // It replaces big.Float due to following reason:
+ // big.Float comes with a default precision of 64, and setting a
+ // larger precision results in more memory being allocated
+ // (regardless of the actual number we are parsing with SetString).
+ //
+ // Note: If we're so close to zero that big.Float says we are zero, do
+ // *not* big.Rat).SetString on the original string it'll potentially
+ // take very long.
+ var a *big.Rat
+ fa, ok := new(big.Float).SetString(string(x))
if !ok {
panic("illegal value")
}
+ if fa.IsInt() {
+ if i, _ := fa.Int64(); i == 0 {
+ a = new(big.Rat).SetInt64(0)
+ }
+ }
+ if a == nil {
+ a, ok = new(big.Rat).SetString(string(x))
+ if !ok {
+ panic("illegal value")
+ }
+ }
equal = func(b Value) bool {
- if b, ok := b.(Number); ok {
- b, ok := new(big.Float).SetString(string(b))
+ if bNum, ok := b.(Number); ok {
+ var b *big.Rat
+ fb, ok := new(big.Float).SetString(string(bNum))
if !ok {
panic("illegal value")
}
+ if fb.IsInt() {
+ if i, _ := fb.Int64(); i == 0 {
+ b = new(big.Rat).SetInt64(0)
+ }
+ }
+ if b == nil {
+ b, ok = new(big.Rat).SetString(string(bNum))
+ if !ok {
+ panic("illegal value")
+ }
+ }
return a.Cmp(b) == 0
}
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/ast/transform.go b/constraint/vendor/github.com/open-policy-agent/opa/ast/transform.go
index 7e9af9cc2..0a23a4b20 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/ast/transform.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/ast/transform.go
@@ -59,6 +59,15 @@ func Transform(t Transformer, x interface{}) (interface{}, error) {
return nil, fmt.Errorf("illegal transform: %T != %T", y.Rules[i], rule)
}
}
+ for i := range y.Annotations {
+ a, err := Transform(t, y.Annotations[i])
+ if err != nil {
+ return nil, err
+ }
+ if y.Annotations[i], ok = a.(*Annotations); !ok {
+ return nil, fmt.Errorf("illegal transform: %T != %T", y.Annotations[i], a)
+ }
+ }
for i := range y.Comments {
comment, err := Transform(t, y.Comments[i])
if err != nil {
@@ -348,18 +357,6 @@ func transformBody(t Transformer, body Body) (Body, error) {
return r, nil
}
-func transformExpr(t Transformer, expr *Expr) (*Expr, error) {
- y, err := Transform(t, expr)
- if err != nil {
- return nil, err
- }
- h, ok := y.(*Expr)
- if !ok {
- return nil, fmt.Errorf("illegal transform: %T != %T", expr, y)
- }
- return h, nil
-}
-
func transformTerm(t Transformer, term *Term) (*Term, error) {
v, err := transformValue(t, term.Value)
if err != nil {
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/ast/unify.go b/constraint/vendor/github.com/open-policy-agent/opa/ast/unify.go
index 7a87ea75d..b05845409 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/ast/unify.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/ast/unify.go
@@ -116,12 +116,12 @@ func (u *unifier) unify(a *Term, b *Term) {
u.markAllSafe(a)
case *object:
if a.Len() == b.Len() {
- a.Iter(func(k, v *Term) error {
+ _ = a.Iter(func(k, v *Term) error {
if v2 := b.Get(k); v2 != nil {
u.unify(v, v2)
}
return nil
- })
+ }) // impossible to return error
}
}
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/ast/visit.go b/constraint/vendor/github.com/open-policy-agent/opa/ast/visit.go
index 105fb58ab..139c4de3f 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/ast/visit.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/ast/visit.go
@@ -52,6 +52,9 @@ func walk(v Visitor, x interface{}) {
for _, r := range x.Rules {
Walk(w, r)
}
+ for _, a := range x.Annotations {
+ Walk(w, a)
+ }
for _, c := range x.Comments {
Walk(w, c)
}
@@ -280,6 +283,9 @@ func (vis *GenericVisitor) Walk(x interface{}) {
for _, r := range x.Rules {
vis.Walk(r)
}
+ for _, a := range x.Annotations {
+ vis.Walk(a)
+ }
for _, c := range x.Comments {
vis.Walk(c)
}
@@ -398,6 +404,9 @@ func (vis *BeforeAfterVisitor) Walk(x interface{}) {
for _, r := range x.Rules {
vis.Walk(r)
}
+ for _, a := range x.Annotations {
+ vis.Walk(a)
+ }
for _, c := range x.Comments {
vis.Walk(c)
}
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/bundle/bundle.go b/constraint/vendor/github.com/open-policy-agent/opa/bundle/bundle.go
index 1aefd3426..3dbafa6e0 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/bundle/bundle.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/bundle/bundle.go
@@ -18,42 +18,42 @@ import (
"reflect"
"strings"
- "github.com/open-policy-agent/opa/format"
+ "github.com/pkg/errors"
+ "github.com/open-policy-agent/opa/ast"
+ "github.com/open-policy-agent/opa/format"
"github.com/open-policy-agent/opa/internal/file/archive"
"github.com/open-policy-agent/opa/internal/merge"
"github.com/open-policy-agent/opa/metrics"
-
- "github.com/pkg/errors"
-
- "github.com/open-policy-agent/opa/ast"
"github.com/open-policy-agent/opa/util"
)
// Common file extensions and file names.
const (
- RegoExt = ".rego"
- WasmFile = "/policy.wasm"
- ManifestExt = ".manifest"
- SignaturesFile = "signatures.json"
- dataFile = "data.json"
- yamlDataFile = "data.yaml"
- defaultHashingAlg = "SHA-256"
- BundleLimitBytes = (1024 * 1024 * 1024) + 1 // limit bundle reads to 1GB to protect against gzip bombs
+ RegoExt = ".rego"
+ WasmFile = "policy.wasm"
+ ManifestExt = ".manifest"
+ SignaturesFile = "signatures.json"
+ dataFile = "data.json"
+ yamlDataFile = "data.yaml"
+ defaultHashingAlg = "SHA-256"
+ DefaultSizeLimitBytes = (1024 * 1024 * 1024) // limit bundle reads to 1GB to protect against gzip bombs
)
// Bundle represents a loaded bundle. The bundle can contain data and policies.
type Bundle struct {
- Signatures SignaturesConfig
- Manifest Manifest
- Data map[string]interface{}
- Modules []ModuleFile
- Wasm []byte
+ Signatures SignaturesConfig
+ Manifest Manifest
+ Data map[string]interface{}
+ Modules []ModuleFile
+ Wasm []byte // Deprecated. Use WasmModules instead
+ WasmModules []WasmModuleFile
}
// SignaturesConfig represents an array of JWTs that encapsulate the signatures for the bundle.
type SignaturesConfig struct {
Signatures []string `json:"signatures,omitempty"`
+ Plugin string `json:"plugin,omitempty"`
}
// isEmpty returns if the SignaturesConfig is empty.
@@ -89,8 +89,16 @@ func NewFile(name, hash, alg string) FileInfo {
// Manifest represents the manifest from a bundle. The manifest may contain
// metadata such as the bundle revision.
type Manifest struct {
- Revision string `json:"revision"`
- Roots *[]string `json:"roots,omitempty"`
+ Revision string `json:"revision"`
+ Roots *[]string `json:"roots,omitempty"`
+ WasmResolvers []WasmResolver `json:"wasm,omitempty"`
+ Metadata map[string]interface{} `json:"metadata,omitempty"`
+}
+
+// WasmResolver maps a wasm module to an entrypoint ref.
+type WasmResolver struct {
+ Entrypoint string `json:"entrypoint,omitempty"`
+ Module string `json:"module,omitempty"`
}
// Init initializes the manifest. If you instantiate a manifest
@@ -121,6 +129,16 @@ func (m Manifest) Equal(other Manifest) bool {
return false
}
+ if len(m.WasmResolvers) != len(other.WasmResolvers) {
+ return false
+ }
+
+ for i := 0; i < len(m.WasmResolvers); i++ {
+ if m.WasmResolvers[i] != other.WasmResolvers[i] {
+ return false
+ }
+ }
+
return m.rootSet().Equal(other.rootSet())
}
@@ -130,12 +148,17 @@ func (m Manifest) Copy() Manifest {
roots := make([]string, len(*m.Roots))
copy(roots, *m.Roots)
m.Roots = &roots
+
+ wasmModules := make([]WasmResolver, len(m.WasmResolvers))
+ copy(wasmModules, m.WasmResolvers)
+ m.WasmResolvers = wasmModules
+
return m
}
func (m Manifest) String() string {
m.Init()
- return fmt.Sprintf("", m.Revision, *m.Roots)
+ return fmt.Sprintf("", m.Revision, *m.Roots, m.WasmResolvers)
}
func (m Manifest) rootSet() stringSet {
@@ -198,6 +221,40 @@ func (m *Manifest) validateAndInjectDefaults(b Bundle) error {
}
}
+ // Build a set of wasm module entrypoints to validate
+ wasmModuleToEps := map[string]string{}
+ seenEps := map[string]struct{}{}
+ for _, wm := range b.WasmModules {
+ wasmModuleToEps[wm.Path] = ""
+ }
+
+ for _, wmConfig := range b.Manifest.WasmResolvers {
+ _, ok := wasmModuleToEps[wmConfig.Module]
+ if !ok {
+ return fmt.Errorf("manifest references wasm module '%s' but the module file does not exist", wmConfig.Module)
+ }
+
+ // Ensure wasm module entrypoint in within bundle roots
+ found := false
+ for i := range roots {
+ if strings.HasPrefix(wmConfig.Entrypoint, roots[i]) {
+ found = true
+ break
+ }
+ }
+
+ if !found {
+ return fmt.Errorf("manifest roots %v do not permit '%v' entrypoint for wasm module '%v'", roots, wmConfig.Entrypoint, wmConfig.Module)
+ }
+
+ if _, ok := seenEps[wmConfig.Entrypoint]; ok {
+ return fmt.Errorf("entrypoint '%s' cannot be used by more than one wasm module", wmConfig.Entrypoint)
+ }
+ seenEps[wmConfig.Entrypoint] = struct{}{}
+
+ wasmModuleToEps[wmConfig.Module] = wmConfig.Entrypoint
+ }
+
// Validate data in bundle.
return dfs(b.Data, "", func(path string, node interface{}) (bool, error) {
path = strings.Trim(path, "/")
@@ -217,7 +274,7 @@ func (m *Manifest) validateAndInjectDefaults(b Bundle) error {
})
}
-// ModuleFile represents a single module contained a bundle.
+// ModuleFile represents a single module contained in a bundle.
type ModuleFile struct {
URL string
Path string
@@ -225,6 +282,14 @@ type ModuleFile struct {
Parsed *ast.Module
}
+// WasmModuleFile represents a single wasm module contained in a bundle.
+type WasmModuleFile struct {
+ URL string
+ Path string
+ Entrypoints []ast.Ref
+ Raw []byte
+}
+
// Reader contains the reader to load the bundle from.
type Reader struct {
loader DirectoryLoader
@@ -233,7 +298,9 @@ type Reader struct {
baseDir string
verificationConfig *VerificationConfig
skipVerify bool
+ processAnnotations bool
files map[string]FileInfo // files in the bundle signature payload
+ sizeLimitBytes int64
}
// NewReader is deprecated. Use NewCustomReader instead.
@@ -245,9 +312,10 @@ func NewReader(r io.Reader) *Reader {
// specified DirectoryLoader.
func NewCustomReader(loader DirectoryLoader) *Reader {
nr := Reader{
- loader: loader,
- metrics: metrics.New(),
- files: make(map[string]FileInfo),
+ loader: loader,
+ metrics: metrics.New(),
+ files: make(map[string]FileInfo),
+ sizeLimitBytes: DefaultSizeLimitBytes + 1,
}
return &nr
}
@@ -284,6 +352,19 @@ func (r *Reader) WithSkipBundleVerification(skipVerify bool) *Reader {
return r
}
+// WithProcessAnnotations enables annotation processing during .rego file parsing.
+func (r *Reader) WithProcessAnnotations(yes bool) *Reader {
+ r.processAnnotations = yes
+ return r
+}
+
+// WithSizeLimitBytes sets the size limit to apply to files in the bundle. If files are larger
+// than this, an error will be returned by the reader.
+func (r *Reader) WithSizeLimitBytes(n int64) *Reader {
+ r.sizeLimitBytes = n + 1
+ return r
+}
+
// Read returns a new Bundle loaded from the reader.
func (r *Reader) Read() (Bundle, error) {
@@ -293,7 +374,7 @@ func (r *Reader) Read() (Bundle, error) {
bundle.Data = map[string]interface{}{}
- bundle.Signatures, descriptors, err = listSignaturesAndDescriptors(r.loader, r.skipVerify)
+ bundle.Signatures, descriptors, err = listSignaturesAndDescriptors(r.loader, r.skipVerify, r.sizeLimitBytes)
if err != nil {
return bundle, err
}
@@ -305,13 +386,13 @@ func (r *Reader) Read() (Bundle, error) {
for _, f := range descriptors {
var buf bytes.Buffer
- n, err := f.Read(&buf, BundleLimitBytes)
+ n, err := f.Read(&buf, r.sizeLimitBytes)
f.Close() // always close, even on error
if err != nil && err != io.EOF {
return bundle, err
- } else if err == nil && n >= BundleLimitBytes {
- return bundle, fmt.Errorf("bundle exceeded max size (%v bytes)", BundleLimitBytes-1)
+ } else if err == nil && n >= r.sizeLimitBytes {
+ return bundle, fmt.Errorf("bundle file exceeded max size (%v bytes)", r.sizeLimitBytes-1)
}
// verify the file content
@@ -338,7 +419,7 @@ func (r *Reader) Read() (Bundle, error) {
if strings.HasSuffix(path, RegoExt) {
fullPath := r.fullPath(path)
r.metrics.Timer(metrics.RegoModuleParse).Start()
- module, err := ast.ParseModule(fullPath, buf.String())
+ module, err := ast.ParseModuleWithOpts(fullPath, buf.String(), ast.ParserOptions{ProcessAnnotation: r.processAnnotations})
r.metrics.Timer(metrics.RegoModuleParse).Stop()
if err != nil {
return bundle, err
@@ -352,9 +433,12 @@ func (r *Reader) Read() (Bundle, error) {
}
bundle.Modules = append(bundle.Modules, mf)
- } else if path == WasmFile {
- bundle.Wasm = buf.Bytes()
-
+ } else if filepath.Base(path) == WasmFile {
+ bundle.WasmModules = append(bundle.WasmModules, WasmModuleFile{
+ URL: f.URL(),
+ Path: r.fullPath(path),
+ Raw: buf.Bytes(),
+ })
} else if filepath.Base(path) == dataFile {
var value interface{}
@@ -406,6 +490,22 @@ func (r *Reader) Read() (Bundle, error) {
return bundle, err
}
+ // Inject the wasm module entrypoint refs into the WasmModuleFile structs
+ epMap := map[string][]string{}
+ for _, r := range bundle.Manifest.WasmResolvers {
+ epMap[r.Module] = append(epMap[r.Module], r.Entrypoint)
+ }
+ for i := 0; i < len(bundle.WasmModules); i++ {
+ entrypoints := epMap[bundle.WasmModules[i].Path]
+ for _, entrypoint := range entrypoints {
+ ref, err := ast.PtrRef(ast.DefaultRootDocument, entrypoint)
+ if err != nil {
+ return bundle, fmt.Errorf("failed to parse wasm module entrypoint '%s': %s", entrypoint, err)
+ }
+ bundle.WasmModules[i].Entrypoints = append(bundle.WasmModules[i].Entrypoints, ref)
+ }
+ }
+
if r.includeManifestInData {
var metadata map[string]interface{}
@@ -444,7 +544,7 @@ func (r *Reader) checkSignaturesAndDescriptors(signatures SignaturesConfig) erro
return nil
}
- if signatures.isEmpty() && r.verificationConfig != nil {
+ if signatures.isEmpty() && r.verificationConfig != nil && r.verificationConfig.KeyID != "" {
return fmt.Errorf("bundle missing .signatures.json file")
}
@@ -491,7 +591,6 @@ type Writer struct {
usePath bool
disableFormat bool
w io.Writer
- signingConfig *SigningConfig
}
// NewWriter returns a bundle writer that writes to w.
@@ -541,7 +640,7 @@ func (w *Writer) Write(bundle Bundle) error {
}
}
- if err := writeWasm(tw, bundle); err != nil {
+ if err := w.writeWasm(tw, bundle); err != nil {
return err
}
@@ -560,12 +659,27 @@ func (w *Writer) Write(bundle Bundle) error {
return gw.Close()
}
-func writeWasm(tw *tar.Writer, bundle Bundle) error {
- if len(bundle.Wasm) == 0 {
- return nil
+func (w *Writer) writeWasm(tw *tar.Writer, bundle Bundle) error {
+ for _, wm := range bundle.WasmModules {
+ path := wm.URL
+ if w.usePath {
+ path = wm.Path
+ }
+
+ err := archive.WriteFile(tw, path, wm.Raw)
+ if err != nil {
+ return err
+ }
}
- return archive.WriteFile(tw, WasmFile, bundle.Wasm)
+ if len(bundle.Wasm) > 0 {
+ err := archive.WriteFile(tw, "/"+WasmFile, bundle.Wasm)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
}
func writeManifest(tw *tar.Writer, bundle Bundle) error {
@@ -593,29 +707,37 @@ func writeSignatures(tw *tar.Writer, bundle Bundle) error {
return archive.WriteFile(tw, fmt.Sprintf(".%v", SignaturesFile), bs)
}
-func hashBundleFiles(hash SignatureHasher, data map[string]interface{}, manifest Manifest, wasm []byte) ([]FileInfo, error) {
+func hashBundleFiles(hash SignatureHasher, b *Bundle) ([]FileInfo, error) {
files := []FileInfo{}
- bytes, err := hash.HashFile(data)
+ bs, err := hash.HashFile(b.Data)
if err != nil {
return files, err
}
- files = append(files, NewFile(strings.TrimPrefix("data.json", "/"), hex.EncodeToString(bytes), defaultHashingAlg))
+ files = append(files, NewFile(strings.TrimPrefix("data.json", "/"), hex.EncodeToString(bs), defaultHashingAlg))
+
+ if len(b.Wasm) != 0 {
+ bs, err := hash.HashFile(b.Wasm)
+ if err != nil {
+ return files, err
+ }
+ files = append(files, NewFile(strings.TrimPrefix(WasmFile, "/"), hex.EncodeToString(bs), defaultHashingAlg))
+ }
- if len(wasm) != 0 {
- bytes, err := hash.HashFile(wasm)
+ for _, wasmModule := range b.WasmModules {
+ bs, err := hash.HashFile(wasmModule.Raw)
if err != nil {
return files, err
}
- files = append(files, NewFile(strings.TrimPrefix(WasmFile, "/"), hex.EncodeToString(bytes), defaultHashingAlg))
+ files = append(files, NewFile(strings.TrimPrefix(wasmModule.Path, "/"), hex.EncodeToString(bs), defaultHashingAlg))
}
- bytes, err = hash.HashFile(manifest)
+ bs, err = hash.HashFile(b.Manifest)
if err != nil {
return files, err
}
- files = append(files, NewFile(strings.TrimPrefix(ManifestExt, "/"), hex.EncodeToString(bytes), defaultHashingAlg))
+ files = append(files, NewFile(strings.TrimPrefix(ManifestExt, "/"), hex.EncodeToString(bs), defaultHashingAlg))
return files, err
}
@@ -669,7 +791,7 @@ func (b *Bundle) GenerateSignature(signingConfig *SigningConfig, keyID string, u
files = append(files, NewFile(strings.TrimPrefix(path, "/"), hex.EncodeToString(bytes), defaultHashingAlg))
}
- result, err := hashBundleFiles(hash, b.Data, b.Manifest, b.Wasm)
+ result, err := hashBundleFiles(hash, b)
if err != nil {
return err
}
@@ -685,6 +807,10 @@ func (b *Bundle) GenerateSignature(signingConfig *SigningConfig, keyID string, u
b.Signatures = SignaturesConfig{}
}
+ if signingConfig.Plugin != "" {
+ b.Signatures.Plugin = signingConfig.Plugin
+ }
+
b.Signatures.Signatures = []string{string(token)}
return nil
@@ -839,9 +965,7 @@ func mktree(path []string, value interface{}) (map[string]interface{}, error) {
// Merge accepts a set of bundles and merges them into a single result bundle. If there are
// any conflicts during the merge (e.g., with roots) an error is returned. The result bundle
// will have an empty revision except in the special case where a single bundle is provided
-// (and in that case the bundle is just returned unmodified.) Merge currently returns an error
-// if multiple bundles are provided and any of those bundles contain wasm modules (because
-// wasm module merging is not implemented.)
+// (and in that case the bundle is just returned unmodified.)
func Merge(bundles []*Bundle) (*Bundle, error) {
if len(bundles) == 0 {
@@ -863,10 +987,6 @@ func Merge(bundles []*Bundle) (*Bundle, error) {
roots = append(roots, *b.Manifest.Roots...)
- if len(b.Wasm) > 0 {
- return nil, errors.New("wasm bundles cannot be merged")
- }
-
result.Modules = append(result.Modules, b.Modules...)
for _, root := range *b.Manifest.Roots {
@@ -877,6 +997,10 @@ func Merge(bundles []*Bundle) (*Bundle, error) {
}
}
}
+
+ result.Manifest.WasmResolvers = append(result.Manifest.WasmResolvers, b.Manifest.WasmResolvers...)
+ result.WasmModules = append(result.WasmModules, b.WasmModules...)
+
}
result.Manifest.Roots = &roots
@@ -986,7 +1110,7 @@ func IsStructuredDoc(name string) bool {
filepath.Base(name) == SignaturesFile || filepath.Base(name) == ManifestExt
}
-func listSignaturesAndDescriptors(loader DirectoryLoader, skipVerify bool) (SignaturesConfig, []*Descriptor, error) {
+func listSignaturesAndDescriptors(loader DirectoryLoader, skipVerify bool, sizeLimitBytes int64) (SignaturesConfig, []*Descriptor, error) {
descriptors := []*Descriptor{}
var signatures SignaturesConfig
@@ -1003,12 +1127,12 @@ func listSignaturesAndDescriptors(loader DirectoryLoader, skipVerify bool) (Sign
// check for the signatures file
if !skipVerify && strings.HasSuffix(f.Path(), SignaturesFile) {
var buf bytes.Buffer
- n, err := f.Read(&buf, BundleLimitBytes)
+ n, err := f.Read(&buf, sizeLimitBytes)
f.Close() // always close, even on error
if err != nil && err != io.EOF {
return signatures, nil, err
- } else if err == nil && n >= BundleLimitBytes {
- return signatures, nil, fmt.Errorf("bundle exceeded max size (%v bytes)", BundleLimitBytes-1)
+ } else if err == nil && n >= sizeLimitBytes {
+ return signatures, nil, fmt.Errorf("bundle signatures file exceeded max size (%v bytes)", sizeLimitBytes-1)
}
if err := util.NewJSONDecoder(&buf).Decode(&signatures); err != nil {
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/bundle/filefs.go b/constraint/vendor/github.com/open-policy-agent/opa/bundle/filefs.go
new file mode 100644
index 000000000..60c80fc7d
--- /dev/null
+++ b/constraint/vendor/github.com/open-policy-agent/opa/bundle/filefs.go
@@ -0,0 +1,73 @@
+// +build go1.16
+
+package bundle
+
+import (
+ "fmt"
+ "io"
+ "io/fs"
+ "sync"
+)
+
+const (
+ defaultFSLoaderRoot = "."
+)
+
+type dirLoaderFS struct {
+ sync.Mutex
+ filesystem fs.FS
+ files []string
+ idx int
+}
+
+// NewFSLoader returns a basic DirectoryLoader implementation
+// that will load files from a fs.FS interface
+func NewFSLoader(filesystem fs.FS) (DirectoryLoader, error) {
+ d := dirLoaderFS{
+ filesystem: filesystem,
+ }
+
+ err := fs.WalkDir(d.filesystem, defaultFSLoaderRoot, d.walkDir)
+ if err != nil {
+ return nil, fmt.Errorf("failed to list files: %w", err)
+ }
+
+ return &d, nil
+}
+
+func (d *dirLoaderFS) walkDir(path string, dirEntry fs.DirEntry, err error) error {
+ if err != nil {
+ return err
+ }
+
+ if dirEntry != nil && dirEntry.Type().IsRegular() {
+ d.files = append(d.files, path)
+ }
+
+ return nil
+}
+
+// NextFile iterates to the next file in the directory tree
+// and returns a file Descriptor for the file.
+func (d *dirLoaderFS) NextFile() (*Descriptor, error) {
+ d.Lock()
+ defer d.Unlock()
+
+ // If done reading files then just return io.EOF
+ // errors for each NextFile() call
+ if d.idx >= len(d.files) {
+ return nil, io.EOF
+ }
+
+ fileName := d.files[d.idx]
+ d.idx++
+
+ fh, err := d.filesystem.Open(fileName)
+ if err != nil {
+ return nil, fmt.Errorf("failed to open file %s: %w", fileName, err)
+ }
+
+ fileNameWithSlash := fmt.Sprintf("/%s", fileName)
+ f := newDescriptor(fileNameWithSlash, fileNameWithSlash, fh).withCloser(fh)
+ return f, nil
+}
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/bundle/hash.go b/constraint/vendor/github.com/open-policy-agent/opa/bundle/hash.go
index b7f582cbc..021801bb0 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/bundle/hash.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/bundle/hash.go
@@ -95,7 +95,7 @@ func walk(v interface{}, h io.Writer) {
switch x := v.(type) {
case map[string]interface{}:
- h.Write([]byte("{"))
+ _, _ = h.Write([]byte("{"))
var keys []string
for k := range x {
@@ -105,30 +105,30 @@ func walk(v interface{}, h io.Writer) {
for i, key := range keys {
if i > 0 {
- h.Write([]byte(","))
+ _, _ = h.Write([]byte(","))
}
- h.Write(encodePrimitive(key))
- h.Write([]byte(":"))
+ _, _ = h.Write(encodePrimitive(key))
+ _, _ = h.Write([]byte(":"))
walk(x[key], h)
}
- h.Write([]byte("}"))
+ _, _ = h.Write([]byte("}"))
case []interface{}:
- h.Write([]byte("["))
+ _, _ = h.Write([]byte("["))
for i, e := range x {
if i > 0 {
- h.Write([]byte(","))
+ _, _ = h.Write([]byte(","))
}
walk(e, h)
}
- h.Write([]byte("]"))
+ _, _ = h.Write([]byte("]"))
case []byte:
- h.Write(x)
+ _, _ = h.Write(x)
default:
- h.Write(encodePrimitive(x))
+ _, _ = h.Write(encodePrimitive(x))
}
}
@@ -136,6 +136,6 @@ func encodePrimitive(v interface{}) []byte {
var buf bytes.Buffer
encoder := json.NewEncoder(&buf)
encoder.SetEscapeHTML(false)
- encoder.Encode(v)
- return []byte(strings.Trim(string(buf.Bytes()), "\n"))
+ _ = encoder.Encode(v)
+ return []byte(strings.Trim(buf.String(), "\n"))
}
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/bundle/keys.go b/constraint/vendor/github.com/open-policy-agent/opa/bundle/keys.go
index 35b7cae53..60e50e3c1 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/bundle/keys.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/bundle/keys.go
@@ -6,14 +6,13 @@
package bundle
import (
- "encoding/json"
"fmt"
"io/ioutil"
"os"
- "reflect"
"github.com/open-policy-agent/opa/internal/jwx/jwa"
"github.com/open-policy-agent/opa/internal/jwx/jws/sign"
+ "github.com/open-policy-agent/opa/keys"
"github.com/open-policy-agent/opa/util"
)
@@ -22,6 +21,10 @@ const (
defaultTokenSigningAlg = "RS256"
)
+// KeyConfig holds the keys used to sign or verify bundles and tokens
+// Moved to own package, alias kept for backwards compatibility
+type KeyConfig = keys.Config
+
// VerificationConfig represents the key configuration used to verify a signed bundle
type VerificationConfig struct {
PublicKeys map[string]*KeyConfig
@@ -71,65 +74,9 @@ func (vc *VerificationConfig) GetPublicKey(id string) (*KeyConfig, error) {
return kc, nil
}
-// KeyConfig holds the actual public keys used to verify a signed bundle
-type KeyConfig struct {
- Key string `json:"key"`
- Algorithm string `json:"algorithm"`
- Scope string `json:"scope"`
-}
-
-// NewKeyConfig return a new KeyConfig
-func NewKeyConfig(key, alg, scope string) *KeyConfig {
- return &KeyConfig{
- Key: key,
- Algorithm: alg,
- Scope: scope,
- }
-}
-
-// ParseKeysConfig returns a map containing the public key and the signing algorithm
-func ParseKeysConfig(raw json.RawMessage) (map[string]*KeyConfig, error) {
- keys := map[string]*KeyConfig{}
- var obj map[string]json.RawMessage
-
- if err := util.Unmarshal(raw, &obj); err == nil {
- for k := range obj {
- var keyConfig KeyConfig
- if err = util.Unmarshal(obj[k], &keyConfig); err != nil {
- return nil, err
- }
-
- if err = keyConfig.validateAndInjectDefaults(k); err != nil {
- return nil, err
- }
-
- keys[k] = &keyConfig
- }
- } else {
- return nil, err
- }
- return keys, nil
-}
-
-func (k *KeyConfig) validateAndInjectDefaults(id string) error {
- if k.Key == "" {
- return fmt.Errorf("invalid keys configuration: verification key empty for key ID %v", id)
- }
-
- if k.Algorithm == "" {
- k.Algorithm = defaultTokenSigningAlg
- }
-
- return nil
-}
-
-// Equal returns true if this key config is equal to the other.
-func (k *KeyConfig) Equal(other *KeyConfig) bool {
- return reflect.DeepEqual(k, other)
-}
-
// SigningConfig represents the key configuration used to generate a signed bundle
type SigningConfig struct {
+ Plugin string
Key string
Algorithm string
ClaimsPath string
@@ -142,12 +89,21 @@ func NewSigningConfig(key, alg, claimsPath string) *SigningConfig {
}
return &SigningConfig{
+ Plugin: defaultSignerID,
Key: key,
Algorithm: alg,
ClaimsPath: claimsPath,
}
}
+// WithPlugin sets the signing plugin in the signing config
+func (s *SigningConfig) WithPlugin(plugin string) *SigningConfig {
+ if plugin != "" {
+ s.Plugin = plugin
+ }
+ return s
+}
+
// GetPrivateKey returns the private key or secret from the signing config
func (s *SigningConfig) GetPrivateKey() (interface{}, error) {
var priv string
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/bundle/sign.go b/constraint/vendor/github.com/open-policy-agent/opa/bundle/sign.go
index 673d364f6..13d6667f5 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/bundle/sign.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/bundle/sign.go
@@ -7,15 +7,48 @@ package bundle
import (
"encoding/json"
+ "fmt"
"github.com/open-policy-agent/opa/internal/jwx/jwa"
"github.com/open-policy-agent/opa/internal/jwx/jws"
)
+const defaultSignerID = "_default"
+
+var signers map[string]Signer
+
+// Signer is the interface expected for implementations that generate bundle signatures.
+type Signer interface {
+ GenerateSignedToken([]FileInfo, *SigningConfig, string) (string, error)
+}
+
+// GenerateSignedToken will retrieve the Signer implementation based on the Plugin specified
+// in SigningConfig, and call its implementation of GenerateSignedToken. The signer generates
+// a signed token given the list of files to be included in the payload and the bundle
+// signing config. The keyID if non-empty, represents the value for the "keyid" claim in the token.
+func GenerateSignedToken(files []FileInfo, sc *SigningConfig, keyID string) (string, error) {
+ var plugin string
+ // for backwards compatibility, check if there is no plugin specified, and use default
+ if sc.Plugin == "" {
+ plugin = defaultSignerID
+ } else {
+ plugin = sc.Plugin
+ }
+ signer, err := GetSigner(plugin)
+ if err != nil {
+ return "", err
+ }
+ return signer.GenerateSignedToken(files, sc, keyID)
+}
+
+// DefaultSigner is the default bundle signing implementation. It signs bundles by generating
+// a JWT and signing it using a locally-accessible private key.
+type DefaultSigner struct{}
+
// GenerateSignedToken generates a signed token given the list of files to be
// included in the payload and the bundle signing config. The keyID if non-empty,
// represents the value for the "keyid" claim in the token
-func GenerateSignedToken(files []FileInfo, sc *SigningConfig, keyID string) (string, error) {
+func (*DefaultSigner) GenerateSignedToken(files []FileInfo, sc *SigningConfig, keyID string) (string, error) {
payload, err := generatePayload(files, sc, keyID)
if err != nil {
return "", err
@@ -71,3 +104,27 @@ func generatePayload(files []FileInfo, sc *SigningConfig, keyID string) ([]byte,
}
return json.Marshal(payload)
}
+
+// GetSigner returns the Signer registered under the given id
+func GetSigner(id string) (Signer, error) {
+ signer, ok := signers[id]
+ if !ok {
+ return nil, fmt.Errorf("no signer exists under id %s", id)
+ }
+ return signer, nil
+}
+
+// RegisterSigner registers a Signer under the given id
+func RegisterSigner(id string, s Signer) error {
+ if id == defaultSignerID {
+ return fmt.Errorf("signer id %s is reserved, use a different id", id)
+ }
+ signers[id] = s
+ return nil
+}
+
+func init() {
+ signers = map[string]Signer{
+ defaultSignerID: &DefaultSigner{},
+ }
+}
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/bundle/store.go b/constraint/vendor/github.com/open-policy-agent/opa/bundle/store.go
index 481ff6ef3..1753ffa3e 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/bundle/store.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/bundle/store.go
@@ -6,41 +6,54 @@ package bundle
import (
"context"
+ "encoding/base64"
+ "encoding/json"
"fmt"
"strings"
- "github.com/open-policy-agent/opa/metrics"
-
"github.com/open-policy-agent/opa/ast"
-
+ "github.com/open-policy-agent/opa/metrics"
"github.com/open-policy-agent/opa/storage"
"github.com/open-policy-agent/opa/util"
)
-var bundlesBasePath = storage.MustParsePath("/system/bundles")
+// BundlesBasePath is the storage path used for storing bundle metadata
+var BundlesBasePath = storage.MustParsePath("/system/bundles")
// Note: As needed these helpers could be memoized.
// ManifestStoragePath is the storage path used for the given named bundle manifest.
func ManifestStoragePath(name string) storage.Path {
- return append(bundlesBasePath, name, "manifest")
+ return append(BundlesBasePath, name, "manifest")
}
func namedBundlePath(name string) storage.Path {
- return append(bundlesBasePath, name)
+ return append(BundlesBasePath, name)
}
func rootsPath(name string) storage.Path {
- return append(bundlesBasePath, name, "manifest", "roots")
+ return append(BundlesBasePath, name, "manifest", "roots")
}
func revisionPath(name string) storage.Path {
- return append(bundlesBasePath, name, "manifest", "revision")
+ return append(BundlesBasePath, name, "manifest", "revision")
+}
+
+func wasmModulePath(name string) storage.Path {
+ return append(BundlesBasePath, name, "wasm")
+}
+
+func wasmEntrypointsPath(name string) storage.Path {
+ return append(BundlesBasePath, name, "manifest", "wasm")
+}
+
+func metadataPath(name string) storage.Path {
+ return append(BundlesBasePath, name, "manifest", "metadata")
}
// ReadBundleNamesFromStore will return a list of bundle names which have had their metadata stored.
func ReadBundleNamesFromStore(ctx context.Context, store storage.Store, txn storage.Transaction) ([]string, error) {
- value, err := store.Read(ctx, txn, bundlesBasePath)
+ value, err := store.Read(ctx, txn, BundlesBasePath)
if err != nil {
return nil, err
}
@@ -65,8 +78,7 @@ func WriteManifestToStore(ctx context.Context, store storage.Store, txn storage.
return write(ctx, store, txn, ManifestStoragePath(name), manifest)
}
-func write(ctx context.Context, store storage.Store, txn storage.Transaction, path storage.Path, manifest Manifest) error {
- var value interface{} = manifest
+func write(ctx context.Context, store storage.Store, txn storage.Transaction, path storage.Path, value interface{}) error {
if err := util.RoundTrip(&value); err != nil {
return err
}
@@ -94,6 +106,79 @@ func EraseManifestFromStore(ctx context.Context, store storage.Store, txn storag
return nil
}
+func writeWasmModulesToStore(ctx context.Context, store storage.Store, txn storage.Transaction, name string, b *Bundle) error {
+ basePath := wasmModulePath(name)
+ for _, wm := range b.WasmModules {
+ path := append(basePath, wm.Path)
+ err := write(ctx, store, txn, path, base64.StdEncoding.EncodeToString(wm.Raw))
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func eraseWasmModulesFromStore(ctx context.Context, store storage.Store, txn storage.Transaction, name string) error {
+ path := wasmModulePath(name)
+
+ err := store.Write(ctx, txn, storage.RemoveOp, path, nil)
+ if err != nil && !storage.IsNotFound(err) {
+ return err
+ }
+ return nil
+}
+
+// ReadWasmMetadataFromStore will read Wasm module resolver metadata from the store.
+func ReadWasmMetadataFromStore(ctx context.Context, store storage.Store, txn storage.Transaction, name string) ([]WasmResolver, error) {
+ path := wasmEntrypointsPath(name)
+ value, err := store.Read(ctx, txn, path)
+ if err != nil {
+ return nil, err
+ }
+
+ bs, err := json.Marshal(value)
+ if err != nil {
+ return nil, fmt.Errorf("corrupt wasm manifest data")
+ }
+
+ var wasmMetadata []WasmResolver
+
+ err = util.UnmarshalJSON(bs, &wasmMetadata)
+ if err != nil {
+ return nil, fmt.Errorf("corrupt wasm manifest data")
+ }
+
+ return wasmMetadata, nil
+}
+
+// ReadWasmModulesFromStore will write Wasm module resolver metadata from the store.
+func ReadWasmModulesFromStore(ctx context.Context, store storage.Store, txn storage.Transaction, name string) (map[string][]byte, error) {
+ path := wasmModulePath(name)
+ value, err := store.Read(ctx, txn, path)
+ if err != nil {
+ return nil, err
+ }
+
+ encodedModules, ok := value.(map[string]interface{})
+ if !ok {
+ return nil, fmt.Errorf("corrupt wasm modules")
+ }
+
+ rawModules := map[string][]byte{}
+ for path, enc := range encodedModules {
+ encStr, ok := enc.(string)
+ if !ok {
+ return nil, fmt.Errorf("corrupt wasm modules")
+ }
+ bs, err := base64.StdEncoding.DecodeString(encStr)
+ if err != nil {
+ return nil, err
+ }
+ rawModules[path] = bs
+ }
+ return rawModules, nil
+}
+
// ReadBundleRootsFromStore returns the roots in the specified bundle.
// If the bundle is not activated, this function will return
// storage NotFound error.
@@ -141,11 +226,37 @@ func readRevisionFromStore(ctx context.Context, store storage.Store, txn storage
return str, nil
}
+// ReadBundleMetadataFromStore returns the metadata in the specified bundle.
+// If the bundle is not activated, this function will return
+// storage NotFound error.
+func ReadBundleMetadataFromStore(ctx context.Context, store storage.Store, txn storage.Transaction, name string) (map[string]interface{}, error) {
+ return readMetadataFromStore(ctx, store, txn, metadataPath(name))
+}
+
+func readMetadataFromStore(ctx context.Context, store storage.Store, txn storage.Transaction, path storage.Path) (map[string]interface{}, error) {
+ value, err := store.Read(ctx, txn, path)
+ if err != nil {
+ if storageErr, ok := err.(*storage.Error); ok && storageErr.Code == storage.NotFoundErr {
+ return nil, nil
+ }
+
+ return nil, err
+ }
+
+ data, ok := value.(map[string]interface{})
+ if !ok {
+ return nil, fmt.Errorf("corrupt manifest metadata")
+ }
+
+ return data, nil
+}
+
// ActivateOpts defines options for the Activate API call.
type ActivateOpts struct {
Ctx context.Context
Store storage.Store
Txn storage.Transaction
+ TxnCtx *storage.Context
Compiler *ast.Compiler
Metrics metrics.Metrics
Bundles map[string]*Bundle // Optional
@@ -256,6 +367,10 @@ func activateBundles(opts *ActivateOpts) error {
return err
}
}
+
+ if err := writeWasmModulesToStore(opts.Ctx, opts.Store, opts.Txn, name, b); err != nil {
+ return err
+ }
}
return nil
@@ -282,6 +397,10 @@ func eraseBundles(ctx context.Context, store storage.Store, txn storage.Transact
if err := LegacyEraseManifestFromStore(ctx, store, txn); err != nil && !storage.IsNotFound(err) {
return nil, err
}
+
+ if err := eraseWasmModulesFromStore(ctx, store, txn, name); err != nil && !storage.IsNotFound(err) {
+ return nil, err
+ }
}
return remaining, nil
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/bundle/verify.go b/constraint/vendor/github.com/open-policy-agent/opa/bundle/verify.go
index d26b8e170..f76baf2c8 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/bundle/verify.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/bundle/verify.go
@@ -20,9 +20,45 @@ import (
"github.com/pkg/errors"
)
+const defaultVerifierID = "_default"
+
+var verifiers map[string]Verifier
+
+// Verifier is the interface expected for implementations that verify bundle signatures.
+type Verifier interface {
+ VerifyBundleSignature(SignaturesConfig, *VerificationConfig) (map[string]FileInfo, error)
+}
+
+// VerifyBundleSignature will retrieve the Verifier implementation based
+// on the Plugin specified in SignaturesConfig, and call its implementation
+// of VerifyBundleSignature. VerifyBundleSignature verifies the bundle signature
+// using the given public keys or secret. If a signature is verified, it keeps
+// track of the files specified in the JWT payload
+func VerifyBundleSignature(sc SignaturesConfig, bvc *VerificationConfig) (map[string]FileInfo, error) {
+ // default implementation does not return a nil for map, so don't
+ // do it here either
+ files := make(map[string]FileInfo)
+ var plugin string
+ // for backwards compatibility, check if there is no plugin specified, and use default
+ if sc.Plugin == "" {
+ plugin = defaultVerifierID
+ } else {
+ plugin = sc.Plugin
+ }
+ verifier, err := GetVerifier(plugin)
+ if err != nil {
+ return files, err
+ }
+ return verifier.VerifyBundleSignature(sc, bvc)
+}
+
+// DefaultVerifier is the default bundle verification implementation. It verifies bundles by checking
+// the JWT signature using a locally-accessible public key.
+type DefaultVerifier struct{}
+
// VerifyBundleSignature verifies the bundle signature using the given public keys or secret.
// If a signature is verified, it keeps track of the files specified in the JWT payload
-func VerifyBundleSignature(sc SignaturesConfig, bvc *VerificationConfig) (map[string]FileInfo, error) {
+func (*DefaultVerifier) VerifyBundleSignature(sc SignaturesConfig, bvc *VerificationConfig) (map[string]FileInfo, error) {
files := make(map[string]FileInfo)
if len(sc.Signatures) == 0 {
@@ -171,3 +207,27 @@ func VerifyBundleFile(path string, data bytes.Buffer, files map[string]FileInfo)
delete(files, path)
return nil
}
+
+// GetVerifier returns the Verifier registered under the given id
+func GetVerifier(id string) (Verifier, error) {
+ verifier, ok := verifiers[id]
+ if !ok {
+ return nil, fmt.Errorf("no verifier exists under id %s", id)
+ }
+ return verifier, nil
+}
+
+// RegisterVerifier registers a Verifier under the given id
+func RegisterVerifier(id string, v Verifier) error {
+ if id == defaultVerifierID {
+ return fmt.Errorf("verifier id %s is reserved, use a different id", id)
+ }
+ verifiers[id] = v
+ return nil
+}
+
+func init() {
+ verifiers = map[string]Verifier{
+ defaultVerifierID: &DefaultVerifier{},
+ }
+}
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/format/format.go b/constraint/vendor/github.com/open-policy-agent/opa/format/format.go
index 3baa3b708..be1ff2739 100644
--- a/constraint/vendor/github.com/open-policy-agent/opa/format/format.go
+++ b/constraint/vendor/github.com/open-policy-agent/opa/format/format.go
@@ -141,12 +141,11 @@ func defaultLocation(x ast.Node) *ast.Location {
type writer struct {
buf bytes.Buffer
- indent string
- level int
- inline bool
- beforeEnd *ast.Comment
- delay bool
- wildcardNames map[string]string
+ indent string
+ level int
+ inline bool
+ beforeEnd *ast.Comment
+ delay bool
}
func (w *writer) writeModule(module *ast.Module) {
@@ -259,15 +258,15 @@ func (w *writer) writeRule(rule *ast.Rule, isElse bool, comments []*ast.Comment)
comments = w.writeBody(rule.Body, comments)
- var close *ast.Location
+ var closeLoc *ast.Location
if len(rule.Head.Args) > 0 {
- close = closingLoc('(', ')', '{', '}', rule.Location)
+ closeLoc = closingLoc('(', ')', '{', '}', rule.Location)
} else {
- close = closingLoc('[', ']', '{', '}', rule.Location)
+ closeLoc = closingLoc('[', ']', '{', '}', rule.Location)
}
- comments = w.insertComments(comments, close)
+ comments = w.insertComments(comments, closeLoc)
w.down()
w.startLine()
@@ -322,7 +321,7 @@ func (w *writer) writeElse(rule *ast.Rule, comments []*ast.Comment) []*ast.Comme
w.startLine()
}
- rule.Else.Head.Name = ast.Var("else")
+ rule.Else.Head.Name = "else"
rule.Else.Head.Args = nil
comments = w.insertComments(comments, rule.Else.Head.Location)
@@ -474,7 +473,7 @@ func (w *writer) writeFunctionCall(expr *ast.Expr, comments []*ast.Comment) []*a
if numCallArgs == numDeclArgs {
// Print infix where result is unassigned (e.g., x != y)
comments = w.writeTerm(terms[1], comments)
- w.write(" " + string(bi.Infix) + " ")
+ w.write(" " + bi.Infix + " ")
return w.writeTerm(terms[2], comments)
} else if numCallArgs == numDeclArgs+1 {
// Print infix where result is assigned (e.g., z = x + y)
@@ -490,7 +489,7 @@ func (w *writer) writeFunctionCall(expr *ast.Expr, comments []*ast.Comment) []*a
}
func (w *writer) writeFunctionCallPlain(terms []*ast.Term, comments []*ast.Comment) []*ast.Comment {
- w.write(string(terms[0].String()) + "(")
+ w.write(terms[0].String() + "(")
if len(terms) > 1 {
for _, v := range terms[1 : len(terms)-1] {
comments = w.writeTerm(v, comments)
@@ -546,7 +545,7 @@ func (w *writer) writeTermParens(parens bool, term *ast.Term, comments []*ast.Co
case ast.Var:
w.write(w.formatVar(x))
case ast.Call:
- comments = w.writeCall(parens, x, term.Location, comments)
+ comments = w.writeCall(parens, x, comments)
case fmt.Stringer:
w.write(x.String())
}
@@ -596,11 +595,11 @@ func (w *writer) formatVar(v ast.Var) string {
return v.String()
}
-func (w *writer) writeCall(parens bool, x ast.Call, loc *ast.Location, comments []*ast.Comment) []*ast.Comment {
+func (w *writer) writeCall(parens bool, x ast.Call, comments []*ast.Comment) []*ast.Comment {
bi, ok := ast.BuiltinMap[x[0].String()]
if !ok || bi.Infix == "" {
- return w.writeFunctionCallPlain([]*ast.Term(x), comments)
+ return w.writeFunctionCallPlain(x, comments)
}
// TODO(tsandall): improve to consider precedence?
@@ -929,15 +928,8 @@ func locCmp(a, b interface{}) int {
func getLoc(x interface{}) *ast.Location {
switch x := x.(type) {
case ast.Statement:
+ // Implicitly matches *ast.Head, *ast.Expr, *ast.With, *ast.Term.
return x.Loc()
- case *ast.Head:
- return x.Location
- case *ast.Expr:
- return x.Location
- case *ast.With:
- return x.Location
- case *ast.Term:
- return x.Location
case *ast.Location:
return x
case [2]*ast.Term:
@@ -1087,13 +1079,6 @@ func (w *writer) startMultilineSeq() {
w.startLine()
}
-func (w *writer) endMultilineSeq() {
- w.write(",")
- w.endLine()
- w.down()
- w.startLine()
-}
-
// up increases the indentation level
func (w *writer) up() {
w.level++
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/internal/bundle/utils.go b/constraint/vendor/github.com/open-policy-agent/opa/internal/bundle/utils.go
new file mode 100644
index 000000000..0e0775b1f
--- /dev/null
+++ b/constraint/vendor/github.com/open-policy-agent/opa/internal/bundle/utils.go
@@ -0,0 +1,85 @@
+// Copyright 2020 The OPA Authors. All rights reserved.
+// Use of this source code is governed by an Apache2
+// license that can be found in the LICENSE file.
+
+package bundle
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/open-policy-agent/opa/ast"
+ "github.com/open-policy-agent/opa/bundle"
+ "github.com/open-policy-agent/opa/resolver/wasm"
+ "github.com/open-policy-agent/opa/storage"
+)
+
+// LoadWasmResolversFromStore will lookup all Wasm modules from the store along with the
+// associated bundle manifest configuration and instantiate the respective resolvers.
+func LoadWasmResolversFromStore(ctx context.Context, store storage.Store, txn storage.Transaction, otherBundles map[string]*bundle.Bundle) ([]*wasm.Resolver, error) {
+ bundleNames, err := bundle.ReadBundleNamesFromStore(ctx, store, txn)
+ if err != nil && !storage.IsNotFound(err) {
+ return nil, err
+ }
+
+ var resolversToLoad []*bundle.WasmModuleFile
+ for _, bundleName := range bundleNames {
+ var wasmResolverConfigs []bundle.WasmResolver
+ rawModules := map[string][]byte{}
+
+ // Save round-tripping the bundle that was just activated
+ if _, ok := otherBundles[bundleName]; ok {
+ wasmResolverConfigs = otherBundles[bundleName].Manifest.WasmResolvers
+ for _, wmf := range otherBundles[bundleName].WasmModules {
+ rawModules[wmf.Path] = wmf.Raw
+ }
+ } else {
+ wasmResolverConfigs, err = bundle.ReadWasmMetadataFromStore(ctx, store, txn, bundleName)
+ if err != nil && !storage.IsNotFound(err) {
+ return nil, fmt.Errorf("failed to read wasm module manifest from store: %s", err)
+ }
+ rawModules, err = bundle.ReadWasmModulesFromStore(ctx, store, txn, bundleName)
+ if err != nil && !storage.IsNotFound(err) {
+ return nil, fmt.Errorf("failed to read wasm modules from store: %s", err)
+ }
+ }
+
+ for path, raw := range rawModules {
+ wmf := &bundle.WasmModuleFile{
+ URL: path,
+ Path: path,
+ Raw: raw,
+ }
+ for _, resolverConf := range wasmResolverConfigs {
+ if resolverConf.Module == path {
+ ref, err := ast.PtrRef(ast.DefaultRootDocument, resolverConf.Entrypoint)
+ if err != nil {
+ return nil, fmt.Errorf("failed to parse wasm module entrypoint '%s': %s", resolverConf.Entrypoint, err)
+ }
+ wmf.Entrypoints = append(wmf.Entrypoints, ref)
+ }
+ }
+ if len(wmf.Entrypoints) > 0 {
+ resolversToLoad = append(resolversToLoad, wmf)
+ }
+ }
+ }
+
+ var resolvers []*wasm.Resolver
+ if len(resolversToLoad) > 0 {
+ // Get a full snapshot of the current data (including any from "outside" the bundles)
+ data, err := store.Read(ctx, txn, storage.Path{})
+ if err != nil {
+ return nil, fmt.Errorf("failed to initialize wasm runtime: %s", err)
+ }
+
+ for _, wmf := range resolversToLoad {
+ resolver, err := wasm.New(wmf.Entrypoints, wmf.Raw, data)
+ if err != nil {
+ return nil, fmt.Errorf("failed to initialize wasm module for entrypoints '%s': %s", wmf.Entrypoints, err)
+ }
+ resolvers = append(resolvers, resolver)
+ }
+ }
+ return resolvers, nil
+}
diff --git a/constraint/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/callgraph.csv b/constraint/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/callgraph.csv
new file mode 100644
index 000000000..a9631aa42
--- /dev/null
+++ b/constraint/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/callgraph.csv
@@ -0,0 +1,2314 @@
+opa_agg_count,opa_value_type
+opa_agg_count,opa_unicode_decode_utf8
+opa_agg_count,opa_abort
+opa_agg_count,opa_number_int
+opa_agg_sum,opa_value_type
+opa_agg_sum,mpd_qnew
+opa_agg_sum,mpd_max_ctx
+opa_agg_sum,mpd_qset_i32
+opa_agg_sum,opa_abort
+opa_agg_sum,mpd_del
+opa_agg_sum,opa_number_to_bf
+opa_agg_sum,qadd
+opa_agg_sum,opa_bf_to_number
+opa_agg_product,opa_value_type
+opa_agg_product,mpd_qnew
+opa_agg_product,mpd_max_ctx
+opa_agg_product,mpd_qset_i32
+opa_agg_product,opa_abort
+opa_agg_product,mpd_del
+opa_agg_product,opa_number_to_bf
+opa_agg_product,qmul
+opa_agg_product,opa_bf_to_number
+opa_agg_max,opa_value_type
+opa_agg_max,opa_value_compare
+opa_agg_min,opa_value_type
+opa_agg_min,opa_value_compare
+opa_agg_sort,opa_value_type
+opa_agg_sort,opa_array_with_cap
+opa_agg_sort,opa_array_append
+opa_agg_sort,opa_value_shallow_copy
+opa_agg_sort,opa_array_sort
+opa_agg_all,opa_value_type
+opa_agg_all,opa_boolean
+opa_agg_any,opa_value_type
+opa_agg_any,opa_boolean
+opa_agg_any,opa_set_get
+opa_arith_abs,opa_number_to_bf
+opa_arith_abs,mpd_qnew
+opa_arith_abs,mpd_max_ctx
+opa_arith_abs,mpd_qabs
+opa_arith_abs,mpd_del
+opa_arith_abs,opa_abort
+opa_arith_abs,opa_bf_to_number
+opa_arith_round,opa_number_to_bf
+opa_arith_round,mpd_qnew
+opa_arith_round,mpd_max_ctx
+opa_arith_round,mpd_qround_to_int
+opa_arith_round,mpd_del
+opa_arith_round,opa_abort
+opa_arith_round,opa_bf_to_number
+opa_arith_ceil,opa_number_to_bf
+opa_arith_ceil,mpd_qnew
+opa_arith_ceil,mpd_max_ctx
+opa_arith_ceil,mpd_qceil
+opa_arith_ceil,mpd_del
+opa_arith_ceil,opa_bf_to_number
+opa_arith_floor,opa_number_to_bf
+opa_arith_floor,mpd_qnew
+opa_arith_floor,mpd_max_ctx
+opa_arith_floor,mpd_qfloor
+opa_arith_floor,mpd_del
+opa_arith_floor,opa_bf_to_number
+opa_arith_plus,opa_number_to_bf
+opa_arith_plus,opa_mpd_del
+opa_arith_plus,mpd_qnew
+opa_arith_plus,mpd_max_ctx
+opa_arith_plus,mpd_qadd
+opa_arith_plus,mpd_del
+opa_arith_plus,opa_abort
+opa_arith_plus,opa_bf_to_number
+opa_arith_minus,opa_number_to_bf
+opa_arith_minus,mpd_qnew
+opa_arith_minus,mpd_max_ctx
+opa_arith_minus,mpd_qsub
+opa_arith_minus,mpd_del
+opa_arith_minus,opa_abort
+opa_arith_minus,opa_bf_to_number
+opa_arith_minus,opa_mpd_del
+opa_arith_minus,opa_set_diff
+opa_arith_multiply,opa_number_to_bf
+opa_arith_multiply,opa_mpd_del
+opa_arith_multiply,mpd_qnew
+opa_arith_multiply,mpd_max_ctx
+opa_arith_multiply,mpd_qmul
+opa_arith_multiply,mpd_del
+opa_arith_multiply,opa_abort
+opa_arith_multiply,opa_bf_to_number
+opa_arith_divide,opa_number_to_bf
+opa_arith_divide,opa_mpd_del
+opa_arith_divide,mpd_qnew
+opa_arith_divide,mpd_default_ctx
+opa_arith_divide,mpd_qdiv
+opa_arith_divide,mpd_del
+opa_arith_divide,opa_abort
+opa_arith_divide,opa_bf_to_number
+opa_arith_rem,opa_number_to_bf
+opa_arith_rem,mpd_isinteger
+opa_arith_rem,opa_mpd_del
+opa_arith_rem,mpd_qnew
+opa_arith_rem,mpd_max_ctx
+opa_arith_rem,mpd_qrem
+opa_arith_rem,mpd_del
+opa_arith_rem,opa_bf_to_number
+opa_array_concat,opa_value_type
+opa_array_concat,opa_array_with_cap
+opa_array_concat,opa_array_append
+opa_array_slice,opa_value_type
+opa_array_slice,opa_number_try_int
+opa_array_slice,opa_array_with_cap
+opa_array_slice,opa_array_append
+opa_bits_or,opa_number_to_bf
+opa_bits_or,mpd_isinteger
+opa_bits_or,opa_mpd_del
+opa_bits_or,mpd_sign
+opa_bits_or,qabs
+opa_bits_or,qsub_one
+opa_bits_or,qand
+opa_bits_or,qadd_one
+opa_bits_or,qneg
+opa_bits_or,opa_bf_to_number
+opa_bits_or,qor
+opa_bits_or,qand_not
+opa_bits_and,opa_number_to_bf
+opa_bits_and,mpd_isinteger
+opa_bits_and,opa_mpd_del
+opa_bits_and,mpd_sign
+opa_bits_and,qabs
+opa_bits_and,qsub_one
+opa_bits_and,qor
+opa_bits_and,qadd_one
+opa_bits_and,qneg
+opa_bits_and,opa_bf_to_number
+opa_bits_and,qand
+opa_bits_and,qand_not
+opa_bits_negate,opa_number_to_bf
+opa_bits_negate,mpd_isinteger
+opa_bits_negate,mpd_sign
+opa_bits_negate,qabs
+opa_bits_negate,opa_bf_to_bf_bits
+opa_bits_negate,opa_bf_bits_to_bf
+opa_bits_negate,qsub_one
+opa_bits_negate,opa_bf_to_number
+opa_bits_negate,qadd_one
+opa_bits_negate,qneg
+opa_bits_xor,opa_number_to_bf
+opa_bits_xor,mpd_isinteger
+opa_bits_xor,opa_mpd_del
+opa_bits_xor,mpd_sign
+opa_bits_xor,qabs
+opa_bits_xor,qsub_one
+opa_bits_xor,qxor
+opa_bits_xor,opa_bf_to_number
+opa_bits_xor,qadd_one
+opa_bits_xor,qneg
+opa_bits_shiftleft,opa_number_to_bf
+opa_bits_shiftleft,opa_bf_to_bf_bits
+opa_bits_shiftleft,opa_mpd_del
+opa_bits_shiftleft,opa_value_type
+opa_bits_shiftleft,opa_number_try_int
+opa_bits_shiftleft,mpd_qnew
+opa_bits_shiftleft,mpd_max_ctx
+opa_bits_shiftleft,mpd_qshiftn
+opa_bits_shiftleft,mpd_del
+opa_bits_shiftleft,opa_abort
+opa_bits_shiftleft,opa_bf_bits_to_bf
+opa_bits_shiftleft,opa_bf_to_number
+opa_bits_shiftright,opa_number_to_bf
+opa_bits_shiftright,mpd_isinteger
+opa_bits_shiftright,opa_value_type
+opa_bits_shiftright,mpd_del
+opa_bits_shiftright,opa_number_try_int
+opa_bits_shiftright,mpd_sign
+opa_bits_shiftright,qabs
+opa_bits_shiftright,qsub_one
+opa_bits_shiftright,opa_bf_to_bf_bits
+opa_bits_shiftright,mpd_qshiftr_inplace
+opa_bits_shiftright,opa_bf_bits_to_bf
+opa_bits_shiftright,qadd_one
+opa_bits_shiftright,qneg
+opa_bits_shiftright,opa_bf_to_number
+opa_cidr_contains,opa_value_type
+opa_cidr_contains,parse_cidr
+opa_cidr_contains,parse_ip
+opa_cidr_contains,opa_boolean
+parse_cidr,parse_ip
+parse_cidr,opa_atoi64
+parse_ip,memchr
+opa_cidr_intersects,opa_value_type
+opa_cidr_intersects,parse_cidr
+opa_cidr_intersects,opa_boolean
+opa_cmp_eq,opa_value_compare
+opa_cmp_eq,opa_boolean
+opa_cmp_neq,opa_value_compare
+opa_cmp_neq,opa_boolean
+opa_cmp_gt,opa_value_compare
+opa_cmp_gt,opa_boolean
+opa_cmp_gte,opa_value_compare
+opa_cmp_gte,opa_boolean
+opa_cmp_lt,opa_value_compare
+opa_cmp_lt,opa_boolean
+opa_cmp_lte,opa_value_compare
+opa_cmp_lte,opa_boolean
+opa_eval_ctx_new,opa_malloc
+__force_import_opa_builtins,opa_builtin0
+__force_import_opa_builtins,opa_builtin1
+__force_import_opa_builtins,opa_builtin2
+__force_import_opa_builtins,opa_builtin3
+__force_import_opa_builtins,opa_builtin4
+opa_to_number,opa_value_type
+opa_to_number,opa_number_int
+opa_to_number,opa_atof64
+opa_to_number,opa_number_ref
+opa_base64_is_valid,opa_value_type
+opa_base64_is_valid,base64_gen_decode
+opa_base64_is_valid,free
+opa_base64_is_valid,opa_boolean
+base64_gen_decode,memset
+base64_gen_decode,malloc
+base64_gen_decode,free
+opa_base64_decode,opa_value_type
+opa_base64_decode,base64_gen_decode
+opa_base64_decode,opa_string_allocated
+opa_base64_encode,opa_value_type
+opa_base64_encode,base64_gen_encode
+opa_base64_encode,opa_string_allocated
+base64_gen_encode,malloc
+opa_base64_url_decode,opa_value_type
+opa_base64_url_decode,base64_gen_decode
+opa_base64_url_decode,opa_string_allocated
+opa_base64_url_encode,opa_value_type
+opa_base64_url_encode,base64_gen_encode
+opa_base64_url_encode,opa_string_allocated
+opa_json_unmarshal,opa_value_type
+opa_json_unmarshal,opa_json_parse
+opa_json_marshal,opa_json_dump
+opa_json_marshal,strlen
+opa_json_marshal,opa_string_allocated
+opa_runtime_error,opa_itoa
+opa_runtime_error,opa_strlen
+opa_runtime_error,opa_malloc
+opa_runtime_error,snprintf_
+opa_runtime_error,opa_abort
+builtin_graph_reachable,opa_value_type
+builtin_graph_reachable,opa_set
+builtin_graph_reachable,opa_array
+builtin_graph_reachable,opa_array_append
+builtin_graph_reachable,opa_value_get
+builtin_graph_reachable,opa_set_get
+builtin_graph_reachable,opa_set_add
+opa_json_lex_read_number,opa_isdigit
+opa_json_lex_read_string,opa_ishex
+opa_json_lex_read,opa_strncmp
+opa_json_lex_read,opa_isspace
+opa_json_lex_read,opa_json_lex_read_string
+opa_json_lex_read,opa_isdigit
+opa_json_lex_read,opa_json_lex_read_number
+opa_json_parse_string,opa_malloc
+opa_json_parse_string,opa_string_allocated
+opa_json_parse_string,opa_unicode_decode_unit
+opa_json_parse_string,opa_unicode_surrogate
+opa_json_parse_string,opa_abort
+opa_json_parse_string,opa_unicode_decode_utf8
+opa_json_parse_string,opa_unicode_encode_utf8
+opa_json_parse_string,opa_unicode_decode_surrogate
+opa_json_parse_token,opa_null
+opa_json_parse_token,opa_boolean
+opa_json_parse_token,opa_malloc
+opa_json_parse_token,opa_number_ref_allocated
+opa_json_parse_token,opa_json_parse_string
+opa_json_parse_token,opa_array
+opa_json_parse_token,opa_json_lex_read
+opa_json_parse_token,opa_json_parse_token
+opa_json_parse_token,opa_array_append
+opa_json_parse_token,opa_object
+opa_json_parse_token,opa_json_parse_set
+opa_json_parse_token,opa_json_parse_object
+opa_json_parse_token,opa_set
+opa_json_parse_set,opa_set
+opa_json_parse_set,opa_set_add
+opa_json_parse_set,opa_json_lex_read
+opa_json_parse_set,opa_json_parse_token
+opa_json_parse_object,opa_json_lex_read
+opa_json_parse_object,opa_json_parse_token
+opa_json_parse_object,opa_object
+opa_json_parse_object,opa_object_insert
+opa_json_parse,opa_json_lex_read
+opa_json_parse,opa_json_parse_token
+opa_value_parse,opa_json_lex_read
+opa_value_parse,opa_json_parse_token
+opa_json_writer_emit_boolean,opa_malloc
+opa_json_writer_emit_integer,opa_itoa
+opa_json_writer_emit_integer,opa_strlen
+opa_json_writer_emit_integer,opa_malloc
+opa_json_writer_emit_number,opa_json_writer_emit_integer
+opa_json_writer_emit_number,opa_malloc
+opa_json_writer_emit_number,opa_abort
+opa_json_writer_emit_string,opa_malloc
+opa_json_writer_emit_string,snprintf_
+opa_json_writer_emit_array_element,opa_value_get
+opa_json_writer_emit_array_element,opa_json_writer_emit_value
+opa_json_writer_emit_value,opa_value_type
+opa_json_writer_emit_value,opa_malloc
+opa_json_writer_emit_value,opa_json_writer_emit_boolean
+opa_json_writer_emit_value,opa_json_writer_emit_string
+opa_json_writer_emit_value,opa_json_writer_emit_number
+opa_json_writer_emit_value,opa_json_writer_emit_collection
+opa_json_writer_emit_value,opa_json_writer_emit_set_literal
+opa_json_writer_emit_collection,opa_malloc
+opa_json_writer_emit_collection,opa_value_iter
+opa_json_writer_emit_set_element,opa_json_writer_emit_value
+opa_json_writer_emit_set_literal,opa_value_length
+opa_json_writer_emit_set_literal,opa_malloc
+opa_json_writer_emit_set_literal,opa_json_writer_emit_collection
+opa_json_writer_emit_object_element,opa_value_type
+opa_json_writer_emit_object_element,opa_json_writer_emit_value
+opa_json_writer_emit_object_element,opa_json_writer_write
+opa_json_writer_emit_object_element,opa_string_terminated
+opa_json_writer_emit_object_element,opa_value_free
+opa_json_writer_emit_object_element,opa_free
+opa_json_writer_emit_object_element,opa_malloc
+opa_json_writer_emit_object_element,opa_value_get
+opa_json_writer_write,opa_malloc
+opa_json_writer_write,opa_json_writer_emit_value
+opa_json_writer_write,opa_free
+opa_json_dump,opa_json_writer_write
+opa_value_dump,opa_json_writer_write
+opa_realloc,opa_malloc
+opa_realloc,memcpy
+opa_realloc,opa_free
+opa_builtin_cache_get,opa_abort
+opa_builtin_cache_set,opa_abort
+opa_memoize_init,opa_malloc
+opa_memoize_init,opa_object
+opa_memoize_push,opa_malloc
+opa_memoize_push,opa_object
+opa_memoize_insert,opa_number_int
+opa_memoize_insert,opa_object_insert
+opa_memoize_get,opa_number_init_int
+opa_memoize_get,opa_object_get
+opa_mpd_init,mpd_defaultcontext
+opa_mpd_init,mpd_maxcontext
+opa_mpd_init,mpd_qnew
+opa_mpd_init,mpd_qset_i32
+opa_mpd_init,opa_abort
+opa_mpd_del,mpd_del
+opa_number_to_bf,opa_value_type
+opa_number_to_bf,mpd_qnew
+opa_number_to_bf,malloc
+opa_number_to_bf,memcpy
+opa_number_to_bf,mpd_qset_string
+opa_number_to_bf,opa_abort
+opa_number_to_bf,free
+opa_number_to_bf,mpd_qset_i32
+opa_number_to_bf,snprintf_
+opa_bf_to_number,mpd_qget_i32
+opa_bf_to_number,mpd_del
+opa_bf_to_number,opa_number_int
+opa_bf_to_number,mpd_to_sci
+opa_bf_to_number,opa_strlen
+opa_bf_to_number,opa_number_ref
+opa_bf_to_number_no_free,mpd_qget_i32
+opa_bf_to_number_no_free,opa_number_int
+opa_bf_to_number_no_free,mpd_to_sci
+opa_bf_to_number_no_free,opa_strlen
+opa_bf_to_number_no_free,opa_number_ref
+opa_bf_to_bf_bits,mpd_qnew
+opa_bf_to_bf_bits,mpd_qround_to_intx
+opa_bf_to_bf_bits,mpd_del
+opa_bf_to_bf_bits,mpd_qcmp
+opa_bf_to_bf_bits,opa_abort
+opa_bf_to_bf_bits,mpd_sign
+opa_bf_to_bf_bits,mpd_qabs
+opa_bf_to_bf_bits,mpd_sizeinbase
+opa_bf_to_bf_bits,malloc
+opa_bf_to_bf_bits,mpd_qexport_u16
+opa_bf_to_bf_bits,mpd_qimport_u16
+opa_bf_to_bf_bits,free
+opa_bf_bits_to_bf,mpd_sign
+opa_bf_bits_to_bf,mpd_qnew
+opa_bf_bits_to_bf,mpd_qabs
+opa_bf_bits_to_bf,opa_abort
+opa_bf_bits_to_bf,mpd_del
+opa_bf_bits_to_bf,mpd_sizeinbase
+opa_bf_bits_to_bf,malloc
+opa_bf_bits_to_bf,mpd_qexport_u16
+opa_bf_bits_to_bf,mpd_qimport_u16
+opa_bf_bits_to_bf,free
+qabs,mpd_qnew
+qabs,mpd_qabs
+qabs,opa_abort
+qabs,mpd_del
+qadd_one,mpd_qnew
+qadd_one,mpd_qadd
+qadd_one,opa_abort
+qadd_one,mpd_del
+qadd,mpd_qnew
+qadd,mpd_qadd
+qadd,opa_abort
+qadd,mpd_del
+qsub_one,mpd_qnew
+qsub_one,mpd_qsub
+qsub_one,opa_abort
+qsub_one,mpd_del
+qmul,mpd_qnew
+qmul,mpd_qmul
+qmul,opa_abort
+qmul,mpd_del
+qand,opa_bf_to_bf_bits
+qand,mpd_del
+qand,mpd_qnew
+qand,mpd_qand
+qand,opa_abort
+qand,opa_bf_bits_to_bf
+qand_not,opa_bf_to_bf_bits
+qand_not,mpd_del
+qand_not,mpd_sizeinbase
+qand_not,malloc
+qand_not,mpd_qexport_u16
+qand_not,opa_abort
+qand_not,mpd_qnew
+qand_not,mpd_qimport_u16
+qand_not,free
+qand_not,mpd_qxor
+qand_not,mpd_qand
+qand_not,opa_bf_bits_to_bf
+qor,opa_bf_to_bf_bits
+qor,mpd_del
+qor,mpd_qnew
+qor,mpd_qor
+qor,opa_abort
+qor,opa_bf_bits_to_bf
+qxor,opa_bf_to_bf_bits
+qxor,mpd_del
+qxor,mpd_qnew
+qxor,mpd_qxor
+qxor,opa_abort
+qxor,opa_bf_bits_to_bf
+qneg,opa_bf_to_bf_bits
+qneg,mpd_qnew
+qneg,mpd_qminus
+qneg,mpd_del
+qneg,opa_abort
+qneg,opa_bf_bits_to_bf
+opa_numbers_range,opa_number_to_bf
+opa_numbers_range,mpd_isinteger
+opa_numbers_range,mpd_qcmp
+opa_numbers_range,opa_abort
+opa_numbers_range,opa_array
+opa_numbers_range,opa_bf_to_number_no_free
+opa_numbers_range,opa_array_append
+opa_numbers_range,qsub_one
+opa_numbers_range,qadd_one
+opa_numbers_range,opa_mpd_del
+__paths_to_object,opa_object
+__paths_to_object,opa_value_get
+__paths_to_object,opa_object_insert
+__paths_to_object,opa_value_type
+__paths_to_object,opa_null
+__parse_path,opa_array
+__parse_path,opa_value_type
+__parse_path,opa_array_append
+__parse_path,opa_string_terminated
+__parse_path,opa_strings_trim_left
+__parse_path,opa_strings_split
+__parse_path,opa_strings_replace
+__get_json_paths,opa_array
+__get_json_paths,opa_value_iter
+__get_json_paths,opa_value_type
+__get_json_paths,opa_value_get
+__get_json_paths,__parse_path
+__get_json_paths,opa_array_append
+__json_remove,opa_value_type
+__json_remove,opa_object
+__json_remove,opa_value_iter
+__json_remove,opa_value_get
+__json_remove,__json_remove
+__json_remove,opa_object_insert
+__json_remove,opa_set
+__json_remove,opa_set_add
+__json_remove,opa_array
+__json_remove,opa_number_int
+__json_remove,opa_strings_format_int
+__json_remove,opa_array_append
+__json_filter,opa_null
+__json_filter,opa_value_compare
+__json_filter,opa_value_type
+__json_filter,opa_object
+__json_filter,opa_value_iter
+__json_filter,opa_value_get
+__json_filter,__json_filter
+__json_filter,opa_object_insert
+__json_filter,opa_set
+__json_filter,opa_set_add
+__json_filter,opa_array
+__json_filter,opa_number_int
+__json_filter,opa_strings_format_int
+__json_filter,opa_array_append
+builtin_object_filter,opa_value_type
+builtin_object_filter,opa_object
+builtin_object_filter,opa_value_iter
+builtin_object_filter,opa_value_get
+builtin_object_filter,opa_object_get
+builtin_object_filter,opa_object_insert
+builtin_object_get,opa_value_type
+builtin_object_get,opa_object_get
+builtin_object_remove,opa_value_type
+builtin_object_remove,opa_set
+builtin_object_remove,opa_value_iter
+builtin_object_remove,opa_value_get
+builtin_object_remove,opa_set_add
+builtin_object_remove,opa_object
+builtin_object_remove,opa_set_get
+builtin_object_remove,opa_object_get
+builtin_object_remove,opa_object_insert
+builtin_object_union,opa_value_type
+builtin_object_union,__merge
+__merge,opa_object
+__merge,opa_value_iter
+__merge,opa_object_get
+__merge,opa_value_type
+__merge,__merge
+__merge,opa_object_insert
+__merge,opa_value_get
+builtin_json_remove,opa_value_type
+builtin_json_remove,__get_json_paths
+builtin_json_remove,__paths_to_object
+builtin_json_remove,__json_remove
+builtin_json_filter,opa_value_type
+builtin_json_filter,__get_json_paths
+builtin_json_filter,__paths_to_object
+builtin_json_filter,__json_filter
+opa_set_diff,opa_value_type
+opa_set_diff,opa_set
+opa_set_diff,opa_set_get
+opa_set_diff,opa_set_add
+opa_set_intersection,opa_value_type
+opa_set_intersection,opa_set_with_cap
+opa_set_intersection,opa_set_get
+opa_set_intersection,opa_set_add
+opa_sets_intersection,opa_value_type
+opa_sets_intersection,opa_set
+opa_sets_intersection,opa_set_union
+opa_sets_intersection,opa_set_intersection
+opa_sets_intersection,opa_value_free
+opa_set_union,opa_value_type
+opa_set_union,opa_set
+opa_set_union,opa_set_add
+opa_sets_union,opa_value_type
+opa_sets_union,opa_set
+opa_sets_union,opa_set_union
+opa_sets_union,opa_value_free
+opa_strings_concat,opa_value_type
+opa_strings_concat,opa_malloc
+opa_strings_concat,memcpy
+opa_strings_concat,opa_string_allocated
+opa_strings_contains,opa_value_type
+opa_strings_contains,opa_strncmp
+opa_strings_contains,opa_boolean
+opa_strings_endswith,opa_value_type
+opa_strings_endswith,opa_boolean
+opa_strings_format_int,opa_value_type
+opa_strings_format_int,opa_number_try_int
+opa_strings_format_int,opa_number_to_bf
+opa_strings_format_int,mpd_qnew
+opa_strings_format_int,mpd_max_ctx
+opa_strings_format_int,mpd_qtrunc
+opa_strings_format_int,opa_abort
+opa_strings_format_int,mpd_qget_i32
+opa_strings_format_int,opa_malloc
+opa_strings_format_int,snprintf_
+opa_strings_format_int,opa_strlen
+opa_strings_format_int,opa_string_allocated
+opa_strings_indexof,opa_value_type
+opa_strings_indexof,opa_strncmp
+opa_strings_indexof,opa_number_int
+opa_strings_indexof,opa_unicode_decode_utf8
+opa_strings_indexof,opa_abort
+opa_strings_replace,opa_value_type
+opa_strings_replace,opa_malloc
+opa_strings_replace,opa_strncmp
+opa_strings_replace,opa_realloc
+opa_strings_replace,memcpy
+opa_strings_replace,opa_string_allocated
+opa_strings_replace_n,opa_value_type
+opa_strings_replace_n,opa_malloc
+opa_strings_replace_n,memcpy
+opa_strings_replace_n,opa_string_allocated
+opa_strings_replace_n,opa_strings_replace
+opa_strings_replace_n,opa_value_free
+opa_strings_split,opa_value_type
+opa_strings_split,opa_array
+opa_strings_split,opa_strncmp
+opa_strings_split,opa_malloc
+opa_strings_split,memcpy
+opa_strings_split,opa_string_allocated
+opa_strings_split,opa_array_append
+opa_strings_split,opa_unicode_decode_utf8
+opa_strings_split,opa_abort
+opa_strings_startswith,opa_value_type
+opa_strings_startswith,opa_boolean
+opa_strings_startswith,opa_strncmp
+opa_strings_substring,opa_value_type
+opa_strings_substring,opa_number_try_int
+opa_strings_substring,opa_string_terminated
+opa_strings_substring,opa_unicode_decode_utf8
+opa_strings_substring,opa_abort
+opa_strings_substring,opa_malloc
+opa_strings_substring,memcpy
+opa_strings_substring,opa_string_allocated
+opa_strings_trim,opa_value_type
+opa_strings_trim,opa_strings_trim_left
+opa_strings_trim,opa_strings_trim_right
+opa_strings_trim,opa_value_free
+opa_strings_trim_left,opa_value_type
+opa_strings_trim_left,opa_unicode_decode_utf8
+opa_strings_trim_left,opa_abort
+opa_strings_trim_left,opa_strncmp
+opa_strings_trim_left,opa_malloc
+opa_strings_trim_left,memcpy
+opa_strings_trim_left,opa_string_allocated
+opa_strings_trim_right,opa_value_type
+opa_strings_trim_right,opa_unicode_last_utf8
+opa_strings_trim_right,opa_abort
+opa_strings_trim_right,opa_unicode_decode_utf8
+opa_strings_trim_right,opa_strncmp
+opa_strings_trim_right,opa_malloc
+opa_strings_trim_right,memcpy
+opa_strings_trim_right,opa_string_allocated
+opa_strings_trim_prefix,opa_value_type
+opa_strings_trim_prefix,opa_strncmp
+opa_strings_trim_prefix,opa_malloc
+opa_strings_trim_prefix,memcpy
+opa_strings_trim_prefix,opa_string_allocated
+opa_strings_trim_suffix,opa_value_type
+opa_strings_trim_suffix,opa_strncmp
+opa_strings_trim_suffix,opa_malloc
+opa_strings_trim_suffix,memcpy
+opa_strings_trim_suffix,opa_string_allocated
+opa_strings_trim_space,opa_value_type
+opa_strings_trim_space,trim_space
+opa_strings_trim_space,opa_malloc
+opa_strings_trim_space,memcpy
+opa_strings_trim_space,opa_string_allocated
+trim_space,opa_unicode_decode_utf8
+trim_space,opa_abort
+trim_space,opa_unicode_is_space
+trim_space,opa_unicode_last_utf8
+trim_space,opa_malloc
+trim_space,memcpy
+trim_space,opa_string_allocated
+opa_strings_lower,opa_value_type
+opa_strings_lower,opa_malloc
+opa_strings_lower,opa_string_allocated
+opa_strings_lower,malloc
+opa_strings_lower,opa_unicode_decode_utf8
+opa_strings_lower,opa_abort
+opa_strings_lower,opa_unicode_to_lower
+opa_strings_lower,opa_realloc
+opa_strings_lower,opa_unicode_encode_utf8
+opa_strings_upper,opa_value_type
+opa_strings_upper,opa_malloc
+opa_strings_upper,opa_string_allocated
+opa_strings_upper,malloc
+opa_strings_upper,opa_unicode_decode_utf8
+opa_strings_upper,opa_abort
+opa_strings_upper,opa_unicode_to_upper
+opa_strings_upper,opa_realloc
+opa_strings_upper,opa_unicode_encode_utf8
+opa_types_is_number,opa_value_type
+opa_types_is_number,opa_boolean
+opa_types_is_string,opa_value_type
+opa_types_is_string,opa_boolean
+opa_types_is_boolean,opa_value_type
+opa_types_is_boolean,opa_boolean
+opa_types_is_array,opa_value_type
+opa_types_is_array,opa_boolean
+opa_types_is_set,opa_value_type
+opa_types_is_set,opa_boolean
+opa_types_is_object,opa_value_type
+opa_types_is_object,opa_boolean
+opa_types_is_null,opa_value_type
+opa_types_is_null,opa_boolean
+opa_types_name,opa_value_type
+opa_types_name,opa_string
+opa_value_hash,opa_value_hash
+opa_value_hash,opa_number_hash
+opa_value_compare,opa_value_compare_number
+opa_value_compare,opa_strncmp
+opa_value_compare,opa_value_compare
+opa_value_compare,opa_value_compare_object
+opa_value_compare,opa_value_compare_set
+opa_value_compare,opa_abort
+opa_object_get,opa_value_hash
+opa_object_get,opa_value_compare
+opa_set_get,opa_value_hash
+opa_set_get,opa_value_compare
+opa_number_try_int,opa_atoi64
+opa_number_try_int,opa_abort
+opa_value_get,opa_atoi64
+opa_value_get,opa_abort
+opa_value_get,opa_value_hash
+opa_value_get,opa_value_compare
+opa_value_compare_number,opa_atoi64
+opa_value_compare_number,opa_abort
+opa_value_compare_number,opa_number_to_bf
+opa_value_compare_number,mpd_qcmp
+opa_value_compare_number,mpd_del
+opa_value_compare_object,opa_object_keys
+opa_value_compare_object,opa_value_compare
+opa_value_compare_object,opa_value_hash
+opa_value_compare_object,opa_free
+opa_value_compare_set,opa_malloc
+opa_value_compare_set,opa_free
+opa_value_compare_set,opa_array_append
+opa_value_compare_set,opa_value_compare
+opa_number_hash,opa_atof64
+opa_number_hash,opa_abort
+opa_value_iter,opa_abort
+opa_value_iter,opa_atoi64
+opa_value_iter,opa_value_hash
+opa_value_iter,opa_value_compare
+opa_object_keys,opa_malloc
+opa_object_keys,opa_free
+opa_object_keys,opa_array_append
+opa_object_keys,opa_value_compare
+opa_array_append,opa_malloc
+opa_array_append,opa_free
+opa_value_free,opa_free
+opa_value_merge,opa_malloc
+opa_value_merge,opa_value_get
+opa_value_merge,opa_object_insert
+opa_value_merge,opa_value_merge
+opa_object_insert,opa_value_hash
+opa_object_insert,opa_value_compare
+opa_object_insert,__opa_object_grow
+opa_object_insert,opa_malloc
+__opa_object_grow,opa_malloc
+__opa_object_grow,opa_value_hash
+__opa_object_grow,opa_value_compare
+__opa_object_grow,opa_free
+opa_boolean,opa_malloc
+opa_number_ref,opa_malloc
+opa_number_int,opa_malloc
+opa_string,opa_malloc
+opa_value_shallow_copy_object,opa_malloc
+opa_value_shallow_copy_object,opa_value_iter
+opa_value_shallow_copy_object,opa_value_get
+opa_value_shallow_copy_object,opa_object_insert
+opa_value_shallow_copy_set,opa_malloc
+opa_value_shallow_copy_set,opa_value_iter
+opa_value_shallow_copy_set,opa_set_add
+opa_set_add,opa_value_hash
+opa_set_add,opa_value_compare
+opa_set_add,__opa_set_grow
+opa_set_add,opa_malloc
+__opa_set_grow,opa_malloc
+__opa_set_grow,opa_value_hash
+__opa_set_grow,opa_value_compare
+__opa_set_grow,opa_free
+opa_value_shallow_copy,opa_malloc
+opa_value_shallow_copy,opa_value_shallow_copy_object
+opa_value_shallow_copy,opa_value_shallow_copy_set
+opa_value_shallow_copy,opa_abort
+opa_value_transitive_closure,opa_malloc
+opa_value_transitive_closure,__opa_value_transitive_closure
+__opa_value_transitive_closure,opa_malloc
+__opa_value_transitive_closure,opa_free
+__opa_value_transitive_closure,opa_array_append
+__opa_value_transitive_closure,opa_value_iter
+__opa_value_transitive_closure,opa_value_get
+__opa_value_transitive_closure,__opa_value_transitive_closure
+opa_null,opa_malloc
+opa_number_size,opa_malloc
+opa_number_ref_allocated,opa_malloc
+opa_string_terminated,opa_malloc
+opa_string_terminated,opa_strlen
+opa_string_allocated,opa_malloc
+opa_array,opa_malloc
+opa_array_with_cap,opa_malloc
+opa_array_with_cap,opa_free
+opa_object,opa_malloc
+opa_set,opa_malloc
+opa_set_with_cap,opa_malloc
+opa_value_add_path,opa_value_get
+opa_value_add_path,opa_malloc
+opa_value_add_path,opa_object_insert
+opa_value_add_path,opa_value_free
+opa_value_remove_path,opa_value_get
+opa_value_remove_path,opa_value_hash
+opa_value_remove_path,opa_value_compare
+opa_value_remove_path,opa_value_free
+opa_value_remove_path,opa_free
+opa_lookup,opa_value_get
+opa_lookup,opa_value_iter
+opa_lookup,opa_atoi64
+opa_lookup,opa_abort
+opa_mapping_init,opa_json_parse
+opa_mapping_lookup,opa_lookup
+node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,std::__1::basic_string\2c\20std::__1::allocator\20>::assign\28char\20const*\29
+node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29
+node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\2c\20unsigned\20long\29
+node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,operator\20delete\28void*\29
+node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\29
+node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,escape\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29
+node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,operator\20new\28unsigned\20long\29
+node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,memcpy
+node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,std::__1::__basic_string_common::__throw_length_error\28\29\20const
+escape\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,std::__1::basic_string\2c\20std::__1::allocator\20>::push_back\28char\29
+glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,operator\20new\28unsigned\20long\29
+glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,lexer::lexer\28char\20const*\2c\20unsigned\20long\29
+glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,glob_parse\28lexer*\2c\20node**\29
+glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::compare\28unsigned\20long\2c\20unsigned\20long\2c\20char\20const*\2c\20unsigned\20long\29\20const
+glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,lexer::~lexer\28\29
+glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,operator\20delete\28void*\29
+glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::assign\28char\20const*\29
+glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,opa_unicode_decode_utf8
+glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,escape\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29
+glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\2c\20unsigned\20long\29
+glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\29
+glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29
+glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,node::~node\28\29
+lexer::~lexer\28\29,operator\20delete\28void*\29
+lexer::next\28token*\29,strlen
+lexer::next\28token*\29,operator\20new\28unsigned\20long\29
+lexer::next\28token*\29,memcpy
+lexer::next\28token*\29,operator\20delete\28void*\29
+lexer::next\28token*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::operator=\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29
+lexer::next\28token*\29,lexer::fetch_item\28\29
+lexer::next\28token*\29,lexer::next\28token*\29
+lexer::next\28token*\29,std::__1::__basic_string_common::__throw_length_error\28\29\20const
+lexer::fetch_item\28\29,opa_unicode_decode_utf8
+lexer::fetch_item\28\29,operator\20new\28unsigned\20long\29
+lexer::fetch_item\28\29,memcpy
+lexer::fetch_item\28\29,operator\20delete\28void*\29
+lexer::fetch_item\28\29,lexer::fetch_range\28\29
+lexer::fetch_item\28\29,lexer::fetch_text\28int\20const*\29
+lexer::fetch_item\28\29,std::__1::__basic_string_common::__throw_length_error\28\29\20const
+lexer::fetch_item\28\29,std::__1::__vector_base_common::__throw_length_error\28\29\20const
+lexer::fetch_item\28\29,abort
+lexer::fetch_range\28\29,opa_unicode_decode_utf8
+lexer::fetch_range\28\29,operator\20new\28unsigned\20long\29
+lexer::fetch_range\28\29,memcpy
+lexer::fetch_range\28\29,operator\20delete\28void*\29
+lexer::fetch_range\28\29,lexer::fetch_text\28int\20const*\29
+lexer::fetch_range\28\29,std::__1::__basic_string_common::__throw_length_error\28\29\20const
+lexer::fetch_range\28\29,std::__1::__vector_base_common::__throw_length_error\28\29\20const
+lexer::fetch_range\28\29,abort
+lexer::fetch_text\28int\20const*\29,opa_unicode_decode_utf8
+lexer::fetch_text\28int\20const*\29,operator\20new\28unsigned\20long\29
+lexer::fetch_text\28int\20const*\29,memcpy
+lexer::fetch_text\28int\20const*\29,operator\20delete\28void*\29
+lexer::fetch_text\28int\20const*\29,std::__1::__vector_base_common::__throw_length_error\28\29\20const
+lexer::fetch_text\28int\20const*\29,opa_malloc
+lexer::fetch_text\28int\20const*\29,opa_free
+lexer::fetch_text\28int\20const*\29,abort
+lexer::fetch_text\28int\20const*\29,std::__1::__basic_string_common::__throw_length_error\28\29\20const
+node::~node\28\29,node::~node\28\29
+node::~node\28\29,operator\20delete\28void*\29
+node::insert\28node*\29,operator\20new\28unsigned\20long\29
+node::insert\28node*\29,memcpy
+node::insert\28node*\29,operator\20delete\28void*\29
+node::insert\28node*\29,std::__1::__vector_base_common::__throw_length_error\28\29\20const
+node::insert\28node*\29,abort
+glob_parse\28lexer*\2c\20node**\29,operator\20new\28unsigned\20long\29
+glob_parse\28lexer*\2c\20node**\29,std::__1::basic_string\2c\20std::__1::allocator\20>::compare\28unsigned\20long\2c\20unsigned\20long\2c\20char\20const*\2c\20unsigned\20long\29\20const
+glob_parse\28lexer*\2c\20node**\29,node::~node\28\29
+glob_parse\28lexer*\2c\20node**\29,operator\20delete\28void*\29
+glob_parse\28lexer*\2c\20node**\29,std::__1::basic_string\2c\20std::__1::allocator\20>::basic_string\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29
+parser_main\28state*\2c\20lexer*\29,lexer::next\28token*\29
+parser_main\28state*\2c\20lexer*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::operator=\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29
+parser_main\28state*\2c\20lexer*\29,operator\20new\28unsigned\20long\29
+parser_main\28state*\2c\20lexer*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::basic_string\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29
+parser_main\28state*\2c\20lexer*\29,node::insert\28node*\29
+parser_main\28state*\2c\20lexer*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::assign\28char\20const*\29
+parser_main\28state*\2c\20lexer*\29,operator\20delete\28void*\29
+parser_range\28state*\2c\20lexer*\29,lexer::next\28token*\29
+parser_range\28state*\2c\20lexer*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::assign\28char\20const*\29
+parser_range\28state*\2c\20lexer*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::operator=\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29
+parser_range\28state*\2c\20lexer*\29,opa_unicode_decode_utf8
+parser_range\28state*\2c\20lexer*\29,memcmp
+parser_range\28state*\2c\20lexer*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::compare\28unsigned\20long\2c\20unsigned\20long\2c\20char\20const*\2c\20unsigned\20long\29\20const
+parser_range\28state*\2c\20lexer*\29,operator\20new\28unsigned\20long\29
+parser_range\28state*\2c\20lexer*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::basic_string\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29
+parser_range\28state*\2c\20lexer*\29,node::insert\28node*\29
+parser_range\28state*\2c\20lexer*\29,operator\20delete\28void*\29
+opa_glob_match,opa_value_type
+opa_glob_match,opa_value_iter
+opa_glob_match,opa_value_get
+opa_glob_match,operator\20new\28unsigned\20long\29
+opa_glob_match,memcpy
+opa_glob_match,void\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>::__push_back_slow_path\2c\20std::__1::allocator\20>\20>\28std::__1::basic_string\2c\20std::__1::allocator\20>&&\29
+opa_glob_match,operator\20delete\28void*\29
+opa_glob_match,opa_builtin_cache_get
+opa_glob_match,opa_builtin_cache_set
+opa_glob_match,std::__1::basic_string\2c\20std::__1::allocator\20>::basic_string\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29
+opa_glob_match,std::__1::__hash_iterator\2c\20std::__1::allocator\20>\20>\2c\20void*>*>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::find\28cache_key\20const&\29
+opa_glob_match,std::__1::basic_string\2c\20std::__1::allocator\20>::operator=\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29
+opa_glob_match,glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29
+opa_glob_match,std::__1::pair\2c\20std::__1::allocator\20>\20>::pair\2c\20std::__1::allocator