diff --git a/go.mod b/go.mod index f9f0384aeb..9698c8289e 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( github.com/linuxkit/virtsock v0.0.0-20241009230534-cb6a20cc0422 github.com/mattn/go-shellwords v1.0.13 github.com/moby/sys/user v0.4.0 - github.com/open-policy-agent/opa v0.70.0 + github.com/open-policy-agent/opa v1.4.0 github.com/opencontainers/cgroups v0.0.6 github.com/opencontainers/runc v1.4.2 github.com/opencontainers/runtime-spec v1.3.0 @@ -67,8 +67,7 @@ require ( require ( cyphar.com/go-pathrs v0.2.4 // indirect - github.com/OneOfOne/xxhash v1.2.8 // indirect - github.com/agnivade/levenshtein v1.2.0 // indirect + github.com/agnivade/levenshtein v1.2.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/checkpoint-restore/go-criu/v7 v7.2.0 // indirect diff --git a/go.sum b/go.sum index 202a63fd86..b593058454 100644 --- a/go.sum +++ b/go.sum @@ -369,10 +369,8 @@ github.com/Microsoft/didx509go v0.0.3/go.mod h1:wWt+iQsLzn3011+VfESzznLIp/Owhuj7 github.com/Microsoft/go-winio v0.6.3-0.20251027160822-ad3df93bed29 h1:0kQAzHq8vLs7Pptv+7TxjdETLf/nIqJpIB4oC6Ba4vY= github.com/Microsoft/go-winio v0.6.3-0.20251027160822-ad3df93bed29/go.mod h1:ZWa7ssZJT30CCDGJ7fk/2SBTq9BIQrrVjrcss0UW2s0= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= -github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/agnivade/levenshtein v1.2.0 h1:U9L4IOT0Y3i0TIlUIDJ7rVUziKi/zPbrJGaFrtYH3SY= -github.com/agnivade/levenshtein v1.2.0/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU= +github.com/agnivade/levenshtein v1.2.1 h1:EHBY3UOn1gwdy/VbFwgo4cxecRznFk7fKWN1KOX7eoM= +github.com/agnivade/levenshtein v1.2.1/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= @@ -402,7 +400,6 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -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/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -485,10 +482,10 @@ 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/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= -github.com/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg= -github.com/dgraph-io/badger/v3 v3.2103.5/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= -github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= -github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +github.com/dgraph-io/badger/v4 v4.7.0 h1:Q+J8HApYAY7UMpL8d9owqiB+odzEc0zn/aqOD9jhc6Y= +github.com/dgraph-io/badger/v4 v4.7.0/go.mod h1:He7TzG3YBy3j4f5baj5B7Zl2XyfNe5bl4Udl0aPemVA= +github.com/dgraph-io/ristretto/v2 v2.2.0 h1:bkY3XzJcXoMuELV8F+vS8kzNgicwQFAaGINAEJdWGOM= +github.com/dgraph-io/ristretto/v2 v2.2.0/go.mod h1:RZrm63UmcBAaYWC1DotLYBmTvgkrs0+XhBd7Npn7/zI= github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54 h1:SG7nF6SRlWhcT7cNTs5R6Hk4V2lcmLz2NsG2VnInyNo= github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/docker/cli v29.4.3+incompatible h1:u+UliYm2J/rYrIh2FqHQg32neRG8GjbvNuwQRTzGspU= @@ -585,7 +582,6 @@ github.com/goccy/go-yaml v1.9.8/go.mod h1:JubOolP3gh0HpiBc4BLRD4YmjEjHAmIIB2aaXK github.com/goccy/go-yaml v1.11.0/go.mod h1:H+mJrWtjPTJAHvRbV09MCK9xYwODM+wRTVFFTWckfng= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -597,8 +593,6 @@ github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwm github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/glog v1.2.3/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= -github.com/golang/glog v1.2.5 h1:DrW6hGnjIhtvhOIiAKT6Psh/Kd/ldepEa81DKeiRJ5I= -github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -636,14 +630,14 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/flatbuffers v23.5.26+incompatible h1:M9dgRyhJemaM4Sw8+66GHBu8ioaQmyPLg1b8VwK5WJg= github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q= +github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= 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= @@ -848,8 +842,8 @@ github.com/mrunalp/fileutils v0.5.1 h1:F+S7ZlNKnrwHfSwdlgNSkKo67ReVf8o9fel6C3dkm github.com/mrunalp/fileutils v0.5.1/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/open-policy-agent/opa v0.70.0 h1:B3cqCN2iQAyKxK6+GI+N40uqkin+wzIrM7YA60t9x1U= -github.com/open-policy-agent/opa v0.70.0/go.mod h1:Y/nm5NY0BX0BqjBriKUiV81sCl8XOjjvqQG7dXrggtI= +github.com/open-policy-agent/opa v1.4.0 h1:IGO3xt5HhQKQq2axfa9memIFx5lCyaBlG+fXcgHpd3A= +github.com/open-policy-agent/opa v1.4.0/go.mod h1:DNzZPKqKh4U0n0ANxcCVlw8lCSv2c+h5G/3QvSYdWZ8= github.com/opencontainers/cgroups v0.0.6 h1:tfZFWTIIGaUUFImTyuTg+Mr5x8XRiSdZESgEBW7UxuI= github.com/opencontainers/cgroups v0.0.6/go.mod h1:oWVzJsKK0gG9SCRBfTpnn16WcGEqDI8PAcpMGbqWxcs= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -1039,6 +1033,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0f go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= diff --git a/internal/regopolicyinterpreter/regopolicyinterpreter.go b/internal/regopolicyinterpreter/regopolicyinterpreter.go index 4872c298eb..c15d382498 100644 --- a/internal/regopolicyinterpreter/regopolicyinterpreter.go +++ b/internal/regopolicyinterpreter/regopolicyinterpreter.go @@ -10,10 +10,10 @@ import ( "os" "sync" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/rego" - "github.com/open-policy-agent/opa/storage/inmem" - "github.com/open-policy-agent/opa/topdown" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/rego" + "github.com/open-policy-agent/opa/v1/storage/inmem" + "github.com/open-policy-agent/opa/v1/topdown" "github.com/pkg/errors" ) @@ -439,6 +439,9 @@ func (r *RegoPolicyInterpreter) compile() error { options := ast.CompileOpts{ EnablePrintStatements: r.logLevel != LogNone, + ParserOptions: ast.ParserOptions{ + RegoVersion: ast.RegoV0, + }, } if compiled, err := ast.CompileModulesWithOpt(modules, options); err == nil { @@ -614,6 +617,7 @@ func (r *RegoPolicyInterpreter) query(rule string, input map[string]interface{}) rego.Query(rule), rego.Input(input), rego.Store(store), + rego.SetRegoVersion(ast.RegoV0), rego.EnablePrintStatements(r.logLevel != LogNone), rego.PrintHook(topdown.NewPrintHook(&buf)), rego.Compiler(r.compiledModules)) diff --git a/pkg/securitypolicy/rego_utils_test.go b/pkg/securitypolicy/rego_utils_test.go index 6afe7de6cc..f05cf16465 100644 --- a/pkg/securitypolicy/rego_utils_test.go +++ b/pkg/securitypolicy/rego_utils_test.go @@ -25,7 +25,8 @@ import ( "github.com/Microsoft/hcsshim/internal/protocol/guestrequest" rpi "github.com/Microsoft/hcsshim/internal/regopolicyinterpreter" "github.com/blang/semver/v4" - "github.com/open-policy-agent/opa/rego" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/rego" oci "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" ) @@ -95,6 +96,7 @@ func init() { func Test_RegoTemplates(t *testing.T) { query := rego.New( rego.Query("data.api"), + rego.SetRegoVersion(ast.RegoV0), rego.Module("api.rego", APICode)) ctx := context.Background() @@ -124,6 +126,7 @@ func Test_RegoTemplates(t *testing.T) { func verifyPolicyRules(apiVersion string, enforcementPoints map[string]interface{}, policyCode string) error { query := rego.New( rego.Query("data.policy"), + rego.SetRegoVersion(ast.RegoV0), rego.Module("policy.rego", policyCode), rego.Module("framework.rego", FrameworkCode), ) diff --git a/test/go.mod b/test/go.mod index 922f1cedd3..cf9fb17557 100644 --- a/test/go.mod +++ b/test/go.mod @@ -33,8 +33,7 @@ require ( cyphar.com/go-pathrs v0.2.4 // indirect github.com/Microsoft/cosesign1go v1.6.0 // indirect github.com/Microsoft/didx509go v0.0.3 // indirect - github.com/OneOfOne/xxhash v1.2.8 // indirect - github.com/agnivade/levenshtein v1.2.0 // indirect + github.com/agnivade/levenshtein v1.2.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -84,7 +83,7 @@ require ( github.com/moby/sys/userns v0.1.0 // indirect github.com/mrunalp/fileutils v0.5.1 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/open-policy-agent/opa v0.70.0 // indirect + github.com/open-policy-agent/opa v1.4.0 // indirect github.com/opencontainers/cgroups v0.0.6 // indirect github.com/opencontainers/runc v1.4.2 // indirect github.com/opencontainers/selinux v1.13.1 // indirect diff --git a/test/go.sum b/test/go.sum index eb043d9407..4c2417a7ff 100644 --- a/test/go.sum +++ b/test/go.sum @@ -10,10 +10,8 @@ github.com/Microsoft/didx509go v0.0.3 h1:n/owuFOXVzCEzSyzivMEolKEouBm9G0NrEDgoTe github.com/Microsoft/didx509go v0.0.3/go.mod h1:wWt+iQsLzn3011+VfESzznLIp/Owhuj7rLF7yLglYbk= github.com/Microsoft/go-winio v0.6.3-0.20251027160822-ad3df93bed29 h1:0kQAzHq8vLs7Pptv+7TxjdETLf/nIqJpIB4oC6Ba4vY= github.com/Microsoft/go-winio v0.6.3-0.20251027160822-ad3df93bed29/go.mod h1:ZWa7ssZJT30CCDGJ7fk/2SBTq9BIQrrVjrcss0UW2s0= -github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= -github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/agnivade/levenshtein v1.2.0 h1:U9L4IOT0Y3i0TIlUIDJ7rVUziKi/zPbrJGaFrtYH3SY= -github.com/agnivade/levenshtein v1.2.0/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU= +github.com/agnivade/levenshtein v1.2.1 h1:EHBY3UOn1gwdy/VbFwgo4cxecRznFk7fKWN1KOX7eoM= +github.com/agnivade/levenshtein v1.2.1/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -25,8 +23,6 @@ github.com/bytecodealliance/wasmtime-go/v3 v3.0.2/go.mod h1:RnUjnIXxEJcL6BgCvNyz github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/checkpoint-restore/go-criu/v7 v7.2.0 h1:qGiWA4App1gGlEfIJ68WR9jbezV9J7yZdjzglezcqKo= @@ -74,10 +70,10 @@ 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/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= -github.com/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg= -github.com/dgraph-io/badger/v3 v3.2103.5/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= -github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= -github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +github.com/dgraph-io/badger/v4 v4.7.0 h1:Q+J8HApYAY7UMpL8d9owqiB+odzEc0zn/aqOD9jhc6Y= +github.com/dgraph-io/badger/v4 v4.7.0/go.mod h1:He7TzG3YBy3j4f5baj5B7Zl2XyfNe5bl4Udl0aPemVA= +github.com/dgraph-io/ristretto/v2 v2.2.0 h1:bkY3XzJcXoMuELV8F+vS8kzNgicwQFAaGINAEJdWGOM= +github.com/dgraph-io/ristretto/v2 v2.2.0/go.mod h1:RZrm63UmcBAaYWC1DotLYBmTvgkrs0+XhBd7Npn7/zI= github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54 h1:SG7nF6SRlWhcT7cNTs5R6Hk4V2lcmLz2NsG2VnInyNo= github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= @@ -88,8 +84,8 @@ github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqI github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= 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= @@ -117,11 +113,7 @@ github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -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/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.5 h1:DrW6hGnjIhtvhOIiAKT6Psh/Kd/ldepEa81DKeiRJ5I= -github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= @@ -137,10 +129,8 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= -github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q= +github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= 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= @@ -213,8 +203,8 @@ github.com/mrunalp/fileutils v0.5.1 h1:F+S7ZlNKnrwHfSwdlgNSkKo67ReVf8o9fel6C3dkm github.com/mrunalp/fileutils v0.5.1/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/open-policy-agent/opa v0.70.0 h1:B3cqCN2iQAyKxK6+GI+N40uqkin+wzIrM7YA60t9x1U= -github.com/open-policy-agent/opa v0.70.0/go.mod h1:Y/nm5NY0BX0BqjBriKUiV81sCl8XOjjvqQG7dXrggtI= +github.com/open-policy-agent/opa v1.4.0 h1:IGO3xt5HhQKQq2axfa9memIFx5lCyaBlG+fXcgHpd3A= +github.com/open-policy-agent/opa v1.4.0/go.mod h1:DNzZPKqKh4U0n0ANxcCVlw8lCSv2c+h5G/3QvSYdWZ8= github.com/opencontainers/cgroups v0.0.6 h1:tfZFWTIIGaUUFImTyuTg+Mr5x8XRiSdZESgEBW7UxuI= github.com/opencontainers/cgroups v0.0.6/go.mod h1:oWVzJsKK0gG9SCRBfTpnn16WcGEqDI8PAcpMGbqWxcs= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -299,6 +289,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0f go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk= go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= diff --git a/vendor/github.com/OneOfOne/xxhash/.gitignore b/vendor/github.com/OneOfOne/xxhash/.gitignore deleted file mode 100644 index f4faa7f8f1..0000000000 --- a/vendor/github.com/OneOfOne/xxhash/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.txt -*.pprof -cmap2/ -cache/ diff --git a/vendor/github.com/OneOfOne/xxhash/.travis.yml b/vendor/github.com/OneOfOne/xxhash/.travis.yml deleted file mode 100644 index 1c6dc55bc7..0000000000 --- a/vendor/github.com/OneOfOne/xxhash/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: go -sudo: false - -go: - - "1.10" - - "1.11" - - "1.12" - - master - -script: - - go test -tags safe ./... - - go test ./... - - diff --git a/vendor/github.com/OneOfOne/xxhash/LICENSE b/vendor/github.com/OneOfOne/xxhash/LICENSE deleted file mode 100644 index 9e30b4f342..0000000000 --- a/vendor/github.com/OneOfOne/xxhash/LICENSE +++ /dev/null @@ -1,187 +0,0 @@ - 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. diff --git a/vendor/github.com/OneOfOne/xxhash/README.md b/vendor/github.com/OneOfOne/xxhash/README.md deleted file mode 100644 index 8eea28c394..0000000000 --- a/vendor/github.com/OneOfOne/xxhash/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# xxhash [![GoDoc](https://godoc.org/github.com/OneOfOne/xxhash?status.svg)](https://godoc.org/github.com/OneOfOne/xxhash) [![Build Status](https://travis-ci.org/OneOfOne/xxhash.svg?branch=master)](https://travis-ci.org/OneOfOne/xxhash) [![Coverage](https://gocover.io/_badge/github.com/OneOfOne/xxhash)](https://gocover.io/github.com/OneOfOne/xxhash) - -This is a native Go implementation of the excellent [xxhash](https://github.com/Cyan4973/xxHash)* algorithm, an extremely fast non-cryptographic Hash algorithm, working at speeds close to RAM limits. - -* The C implementation is ([Copyright](https://github.com/Cyan4973/xxHash/blob/master/LICENSE) (c) 2012-2014, Yann Collet) - -## Install - - go get github.com/OneOfOne/xxhash - -## Features - -* On Go 1.7+ the pure go version is faster than CGO for all inputs. -* Supports ChecksumString{32,64} xxhash{32,64}.WriteString, which uses no copies when it can, falls back to copy on appengine. -* The native version falls back to a less optimized version on appengine due to the lack of unsafe. -* Almost as fast as the mostly pure assembly version written by the brilliant [cespare](https://github.com/cespare/xxhash), while also supporting seeds. -* To manually toggle the appengine version build with `-tags safe`. - -## Benchmark - -### Core i7-4790 @ 3.60GHz, Linux 4.12.6-1-ARCH (64bit), Go tip (+ff90f4af66 2017-08-19) - -```bash -➤ go test -bench '64' -count 5 -tags cespare | benchstat /dev/stdin -name time/op - -# https://github.com/cespare/xxhash -XXSum64Cespare/Func-8 160ns ± 2% -XXSum64Cespare/Struct-8 173ns ± 1% -XXSum64ShortCespare/Func-8 6.78ns ± 1% -XXSum64ShortCespare/Struct-8 19.6ns ± 2% - -# this package (default mode, using unsafe) -XXSum64/Func-8 170ns ± 1% -XXSum64/Struct-8 182ns ± 1% -XXSum64Short/Func-8 13.5ns ± 3% -XXSum64Short/Struct-8 20.4ns ± 0% - -# this package (appengine, *not* using unsafe) -XXSum64/Func-8 241ns ± 5% -XXSum64/Struct-8 243ns ± 6% -XXSum64Short/Func-8 15.2ns ± 2% -XXSum64Short/Struct-8 23.7ns ± 5% - -CRC64ISO-8 1.23µs ± 1% -CRC64ISOString-8 2.71µs ± 4% -CRC64ISOShort-8 22.2ns ± 3% - -Fnv64-8 2.34µs ± 1% -Fnv64Short-8 74.7ns ± 8% -``` - -## Usage - -```go - h := xxhash.New64() - // r, err := os.Open("......") - // defer f.Close() - r := strings.NewReader(F) - io.Copy(h, r) - fmt.Println("xxhash.Backend:", xxhash.Backend) - fmt.Println("File checksum:", h.Sum64()) -``` - -[playground](https://play.golang.org/p/wHKBwfu6CPV) - -## TODO - -* Rewrite the 32bit version to be more optimized. -* General cleanup as the Go inliner gets smarter. - -## License - -This project is released under the Apache v2. license. See [LICENSE](LICENSE) for more details. diff --git a/vendor/github.com/OneOfOne/xxhash/xxhash.go b/vendor/github.com/OneOfOne/xxhash/xxhash.go deleted file mode 100644 index af2496b77f..0000000000 --- a/vendor/github.com/OneOfOne/xxhash/xxhash.go +++ /dev/null @@ -1,294 +0,0 @@ -package xxhash - -import ( - "encoding/binary" - "errors" - "hash" -) - -const ( - prime32x1 uint32 = 2654435761 - prime32x2 uint32 = 2246822519 - prime32x3 uint32 = 3266489917 - prime32x4 uint32 = 668265263 - prime32x5 uint32 = 374761393 - - prime64x1 uint64 = 11400714785074694791 - prime64x2 uint64 = 14029467366897019727 - prime64x3 uint64 = 1609587929392839161 - prime64x4 uint64 = 9650029242287828579 - prime64x5 uint64 = 2870177450012600261 - - maxInt32 int32 = (1<<31 - 1) - - // precomputed zero Vs for seed 0 - zero64x1 = 0x60ea27eeadc0b5d6 - zero64x2 = 0xc2b2ae3d27d4eb4f - zero64x3 = 0x0 - zero64x4 = 0x61c8864e7a143579 -) - -const ( - magic32 = "xxh\x07" - magic64 = "xxh\x08" - marshaled32Size = len(magic32) + 4*7 + 16 - marshaled64Size = len(magic64) + 8*6 + 32 + 1 -) - -func NewHash32() hash.Hash { return New32() } -func NewHash64() hash.Hash { return New64() } - -// Checksum32 returns the checksum of the input data with the seed set to 0. -func Checksum32(in []byte) uint32 { - return Checksum32S(in, 0) -} - -// ChecksumString32 returns the checksum of the input data, without creating a copy, with the seed set to 0. -func ChecksumString32(s string) uint32 { - return ChecksumString32S(s, 0) -} - -type XXHash32 struct { - mem [16]byte - ln, memIdx int32 - v1, v2, v3, v4 uint32 - seed uint32 -} - -// Size returns the number of bytes Sum will return. -func (xx *XXHash32) Size() int { - return 4 -} - -// BlockSize returns the hash's underlying block size. -// The Write method must be able to accept any amount -// of data, but it may operate more efficiently if all writes -// are a multiple of the block size. -func (xx *XXHash32) BlockSize() int { - return 16 -} - -// NewS32 creates a new hash.Hash32 computing the 32bit xxHash checksum starting with the specific seed. -func NewS32(seed uint32) (xx *XXHash32) { - xx = &XXHash32{ - seed: seed, - } - xx.Reset() - return -} - -// New32 creates a new hash.Hash32 computing the 32bit xxHash checksum starting with the seed set to 0. -func New32() *XXHash32 { - return NewS32(0) -} - -func (xx *XXHash32) Reset() { - xx.v1 = xx.seed + prime32x1 + prime32x2 - xx.v2 = xx.seed + prime32x2 - xx.v3 = xx.seed - xx.v4 = xx.seed - prime32x1 - xx.ln, xx.memIdx = 0, 0 -} - -// Sum appends the current hash to b and returns the resulting slice. -// It does not change the underlying hash state. -func (xx *XXHash32) Sum(in []byte) []byte { - s := xx.Sum32() - return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s)) -} - -// MarshalBinary implements the encoding.BinaryMarshaler interface. -func (xx *XXHash32) MarshalBinary() ([]byte, error) { - b := make([]byte, 0, marshaled32Size) - b = append(b, magic32...) - b = appendUint32(b, xx.v1) - b = appendUint32(b, xx.v2) - b = appendUint32(b, xx.v3) - b = appendUint32(b, xx.v4) - b = appendUint32(b, xx.seed) - b = appendInt32(b, xx.ln) - b = appendInt32(b, xx.memIdx) - b = append(b, xx.mem[:]...) - return b, nil -} - -// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. -func (xx *XXHash32) UnmarshalBinary(b []byte) error { - if len(b) < len(magic32) || string(b[:len(magic32)]) != magic32 { - return errors.New("xxhash: invalid hash state identifier") - } - if len(b) != marshaled32Size { - return errors.New("xxhash: invalid hash state size") - } - b = b[len(magic32):] - b, xx.v1 = consumeUint32(b) - b, xx.v2 = consumeUint32(b) - b, xx.v3 = consumeUint32(b) - b, xx.v4 = consumeUint32(b) - b, xx.seed = consumeUint32(b) - b, xx.ln = consumeInt32(b) - b, xx.memIdx = consumeInt32(b) - copy(xx.mem[:], b) - return nil -} - -// Checksum64 an alias for Checksum64S(in, 0) -func Checksum64(in []byte) uint64 { - return Checksum64S(in, 0) -} - -// ChecksumString64 returns the checksum of the input data, without creating a copy, with the seed set to 0. -func ChecksumString64(s string) uint64 { - return ChecksumString64S(s, 0) -} - -type XXHash64 struct { - v1, v2, v3, v4 uint64 - seed uint64 - ln uint64 - mem [32]byte - memIdx int8 -} - -// Size returns the number of bytes Sum will return. -func (xx *XXHash64) Size() int { - return 8 -} - -// BlockSize returns the hash's underlying block size. -// The Write method must be able to accept any amount -// of data, but it may operate more efficiently if all writes -// are a multiple of the block size. -func (xx *XXHash64) BlockSize() int { - return 32 -} - -// NewS64 creates a new hash.Hash64 computing the 64bit xxHash checksum starting with the specific seed. -func NewS64(seed uint64) (xx *XXHash64) { - xx = &XXHash64{ - seed: seed, - } - xx.Reset() - return -} - -// New64 creates a new hash.Hash64 computing the 64bit xxHash checksum starting with the seed set to 0x0. -func New64() *XXHash64 { - return NewS64(0) -} - -func (xx *XXHash64) Reset() { - xx.ln, xx.memIdx = 0, 0 - xx.v1, xx.v2, xx.v3, xx.v4 = resetVs64(xx.seed) -} - -// Sum appends the current hash to b and returns the resulting slice. -// It does not change the underlying hash state. -func (xx *XXHash64) Sum(in []byte) []byte { - s := xx.Sum64() - return append(in, byte(s>>56), byte(s>>48), byte(s>>40), byte(s>>32), byte(s>>24), byte(s>>16), byte(s>>8), byte(s)) -} - -// MarshalBinary implements the encoding.BinaryMarshaler interface. -func (xx *XXHash64) MarshalBinary() ([]byte, error) { - b := make([]byte, 0, marshaled64Size) - b = append(b, magic64...) - b = appendUint64(b, xx.v1) - b = appendUint64(b, xx.v2) - b = appendUint64(b, xx.v3) - b = appendUint64(b, xx.v4) - b = appendUint64(b, xx.seed) - b = appendUint64(b, xx.ln) - b = append(b, byte(xx.memIdx)) - b = append(b, xx.mem[:]...) - return b, nil -} - -// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. -func (xx *XXHash64) UnmarshalBinary(b []byte) error { - if len(b) < len(magic64) || string(b[:len(magic64)]) != magic64 { - return errors.New("xxhash: invalid hash state identifier") - } - if len(b) != marshaled64Size { - return errors.New("xxhash: invalid hash state size") - } - b = b[len(magic64):] - b, xx.v1 = consumeUint64(b) - b, xx.v2 = consumeUint64(b) - b, xx.v3 = consumeUint64(b) - b, xx.v4 = consumeUint64(b) - b, xx.seed = consumeUint64(b) - b, xx.ln = consumeUint64(b) - xx.memIdx = int8(b[0]) - b = b[1:] - copy(xx.mem[:], b) - return nil -} - -func appendInt32(b []byte, x int32) []byte { return appendUint32(b, uint32(x)) } - -func appendUint32(b []byte, x uint32) []byte { - var a [4]byte - binary.LittleEndian.PutUint32(a[:], x) - return append(b, a[:]...) -} - -func appendUint64(b []byte, x uint64) []byte { - var a [8]byte - binary.LittleEndian.PutUint64(a[:], x) - return append(b, a[:]...) -} - -func consumeInt32(b []byte) ([]byte, int32) { bn, x := consumeUint32(b); return bn, int32(x) } -func consumeUint32(b []byte) ([]byte, uint32) { x := u32(b); return b[4:], x } -func consumeUint64(b []byte) ([]byte, uint64) { x := u64(b); return b[8:], x } - -// force the compiler to use ROTL instructions - -func rotl32_1(x uint32) uint32 { return (x << 1) | (x >> (32 - 1)) } -func rotl32_7(x uint32) uint32 { return (x << 7) | (x >> (32 - 7)) } -func rotl32_11(x uint32) uint32 { return (x << 11) | (x >> (32 - 11)) } -func rotl32_12(x uint32) uint32 { return (x << 12) | (x >> (32 - 12)) } -func rotl32_13(x uint32) uint32 { return (x << 13) | (x >> (32 - 13)) } -func rotl32_17(x uint32) uint32 { return (x << 17) | (x >> (32 - 17)) } -func rotl32_18(x uint32) uint32 { return (x << 18) | (x >> (32 - 18)) } - -func rotl64_1(x uint64) uint64 { return (x << 1) | (x >> (64 - 1)) } -func rotl64_7(x uint64) uint64 { return (x << 7) | (x >> (64 - 7)) } -func rotl64_11(x uint64) uint64 { return (x << 11) | (x >> (64 - 11)) } -func rotl64_12(x uint64) uint64 { return (x << 12) | (x >> (64 - 12)) } -func rotl64_18(x uint64) uint64 { return (x << 18) | (x >> (64 - 18)) } -func rotl64_23(x uint64) uint64 { return (x << 23) | (x >> (64 - 23)) } -func rotl64_27(x uint64) uint64 { return (x << 27) | (x >> (64 - 27)) } -func rotl64_31(x uint64) uint64 { return (x << 31) | (x >> (64 - 31)) } - -func mix64(h uint64) uint64 { - h ^= h >> 33 - h *= prime64x2 - h ^= h >> 29 - h *= prime64x3 - h ^= h >> 32 - return h -} - -func resetVs64(seed uint64) (v1, v2, v3, v4 uint64) { - if seed == 0 { - return zero64x1, zero64x2, zero64x3, zero64x4 - } - return (seed + prime64x1 + prime64x2), (seed + prime64x2), (seed), (seed - prime64x1) -} - -// borrowed from cespare -func round64(h, v uint64) uint64 { - h += v * prime64x2 - h = rotl64_31(h) - h *= prime64x1 - return h -} - -func mergeRound64(h, v uint64) uint64 { - v = round64(0, v) - h ^= v - h = h*prime64x1 + prime64x4 - return h -} diff --git a/vendor/github.com/OneOfOne/xxhash/xxhash_go17.go b/vendor/github.com/OneOfOne/xxhash/xxhash_go17.go deleted file mode 100644 index ae48e0c5ca..0000000000 --- a/vendor/github.com/OneOfOne/xxhash/xxhash_go17.go +++ /dev/null @@ -1,161 +0,0 @@ -package xxhash - -func u32(in []byte) uint32 { - return uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24 -} - -func u64(in []byte) uint64 { - return uint64(in[0]) | uint64(in[1])<<8 | uint64(in[2])<<16 | uint64(in[3])<<24 | uint64(in[4])<<32 | uint64(in[5])<<40 | uint64(in[6])<<48 | uint64(in[7])<<56 -} - -// Checksum32S returns the checksum of the input bytes with the specific seed. -func Checksum32S(in []byte, seed uint32) (h uint32) { - var i int - - if len(in) > 15 { - var ( - v1 = seed + prime32x1 + prime32x2 - v2 = seed + prime32x2 - v3 = seed + 0 - v4 = seed - prime32x1 - ) - for ; i < len(in)-15; i += 16 { - in := in[i : i+16 : len(in)] - v1 += u32(in[0:4:len(in)]) * prime32x2 - v1 = rotl32_13(v1) * prime32x1 - - v2 += u32(in[4:8:len(in)]) * prime32x2 - v2 = rotl32_13(v2) * prime32x1 - - v3 += u32(in[8:12:len(in)]) * prime32x2 - v3 = rotl32_13(v3) * prime32x1 - - v4 += u32(in[12:16:len(in)]) * prime32x2 - v4 = rotl32_13(v4) * prime32x1 - } - - h = rotl32_1(v1) + rotl32_7(v2) + rotl32_12(v3) + rotl32_18(v4) - - } else { - h = seed + prime32x5 - } - - h += uint32(len(in)) - for ; i <= len(in)-4; i += 4 { - in := in[i : i+4 : len(in)] - h += u32(in[0:4:len(in)]) * prime32x3 - h = rotl32_17(h) * prime32x4 - } - - for ; i < len(in); i++ { - h += uint32(in[i]) * prime32x5 - h = rotl32_11(h) * prime32x1 - } - - h ^= h >> 15 - h *= prime32x2 - h ^= h >> 13 - h *= prime32x3 - h ^= h >> 16 - - return -} - -func (xx *XXHash32) Write(in []byte) (n int, err error) { - i, ml := 0, int(xx.memIdx) - n = len(in) - xx.ln += int32(n) - - if d := 16 - ml; ml > 0 && ml+len(in) > 16 { - xx.memIdx += int32(copy(xx.mem[xx.memIdx:], in[:d])) - ml, in = 16, in[d:len(in):len(in)] - } else if ml+len(in) < 16 { - xx.memIdx += int32(copy(xx.mem[xx.memIdx:], in)) - return - } - - if ml > 0 { - i += 16 - ml - xx.memIdx += int32(copy(xx.mem[xx.memIdx:len(xx.mem):len(xx.mem)], in)) - in := xx.mem[:16:len(xx.mem)] - - xx.v1 += u32(in[0:4:len(in)]) * prime32x2 - xx.v1 = rotl32_13(xx.v1) * prime32x1 - - xx.v2 += u32(in[4:8:len(in)]) * prime32x2 - xx.v2 = rotl32_13(xx.v2) * prime32x1 - - xx.v3 += u32(in[8:12:len(in)]) * prime32x2 - xx.v3 = rotl32_13(xx.v3) * prime32x1 - - xx.v4 += u32(in[12:16:len(in)]) * prime32x2 - xx.v4 = rotl32_13(xx.v4) * prime32x1 - - xx.memIdx = 0 - } - - for ; i <= len(in)-16; i += 16 { - in := in[i : i+16 : len(in)] - xx.v1 += u32(in[0:4:len(in)]) * prime32x2 - xx.v1 = rotl32_13(xx.v1) * prime32x1 - - xx.v2 += u32(in[4:8:len(in)]) * prime32x2 - xx.v2 = rotl32_13(xx.v2) * prime32x1 - - xx.v3 += u32(in[8:12:len(in)]) * prime32x2 - xx.v3 = rotl32_13(xx.v3) * prime32x1 - - xx.v4 += u32(in[12:16:len(in)]) * prime32x2 - xx.v4 = rotl32_13(xx.v4) * prime32x1 - } - - if len(in)-i != 0 { - xx.memIdx += int32(copy(xx.mem[xx.memIdx:], in[i:len(in):len(in)])) - } - - return -} - -func (xx *XXHash32) Sum32() (h uint32) { - var i int32 - if xx.ln > 15 { - h = rotl32_1(xx.v1) + rotl32_7(xx.v2) + rotl32_12(xx.v3) + rotl32_18(xx.v4) - } else { - h = xx.seed + prime32x5 - } - - h += uint32(xx.ln) - - if xx.memIdx > 0 { - for ; i < xx.memIdx-3; i += 4 { - in := xx.mem[i : i+4 : len(xx.mem)] - h += u32(in[0:4:len(in)]) * prime32x3 - h = rotl32_17(h) * prime32x4 - } - - for ; i < xx.memIdx; i++ { - h += uint32(xx.mem[i]) * prime32x5 - h = rotl32_11(h) * prime32x1 - } - } - h ^= h >> 15 - h *= prime32x2 - h ^= h >> 13 - h *= prime32x3 - h ^= h >> 16 - - return -} - -// Checksum64S returns the 64bit xxhash checksum for a single input -func Checksum64S(in []byte, seed uint64) uint64 { - if len(in) == 0 && seed == 0 { - return 0xef46db3751d8e999 - } - - if len(in) > 31 { - return checksum64(in, seed) - } - - return checksum64Short(in, seed) -} diff --git a/vendor/github.com/OneOfOne/xxhash/xxhash_safe.go b/vendor/github.com/OneOfOne/xxhash/xxhash_safe.go deleted file mode 100644 index e92ec29e02..0000000000 --- a/vendor/github.com/OneOfOne/xxhash/xxhash_safe.go +++ /dev/null @@ -1,183 +0,0 @@ -// +build appengine safe ppc64le ppc64be mipsle mips s390x - -package xxhash - -// Backend returns the current version of xxhash being used. -const Backend = "GoSafe" - -func ChecksumString32S(s string, seed uint32) uint32 { - return Checksum32S([]byte(s), seed) -} - -func (xx *XXHash32) WriteString(s string) (int, error) { - if len(s) == 0 { - return 0, nil - } - return xx.Write([]byte(s)) -} - -func ChecksumString64S(s string, seed uint64) uint64 { - return Checksum64S([]byte(s), seed) -} - -func (xx *XXHash64) WriteString(s string) (int, error) { - if len(s) == 0 { - return 0, nil - } - return xx.Write([]byte(s)) -} - -func checksum64(in []byte, seed uint64) (h uint64) { - var ( - v1, v2, v3, v4 = resetVs64(seed) - - i int - ) - - for ; i < len(in)-31; i += 32 { - in := in[i : i+32 : len(in)] - v1 = round64(v1, u64(in[0:8:len(in)])) - v2 = round64(v2, u64(in[8:16:len(in)])) - v3 = round64(v3, u64(in[16:24:len(in)])) - v4 = round64(v4, u64(in[24:32:len(in)])) - } - - h = rotl64_1(v1) + rotl64_7(v2) + rotl64_12(v3) + rotl64_18(v4) - - h = mergeRound64(h, v1) - h = mergeRound64(h, v2) - h = mergeRound64(h, v3) - h = mergeRound64(h, v4) - - h += uint64(len(in)) - - for ; i < len(in)-7; i += 8 { - h ^= round64(0, u64(in[i:len(in):len(in)])) - h = rotl64_27(h)*prime64x1 + prime64x4 - } - - for ; i < len(in)-3; i += 4 { - h ^= uint64(u32(in[i:len(in):len(in)])) * prime64x1 - h = rotl64_23(h)*prime64x2 + prime64x3 - } - - for ; i < len(in); i++ { - h ^= uint64(in[i]) * prime64x5 - h = rotl64_11(h) * prime64x1 - } - - return mix64(h) -} - -func checksum64Short(in []byte, seed uint64) uint64 { - var ( - h = seed + prime64x5 + uint64(len(in)) - i int - ) - - for ; i < len(in)-7; i += 8 { - k := u64(in[i : i+8 : len(in)]) - h ^= round64(0, k) - h = rotl64_27(h)*prime64x1 + prime64x4 - } - - for ; i < len(in)-3; i += 4 { - h ^= uint64(u32(in[i:i+4:len(in)])) * prime64x1 - h = rotl64_23(h)*prime64x2 + prime64x3 - } - - for ; i < len(in); i++ { - h ^= uint64(in[i]) * prime64x5 - h = rotl64_11(h) * prime64x1 - } - - return mix64(h) -} - -func (xx *XXHash64) Write(in []byte) (n int, err error) { - var ( - ml = int(xx.memIdx) - d = 32 - ml - ) - - n = len(in) - xx.ln += uint64(n) - - if ml+len(in) < 32 { - xx.memIdx += int8(copy(xx.mem[xx.memIdx:len(xx.mem):len(xx.mem)], in)) - return - } - - i, v1, v2, v3, v4 := 0, xx.v1, xx.v2, xx.v3, xx.v4 - if ml > 0 && ml+len(in) > 32 { - xx.memIdx += int8(copy(xx.mem[xx.memIdx:len(xx.mem):len(xx.mem)], in[:d:len(in)])) - in = in[d:len(in):len(in)] - - in := xx.mem[0:32:len(xx.mem)] - - v1 = round64(v1, u64(in[0:8:len(in)])) - v2 = round64(v2, u64(in[8:16:len(in)])) - v3 = round64(v3, u64(in[16:24:len(in)])) - v4 = round64(v4, u64(in[24:32:len(in)])) - - xx.memIdx = 0 - } - - for ; i < len(in)-31; i += 32 { - in := in[i : i+32 : len(in)] - v1 = round64(v1, u64(in[0:8:len(in)])) - v2 = round64(v2, u64(in[8:16:len(in)])) - v3 = round64(v3, u64(in[16:24:len(in)])) - v4 = round64(v4, u64(in[24:32:len(in)])) - } - - if len(in)-i != 0 { - xx.memIdx += int8(copy(xx.mem[xx.memIdx:], in[i:len(in):len(in)])) - } - - xx.v1, xx.v2, xx.v3, xx.v4 = v1, v2, v3, v4 - - return -} - -func (xx *XXHash64) Sum64() (h uint64) { - var i int - if xx.ln > 31 { - v1, v2, v3, v4 := xx.v1, xx.v2, xx.v3, xx.v4 - h = rotl64_1(v1) + rotl64_7(v2) + rotl64_12(v3) + rotl64_18(v4) - - h = mergeRound64(h, v1) - h = mergeRound64(h, v2) - h = mergeRound64(h, v3) - h = mergeRound64(h, v4) - } else { - h = xx.seed + prime64x5 - } - - h += uint64(xx.ln) - if xx.memIdx > 0 { - in := xx.mem[:xx.memIdx] - for ; i < int(xx.memIdx)-7; i += 8 { - in := in[i : i+8 : len(in)] - k := u64(in[0:8:len(in)]) - k *= prime64x2 - k = rotl64_31(k) - k *= prime64x1 - h ^= k - h = rotl64_27(h)*prime64x1 + prime64x4 - } - - for ; i < int(xx.memIdx)-3; i += 4 { - in := in[i : i+4 : len(in)] - h ^= uint64(u32(in[0:4:len(in)])) * prime64x1 - h = rotl64_23(h)*prime64x2 + prime64x3 - } - - for ; i < int(xx.memIdx); i++ { - h ^= uint64(in[i]) * prime64x5 - h = rotl64_11(h) * prime64x1 - } - } - - return mix64(h) -} diff --git a/vendor/github.com/OneOfOne/xxhash/xxhash_unsafe.go b/vendor/github.com/OneOfOne/xxhash/xxhash_unsafe.go deleted file mode 100644 index 1e2b5e8f1f..0000000000 --- a/vendor/github.com/OneOfOne/xxhash/xxhash_unsafe.go +++ /dev/null @@ -1,240 +0,0 @@ -// +build !safe -// +build !appengine -// +build !ppc64le -// +build !mipsle -// +build !ppc64be -// +build !mips -// +build !s390x - -package xxhash - -import ( - "reflect" - "unsafe" -) - -// Backend returns the current version of xxhash being used. -const Backend = "GoUnsafe" - -// ChecksumString32S returns the checksum of the input data, without creating a copy, with the specific seed. -func ChecksumString32S(s string, seed uint32) uint32 { - if len(s) == 0 { - return Checksum32S(nil, seed) - } - ss := (*reflect.StringHeader)(unsafe.Pointer(&s)) - return Checksum32S((*[maxInt32]byte)(unsafe.Pointer(ss.Data))[:len(s):len(s)], seed) -} - -func (xx *XXHash32) WriteString(s string) (int, error) { - if len(s) == 0 { - return 0, nil - } - - ss := (*reflect.StringHeader)(unsafe.Pointer(&s)) - return xx.Write((*[maxInt32]byte)(unsafe.Pointer(ss.Data))[:len(s):len(s)]) -} - -// ChecksumString64S returns the checksum of the input data, without creating a copy, with the specific seed. -func ChecksumString64S(s string, seed uint64) uint64 { - if len(s) == 0 { - return Checksum64S(nil, seed) - } - - ss := (*reflect.StringHeader)(unsafe.Pointer(&s)) - return Checksum64S((*[maxInt32]byte)(unsafe.Pointer(ss.Data))[:len(s):len(s)], seed) -} - -func (xx *XXHash64) WriteString(s string) (int, error) { - if len(s) == 0 { - return 0, nil - } - ss := (*reflect.StringHeader)(unsafe.Pointer(&s)) - return xx.Write((*[maxInt32]byte)(unsafe.Pointer(ss.Data))[:len(s):len(s)]) -} - -//go:nocheckptr -func checksum64(in []byte, seed uint64) uint64 { - var ( - wordsLen = len(in) >> 3 - words = ((*[maxInt32 / 8]uint64)(unsafe.Pointer(&in[0])))[:wordsLen:wordsLen] - - v1, v2, v3, v4 = resetVs64(seed) - - h uint64 - i int - ) - - for ; i < len(words)-3; i += 4 { - words := (*[4]uint64)(unsafe.Pointer(&words[i])) - - v1 = round64(v1, words[0]) - v2 = round64(v2, words[1]) - v3 = round64(v3, words[2]) - v4 = round64(v4, words[3]) - } - - h = rotl64_1(v1) + rotl64_7(v2) + rotl64_12(v3) + rotl64_18(v4) - - h = mergeRound64(h, v1) - h = mergeRound64(h, v2) - h = mergeRound64(h, v3) - h = mergeRound64(h, v4) - - h += uint64(len(in)) - - for _, k := range words[i:] { - h ^= round64(0, k) - h = rotl64_27(h)*prime64x1 + prime64x4 - } - - if in = in[wordsLen<<3 : len(in) : len(in)]; len(in) > 3 { - words := (*[1]uint32)(unsafe.Pointer(&in[0])) - h ^= uint64(words[0]) * prime64x1 - h = rotl64_23(h)*prime64x2 + prime64x3 - - in = in[4:len(in):len(in)] - } - - for _, b := range in { - h ^= uint64(b) * prime64x5 - h = rotl64_11(h) * prime64x1 - } - - return mix64(h) -} - -//go:nocheckptr -func checksum64Short(in []byte, seed uint64) uint64 { - var ( - h = seed + prime64x5 + uint64(len(in)) - i int - ) - - if len(in) > 7 { - var ( - wordsLen = len(in) >> 3 - words = ((*[maxInt32 / 8]uint64)(unsafe.Pointer(&in[0])))[:wordsLen:wordsLen] - ) - - for i := range words { - h ^= round64(0, words[i]) - h = rotl64_27(h)*prime64x1 + prime64x4 - } - - i = wordsLen << 3 - } - - if in = in[i:len(in):len(in)]; len(in) > 3 { - words := (*[1]uint32)(unsafe.Pointer(&in[0])) - h ^= uint64(words[0]) * prime64x1 - h = rotl64_23(h)*prime64x2 + prime64x3 - - in = in[4:len(in):len(in)] - } - - for _, b := range in { - h ^= uint64(b) * prime64x5 - h = rotl64_11(h) * prime64x1 - } - - return mix64(h) -} - -func (xx *XXHash64) Write(in []byte) (n int, err error) { - mem, idx := xx.mem[:], int(xx.memIdx) - - xx.ln, n = xx.ln+uint64(len(in)), len(in) - - if idx+len(in) < 32 { - xx.memIdx += int8(copy(mem[idx:len(mem):len(mem)], in)) - return - } - - var ( - v1, v2, v3, v4 = xx.v1, xx.v2, xx.v3, xx.v4 - - i int - ) - - if d := 32 - int(idx); d > 0 && int(idx)+len(in) > 31 { - copy(mem[idx:len(mem):len(mem)], in[:len(in):len(in)]) - - words := (*[4]uint64)(unsafe.Pointer(&mem[0])) - - v1 = round64(v1, words[0]) - v2 = round64(v2, words[1]) - v3 = round64(v3, words[2]) - v4 = round64(v4, words[3]) - - if in, xx.memIdx = in[d:len(in):len(in)], 0; len(in) == 0 { - goto RET - } - } - - for ; i < len(in)-31; i += 32 { - words := (*[4]uint64)(unsafe.Pointer(&in[i])) - - v1 = round64(v1, words[0]) - v2 = round64(v2, words[1]) - v3 = round64(v3, words[2]) - v4 = round64(v4, words[3]) - } - - if len(in)-i != 0 { - xx.memIdx += int8(copy(mem[xx.memIdx:len(mem):len(mem)], in[i:len(in):len(in)])) - } - -RET: - xx.v1, xx.v2, xx.v3, xx.v4 = v1, v2, v3, v4 - - return -} - -func (xx *XXHash64) Sum64() (h uint64) { - if seed := xx.seed; xx.ln > 31 { - v1, v2, v3, v4 := xx.v1, xx.v2, xx.v3, xx.v4 - h = rotl64_1(v1) + rotl64_7(v2) + rotl64_12(v3) + rotl64_18(v4) - - h = mergeRound64(h, v1) - h = mergeRound64(h, v2) - h = mergeRound64(h, v3) - h = mergeRound64(h, v4) - } else if seed == 0 { - h = prime64x5 - } else { - h = seed + prime64x5 - } - - h += uint64(xx.ln) - - if xx.memIdx == 0 { - return mix64(h) - } - - var ( - in = xx.mem[:xx.memIdx:xx.memIdx] - wordsLen = len(in) >> 3 - words = ((*[maxInt32 / 8]uint64)(unsafe.Pointer(&in[0])))[:wordsLen:wordsLen] - ) - - for _, k := range words { - h ^= round64(0, k) - h = rotl64_27(h)*prime64x1 + prime64x4 - } - - if in = in[wordsLen<<3 : len(in) : len(in)]; len(in) > 3 { - words := (*[1]uint32)(unsafe.Pointer(&in[0])) - - h ^= uint64(words[0]) * prime64x1 - h = rotl64_23(h)*prime64x2 + prime64x3 - - in = in[4:len(in):len(in)] - } - - for _, b := range in { - h ^= uint64(b) * prime64x5 - h = rotl64_11(h) * prime64x1 - } - - return mix64(h) -} diff --git a/vendor/github.com/open-policy-agent/opa/ast/json/json.go b/vendor/github.com/open-policy-agent/opa/ast/json/json.go deleted file mode 100644 index 565017d58e..0000000000 --- a/vendor/github.com/open-policy-agent/opa/ast/json/json.go +++ /dev/null @@ -1,36 +0,0 @@ -package json - -// Options defines the options for JSON operations, -// currently only marshaling can be configured -type Options struct { - MarshalOptions MarshalOptions -} - -// MarshalOptions defines the options for JSON marshaling, -// currently only toggling the marshaling of location information is supported -type MarshalOptions struct { - // IncludeLocation toggles the marshaling of location information - IncludeLocation NodeToggle - // IncludeLocationText additionally/optionally includes the text of the location - IncludeLocationText bool - // ExcludeLocationFile additionally/optionally excludes the file of the location - // Note that this is inverted (i.e. not "include" as the default needs to remain false) - ExcludeLocationFile bool -} - -// NodeToggle is a generic struct to allow the toggling of -// settings for different ast node types -type NodeToggle struct { - Term bool - Package bool - Comment bool - Import bool - Rule bool - Head bool - Expr bool - SomeDecl bool - Every bool - With bool - Annotations bool - AnnotationsRef bool -} diff --git a/vendor/github.com/open-policy-agent/opa/ast/marshal.go b/vendor/github.com/open-policy-agent/opa/ast/marshal.go deleted file mode 100644 index 53fb112044..0000000000 --- a/vendor/github.com/open-policy-agent/opa/ast/marshal.go +++ /dev/null @@ -1,11 +0,0 @@ -package ast - -import ( - astJSON "github.com/open-policy-agent/opa/ast/json" -) - -// customJSON is an interface that can be implemented by AST nodes that -// allows the parser to set options for JSON operations on that node. -type customJSON interface { - setJSONOptions(astJSON.Options) -} diff --git a/vendor/github.com/open-policy-agent/opa/ast/strings.go b/vendor/github.com/open-policy-agent/opa/ast/strings.go deleted file mode 100644 index e489f6977c..0000000000 --- a/vendor/github.com/open-policy-agent/opa/ast/strings.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2016 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 ( - "reflect" - "strings" -) - -// TypeName returns a human readable name for the AST element type. -func TypeName(x interface{}) string { - if _, ok := x.(*lazyObj); ok { - return "object" - } - return strings.ToLower(reflect.Indirect(reflect.ValueOf(x)).Type().Name()) -} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/doc.go b/vendor/github.com/open-policy-agent/opa/capabilities/doc.go new file mode 100644 index 0000000000..189c2e727a --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/doc.go @@ -0,0 +1,8 @@ +// Copyright 2024 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. + +// Deprecated: This package is intended for older projects transitioning from OPA v0.x and will remain for the lifetime of OPA v1.x, but its use is not recommended. +// For newer features and behaviours, such as defaulting to the Rego v1 syntax, use the corresponding components in the [github.com/open-policy-agent/opa/v1] package instead. +// See https://www.openpolicyagent.org/docs/latest/v0-compatibility/ for more information. +package capabilities diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v1.0.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v1.0.0.json new file mode 100644 index 0000000000..48a87b0c35 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v1.0.0.json @@ -0,0 +1,4835 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.equal", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.parse_private_keys", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates_with_options", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_keypair", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.marshal_with_options", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "indent", + "value": { + "type": "string" + } + }, + { + "key": "prefix", + "value": { + "type": "string" + } + }, + { + "key": "pretty", + "value": { + "type": "boolean" + } + } + ], + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "numbers.range_step", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.count", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "strings.render_template", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rego_v1" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v1.0.1.json b/vendor/github.com/open-policy-agent/opa/capabilities/v1.0.1.json new file mode 100644 index 0000000000..48a87b0c35 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v1.0.1.json @@ -0,0 +1,4835 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.equal", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.parse_private_keys", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates_with_options", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_keypair", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.marshal_with_options", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "indent", + "value": { + "type": "string" + } + }, + { + "key": "prefix", + "value": { + "type": "string" + } + }, + { + "key": "pretty", + "value": { + "type": "boolean" + } + } + ], + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "numbers.range_step", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.count", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "strings.render_template", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rego_v1" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v1.1.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v1.1.0.json new file mode 100644 index 0000000000..48a87b0c35 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v1.1.0.json @@ -0,0 +1,4835 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.equal", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.parse_private_keys", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates_with_options", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_keypair", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.marshal_with_options", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "indent", + "value": { + "type": "string" + } + }, + { + "key": "prefix", + "value": { + "type": "string" + } + }, + { + "key": "pretty", + "value": { + "type": "boolean" + } + } + ], + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "numbers.range_step", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.count", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "strings.render_template", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rego_v1" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v1.2.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v1.2.0.json new file mode 100644 index 0000000000..1253c88b30 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v1.2.0.json @@ -0,0 +1,4849 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.equal", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.parse_private_keys", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates_with_options", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_keypair", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "internal.test_case", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.marshal_with_options", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "indent", + "value": { + "type": "string" + } + }, + { + "key": "prefix", + "value": { + "type": "string" + } + }, + { + "key": "pretty", + "value": { + "type": "boolean" + } + } + ], + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "numbers.range_step", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.count", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "strings.render_template", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rego_v1" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v1.3.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v1.3.0.json new file mode 100644 index 0000000000..1253c88b30 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v1.3.0.json @@ -0,0 +1,4849 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.equal", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.parse_private_keys", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates_with_options", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_keypair", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "internal.test_case", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.marshal_with_options", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "indent", + "value": { + "type": "string" + } + }, + { + "key": "prefix", + "value": { + "type": "string" + } + }, + { + "key": "pretty", + "value": { + "type": "boolean" + } + } + ], + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "numbers.range_step", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.count", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "strings.render_template", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rego_v1" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v1.4.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v1.4.0.json new file mode 100644 index 0000000000..1253c88b30 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v1.4.0.json @@ -0,0 +1,4849 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.equal", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.parse_private_keys", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates_with_options", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_keypair", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "internal.test_case", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.marshal_with_options", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "indent", + "value": { + "type": "string" + } + }, + { + "key": "prefix", + "value": { + "type": "string" + } + }, + { + "key": "pretty", + "value": { + "type": "boolean" + } + } + ], + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "numbers.range_step", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.count", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "strings.render_template", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rego_v1" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/bundle/utils.go b/vendor/github.com/open-policy-agent/opa/internal/bundle/utils.go index 064649733a..836aa586b9 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/bundle/utils.go +++ b/vendor/github.com/open-policy-agent/opa/internal/bundle/utils.go @@ -6,15 +6,16 @@ package bundle import ( "context" + "errors" "fmt" "io" "os" "path/filepath" - "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" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/bundle" + "github.com/open-policy-agent/opa/v1/resolver/wasm" + "github.com/open-policy-agent/opa/v1/storage" ) // LoadWasmResolversFromStore will lookup all Wasm modules from the store along with the @@ -97,7 +98,7 @@ func LoadBundleFromDiskForRegoVersion(regoVersion ast.RegoVersion, path, name st _, err := os.Stat(bundlePath) if err == nil { - f, err := os.Open(filepath.Join(bundlePath)) + f, err := os.Open(bundlePath) if err != nil { return nil, err } @@ -132,7 +133,7 @@ func SaveBundleToDisk(path string, raw io.Reader) (string, error) { } if raw == nil { - return "", fmt.Errorf("no raw bundle bytes to persist to disk") + return "", errors.New("no raw bundle bytes to persist to disk") } dest, err := os.CreateTemp(path, ".bundle.tar.gz.*.tmp") diff --git a/vendor/github.com/open-policy-agent/opa/internal/cidr/merge/merge.go b/vendor/github.com/open-policy-agent/opa/internal/cidr/merge/merge.go index a019cde128..c2392b6775 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/cidr/merge/merge.go +++ b/vendor/github.com/open-policy-agent/opa/internal/cidr/merge/merge.go @@ -114,7 +114,7 @@ func GetAddressRange(ipNet net.IPNet) (net.IP, net.IP) { copy(lastIPMask, ipNet.Mask) for i := range lastIPMask { lastIPMask[len(lastIPMask)-i-1] = ^lastIPMask[len(lastIPMask)-i-1] - lastIP[net.IPv6len-i-1] = lastIP[net.IPv6len-i-1] | lastIPMask[len(lastIPMask)-i-1] + lastIP[net.IPv6len-i-1] |= lastIPMask[len(lastIPMask)-i-1] } return firstIP, lastIP diff --git a/vendor/github.com/open-policy-agent/opa/internal/compiler/utils.go b/vendor/github.com/open-policy-agent/opa/internal/compiler/utils.go index 4d80aeeef9..5d2e778b13 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/compiler/utils.go +++ b/vendor/github.com/open-policy-agent/opa/internal/compiler/utils.go @@ -5,9 +5,12 @@ package compiler import ( - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/schemas" - "github.com/open-policy-agent/opa/util" + "errors" + "sync" + + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/schemas" + "github.com/open-policy-agent/opa/v1/util" ) type SchemaFile string @@ -16,12 +19,35 @@ const ( AuthorizationPolicySchema SchemaFile = "authorizationPolicy.json" ) -var schemaDefinitions = map[SchemaFile]interface{}{} +var schemaDefinitions = map[SchemaFile]any{} + +var loadOnce = sync.OnceValue(func() error { + cont, err := schemas.FS.ReadFile(string(AuthorizationPolicySchema)) + if err != nil { + return err + } + + if len(cont) == 0 { + return errors.New("expected authorization policy schema file to be present") + } + + var schema any + if err := util.Unmarshal(cont, &schema); err != nil { + return err + } + + schemaDefinitions[AuthorizationPolicySchema] = schema + + return nil +}) // VerifyAuthorizationPolicySchema performs type checking on rules against the schema for the Authorization Policy // Input document. // NOTE: The provided compiler should have already run the compilation process on the input modules func VerifyAuthorizationPolicySchema(compiler *ast.Compiler, ref ast.Ref) error { + if err := loadOnce(); err != nil { + panic(err) + } rules := getRulesWithDependencies(compiler, ref) @@ -32,7 +58,10 @@ func VerifyAuthorizationPolicySchema(compiler *ast.Compiler, ref ast.Ref) error schemaSet := ast.NewSchemaSet() schemaSet.Put(ast.SchemaRootRef, schemaDefinitions[AuthorizationPolicySchema]) - errs := ast.NewCompiler().WithSchemas(schemaSet).PassesTypeCheckRules(rules) + errs := ast.NewCompiler(). + WithDefaultRegoVersion(compiler.DefaultRegoVersion()). + WithSchemas(schemaSet). + PassesTypeCheckRules(rules) if len(errs) > 0 { return errs @@ -64,26 +93,3 @@ func transitiveDependencies(compiler *ast.Compiler, rule *ast.Rule, deps map[*as transitiveDependencies(compiler, other, deps) } } - -func loadAuthorizationPolicySchema() { - - cont, err := schemas.FS.ReadFile(string(AuthorizationPolicySchema)) - if err != nil { - panic(err) - } - - if len(cont) == 0 { - panic("expected authorization policy schema file to be present") - } - - var schema interface{} - if err := util.Unmarshal(cont, &schema); err != nil { - panic(err) - } - - schemaDefinitions[AuthorizationPolicySchema] = schema -} - -func init() { - loadAuthorizationPolicySchema() -} diff --git a/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/wasm.go b/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/wasm.go index 9a5cebec54..25cbc13b47 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/wasm.go +++ b/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/wasm.go @@ -12,7 +12,6 @@ import ( "fmt" "io" - "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/internal/compiler/wasm/opa" "github.com/open-policy-agent/opa/internal/debug" "github.com/open-policy-agent/opa/internal/wasm/encoding" @@ -20,8 +19,9 @@ import ( "github.com/open-policy-agent/opa/internal/wasm/module" "github.com/open-policy-agent/opa/internal/wasm/types" "github.com/open-policy-agent/opa/internal/wasm/util" - "github.com/open-policy-agent/opa/ir" - opatypes "github.com/open-policy-agent/opa/types" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/ir" + opatypes "github.com/open-policy-agent/opa/v1/types" ) // Record Wasm ABI version in exported global variable @@ -340,7 +340,7 @@ func (c *Compiler) initModule() error { // two times. But let's deal with that when it happens. if _, ok := c.funcs[name]; ok { // already seen c.debug.Printf("function name duplicate: %s (%d)", name, fn.Index) - name = name + ".1" + name += ".1" } c.funcs[name] = fn.Index } @@ -348,7 +348,7 @@ func (c *Compiler) initModule() error { for _, fn := range c.policy.Funcs.Funcs { params := make([]types.ValueType, len(fn.Params)) - for i := 0; i < len(params); i++ { + for i := range params { params[i] = types.I32 } @@ -827,7 +827,7 @@ func (c *Compiler) compileFunc(fn *ir.Func) error { memoize := len(fn.Params) == 2 if len(fn.Params) == 0 { - return fmt.Errorf("illegal function: zero args") + return errors.New("illegal function: zero args") } c.nextLocal = 0 @@ -996,12 +996,16 @@ func (c *Compiler) compileBlock(block *ir.Block) ([]instruction.Instruction, err for _, stmt := range block.Stmts { switch stmt := stmt.(type) { case *ir.ResultSetAddStmt: - instrs = append(instrs, instruction.GetLocal{Index: c.lrs}) - instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.Value)}) - instrs = append(instrs, instruction.Call{Index: c.function(opaSetAdd)}) + instrs = append(instrs, + instruction.GetLocal{Index: c.lrs}, + instruction.GetLocal{Index: c.local(stmt.Value)}, + instruction.Call{Index: c.function(opaSetAdd)}, + ) case *ir.ReturnLocalStmt: - instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.Source)}) - instrs = append(instrs, instruction.Return{}) + instrs = append(instrs, + instruction.GetLocal{Index: c.local(stmt.Source)}, + instruction.Return{}, + ) case *ir.BlockStmt: for i := range stmt.Blocks { block, err := c.compileBlock(stmt.Blocks[i]) @@ -1029,8 +1033,10 @@ func (c *Compiler) compileBlock(block *ir.Block) ([]instruction.Instruction, err return instrs, err } case *ir.AssignVarStmt: - instrs = append(instrs, c.instrRead(stmt.Source)) - instrs = append(instrs, instruction.SetLocal{Index: c.local(stmt.Target)}) + instrs = append(instrs, + c.instrRead(stmt.Source), + instruction.SetLocal{Index: c.local(stmt.Target)}, + ) case *ir.AssignVarOnceStmt: instrs = append(instrs, instruction.Block{ Instrs: []instruction.Instruction{ @@ -1360,7 +1366,7 @@ func (c *Compiler) compileUpsert(local ir.Local, path []int, value ir.Operand, _ // Initialize the locals that specify the path of the upsert operation. lpath := make(map[int]uint32, len(path)) - for i := 0; i < len(path); i++ { + for i := range path { lpath[i] = c.genLocal() instrs = append(instrs, instruction.I32Const{Value: c.opaStringAddr(path[i])}) instrs = append(instrs, instruction.SetLocal{Index: lpath[i]}) @@ -1369,10 +1375,10 @@ func (c *Compiler) compileUpsert(local ir.Local, path []int, value ir.Operand, _ // Generate a block that traverses the path of the upsert operation, // shallowing copying values at each step as needed. Stop before the final // segment that will only be inserted. - var inner []instruction.Instruction + inner := make([]instruction.Instruction, 0, len(path)*21+1) ltemp := c.genLocal() - for i := 0; i < len(path)-1; i++ { + for i := range len(path) - 1 { // Lookup the next part of the path. inner = append(inner, instruction.GetLocal{Index: lcopy}) @@ -1408,10 +1414,10 @@ func (c *Compiler) compileUpsert(local ir.Local, path []int, value ir.Operand, _ inner = append(inner, instruction.Br{Index: uint32(len(path) - 1)}) // Generate blocks that handle missing nodes during traversal. - var block []instruction.Instruction + block := make([]instruction.Instruction, 0, len(path)*10) lval := c.genLocal() - for i := 0; i < len(path)-1; i++ { + for i := range len(path) - 1 { block = append(block, instruction.Block{Instrs: inner}) block = append(block, instruction.Call{Index: c.function(opaObject)}) block = append(block, instruction.SetLocal{Index: lval}) @@ -1535,8 +1541,7 @@ func (c *Compiler) compileExternalCall(stmt *ir.CallStmt, ef externalFunc, resul } instrs := *result - instrs = append(instrs, instruction.I32Const{Value: ef.ID}) - instrs = append(instrs, instruction.I32Const{Value: 0}) // unused context parameter + instrs = append(instrs, instruction.I32Const{Value: ef.ID}, instruction.I32Const{Value: 0}) // unused context parameter for _, arg := range stmt.Args { instrs = append(instrs, c.instrRead(arg)) @@ -1545,9 +1550,11 @@ func (c *Compiler) compileExternalCall(stmt *ir.CallStmt, ef externalFunc, resul instrs = append(instrs, instruction.Call{Index: c.function(builtinDispatchers[len(stmt.Args)])}) if ef.Decl.Result() != nil { - instrs = append(instrs, instruction.TeeLocal{Index: c.local(stmt.Result)}) - instrs = append(instrs, instruction.I32Eqz{}) - instrs = append(instrs, instruction.BrIf{Index: 0}) + instrs = append(instrs, + instruction.TeeLocal{Index: c.local(stmt.Result)}, + instruction.I32Eqz{}, + instruction.BrIf{Index: 0}, + ) } else { instrs = append(instrs, instruction.Drop{}) } @@ -1678,7 +1685,7 @@ func (c *Compiler) genLocal() uint32 { func (c *Compiler) function(name string) uint32 { fidx, ok := c.funcs[name] if !ok { - panic(fmt.Sprintf("function not found: %s", name)) + panic("function not found: " + name) } return fidx } diff --git a/vendor/github.com/open-policy-agent/opa/internal/config/config.go b/vendor/github.com/open-policy-agent/opa/internal/config/config.go index b1a9731f65..fdac487720 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/config/config.go +++ b/vendor/github.com/open-policy-agent/opa/internal/config/config.go @@ -15,11 +15,11 @@ import ( "sigs.k8s.io/yaml" "github.com/open-policy-agent/opa/internal/strvals" - "github.com/open-policy-agent/opa/keys" - "github.com/open-policy-agent/opa/logging" - "github.com/open-policy-agent/opa/plugins/rest" - "github.com/open-policy-agent/opa/tracing" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/keys" + "github.com/open-policy-agent/opa/v1/logging" + "github.com/open-policy-agent/opa/v1/plugins/rest" + "github.com/open-policy-agent/opa/v1/tracing" + "github.com/open-policy-agent/opa/v1/util" ) // ServiceOptions stores the options passed to ParseServicesConfig diff --git a/vendor/github.com/open-policy-agent/opa/internal/edittree/bitvector/bitvector.go b/vendor/github.com/open-policy-agent/opa/internal/edittree/bitvector/bitvector.go index 89e7e137b7..8e4d65ed3f 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/edittree/bitvector/bitvector.go +++ b/vendor/github.com/open-policy-agent/opa/internal/edittree/bitvector/bitvector.go @@ -36,7 +36,7 @@ func (vector *BitVector) Length() int { // position of the last byte in the slice. // This returns the bit that was shifted off of the last byte. func shiftLower(bit byte, b []byte) byte { - bit = bit << 7 + bit <<= 7 for i := len(b) - 1; i >= 0; i-- { newByte := b[i] >> 1 newByte |= bit diff --git a/vendor/github.com/open-policy-agent/opa/internal/edittree/edittree.go b/vendor/github.com/open-policy-agent/opa/internal/edittree/edittree.go index 9cfaee8baf..378fe99a32 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/edittree/edittree.go +++ b/vendor/github.com/open-policy-agent/opa/internal/edittree/edittree.go @@ -146,14 +146,14 @@ package edittree import ( - "encoding/json" + "errors" "fmt" "math/big" "sort" "strings" - "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/internal/edittree/bitvector" + "github.com/open-policy-agent/opa/v1/ast" ) // Deletions are encoded with a nil value pointer. @@ -213,10 +213,10 @@ func (e *EditTree) getKeyHash(key *ast.Term) (int, bool) { case ast.Null, ast.Boolean, ast.String, ast.Var: equal = func(y ast.Value) bool { return x == y } case ast.Number: - if xi, err := json.Number(x).Int64(); err == nil { + if xi, ok := x.Int64(); ok { equal = func(y ast.Value) bool { if y, ok := y.(ast.Number); ok { - if yi, err := json.Number(y).Int64(); err == nil { + if yi, ok := y.Int64(); ok { return xi == yi } } @@ -336,13 +336,13 @@ func (e *EditTree) deleteChildValue(hash int) { // Insert creates a new child of e, and returns the new child EditTree node. func (e *EditTree) Insert(key, value *ast.Term) (*EditTree, error) { if e.value == nil { - return nil, fmt.Errorf("deleted node encountered during insert operation") + return nil, errors.New("deleted node encountered during insert operation") } if key == nil { - return nil, fmt.Errorf("nil key provided for insert operation") + return nil, errors.New("nil key provided for insert operation") } if value == nil { - return nil, fmt.Errorf("nil value provided for insert operation") + return nil, errors.New("nil value provided for insert operation") } switch x := e.value.Value.(type) { @@ -368,7 +368,7 @@ func (e *EditTree) Insert(key, value *ast.Term) (*EditTree, error) { return nil, err } if idx < 0 || idx > e.insertions.Length() { - return nil, fmt.Errorf("index for array insertion out of bounds") + return nil, errors.New("index for array insertion out of bounds") } return e.unsafeInsertArray(idx, value), nil default: @@ -458,10 +458,10 @@ func (e *EditTree) unsafeInsertArray(idx int, value *ast.Term) *EditTree { // already present in e. It then returns the deleted child EditTree node. func (e *EditTree) Delete(key *ast.Term) (*EditTree, error) { if e.value == nil { - return nil, fmt.Errorf("deleted node encountered during delete operation") + return nil, errors.New("deleted node encountered during delete operation") } if key == nil { - return nil, fmt.Errorf("nil key provided for delete operation") + return nil, errors.New("nil key provided for delete operation") } switch e.value.Value.(type) { @@ -532,7 +532,7 @@ func (e *EditTree) Delete(key *ast.Term) (*EditTree, error) { return nil, err } if idx < 0 || idx > e.insertions.Length()-1 { - return nil, fmt.Errorf("index for array delete out of bounds") + return nil, errors.New("index for array delete out of bounds") } // Collect insertion indexes above the delete site for rewriting. @@ -553,14 +553,14 @@ func (e *EditTree) Delete(key *ast.Term) (*EditTree, error) { } // Do rewrites to clear out the newly-removed element. e.deleteChildValue(idx) - for i := 0; i < len(rewritesScalars); i++ { + for i := range rewritesScalars { originalIdx := rewritesScalars[i] rewriteIdx := rewritesScalars[i] - 1 v := e.childScalarValues[originalIdx] e.deleteChildValue(originalIdx) e.setChildScalarValue(rewriteIdx, v) } - for i := 0; i < len(rewritesComposites); i++ { + for i := range rewritesComposites { originalIdx := rewritesComposites[i] rewriteIdx := rewritesComposites[i] - 1 v := e.childCompositeValues[originalIdx] @@ -592,7 +592,7 @@ func (e *EditTree) Delete(key *ast.Term) (*EditTree, error) { //gcassert:inline func sumZeroesBelowIndex(index int, bv *bitvector.BitVector) int { zeroesSeen := 0 - for i := 0; i < index; i++ { + for i := range index { if bv.Element(i) == 0 { zeroesSeen++ } @@ -602,7 +602,7 @@ func sumZeroesBelowIndex(index int, bv *bitvector.BitVector) int { func findIndexOfNthZero(n int, bv *bitvector.BitVector) (int, bool) { zeroesSeen := 0 - for i := 0; i < bv.Length(); i++ { + for i := range bv.Length() { if bv.Element(i) == 0 { zeroesSeen++ } @@ -638,7 +638,7 @@ func (e *EditTree) Unfold(path ast.Ref) (*EditTree, error) { } // 1+ path segment case. if e.value == nil { - return nil, fmt.Errorf("nil value encountered where composite value was expected") + return nil, errors.New("nil value encountered where composite value was expected") } // Switch behavior based on types. @@ -725,9 +725,9 @@ func (e *EditTree) Unfold(path ast.Ref) (*EditTree, error) { // Fall back to looking up the key in e.value. // Extend the tree if key is present. Error otherwise. - if v, err := x.Find(ast.Ref{ast.IntNumberTerm(idx)}); err == nil { + if v, err := x.Find(ast.Ref{ast.InternedIntNumberTerm(idx)}); err == nil { // TODO: Consider a more efficient "Replace" function that special-cases this for arrays instead? - _, err := e.Delete(ast.IntNumberTerm(idx)) + _, err := e.Delete(ast.InternedIntNumberTerm(idx)) if err != nil { return nil, err } @@ -832,7 +832,7 @@ func (e *EditTree) Render() *ast.Term { // original array. We build a new Array with modified/deleted keys. out := make([]*ast.Term, 0, e.insertions.Length()) eIdx := 0 - for i := 0; i < e.insertions.Length(); i++ { + for i := range e.insertions.Length() { // If the index == 0, that indicates we should look up the next // surviving original element. // If the index == 1, that indicates we should look up that @@ -880,7 +880,7 @@ func (e *EditTree) Render() *ast.Term { // Returns the inserted EditTree node. func (e *EditTree) InsertAtPath(path ast.Ref, value *ast.Term) (*EditTree, error) { if value == nil { - return nil, fmt.Errorf("cannot insert nil value into EditTree") + return nil, errors.New("cannot insert nil value into EditTree") } if len(path) == 0 { @@ -911,7 +911,7 @@ func (e *EditTree) DeleteAtPath(path ast.Ref) (*EditTree, error) { // Root document case: if len(path) == 0 { if e.value == nil { - return nil, fmt.Errorf("deleted node encountered during delete operation") + return nil, errors.New("deleted node encountered during delete operation") } e.value = nil e.childKeys = nil @@ -1026,8 +1026,7 @@ func (e *EditTree) Exists(path ast.Ref) bool { } // Fallback if child lookup failed. // We have to ensure that the lookup term is a number here, or Find will fail. - k := ast.Ref{ast.IntNumberTerm(idx)}.Concat(path[1:]) - _, err = x.Find(k) + _, err = x.Find(ast.Ref{ast.InternedIntNumberTerm(idx)}.Concat(path[1:])) return err == nil default: // Catch all primitive types. @@ -1048,7 +1047,7 @@ func toIndex(arrayLength int, term *ast.Term) (int, error) { switch v := term.Value.(type) { case ast.Number: if i, ok = v.Int(); !ok { - return 0, fmt.Errorf("invalid number type for indexing") + return 0, errors.New("invalid number type for indexing") } case ast.String: if v == "-" { @@ -1056,13 +1055,13 @@ func toIndex(arrayLength int, term *ast.Term) (int, error) { } num := ast.Number(v) if i, ok = num.Int(); !ok { - return 0, fmt.Errorf("invalid string for indexing") + return 0, errors.New("invalid string for indexing") } if v != "0" && strings.HasPrefix(string(v), "0") { - return 0, fmt.Errorf("leading zeros are not allowed in JSON paths") + return 0, errors.New("leading zeros are not allowed in JSON paths") } default: - return 0, fmt.Errorf("invalid type for indexing") + return 0, errors.New("invalid type for indexing") } return i, nil @@ -1181,5 +1180,5 @@ func (e *EditTree) Filter(paths []ast.Ref) *ast.Term { type termSlice []*ast.Term func (s termSlice) Less(i, j int) bool { return ast.Compare(s[i].Value, s[j].Value) < 0 } -func (s termSlice) Swap(i, j int) { x := s[i]; s[i] = s[j]; s[j] = x } +func (s termSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s termSlice) Len() int { return len(s) } diff --git a/vendor/github.com/open-policy-agent/opa/internal/future/filter_imports.go b/vendor/github.com/open-policy-agent/opa/internal/future/filter_imports.go index cf5721101a..f8037ed63e 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/future/filter_imports.go +++ b/vendor/github.com/open-policy-agent/opa/internal/future/filter_imports.go @@ -4,7 +4,7 @@ package future -import "github.com/open-policy-agent/opa/ast" +import "github.com/open-policy-agent/opa/v1/ast" // FilterFutureImports filters OUT any future imports from the passed slice of // `*ast.Import`s. @@ -19,12 +19,14 @@ func FilterFutureImports(imps []*ast.Import) []*ast.Import { return ret } +var keywordsTerm = ast.StringTerm("keywords") + // IsAllFutureKeywords returns true if the passed *ast.Import is `future.keywords` func IsAllFutureKeywords(imp *ast.Import) bool { path := imp.Path.Value.(ast.Ref) return len(path) == 2 && ast.FutureRootDocument.Equal(path[0]) && - path[1].Equal(ast.StringTerm("keywords")) + path[1].Equal(keywordsTerm) } // IsFutureKeyword returns true if the passed *ast.Import is `future.keywords.{kw}` @@ -32,7 +34,7 @@ func IsFutureKeyword(imp *ast.Import, kw string) bool { path := imp.Path.Value.(ast.Ref) return len(path) == 3 && ast.FutureRootDocument.Equal(path[0]) && - path[1].Equal(ast.StringTerm("keywords")) && + path[1].Equal(keywordsTerm) && path[2].Equal(ast.StringTerm(kw)) } @@ -40,7 +42,7 @@ func WhichFutureKeyword(imp *ast.Import) (string, bool) { path := imp.Path.Value.(ast.Ref) if len(path) == 3 && ast.FutureRootDocument.Equal(path[0]) && - path[1].Equal(ast.StringTerm("keywords")) { + path[1].Equal(keywordsTerm) { if str, ok := path[2].Value.(ast.String); ok { return string(str), true } diff --git a/vendor/github.com/open-policy-agent/opa/internal/future/parser_opts.go b/vendor/github.com/open-policy-agent/opa/internal/future/parser_opts.go index 804702b945..eaeb87e296 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/future/parser_opts.go +++ b/vendor/github.com/open-policy-agent/opa/internal/future/parser_opts.go @@ -5,9 +5,10 @@ package future import ( + "errors" "fmt" - "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/v1/ast" ) // ParserOptionsFromFutureImports transforms a slice of `ast.Import`s into the @@ -33,7 +34,7 @@ func ParserOptionsFromFutureImports(imports []*ast.Import) (ast.ParserOptions, e } if len(path) == 3 { if imp.Alias != "" { - return popts, fmt.Errorf("alias not supported") + return popts, errors.New("alias not supported") } popts.FutureKeywords = append(popts.FutureKeywords, string(path[2].Value.(ast.String))) } diff --git a/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/schemaReferencePool.go b/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/schemaReferencePool.go index 876419f56c..515702095b 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/schemaReferencePool.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/schemaReferencePool.go @@ -25,10 +25,6 @@ package gojsonschema -import ( - "fmt" -) - type schemaReferencePool struct { documents map[string]*SubSchema } @@ -44,7 +40,7 @@ func newSchemaReferencePool() *schemaReferencePool { func (p *schemaReferencePool) Get(ref string) (r *SubSchema, o bool) { if internalLogEnabled { - internalLog(fmt.Sprintf("Schema Reference ( %s )", ref)) + internalLog("Schema Reference ( %s )", ref) } if sch, ok := p.documents[ref]; ok { @@ -60,7 +56,7 @@ func (p *schemaReferencePool) Get(ref string) (r *SubSchema, o bool) { func (p *schemaReferencePool) Add(ref string, sch *SubSchema) { if internalLogEnabled { - internalLog(fmt.Sprintf("Add Schema Reference %s to pool", ref)) + internalLog("Add Schema Reference %s to pool", ref) } if _, ok := p.documents[ref]; !ok { p.documents[ref] = sch diff --git a/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/validation.go b/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/validation.go index 7c86e37245..efdea58b6b 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/validation.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/validation.go @@ -348,7 +348,7 @@ func (v *SubSchema) validateSchema(currentSubSchema *SubSchema, currentNode inte } } - if currentSubSchema.dependencies != nil && len(currentSubSchema.dependencies) > 0 { + if len(currentSubSchema.dependencies) > 0 { if currentNodeMap, ok := currentNode.(map[string]interface{}); ok { for elementKey := range currentNodeMap { if dependency, ok := currentSubSchema.dependencies[elementKey]; ok { @@ -469,7 +469,7 @@ func (v *SubSchema) validateArray(currentSubSchema *SubSchema, value []interface result.mergeErrors(validationResult) } } else { - if currentSubSchema.ItemsChildren != nil && len(currentSubSchema.ItemsChildren) > 0 { + if len(currentSubSchema.ItemsChildren) > 0 { nbItems := len(currentSubSchema.ItemsChildren) diff --git a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/definition.go b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/definition.go index d203908168..ee3d4df3ac 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/definition.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/definition.go @@ -29,7 +29,7 @@ type Definition struct { Types []string // union EnumValues EnumValueList // enum - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` BuiltIn bool `dump:"-"` } @@ -65,7 +65,7 @@ type FieldDefinition struct { DefaultValue *Value // only for input objects Type *Type Directives DirectiveList - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` } type ArgumentDefinition struct { @@ -74,14 +74,14 @@ type ArgumentDefinition struct { DefaultValue *Value Type *Type Directives DirectiveList - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` } type EnumValueDefinition struct { Description string Name string Directives DirectiveList - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` } type DirectiveDefinition struct { @@ -90,5 +90,5 @@ type DirectiveDefinition struct { Arguments ArgumentDefinitionList Locations []DirectiveLocation IsRepeatable bool - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` } diff --git a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/directive.go b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/directive.go index 5f6e8531f5..b11867c2e4 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/directive.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/directive.go @@ -30,7 +30,7 @@ const ( type Directive struct { Name string Arguments ArgumentList - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` // Requires validation ParentDefinition *Definition diff --git a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/document.go b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/document.go index 43bfb54ff5..4a6654b9aa 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/document.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/document.go @@ -3,7 +3,7 @@ package ast type QueryDocument struct { Operations OperationList Fragments FragmentDefinitionList - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` } type SchemaDocument struct { @@ -12,7 +12,7 @@ type SchemaDocument struct { Directives DirectiveDefinitionList Definitions DefinitionList Extensions DefinitionList - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` } func (d *SchemaDocument) Merge(other *SchemaDocument) { @@ -69,11 +69,11 @@ type SchemaDefinition struct { Description string Directives DirectiveList OperationTypes OperationTypeDefinitionList - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` } type OperationTypeDefinition struct { Operation Operation Type string - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` } diff --git a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/dumper.go b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/dumper.go index dbb7a7efaf..84266a618f 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/dumper.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/dumper.go @@ -40,10 +40,10 @@ func (d *dumper) dump(v reflect.Value) { d.WriteString("false") } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - d.WriteString(fmt.Sprintf("%d", v.Int())) + d.WriteString(strconv.FormatInt(v.Int(), 10)) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - d.WriteString(fmt.Sprintf("%d", v.Uint())) + d.WriteString(strconv.FormatUint(v.Uint(), 10)) case reflect.Float32, reflect.Float64: d.WriteString(fmt.Sprintf("%.2f", v.Float())) @@ -88,7 +88,7 @@ func typeName(t reflect.Type) string { func (d *dumper) dumpArray(v reflect.Value) { d.WriteString("[" + typeName(v.Type().Elem()) + "]") - for i := 0; i < v.Len(); i++ { + for i := range v.Len() { d.nl() d.WriteString("- ") d.indent++ @@ -102,7 +102,7 @@ func (d *dumper) dumpStruct(v reflect.Value) { d.indent++ typ := v.Type() - for i := 0; i < v.NumField(); i++ { + for i := range v.NumField() { f := v.Field(i) if typ.Field(i).Tag.Get("dump") == "-" { continue @@ -132,13 +132,13 @@ func isZero(v reflect.Value) bool { return true } z := true - for i := 0; i < v.Len(); i++ { + for i := range v.Len() { z = z && isZero(v.Index(i)) } return z case reflect.Struct: z := true - for i := 0; i < v.NumField(); i++ { + for i := range v.NumField() { z = z && isZero(v.Field(i)) } return z diff --git a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/fragment.go b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/fragment.go index 57ab56c7c6..723d833999 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/fragment.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/fragment.go @@ -8,7 +8,7 @@ type FragmentSpread struct { ObjectDefinition *Definition Definition *FragmentDefinition - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` } type InlineFragment struct { @@ -19,7 +19,7 @@ type InlineFragment struct { // Require validation ObjectDefinition *Definition - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` } type FragmentDefinition struct { @@ -34,5 +34,5 @@ type FragmentDefinition struct { // Require validation Definition *Definition - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` } diff --git a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/operation.go b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/operation.go index 3b37f81bf3..5fc2f3b246 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/operation.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/operation.go @@ -14,7 +14,7 @@ type OperationDefinition struct { VariableDefinitions VariableDefinitionList Directives DirectiveList SelectionSet SelectionSet - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` } type VariableDefinition struct { @@ -22,7 +22,7 @@ type VariableDefinition struct { Type *Type DefaultValue *Value Directives DirectiveList - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` // Requires validation Definition *Definition diff --git a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/selection.go b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/selection.go index 5ef26c6ab3..677300edd5 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/selection.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/selection.go @@ -21,7 +21,7 @@ type Field struct { Arguments ArgumentList Directives DirectiveList SelectionSet SelectionSet - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` // Require validation Definition *FieldDefinition @@ -31,7 +31,7 @@ type Field struct { type Argument struct { Name string Value *Value - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` } func (s *Field) ArgumentMap(vars map[string]interface{}) map[string]interface{} { diff --git a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/type.go b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/type.go index 5f77bc7ce4..669f1da57e 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/type.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/type.go @@ -20,7 +20,7 @@ type Type struct { NamedType string Elem *Type NonNull bool - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` } func (t *Type) Name() string { diff --git a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/value.go b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/value.go index c25ef15059..ae23a98d7d 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/value.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/ast/value.go @@ -25,7 +25,7 @@ type Value struct { Raw string Children ChildValueList Kind ValueKind - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` // Require validation Definition *Definition @@ -36,7 +36,7 @@ type Value struct { type ChildValue struct { Name string Value *Value - Position *Position `dump:"-"` + Position *Position `dump:"-" json:"-"` } func (v *Value) Value(vars map[string]interface{}) (interface{}, error) { diff --git a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/rules/fields_on_correct_type.go b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/rules/fields_on_correct_type.go index d536e5e5f4..f681767475 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/rules/fields_on_correct_type.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/rules/fields_on_correct_type.go @@ -27,7 +27,7 @@ func init() { } addError( - Message(message), + Message(message), //nolint:govet At(field.Position), ) }) diff --git a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/rules/fragments_on_composite_types.go b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/rules/fragments_on_composite_types.go index 66bd348c47..861e3b16cf 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/rules/fragments_on_composite_types.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/rules/fragments_on_composite_types.go @@ -20,7 +20,7 @@ func init() { message := fmt.Sprintf(`Fragment cannot condition on non composite type "%s".`, inlineFragment.TypeCondition) addError( - Message(message), + Message(message), //nolint:govet At(inlineFragment.Position), ) }) @@ -33,7 +33,7 @@ func init() { message := fmt.Sprintf(`Fragment "%s" cannot condition on non composite type "%s".`, fragment.Name, fragment.TypeCondition) addError( - Message(message), + Message(message), //nolint:govet At(fragment.Position), ) }) diff --git a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/rules/no_fragment_cycles.go b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/rules/no_fragment_cycles.go index a7de611f17..edc562ddd4 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/rules/no_fragment_cycles.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/rules/no_fragment_cycles.go @@ -51,7 +51,7 @@ func init() { } var via string if len(fragmentNames) != 0 { - via = fmt.Sprintf(" via %s", strings.Join(fragmentNames, ", ")) + via = " via " + strings.Join(fragmentNames, ", ") } addError( Message(`Cannot spread fragment "%s" within itself%s.`, spreadName, via), diff --git a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/rules/values_of_correct_type.go b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/rules/values_of_correct_type.go index 8858023d4e..afd9f54f10 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/rules/values_of_correct_type.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/rules/values_of_correct_type.go @@ -159,8 +159,6 @@ func unexpectedTypeMessageOnly(v *ast.Value) ErrorOption { return Message(`Float cannot represent non numeric value: %s`, v.String()) case "ID", "ID!": return Message(`ID cannot represent a non-string and non-integer value: %s`, v.String()) - //case "Enum": - // return Message(`Enum "%s" cannot represent non-enum value: %s`, v.ExpectedType.String(), v.String()) default: if v.Definition.Kind == ast.Enum { return Message(`Enum "%s" cannot represent non-enum value: %s.`, v.ExpectedType.String(), v.String()) diff --git a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/vars.go b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/vars.go index 86be7c4df2..66924148ba 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/vars.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gqlparser/validator/vars.go @@ -2,6 +2,7 @@ package validator import ( "encoding/json" + "errors" "fmt" "reflect" "strconv" @@ -11,7 +12,7 @@ import ( "github.com/open-policy-agent/opa/internal/gqlparser/gqlerror" ) -var ErrUnexpectedType = fmt.Errorf("Unexpected Type") +var ErrUnexpectedType = errors.New("Unexpected Type") // VariableValues coerces and validates variable values func VariableValues(schema *ast.Schema, op *ast.OperationDefinition, variables map[string]interface{}) (map[string]interface{}, error) { @@ -106,7 +107,7 @@ func (v *varValidator) validateVarType(typ *ast.Type, val reflect.Value) (reflec slc = reflect.Append(slc, val) val = slc } - for i := 0; i < val.Len(); i++ { + for i := range val.Len() { resetPath() v.path = append(v.path, ast.PathIndex(i)) field := val.Index(i) @@ -222,7 +223,7 @@ func (v *varValidator) validateVarType(typ *ast.Type, val reflect.Value) (reflec if fieldDef.Type.NonNull && field.IsNil() { return val, gqlerror.ErrorPathf(v.path, "cannot be null") } - //allow null object field and skip it + // allow null object field and skip it if !fieldDef.Type.NonNull && field.IsNil() { continue } diff --git a/vendor/github.com/open-policy-agent/opa/internal/json/patch/patch.go b/vendor/github.com/open-policy-agent/opa/internal/json/patch/patch.go index 31c89869da..9ddb93506e 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/json/patch/patch.go +++ b/vendor/github.com/open-policy-agent/opa/internal/json/patch/patch.go @@ -7,7 +7,7 @@ package patch import ( "strings" - "github.com/open-policy-agent/opa/storage" + "github.com/open-policy-agent/opa/v1/storage" ) // ParsePatchPathEscaped returns a new path for the given escaped str. @@ -37,8 +37,8 @@ func ParsePatchPathEscaped(str string) (path storage.Path, ok bool) { // the substitutions in this order, an implementation avoids the error of // turning '~01' first into '~1' and then into '/', which would be // incorrect (the string '~01' correctly becomes '~1' after transformation)." - path[i] = strings.Replace(path[i], "~1", "/", -1) - path[i] = strings.Replace(path[i], "~0", "~", -1) + path[i] = strings.ReplaceAll(path[i], "~1", "/") + path[i] = strings.ReplaceAll(path[i], "~0", "~") } return diff --git a/vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/jwk.go b/vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/jwk.go index aa22a3830f..7de27d4e4e 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/jwk.go +++ b/vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/jwk.go @@ -114,7 +114,7 @@ func parse(jwkSrc string) (*Set, error) { // ParseBytes parses JWK from the incoming byte buffer. func ParseBytes(buf []byte) (*Set, error) { - return parse(string(buf[:])) + return parse(string(buf)) } // ParseString parses JWK from the incoming string. diff --git a/vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/key_ops.go b/vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/key_ops.go index e8fe4cd854..c02b0b9990 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/key_ops.go +++ b/vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/key_ops.go @@ -2,6 +2,7 @@ package jwk import ( "encoding/json" + "errors" "fmt" ) @@ -53,12 +54,12 @@ func (keyOperationList *KeyOperationList) UnmarshalJSON(data []byte) error { var tempKeyOperationList []string err := json.Unmarshal(data, &tempKeyOperationList) if err != nil { - return fmt.Errorf("invalid key operation") + return errors.New("invalid key operation") } for _, value := range tempKeyOperationList { _, ok := keyOps[value] if !ok { - return fmt.Errorf("unknown key operation") + return errors.New("unknown key operation") } *keyOperationList = append(*keyOperationList, KeyOperation(value)) } diff --git a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/jws.go b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/jws.go index 2a5fe3c173..20fb957d3e 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/jws.go +++ b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/jws.go @@ -111,7 +111,7 @@ func Verify(buf []byte, alg jwa.SignatureAlgorithm, key interface{}) (ret []byte return nil, errors.New(`attempt to verify empty buffer`) } - parts, err := SplitCompact(string(buf[:])) + parts, err := SplitCompact(string(buf)) if err != nil { return nil, fmt.Errorf("failed extract from compact serialization format: %w", err) } @@ -164,7 +164,7 @@ func VerifyWithJWKSet(buf []byte, keyset *jwk.Set) (payload []byte, err error) { // ParseByte parses a JWS value serialized via compact serialization and provided as []byte. func ParseByte(jwsCompact []byte) (m *Message, err error) { - return parseCompact(string(jwsCompact[:])) + return parseCompact(string(jwsCompact)) } // ParseString parses a JWS value serialized via compact serialization and provided as string. diff --git a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/sign.go b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/sign.go index 7db7bbd69c..fd123eb759 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/sign.go +++ b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/sign.go @@ -3,6 +3,7 @@ package sign import ( "crypto/x509" "encoding/pem" + "errors" "fmt" "github.com/open-policy-agent/opa/internal/jwx/jwa" @@ -30,7 +31,7 @@ func GetSigningKey(key string, alg jwa.SignatureAlgorithm) (interface{}, error) case jwa.RS256, jwa.RS384, jwa.RS512, jwa.PS256, jwa.PS384, jwa.PS512: block, _ := pem.Decode([]byte(key)) if block == nil { - return nil, fmt.Errorf("failed to parse PEM block containing the key") + return nil, errors.New("failed to parse PEM block containing the key") } priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) @@ -45,7 +46,7 @@ func GetSigningKey(key string, alg jwa.SignatureAlgorithm) (interface{}, error) case jwa.ES256, jwa.ES384, jwa.ES512: block, _ := pem.Decode([]byte(key)) if block == nil { - return nil, fmt.Errorf("failed to parse PEM block containing the key") + return nil, errors.New("failed to parse PEM block containing the key") } priv, err := x509.ParseECPrivateKey(block.Bytes) diff --git a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/verify.go b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/verify.go index 05720a64e0..04ee9141e9 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/verify.go +++ b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/verify.go @@ -5,6 +5,7 @@ import ( "crypto/rsa" "crypto/x509" "encoding/pem" + "errors" "fmt" "github.com/open-policy-agent/opa/internal/jwx/jwa" @@ -33,7 +34,7 @@ func GetSigningKey(key string, alg jwa.SignatureAlgorithm) (interface{}, error) case jwa.RS256, jwa.RS384, jwa.RS512, jwa.PS256, jwa.PS384, jwa.PS512, jwa.ES256, jwa.ES384, jwa.ES512: block, _ := pem.Decode([]byte(key)) if block == nil { - return nil, fmt.Errorf("failed to parse PEM block containing the key") + return nil, errors.New("failed to parse PEM block containing the key") } pub, err := x509.ParsePKIXPublicKey(block.Bytes) diff --git a/vendor/github.com/open-policy-agent/opa/internal/planner/planner.go b/vendor/github.com/open-policy-agent/opa/internal/planner/planner.go index b75d26ddab..661703e08c 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/planner/planner.go +++ b/vendor/github.com/open-policy-agent/opa/internal/planner/planner.go @@ -11,10 +11,10 @@ import ( "io" "sort" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/ast/location" "github.com/open-policy-agent/opa/internal/debug" - "github.com/open-policy-agent/opa/ir" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/ast/location" + "github.com/open-policy-agent/opa/v1/ir" ) // QuerySet represents the input to the planner. @@ -223,7 +223,7 @@ func (p *Planner) planRules(rules []*ast.Rule) (string, error) { } // Initialize parameters for functions. - for i := 0; i < len(rules[0].Head.Args); i++ { + for range len(rules[0].Head.Args) { fn.Params = append(fn.Params, p.newLocal()) } @@ -385,7 +385,7 @@ func (p *Planner) planRules(rules []*ast.Rule) (string, error) { return nil }) default: - return fmt.Errorf("illegal rule kind") + return errors.New("illegal rule kind") } }) }) @@ -497,7 +497,6 @@ func (p *Planner) planDotOr(obj ir.Local, key ir.Operand, or stmtFactory, iter p func (p *Planner) planNestedObjects(obj ir.Local, ref ast.Ref, iter planLocalIter) error { if len(ref) == 0 { - //return fmt.Errorf("nested object construction didn't create object") return iter(obj) } @@ -991,8 +990,7 @@ func (p *Planner) planExprCall(e *ast.Expr, iter planiter) error { op := e.Operator() if replacement := p.mocks.Lookup(operator); replacement != nil { - switch r := replacement.Value.(type) { - case ast.Ref: + if r, ok := replacement.Value.(ast.Ref); ok { if !r.HasPrefix(ast.DefaultRootRef) && !r.HasPrefix(ast.InputRootRef) { // replacement is builtin operator = r.String() @@ -1037,7 +1035,7 @@ func (p *Planner) planExprCall(e *ast.Expr, iter planiter) error { args = p.defaultOperands() } else if decl, ok := p.decls[operator]; ok { relation = decl.Relation - arity = len(decl.Decl.Args()) + arity = decl.Decl.Arity() void = decl.Decl.Result() == nil name = operator p.externs[operator] = decl @@ -1147,7 +1145,7 @@ func (p *Planner) planExprCallFunc(name string, arity int, void bool, operands [ }) default: - return fmt.Errorf("impossible replacement, arity mismatch") + return errors.New("impossible replacement, arity mismatch") } } @@ -1173,7 +1171,7 @@ func (p *Planner) planExprCallValue(value *ast.Term, arity int, operands []*ast. }) }) default: - return fmt.Errorf("impossible replacement, arity mismatch") + return errors.New("impossible replacement, arity mismatch") } } @@ -1519,7 +1517,7 @@ func (p *Planner) planValue(t ast.Value, loc *ast.Location, iter planiter) error p.loc = loc return p.planObjectComprehension(v, iter) default: - return fmt.Errorf("%v term not implemented", ast.TypeName(v)) + return fmt.Errorf("%v term not implemented", ast.ValueName(v)) } } @@ -1750,7 +1748,7 @@ func (p *Planner) planRef(ref ast.Ref, iter planiter) error { head, ok := ref[0].Value.(ast.Var) if !ok { - return fmt.Errorf("illegal ref: non-var head") + return errors.New("illegal ref: non-var head") } if head.Compare(ast.DefaultRootDocument.Value) == 0 { @@ -1767,7 +1765,7 @@ func (p *Planner) planRef(ref ast.Ref, iter planiter) error { p.ltarget, ok = p.vars.GetOp(head) if !ok { - return fmt.Errorf("illegal ref: unsafe head") + return errors.New("illegal ref: unsafe head") } return p.planRefRec(ref, 1, iter) @@ -2365,6 +2363,10 @@ func rewrittenVar(vars map[ast.Var]ast.Var, k ast.Var) ast.Var { return rw } +func dont() ([][]*ast.Rule, []ir.Operand, int, bool) { + return nil, nil, 0, false +} + // optimizeLookup returns a set of rulesets and required statements planning // the locals (strings) needed with the used local variables, and the index // into ref's parth that is still to be planned; if the passed ref's vars @@ -2381,9 +2383,6 @@ func rewrittenVar(vars map[ast.Var]ast.Var, k ast.Var) ast.Var { // var actually matched_ -- so we don't know which subtree to evaluate // with the results. func (p *Planner) optimizeLookup(t *ruletrie, ref ast.Ref) ([][]*ast.Rule, []ir.Operand, int, bool) { - dont := func() ([][]*ast.Rule, []ir.Operand, int, bool) { - return nil, nil, 0, false - } if t == nil { p.debugf("no optimization of %s: trie is nil", ref) return dont() @@ -2411,6 +2410,10 @@ outer: opt = true // take all children, they might match for _, node := range nodes { + if nr := node.Rules(); len(nr) > 0 { + p.debugf("no optimization of %s: node with rules (%v)", ref, refsOfRules(nr)) + return dont() + } for _, child := range node.Children() { if node := node.Get(child); node != nil { nextNodes = append(nextNodes, node) @@ -2418,8 +2421,12 @@ outer: } } case ast.String: - // take all children that either match or have a var key + // take all children that either match or have a var key // TODO(sr): Where's the code for the second part, having a var key? for _, node := range nodes { + if nr := node.Rules(); len(nr) > 0 { + p.debugf("no optimization of %s: node with rules (%v)", ref, refsOfRules(nr)) + return dont() + } if node := node.Get(r); node != nil { nextNodes = append(nextNodes, node) } @@ -2438,10 +2445,20 @@ outer: // let us break, too. all := 0 for _, node := range nodes { - all += node.ChildrenCount() + if i < len(ref)-1 { + // Look ahead one term to only count those children relevant to your planned ref. + switch ref[i+1].Value.(type) { + case ast.Var: + all += node.ChildrenCount() + default: + if relChildren := node.Get(ref[i+1].Value); relChildren != nil { + all++ + } + } + } } if all == 0 { - p.debugf("ref %s: all nodes have 0 children, break", ref[0:index+1]) + p.debugf("ref %s: all nodes have 0 relevant children, break", ref[0:index+1]) break } @@ -2550,3 +2567,11 @@ func (p *Planner) isFunction(r ast.Ref) bool { func op(v ir.Val) ir.Operand { return ir.Operand{Value: v} } + +func refsOfRules(rs []*ast.Rule) []string { + refs := make([]string, len(rs)) + for i := range rs { + refs[i] = rs[i].Head.Ref().String() + } + return refs +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/planner/rules.go b/vendor/github.com/open-policy-agent/opa/internal/planner/rules.go index f5d6f3fc6c..cc7f12bd2b 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/planner/rules.go +++ b/vendor/github.com/open-policy-agent/opa/internal/planner/rules.go @@ -4,7 +4,7 @@ import ( "fmt" "sort" - "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/v1/ast" ) // funcstack implements a simple map structure used to keep track of virtual @@ -111,7 +111,7 @@ func (t *ruletrie) Rules() []*ast.Rule { func (t *ruletrie) Push(key ast.Ref) { node := t - for i := 0; i < len(key)-1; i++ { + for i := range len(key) - 1 { node = node.Get(key[i].Value) if node == nil { return @@ -123,7 +123,7 @@ func (t *ruletrie) Push(key ast.Ref) { func (t *ruletrie) Pop(key ast.Ref) { node := t - for i := 0; i < len(key)-1; i++ { + for i := range len(key) - 1 { node = node.Get(key[i].Value) if node == nil { return diff --git a/vendor/github.com/open-policy-agent/opa/internal/planner/varstack.go b/vendor/github.com/open-policy-agent/opa/internal/planner/varstack.go index dccff1b5c1..0df6bcd8b2 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/planner/varstack.go +++ b/vendor/github.com/open-policy-agent/opa/internal/planner/varstack.go @@ -5,8 +5,8 @@ package planner import ( - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/ir" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/ir" ) type varstack []map[ast.Var]ir.Local diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/crypto/compare.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/crypto/compare.go index 1d0f25f8c2..103dc77667 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/crypto/compare.go +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/crypto/compare.go @@ -1,6 +1,6 @@ package crypto -import "fmt" +import "errors" // ConstantTimeByteCompare is a constant-time byte comparison of x and y. This function performs an absolute comparison // if the two byte slices assuming they represent a big-endian number. @@ -11,7 +11,7 @@ import "fmt" // +1 if x > y func ConstantTimeByteCompare(x, y []byte) (int, error) { if len(x) != len(y) { - return 0, fmt.Errorf("slice lengths do not match") + return 0, errors.New("slice lengths do not match") } xLarger, yLarger := 0, 0 diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/crypto/ecc.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/crypto/ecc.go index 758c73fcb3..12679a15be 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/crypto/ecc.go +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/crypto/ecc.go @@ -7,6 +7,7 @@ import ( "crypto/hmac" "encoding/asn1" "encoding/binary" + "errors" "fmt" "hash" "math" @@ -82,7 +83,7 @@ func HMACKeyDerivation(hash func() hash.Hash, bitLen int, key []byte, label, con // verify the requested bit length is not larger then the length encoding size if int64(bitLen) > 0x7FFFFFFF { - return nil, fmt.Errorf("bitLen is greater than 32-bits") + return nil, errors.New("bitLen is greater than 32-bits") } fixedInput := bytes.NewBuffer(nil) diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/ecr.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/ecr.go index 179b5b5d5e..55e587e9f5 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/ecr.go +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/ecr.go @@ -11,7 +11,7 @@ import ( "time" "github.com/open-policy-agent/opa/internal/version" - "github.com/open-policy-agent/opa/logging" + "github.com/open-policy-agent/opa/v1/logging" ) // Values taken from diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/kms.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/kms.go index 77c0bc9349..6dfb06a496 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/kms.go +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/kms.go @@ -10,7 +10,7 @@ import ( "time" "github.com/open-policy-agent/opa/internal/version" - "github.com/open-policy-agent/opa/logging" + "github.com/open-policy-agent/opa/v1/logging" ) // Values taken from diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/signing_v4.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/signing_v4.go index bfb780754b..07aa568fa2 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/signing_v4.go +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/signing_v4.go @@ -8,18 +8,19 @@ import ( "bytes" "crypto/hmac" "crypto/sha256" + "encoding/hex" "errors" "fmt" "io" "net/http" "net/url" - "sort" "strings" "time" v4 "github.com/open-policy-agent/opa/internal/providers/aws/v4" - "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/util" ) func stringFromTerm(t *ast.Term) string { @@ -67,19 +68,6 @@ func sha256MAC(message string, key []byte) []byte { return mac.Sum(nil) } -func sortKeys(strMap map[string][]string) []string { - keys := make([]string, len(strMap)) - - i := 0 - for k := range strMap { - keys[i] = k - i++ - } - sort.Strings(keys) - - return keys -} - // SignRequest modifies an http.Request to include an AWS V4 signature based on the provided credentials. func SignRequest(req *http.Request, service string, creds Credentials, theTime time.Time, sigVersion string) error { // General ref. https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html @@ -168,7 +156,7 @@ func SignV4(headers map[string][]string, method string, theURL *url.URL, body [] canonicalReq += theURL.RawQuery + "\n" // RAW Query String // include the values for the signed headers - orderedKeys := sortKeys(headersToSign) + orderedKeys := util.KeysSorted(headersToSign) for _, k := range orderedKeys { canonicalReq += k + ":" + strings.Join(headersToSign[k], ",") + "\n" } @@ -202,7 +190,7 @@ func SignV4(headers map[string][]string, method string, theURL *url.URL, body [] authHeader := "AWS4-HMAC-SHA256 Credential=" + awsCreds.AccessKey + "/" + dateNow authHeader += "/" + awsCreds.RegionName + "/" + service + "/aws4_request," authHeader += "SignedHeaders=" + headerList + "," - authHeader += "Signature=" + fmt.Sprintf("%x", signature) + authHeader += "Signature=" + hex.EncodeToString(signature) return authHeader, awsHeaders } diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/signing_v4a.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/signing_v4a.go index 929f2006e7..8f6d760e82 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/signing_v4a.go +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/signing_v4a.go @@ -9,7 +9,7 @@ import ( "crypto/rand" "crypto/sha256" "encoding/hex" - "fmt" + "errors" "hash" "io" "math/big" @@ -107,7 +107,7 @@ func deriveKeyFromAccessKeyPair(accessKey, secretKey string) (*ecdsa.PrivateKey, counter++ if counter > 0xFF { - return nil, fmt.Errorf("exhausted single byte external counter") + return nil, errors.New("exhausted single byte external counter") } } d = d.Add(d, one) @@ -146,7 +146,7 @@ func retrievePrivateKey(symmetric Credentials) (v4aCredentials, error) { privateKey, err := deriveKeyFromAccessKeyPair(symmetric.AccessKey, symmetric.SecretKey) if err != nil { - return v4aCredentials{}, fmt.Errorf("failed to derive asymmetric key from credentials") + return v4aCredentials{}, errors.New("failed to derive asymmetric key from credentials") } creds := v4aCredentials{ @@ -216,7 +216,7 @@ func (s *httpSigner) Build() (signedRequest, error) { signedHeaders, signedHeadersStr, canonicalHeaderStr := s.buildCanonicalHeaders(host, v4Internal.IgnoredHeaders, unsignedHeaders, s.Request.ContentLength) - rawQuery := strings.Replace(query.Encode(), "+", "%20", -1) + rawQuery := strings.ReplaceAll(query.Encode(), "+", "%20") canonicalURI := v4Internal.GetURIPath(req.URL) @@ -280,7 +280,7 @@ func buildAuthorizationHeader(credentialStr, signedHeadersStr, signingSignature return parts.String() } -func (s *httpSigner) buildCanonicalHeaders(host string, rule v4Internal.Rule, header http.Header, length int64) (signed http.Header, signedHeaders, canonicalHeadersStr string) { +func (*httpSigner) buildCanonicalHeaders(host string, rule v4Internal.Rule, header http.Header, length int64) (signed http.Header, signedHeaders, canonicalHeadersStr string) { signed = make(http.Header) const hostHeader = "host" @@ -314,7 +314,7 @@ func (s *httpSigner) buildCanonicalHeaders(host string, rule v4Internal.Rule, he var canonicalHeaders strings.Builder n := len(headers) const colon = ':' - for i := 0; i < n; i++ { + for i := range n { if headers[i] == hostHeader { canonicalHeaders.WriteString(hostHeader) canonicalHeaders.WriteRune(colon) diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/util.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/util.go index e033da7460..9ce9af90da 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/util.go +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/util.go @@ -5,7 +5,7 @@ import ( "io" "net/http" - "github.com/open-policy-agent/opa/logging" + "github.com/open-policy-agent/opa/v1/logging" ) // DoRequestWithClient is a convenience function to get the body of an HTTP response with diff --git a/vendor/github.com/open-policy-agent/opa/internal/ref/ref.go b/vendor/github.com/open-policy-agent/opa/internal/ref/ref.go index 6e84df4b08..173b5a3c1b 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/ref/ref.go +++ b/vendor/github.com/open-policy-agent/opa/internal/ref/ref.go @@ -9,8 +9,8 @@ import ( "errors" "strings" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/storage" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/storage" ) // ParseDataPath returns a ref from the slash separated path s rooted at data. diff --git a/vendor/github.com/open-policy-agent/opa/internal/rego/opa/options.go b/vendor/github.com/open-policy-agent/opa/internal/rego/opa/options.go index b58a05ee8e..072e37667a 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/rego/opa/options.go +++ b/vendor/github.com/open-policy-agent/opa/internal/rego/opa/options.go @@ -4,11 +4,11 @@ import ( "io" "time" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/metrics" - "github.com/open-policy-agent/opa/topdown/builtins" - "github.com/open-policy-agent/opa/topdown/cache" - "github.com/open-policy-agent/opa/topdown/print" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/metrics" + "github.com/open-policy-agent/opa/v1/topdown/builtins" + "github.com/open-policy-agent/opa/v1/topdown/cache" + "github.com/open-policy-agent/opa/v1/topdown/print" ) // Result holds the evaluation result. diff --git a/vendor/github.com/open-policy-agent/opa/internal/report/report.go b/vendor/github.com/open-policy-agent/opa/internal/report/report.go index 145d0a9465..55f4cfe210 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/report/report.go +++ b/vendor/github.com/open-policy-agent/opa/internal/report/report.go @@ -17,12 +17,12 @@ import ( "sync" "time" - "github.com/open-policy-agent/opa/keys" - "github.com/open-policy-agent/opa/logging" + "github.com/open-policy-agent/opa/v1/keys" + "github.com/open-policy-agent/opa/v1/logging" + "github.com/open-policy-agent/opa/v1/version" - "github.com/open-policy-agent/opa/plugins/rest" - "github.com/open-policy-agent/opa/util" - "github.com/open-policy-agent/opa/version" + "github.com/open-policy-agent/opa/v1/plugins/rest" + "github.com/open-policy-agent/opa/v1/util" ) // ExternalServiceURL is the base HTTP URL for a telemetry service. diff --git a/vendor/github.com/open-policy-agent/opa/internal/runtime/init/init.go b/vendor/github.com/open-policy-agent/opa/internal/runtime/init/init.go index b1a5b71577..814847a12a 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/runtime/init/init.go +++ b/vendor/github.com/open-policy-agent/opa/internal/runtime/init/init.go @@ -12,12 +12,12 @@ import ( "path/filepath" "strings" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/bundle" storedversion "github.com/open-policy-agent/opa/internal/version" - "github.com/open-policy-agent/opa/loader" - "github.com/open-policy-agent/opa/metrics" - "github.com/open-policy-agent/opa/storage" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/bundle" + "github.com/open-policy-agent/opa/v1/loader" + "github.com/open-policy-agent/opa/v1/metrics" + "github.com/open-policy-agent/opa/v1/storage" ) // InsertAndCompileOptions contains the input for the operation. @@ -53,6 +53,7 @@ func InsertAndCompile(ctx context.Context, opts InsertAndCompileOptions) (*Inser } compiler := ast.NewCompiler(). + WithDefaultRegoVersion(opts.ParserOptions.RegoVersion). SetErrorLimit(opts.MaxErrors). WithPathConflictsCheck(storage.NonEmpty(ctx, opts.Store, opts.Txn)). WithEnablePrintStatements(opts.EnablePrintStatements) diff --git a/vendor/github.com/open-policy-agent/opa/internal/strings/strings.go b/vendor/github.com/open-policy-agent/opa/internal/strings/strings.go index 08f3bf9182..f2838ac36a 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/strings/strings.go +++ b/vendor/github.com/open-policy-agent/opa/internal/strings/strings.go @@ -57,7 +57,7 @@ func TruncateFilePaths(maxIdealWidth, maxWidth int, path ...string) (map[string] } // Drop the overall length down to match our substitution - longestLocation = longestLocation - (len(lcs) - 3) + longestLocation -= (len(lcs) - 3) } return result, longestLocation diff --git a/vendor/github.com/open-policy-agent/opa/internal/strvals/parser.go b/vendor/github.com/open-policy-agent/opa/internal/strvals/parser.go index 1fc07f68c3..3b12d9526b 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/strvals/parser.go +++ b/vendor/github.com/open-policy-agent/opa/internal/strvals/parser.go @@ -31,7 +31,7 @@ var ErrNotList = errors.New("not a list") // MaxIndex is the maximum index that will be allowed by setIndex. // The default value 65536 = 1024 * 64 -var MaxIndex = 65536 +const MaxIndex = 65536 // ToYAML takes a string of arguments and converts to a YAML document. func ToYAML(s string) (string, error) { @@ -148,8 +148,6 @@ func (t *parser) key(data map[string]interface{}) error { return err } return fmt.Errorf("key %q has no value", string(k)) - //set(data, string(k), "") - //return err case last == '[': // We are in a list index context, so we need to set an index. i, err := t.keyIndex() @@ -168,7 +166,7 @@ func (t *parser) key(data map[string]interface{}) error { set(data, kk, list) return err case last == '=': - //End of key. Consume =, Get value. + // End of key. Consume =, Get value. // FIXME: Get value list first vl, e := t.valList() switch e { diff --git a/vendor/github.com/open-policy-agent/opa/internal/version/version.go b/vendor/github.com/open-policy-agent/opa/internal/version/version.go index 1c2e9ecd01..dc52733fc2 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/version/version.go +++ b/vendor/github.com/open-policy-agent/opa/internal/version/version.go @@ -10,8 +10,8 @@ import ( "fmt" "runtime" - "github.com/open-policy-agent/opa/storage" - "github.com/open-policy-agent/opa/version" + "github.com/open-policy-agent/opa/v1/storage" + "github.com/open-policy-agent/opa/v1/version" ) var versionPath = storage.MustParsePath("/system/version") diff --git a/vendor/github.com/open-policy-agent/opa/internal/wasm/encoding/reader.go b/vendor/github.com/open-policy-agent/opa/internal/wasm/encoding/reader.go index 35e6059c72..0695ce94fe 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/wasm/encoding/reader.go +++ b/vendor/github.com/open-policy-agent/opa/internal/wasm/encoding/reader.go @@ -7,6 +7,7 @@ package encoding import ( "bytes" "encoding/binary" + "errors" "fmt" "io" @@ -105,7 +106,7 @@ func readMagic(r io.Reader) error { if err := binary.Read(r, binary.LittleEndian, &v); err != nil { return err } else if v != constant.Magic { - return fmt.Errorf("illegal magic value") + return errors.New("illegal magic value") } return nil } @@ -115,7 +116,7 @@ func readVersion(r io.Reader) error { if err := binary.Read(r, binary.LittleEndian, &v); err != nil { return err } else if v != constant.Version { - return fmt.Errorf("illegal wasm version") + return errors.New("illegal wasm version") } return nil } @@ -199,7 +200,7 @@ func readSections(r io.Reader, m *module.Module) error { return fmt.Errorf("code section: %w", err) } default: - return fmt.Errorf("illegal section id") + return errors.New("illegal section id") } } } @@ -269,7 +270,7 @@ func readNameMap(r io.Reader) ([]module.NameMap, error) { return nil, err } nm := make([]module.NameMap, n) - for i := uint32(0); i < n; i++ { + for i := range n { var name string id, err := leb128.ReadVarUint32(r) if err != nil { @@ -289,7 +290,7 @@ func readNameSectionLocals(r io.Reader, s *module.NameSection) error { if err != nil { return err } - for i := uint32(0); i < n; i++ { + for range n { id, err := leb128.ReadVarUint32(r) // func index if err != nil { return err @@ -326,7 +327,7 @@ func readTypeSection(r io.Reader, s *module.TypeSection) error { return err } - for i := uint32(0); i < n; i++ { + for range n { var ftype module.FunctionType if err := readFunctionType(r, &ftype); err != nil { @@ -346,7 +347,7 @@ func readImportSection(r io.Reader, s *module.ImportSection) error { return err } - for i := uint32(0); i < n; i++ { + for range n { var imp module.Import @@ -367,14 +368,14 @@ func readTableSection(r io.Reader, s *module.TableSection) error { return err } - for i := uint32(0); i < n; i++ { + for range n { var table module.Table if elem, err := readByte(r); err != nil { return err } else if elem != constant.ElementTypeAnyFunc { - return fmt.Errorf("illegal element type") + return errors.New("illegal element type") } table.Type = types.Anyfunc @@ -396,7 +397,7 @@ func readMemorySection(r io.Reader, s *module.MemorySection) error { return err } - for i := uint32(0); i < n; i++ { + for range n { var mem module.Memory @@ -417,7 +418,7 @@ func readGlobalSection(r io.Reader, s *module.GlobalSection) error { return err } - for i := uint32(0); i < n; i++ { + for range n { var global module.Global @@ -442,7 +443,7 @@ func readExportSection(r io.Reader, s *module.ExportSection) error { return err } - for i := uint32(0); i < n; i++ { + for range n { var exp module.Export @@ -463,7 +464,7 @@ func readElementSection(r io.Reader, s *module.ElementSection) error { return err } - for i := uint32(0); i < n; i++ { + for range n { var seg module.ElementSegment @@ -484,7 +485,7 @@ func readDataSection(r io.Reader, s *module.DataSection) error { return err } - for i := uint32(0); i < n; i++ { + for range n { var seg module.DataSegment @@ -505,7 +506,7 @@ func readRawCodeSection(r io.Reader, s *module.RawCodeSection) error { return err } - for i := uint32(0); i < n; i++ { + for range n { var seg module.RawCodeSegment if err := readRawCodeSegment(r, &seg); err != nil { @@ -547,7 +548,7 @@ func readGlobal(r io.Reader, global *module.Global) error { if b == 1 { global.Mutable = true } else if b != 0 { - return fmt.Errorf("illegal mutability flag") + return errors.New("illegal mutability flag") } return readConstantExpr(r, &global.Init) @@ -584,7 +585,7 @@ func readImport(r io.Reader, imp *module.Import) error { if elem, err := readByte(r); err != nil { return err } else if elem != constant.ElementTypeAnyFunc { - return fmt.Errorf("illegal element type") + return errors.New("illegal element type") } desc := module.TableImport{ Type: types.Anyfunc, @@ -617,12 +618,12 @@ func readImport(r io.Reader, imp *module.Import) error { if b == 1 { desc.Mutable = true } else if b != 0 { - return fmt.Errorf("illegal mutability flag") + return errors.New("illegal mutability flag") } return nil } - return fmt.Errorf("illegal import descriptor type") + return errors.New("illegal import descriptor type") } func readExport(r io.Reader, exp *module.Export) error { @@ -646,7 +647,7 @@ func readExport(r io.Reader, exp *module.Export) error { case constant.ExportDescGlobal: exp.Descriptor.Type = module.GlobalExportType default: - return fmt.Errorf("illegal export descriptor type") + return errors.New("illegal export descriptor type") } exp.Descriptor.Index, err = leb128.ReadVarUint32(r) @@ -727,7 +728,7 @@ func readExpr(r io.Reader, expr *module.Expr) (err error) { case error: err = r default: - err = fmt.Errorf("unknown panic") + err = errors.New("unknown panic") } } }() @@ -809,21 +810,21 @@ func readLimits(r io.Reader, l *module.Limit) error { return err } - min, err := leb128.ReadVarUint32(r) + minLim, err := leb128.ReadVarUint32(r) if err != nil { return err } - l.Min = min + l.Min = minLim if b == 1 { - max, err := leb128.ReadVarUint32(r) + maxLim, err := leb128.ReadVarUint32(r) if err != nil { return err } - l.Max = &max + l.Max = &maxLim } else if b != 0 { - return fmt.Errorf("illegal limit flag") + return errors.New("illegal limit flag") } return nil @@ -838,7 +839,7 @@ func readLocals(r io.Reader, locals *[]module.LocalDeclaration) error { ret := make([]module.LocalDeclaration, n) - for i := uint32(0); i < n; i++ { + for i := range n { if err := readVarUint32(r, &ret[i].Count); err != nil { return err } @@ -888,7 +889,7 @@ func readVarUint32Vector(r io.Reader, v *[]uint32) error { ret := make([]uint32, n) - for i := uint32(0); i < n; i++ { + for i := range n { if err := readVarUint32(r, &ret[i]); err != nil { return err } @@ -907,7 +908,7 @@ func readValueTypeVector(r io.Reader, v *[]types.ValueType) error { ret := make([]types.ValueType, n) - for i := uint32(0); i < n; i++ { + for i := range n { if err := readValueType(r, &ret[i]); err != nil { return err } diff --git a/vendor/github.com/open-policy-agent/opa/internal/wasm/encoding/writer.go b/vendor/github.com/open-policy-agent/opa/internal/wasm/encoding/writer.go index 6917b8d1d1..19df3bd6e6 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/wasm/encoding/writer.go +++ b/vendor/github.com/open-policy-agent/opa/internal/wasm/encoding/writer.go @@ -7,6 +7,7 @@ package encoding import ( "bytes" "encoding/binary" + "errors" "fmt" "io" "math" @@ -260,7 +261,7 @@ func writeTableSection(w io.Writer, s module.TableSection) error { return err } default: - return fmt.Errorf("illegal table element type") + return errors.New("illegal table element type") } if err := writeLimits(&buf, table.Lim); err != nil { return err @@ -588,7 +589,7 @@ func writeImport(w io.Writer, imp module.Import) error { } return writeByte(w, constant.Const) default: - return fmt.Errorf("illegal import descriptor type") + return errors.New("illegal import descriptor type") } } diff --git a/vendor/github.com/open-policy-agent/opa/internal/wasm/module/module.go b/vendor/github.com/open-policy-agent/opa/internal/wasm/module/module.go index 913863c10c..033d429c89 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/wasm/module/module.go +++ b/vendor/github.com/open-policy-agent/opa/internal/wasm/module/module.go @@ -288,7 +288,7 @@ func (x ExportDescriptorType) String() string { } // Kind returns the function import type kind. -func (i FunctionImport) Kind() ImportDescriptorType { +func (FunctionImport) Kind() ImportDescriptorType { return FunctionImportType } @@ -297,7 +297,7 @@ func (i FunctionImport) String() string { } // Kind returns the memory import type kind. -func (i MemoryImport) Kind() ImportDescriptorType { +func (MemoryImport) Kind() ImportDescriptorType { return MemoryImportType } @@ -306,7 +306,7 @@ func (i MemoryImport) String() string { } // Kind returns the table import type kind. -func (i TableImport) Kind() ImportDescriptorType { +func (TableImport) Kind() ImportDescriptorType { return TableImportType } @@ -315,7 +315,7 @@ func (i TableImport) String() string { } // Kind returns the global import type kind. -func (i GlobalImport) Kind() ImportDescriptorType { +func (GlobalImport) Kind() ImportDescriptorType { return GlobalImportType } diff --git a/vendor/github.com/open-policy-agent/opa/topdown/type_name.go b/vendor/github.com/open-policy-agent/opa/topdown/type_name.go deleted file mode 100644 index 0a8b44aed3..0000000000 --- a/vendor/github.com/open-policy-agent/opa/topdown/type_name.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2018 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 topdown - -import ( - "fmt" - - "github.com/open-policy-agent/opa/ast" -) - -func builtinTypeName(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - switch operands[0].Value.(type) { - case ast.Null: - return iter(ast.StringTerm("null")) - case ast.Boolean: - return iter(ast.StringTerm("boolean")) - case ast.Number: - return iter(ast.StringTerm("number")) - case ast.String: - return iter(ast.StringTerm("string")) - case *ast.Array: - return iter(ast.StringTerm("array")) - case ast.Object: - return iter(ast.StringTerm("object")) - case ast.Set: - return iter(ast.StringTerm("set")) - } - - return fmt.Errorf("illegal value") -} - -func init() { - RegisterBuiltinFunc(ast.TypeNameBuiltin.Name, builtinTypeName) -} diff --git a/vendor/github.com/open-policy-agent/opa/util/backoff.go b/vendor/github.com/open-policy-agent/opa/util/backoff.go deleted file mode 100644 index 6fbf63ef77..0000000000 --- a/vendor/github.com/open-policy-agent/opa/util/backoff.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2018 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 util - -import ( - "math/rand" - "time" -) - -func init() { - // NOTE(sr): We don't need good random numbers here; it's used for jittering - // the backup timing a bit. But anyways, let's make it random enough; without - // a call to rand.Seed() we'd get the same stream of numbers for each program - // run. (Or not, if some other packages happens to seed the global randomness - // source.) - // Note(philipc): rand.Seed() was deprecated in Go 1.20, so we've switched to - // using the recommended rand.New(rand.NewSource(seed)) style. - rand.New(rand.NewSource(time.Now().UnixNano())) -} - -// DefaultBackoff returns a delay with an exponential backoff based on the -// number of retries. -func DefaultBackoff(base, max float64, retries int) time.Duration { - return Backoff(base, max, .2, 1.6, retries) -} - -// Backoff returns a delay with an exponential backoff based on the number of -// retries. Same algorithm used in gRPC. -func Backoff(base, max, jitter, factor float64, retries int) time.Duration { - if retries == 0 { - return 0 - } - - backoff, max := base, max - for backoff < max && retries > 0 { - backoff *= factor - retries-- - } - if backoff > max { - backoff = max - } - - // Randomize backoff delays so that if a cluster of requests start at - // the same time, they won't operate in lockstep. - backoff *= 1 + jitter*(rand.Float64()*2-1) - if backoff < 0 { - return 0 - } - - return time.Duration(backoff) -} diff --git a/vendor/github.com/open-policy-agent/opa/util/hashmap.go b/vendor/github.com/open-policy-agent/opa/util/hashmap.go deleted file mode 100644 index 8875a6323e..0000000000 --- a/vendor/github.com/open-policy-agent/opa/util/hashmap.go +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2016 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 util - -import ( - "fmt" - "strings" -) - -// T is a concise way to refer to T. -type T interface{} - -type hashEntry struct { - k T - v T - next *hashEntry -} - -// HashMap represents a key/value map. -type HashMap struct { - eq func(T, T) bool - hash func(T) int - table map[int]*hashEntry - size int -} - -// NewHashMap returns a new empty HashMap. -func NewHashMap(eq func(T, T) bool, hash func(T) int) *HashMap { - return &HashMap{ - eq: eq, - hash: hash, - table: make(map[int]*hashEntry), - size: 0, - } -} - -// Copy returns a shallow copy of this HashMap. -func (h *HashMap) Copy() *HashMap { - cpy := NewHashMap(h.eq, h.hash) - h.Iter(func(k, v T) bool { - cpy.Put(k, v) - return false - }) - return cpy -} - -// Equal returns true if this HashMap equals the other HashMap. -// Two hash maps are equal if they contain the same key/value pairs. -func (h *HashMap) Equal(other *HashMap) bool { - if h.Len() != other.Len() { - return false - } - return !h.Iter(func(k, v T) bool { - ov, ok := other.Get(k) - if !ok { - return true - } - return !h.eq(v, ov) - }) -} - -// Get returns the value for k. -func (h *HashMap) Get(k T) (T, bool) { - hash := h.hash(k) - for entry := h.table[hash]; entry != nil; entry = entry.next { - if h.eq(entry.k, k) { - return entry.v, true - } - } - return nil, false -} - -// Delete removes the key k. -func (h *HashMap) Delete(k T) { - hash := h.hash(k) - var prev *hashEntry - for entry := h.table[hash]; entry != nil; entry = entry.next { - if h.eq(entry.k, k) { - if prev != nil { - prev.next = entry.next - } else { - h.table[hash] = entry.next - } - h.size-- - return - } - prev = entry - } -} - -// Hash returns the hash code for this hash map. -func (h *HashMap) Hash() int { - var hash int - h.Iter(func(k, v T) bool { - hash += h.hash(k) + h.hash(v) - return false - }) - return hash -} - -// Iter invokes the iter function for each element in the HashMap. -// If the iter function returns true, iteration stops and the return value is true. -// If the iter function never returns true, iteration proceeds through all elements -// and the return value is false. -func (h *HashMap) Iter(iter func(T, T) bool) bool { - for _, entry := range h.table { - for ; entry != nil; entry = entry.next { - if iter(entry.k, entry.v) { - return true - } - } - } - return false -} - -// Len returns the current size of this HashMap. -func (h *HashMap) Len() int { - return h.size -} - -// Put inserts a key/value pair into this HashMap. If the key is already present, the existing -// value is overwritten. -func (h *HashMap) Put(k T, v T) { - hash := h.hash(k) - head := h.table[hash] - for entry := head; entry != nil; entry = entry.next { - if h.eq(entry.k, k) { - entry.v = v - return - } - } - h.table[hash] = &hashEntry{k: k, v: v, next: head} - h.size++ -} - -func (h *HashMap) String() string { - var buf []string - h.Iter(func(k T, v T) bool { - buf = append(buf, fmt.Sprintf("%v: %v", k, v)) - return false - }) - return "{" + strings.Join(buf, ", ") + "}" -} - -// Update returns a new HashMap with elements from the other HashMap put into this HashMap. -// If the other HashMap contains elements with the same key as this HashMap, the value -// from the other HashMap overwrites the value from this HashMap. -func (h *HashMap) Update(other *HashMap) *HashMap { - updated := h.Copy() - other.Iter(func(k, v T) bool { - updated.Put(k, v) - return false - }) - return updated -} diff --git a/vendor/github.com/open-policy-agent/opa/util/maps.go b/vendor/github.com/open-policy-agent/opa/util/maps.go deleted file mode 100644 index d943b4d0a8..0000000000 --- a/vendor/github.com/open-policy-agent/opa/util/maps.go +++ /dev/null @@ -1,10 +0,0 @@ -package util - -// Values returns a slice of values from any map. Copied from golang.org/x/exp/maps. -func Values[M ~map[K]V, K comparable, V any](m M) []V { - r := make([]V, 0, len(m)) - for _, v := range m { - r = append(r, v) - } - return r -} diff --git a/vendor/github.com/open-policy-agent/opa/ast/annotations.go b/vendor/github.com/open-policy-agent/opa/v1/ast/annotations.go similarity index 86% rename from vendor/github.com/open-policy-agent/opa/ast/annotations.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/annotations.go index d6267a0e64..def7604edf 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/annotations.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/annotations.go @@ -8,22 +8,42 @@ import ( "encoding/json" "fmt" "net/url" - "sort" + "slices" "strings" - astJSON "github.com/open-policy-agent/opa/ast/json" "github.com/open-policy-agent/opa/internal/deepcopy" - "github.com/open-policy-agent/opa/util" + astJSON "github.com/open-policy-agent/opa/v1/ast/json" + "github.com/open-policy-agent/opa/v1/util" ) const ( annotationScopePackage = "package" - annotationScopeImport = "import" annotationScopeRule = "rule" annotationScopeDocument = "document" annotationScopeSubpackages = "subpackages" ) +var ( + scopeTerm = StringTerm("scope") + titleTerm = StringTerm("title") + entrypointTerm = StringTerm("entrypoint") + descriptionTerm = StringTerm("description") + organizationsTerm = StringTerm("organizations") + authorsTerm = StringTerm("authors") + relatedResourcesTerm = StringTerm("related_resources") + schemasTerm = StringTerm("schemas") + customTerm = StringTerm("custom") + refTerm = StringTerm("ref") + nameTerm = StringTerm("name") + emailTerm = StringTerm("email") + schemaTerm = StringTerm("schema") + definitionTerm = StringTerm("definition") + documentTerm = StringTerm(annotationScopeDocument) + packageTerm = StringTerm(annotationScopePackage) + ruleTerm = StringTerm(annotationScopeRule) + subpackagesTerm = StringTerm(annotationScopeSubpackages) +) + type ( // Annotations represents metadata attached to other AST nodes such as rules. Annotations struct { @@ -38,9 +58,8 @@ type ( Custom map[string]interface{} `json:"custom,omitempty"` Location *Location `json:"location,omitempty"` - comments []*Comment - node Node - jsonOptions astJSON.Options + comments []*Comment + node Node } // SchemaAnnotation contains a schema declaration for the document identified by the path. @@ -77,8 +96,6 @@ type ( Annotations *Annotations `json:"annotations,omitempty"` Location *Location `json:"location,omitempty"` // The location of the node the annotations are applied to - jsonOptions astJSON.Options - node Node // The node the annotations are applied to } @@ -181,13 +198,6 @@ func (a *Annotations) GetTargetPath() Ref { } } -func (a *Annotations) setJSONOptions(opts astJSON.Options) { - a.jsonOptions = opts - if a.Location != nil { - a.Location.JSONOptions = opts - } -} - func (a *Annotations) MarshalJSON() ([]byte, error) { if a == nil { return []byte(`{"scope":""}`), nil @@ -229,7 +239,7 @@ func (a *Annotations) MarshalJSON() ([]byte, error) { data["custom"] = a.Custom } - if a.jsonOptions.MarshalOptions.IncludeLocation.Annotations { + if astJSON.GetOptions().MarshalOptions.IncludeLocation.Annotations { if a.Location != nil { data["location"] = a.Location } @@ -249,7 +259,6 @@ func NewAnnotationsRef(a *Annotations) *AnnotationsRef { Path: a.GetTargetPath(), Annotations: a, node: a.node, - jsonOptions: a.jsonOptions, } } @@ -282,17 +291,26 @@ func (ar *AnnotationsRef) MarshalJSON() ([]byte, error) { data["annotations"] = ar.Annotations } - if ar.jsonOptions.MarshalOptions.IncludeLocation.AnnotationsRef { + if astJSON.GetOptions().MarshalOptions.IncludeLocation.AnnotationsRef { if ar.Location != nil { data["location"] = ar.Location } + + // The location set for the schema ref terms is wrong (always set to + // row 1) and not really useful anyway.. so strip it out before marshalling + for _, schema := range ar.Annotations.Schemas { + if schema.Path != nil { + for _, term := range schema.Path { + term.Location = nil + } + } + } } return json.Marshal(data) } func scopeCompare(s1, s2 string) int { - o1 := scopeOrder(s1) o2 := scopeOrder(s2) @@ -312,8 +330,7 @@ func scopeCompare(s1, s2 string) int { } func scopeOrder(s string) int { - switch s { - case annotationScopeRule: + if s == annotationScopeRule { return 1 } return 0 @@ -326,7 +343,7 @@ func compareAuthors(a, b []*AuthorAnnotation) int { return -1 } - for i := 0; i < len(a); i++ { + for i := range a { if cmp := a[i].Compare(b[i]); cmp != 0 { return cmp } @@ -342,8 +359,8 @@ func compareRelatedResources(a, b []*RelatedResourceAnnotation) int { return -1 } - for i := 0; i < len(a); i++ { - if cmp := strings.Compare(a[i].String(), b[i].String()); cmp != 0 { + for i := range a { + if cmp := a[i].Compare(b[i]); cmp != 0 { return cmp } } @@ -357,7 +374,7 @@ func compareSchemas(a, b []*SchemaAnnotation) int { maxLen = len(b) } - for i := 0; i < maxLen; i++ { + for i := range maxLen { if cmp := a[i].Compare(b[i]); cmp != 0 { return cmp } @@ -379,7 +396,7 @@ func compareStringLists(a, b []string) int { return -1 } - for i := 0; i < len(a); i++ { + for i := range a { if cmp := strings.Compare(a[i], b[i]); cmp != 0 { return cmp } @@ -410,7 +427,9 @@ func (a *Annotations) Copy(node Node) *Annotations { cpy.Schemas[i] = a.Schemas[i].Copy() } - cpy.Custom = deepcopy.Map(a.Custom) + if a.Custom != nil { + cpy.Custom = deepcopy.Map(a.Custom) + } cpy.node = node @@ -426,19 +445,30 @@ func (a *Annotations) toObject() (*Object, *Error) { } if len(a.Scope) > 0 { - obj.Insert(StringTerm("scope"), StringTerm(a.Scope)) + switch a.Scope { + case annotationScopeDocument: + obj.Insert(scopeTerm, documentTerm) + case annotationScopePackage: + obj.Insert(scopeTerm, packageTerm) + case annotationScopeRule: + obj.Insert(scopeTerm, ruleTerm) + case annotationScopeSubpackages: + obj.Insert(scopeTerm, subpackagesTerm) + default: + obj.Insert(scopeTerm, StringTerm(a.Scope)) + } } if len(a.Title) > 0 { - obj.Insert(StringTerm("title"), StringTerm(a.Title)) + obj.Insert(titleTerm, StringTerm(a.Title)) } if a.Entrypoint { - obj.Insert(StringTerm("entrypoint"), BooleanTerm(true)) + obj.Insert(entrypointTerm, InternedBooleanTerm(true)) } if len(a.Description) > 0 { - obj.Insert(StringTerm("description"), StringTerm(a.Description)) + obj.Insert(descriptionTerm, StringTerm(a.Description)) } if len(a.Organizations) > 0 { @@ -446,19 +476,19 @@ func (a *Annotations) toObject() (*Object, *Error) { for _, org := range a.Organizations { orgs = append(orgs, StringTerm(org)) } - obj.Insert(StringTerm("organizations"), ArrayTerm(orgs...)) + obj.Insert(organizationsTerm, ArrayTerm(orgs...)) } if len(a.RelatedResources) > 0 { rrs := make([]*Term, 0, len(a.RelatedResources)) for _, rr := range a.RelatedResources { - rrObj := NewObject(Item(StringTerm("ref"), StringTerm(rr.Ref.String()))) + rrObj := NewObject(Item(refTerm, StringTerm(rr.Ref.String()))) if len(rr.Description) > 0 { - rrObj.Insert(StringTerm("description"), StringTerm(rr.Description)) + rrObj.Insert(descriptionTerm, StringTerm(rr.Description)) } rrs = append(rrs, NewTerm(rrObj)) } - obj.Insert(StringTerm("related_resources"), ArrayTerm(rrs...)) + obj.Insert(relatedResourcesTerm, ArrayTerm(rrs...)) } if len(a.Authors) > 0 { @@ -466,14 +496,14 @@ func (a *Annotations) toObject() (*Object, *Error) { for _, author := range a.Authors { aObj := NewObject() if len(author.Name) > 0 { - aObj.Insert(StringTerm("name"), StringTerm(author.Name)) + aObj.Insert(nameTerm, StringTerm(author.Name)) } if len(author.Email) > 0 { - aObj.Insert(StringTerm("email"), StringTerm(author.Email)) + aObj.Insert(emailTerm, StringTerm(author.Email)) } as = append(as, NewTerm(aObj)) } - obj.Insert(StringTerm("authors"), ArrayTerm(as...)) + obj.Insert(authorsTerm, ArrayTerm(as...)) } if len(a.Schemas) > 0 { @@ -481,21 +511,21 @@ func (a *Annotations) toObject() (*Object, *Error) { for _, s := range a.Schemas { sObj := NewObject() if len(s.Path) > 0 { - sObj.Insert(StringTerm("path"), NewTerm(s.Path.toArray())) + sObj.Insert(pathTerm, NewTerm(s.Path.toArray())) } if len(s.Schema) > 0 { - sObj.Insert(StringTerm("schema"), NewTerm(s.Schema.toArray())) + sObj.Insert(schemaTerm, NewTerm(s.Schema.toArray())) } if s.Definition != nil { def, err := InterfaceToValue(s.Definition) if err != nil { return nil, NewError(CompileErr, a.Location, "invalid definition in schema annotation: %s", err.Error()) } - sObj.Insert(StringTerm("definition"), NewTerm(def)) + sObj.Insert(definitionTerm, NewTerm(def)) } ss = append(ss, NewTerm(sObj)) } - obj.Insert(StringTerm("schemas"), ArrayTerm(ss...)) + obj.Insert(schemasTerm, ArrayTerm(ss...)) } if len(a.Custom) > 0 { @@ -503,7 +533,7 @@ func (a *Annotations) toObject() (*Object, *Error) { if err != nil { return nil, NewError(CompileErr, a.Location, "invalid custom annotation %s", err.Error()) } - obj.Insert(StringTerm("custom"), NewTerm(c)) + obj.Insert(customTerm, NewTerm(c)) } return &obj, nil @@ -564,7 +594,11 @@ func attachAnnotationsNodes(mod *Module) Errors { case *Package: a.Scope = annotationScopePackage case *Import: - a.Scope = annotationScopeImport + // Note that this isn't a valid scope, but set here so that the + // validate function called below can print an error message with + // a context that makes sense ("invalid scope: 'import'" instead of + // "invalid scope: '') + a.Scope = "import" } } @@ -682,7 +716,6 @@ func (s *SchemaAnnotation) Copy() *SchemaAnnotation { // 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 } @@ -820,9 +853,7 @@ func (as *AnnotationSet) Flatten() FlatAnnotationsRefSet { } // Sort by path, then annotation location, for stable output - sort.SliceStable(refs, func(i, j int) bool { - return refs[i].Compare(refs[j]) < 0 - }) + slices.SortStableFunc(refs, (*AnnotationsRef).Compare) return refs } @@ -854,8 +885,8 @@ func (as *AnnotationSet) Chain(rule *Rule) AnnotationsRefSet { if len(refs) > 1 { // Sort by annotation location; chain must start with annotations declared closest to rule, then going outward - sort.SliceStable(refs, func(i, j int) bool { - return refs[i].Annotations.Location.Compare(refs[j].Annotations.Location) > 0 + slices.SortStableFunc(refs, func(a, b *AnnotationsRef) int { + return -a.Annotations.Location.Compare(b.Annotations.Location) }) } diff --git a/vendor/github.com/open-policy-agent/opa/ast/builtins.go b/vendor/github.com/open-policy-agent/opa/v1/ast/builtins.go similarity index 89% rename from vendor/github.com/open-policy-agent/opa/ast/builtins.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/builtins.go index f54d91d317..32ab2d153f 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/builtins.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/builtins.go @@ -7,7 +7,7 @@ package ast import ( "strings" - "github.com/open-policy-agent/opa/types" + "github.com/open-policy-agent/opa/v1/types" ) // Builtins is the registry of built-in functions supported by OPA. @@ -299,6 +299,9 @@ var DefaultBuiltins = [...]*Builtin{ // Printing Print, InternalPrint, + + // Testing + InternalTestCase, } // BuiltinMap provides a convenient mapping of built-in names to @@ -486,10 +489,10 @@ var Minus = &Builtin{ Description: "Minus subtracts the second number from the first number or computes the difference between two sets.", Decl: types.NewFunction( types.Args( - types.Named("x", types.NewAny(types.N, types.NewSet(types.A))), - types.Named("y", types.NewAny(types.N, types.NewSet(types.A))), + types.Named("x", types.NewAny(types.N, types.SetOfAny)), + types.Named("y", types.NewAny(types.N, types.SetOfAny)), ), - types.Named("z", types.NewAny(types.N, types.NewSet(types.A))).Description("the difference of `x` and `y`"), + types.Named("z", types.NewAny(types.N, types.SetOfAny)).Description("the difference of `x` and `y`"), ), Categories: category("sets", "numbers"), } @@ -563,7 +566,7 @@ var Abs = &Builtin{ Description: "Returns the number without its sign.", Decl: types.NewFunction( types.Args( - types.Named("x", types.N), + types.Named("x", types.N).Description("the number to take the absolute value of"), ), types.Named("y", types.N).Description("the absolute value of `x`"), ), @@ -593,10 +596,10 @@ var BitsOr = &Builtin{ Description: "Returns the bitwise \"OR\" of two integers.", Decl: types.NewFunction( types.Args( - types.Named("x", types.N), - types.Named("y", types.N), + types.Named("x", types.N).Description("the first integer"), + types.Named("y", types.N).Description("the second integer"), ), - types.Named("z", types.N), + types.Named("z", types.N).Description("the bitwise OR of `x` and `y`"), ), } @@ -605,10 +608,10 @@ var BitsAnd = &Builtin{ Description: "Returns the bitwise \"AND\" of two integers.", Decl: types.NewFunction( types.Args( - types.Named("x", types.N), - types.Named("y", types.N), + types.Named("x", types.N).Description("the first integer"), + types.Named("y", types.N).Description("the second integer"), ), - types.Named("z", types.N), + types.Named("z", types.N).Description("the bitwise AND of `x` and `y`"), ), } @@ -617,9 +620,9 @@ var BitsNegate = &Builtin{ Description: "Returns the bitwise negation (flip) of an integer.", Decl: types.NewFunction( types.Args( - types.Named("x", types.N), + types.Named("x", types.N).Description("the integer to negate"), ), - types.Named("z", types.N), + types.Named("z", types.N).Description("the bitwise negation of `x`"), ), } @@ -628,10 +631,10 @@ var BitsXOr = &Builtin{ Description: "Returns the bitwise \"XOR\" (exclusive-or) of two integers.", Decl: types.NewFunction( types.Args( - types.Named("x", types.N), - types.Named("y", types.N), + types.Named("x", types.N).Description("the first integer"), + types.Named("y", types.N).Description("the second integer"), ), - types.Named("z", types.N), + types.Named("z", types.N).Description("the bitwise XOR of `x` and `y`"), ), } @@ -640,10 +643,10 @@ var BitsShiftLeft = &Builtin{ Description: "Returns a new integer with its bits shifted `s` bits to the left.", Decl: types.NewFunction( types.Args( - types.Named("x", types.N), - types.Named("s", types.N), + types.Named("x", types.N).Description("the integer to shift"), + types.Named("s", types.N).Description("the number of bits to shift"), ), - types.Named("z", types.N), + types.Named("z", types.N).Description("the result of shifting `x` `s` bits to the left"), ), } @@ -652,10 +655,10 @@ var BitsShiftRight = &Builtin{ Description: "Returns a new integer with its bits shifted `s` bits to the right.", Decl: types.NewFunction( types.Args( - types.Named("x", types.N), - types.Named("s", types.N), + types.Named("x", types.N).Description("the integer to shift"), + types.Named("s", types.N).Description("the number of bits to shift"), ), - types.Named("z", types.N), + types.Named("z", types.N).Description("the result of shifting `x` `s` bits to the right"), ), } @@ -671,10 +674,10 @@ var And = &Builtin{ Description: "Returns the intersection of two sets.", Decl: types.NewFunction( types.Args( - types.Named("x", types.NewSet(types.A)), - types.Named("y", types.NewSet(types.A)), + types.Named("x", types.SetOfAny).Description("the first set"), + types.Named("y", types.SetOfAny).Description("the second set"), ), - types.Named("z", types.NewSet(types.A)).Description("the intersection of `x` and `y`"), + types.Named("z", types.SetOfAny).Description("the intersection of `x` and `y`"), ), Categories: sets, } @@ -686,10 +689,10 @@ var Or = &Builtin{ Description: "Returns the union of two sets.", Decl: types.NewFunction( types.Args( - types.Named("x", types.NewSet(types.A)), - types.Named("y", types.NewSet(types.A)), + types.Named("x", types.SetOfAny), + types.Named("y", types.SetOfAny), ), - types.Named("z", types.NewSet(types.A)).Description("the union of `x` and `y`"), + types.Named("z", types.SetOfAny).Description("the union of `x` and `y`"), ), Categories: sets, } @@ -699,9 +702,9 @@ var Intersection = &Builtin{ Description: "Returns the intersection of the given input sets.", Decl: types.NewFunction( types.Args( - types.Named("xs", types.NewSet(types.NewSet(types.A))).Description("set of sets to intersect"), + types.Named("xs", types.NewSet(types.SetOfAny)).Description("set of sets to intersect"), ), - types.Named("y", types.NewSet(types.A)).Description("the intersection of all `xs` sets"), + types.Named("y", types.SetOfAny).Description("the intersection of all `xs` sets"), ), Categories: sets, } @@ -711,9 +714,9 @@ var Union = &Builtin{ Description: "Returns the union of the given input sets.", Decl: types.NewFunction( types.Args( - types.Named("xs", types.NewSet(types.NewSet(types.A))).Description("set of sets to merge"), + types.Named("xs", types.NewSet(types.SetOfAny)).Description("set of sets to merge"), ), - types.Named("y", types.NewSet(types.A)).Description("the union of all `xs` sets"), + types.Named("y", types.SetOfAny).Description("the union of all `xs` sets"), ), Categories: sets, } @@ -730,7 +733,7 @@ var Count = &Builtin{ Decl: types.NewFunction( types.Args( types.Named("collection", types.NewAny( - types.NewSet(types.A), + types.SetOfAny, types.NewArray(nil, types.A), types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)), types.S, @@ -747,9 +750,9 @@ var Sum = &Builtin{ Decl: types.NewFunction( types.Args( types.Named("collection", types.NewAny( - types.NewSet(types.N), + types.SetOfNum, types.NewArray(nil, types.N), - )), + )).Description("the set or array of numbers to sum"), ), types.Named("n", types.N).Description("the sum of all elements"), ), @@ -758,13 +761,13 @@ var Sum = &Builtin{ var Product = &Builtin{ Name: "product", - Description: "Muliplies elements of an array or set of numbers", + Description: "Multiplies elements of an array or set of numbers", Decl: types.NewFunction( types.Args( types.Named("collection", types.NewAny( - types.NewSet(types.N), + types.SetOfNum, types.NewArray(nil, types.N), - )), + )).Description("the set or array of numbers to multiply"), ), types.Named("n", types.N).Description("the product of all elements"), ), @@ -777,9 +780,9 @@ var Max = &Builtin{ Decl: types.NewFunction( types.Args( types.Named("collection", types.NewAny( - types.NewSet(types.A), + types.SetOfAny, types.NewArray(nil, types.A), - )), + )).Description("the set or array to be searched"), ), types.Named("n", types.A).Description("the maximum of all elements"), ), @@ -792,9 +795,9 @@ var Min = &Builtin{ Decl: types.NewFunction( types.Args( types.Named("collection", types.NewAny( - types.NewSet(types.A), + types.SetOfAny, types.NewArray(nil, types.A), - )), + )).Description("the set or array to be searched"), ), types.Named("n", types.A).Description("the minimum of all elements"), ), @@ -812,7 +815,7 @@ var Sort = &Builtin{ types.Args( types.Named("collection", types.NewAny( types.NewArray(nil, types.A), - types.NewSet(types.A), + types.SetOfAny, )).Description("the array or set to be sorted"), ), types.Named("n", types.NewArray(nil, types.A)).Description("the sorted array"), @@ -829,8 +832,8 @@ var ArrayConcat = &Builtin{ Description: "Concatenates two arrays.", Decl: types.NewFunction( types.Args( - types.Named("x", types.NewArray(nil, types.A)), - types.Named("y", types.NewArray(nil, types.A)), + types.Named("x", types.NewArray(nil, types.A)).Description("the first array"), + types.Named("y", types.NewArray(nil, types.A)).Description("the second array"), ), types.Named("z", types.NewArray(nil, types.A)).Description("the concatenation of `x` and `y`"), ), @@ -842,8 +845,8 @@ var ArraySlice = &Builtin{ Decl: types.NewFunction( types.Args( types.Named("arr", types.NewArray(nil, types.A)).Description("the array to be sliced"), - types.Named("start", types.NewNumber()).Description("the start index of the returned slice; if less than zero, it's clamped to 0"), - types.Named("stop", types.NewNumber()).Description("the stop index of the returned slice; if larger than `count(arr)`, it's clamped to `count(arr)`"), + types.Named("start", types.N).Description("the start index of the returned slice; if less than zero, it's clamped to 0"), + types.Named("stop", types.N).Description("the stop index of the returned slice; if larger than `count(arr)`, it's clamped to `count(arr)`"), ), types.Named("slice", types.NewArray(nil, types.A)).Description("the subslice of `array`, from `start` to `end`, including `arr[start]`, but excluding `arr[end]`"), ), @@ -875,9 +878,9 @@ var ToNumber = &Builtin{ types.S, types.B, types.NewNull(), - )), + )).Description("value to convert"), ), - types.Named("num", types.N), + types.Named("num", types.N).Description("the numeric representation of `x`"), ), Categories: conversions, } @@ -894,7 +897,7 @@ var RegexMatch = &Builtin{ types.Named("pattern", types.S).Description("regular expression"), types.Named("value", types.S).Description("value to match against `pattern`"), ), - types.Named("result", types.B), + types.Named("result", types.B).Description("true if `value` matches `pattern`"), ), } @@ -905,7 +908,7 @@ var RegexIsValid = &Builtin{ types.Args( types.Named("pattern", types.S).Description("regular expression"), ), - types.Named("result", types.B), + types.Named("result", types.B).Description("true if `pattern` is a valid regular expression"), ), } @@ -918,7 +921,7 @@ var RegexFindAllStringSubmatch = &Builtin{ types.Named("value", types.S).Description("string to match"), types.Named("number", types.N).Description("number of matches to return; `-1` means all matches"), ), - types.Named("output", types.NewArray(nil, types.NewArray(nil, types.S))), + types.Named("output", types.NewArray(nil, types.NewArray(nil, types.S))).Description("array of all matches"), ), } @@ -932,7 +935,7 @@ var RegexTemplateMatch = &Builtin{ types.Named("delimiter_start", types.S).Description("start delimiter of the regular expression in `template`"), types.Named("delimiter_end", types.S).Description("end delimiter of the regular expression in `template`"), ), - types.Named("result", types.B), + types.Named("result", types.B).Description("true if `value` matches the `template`"), ), } // TODO(sr): example:`regex.template_match("urn:foo:{.*}", "urn:foo:bar:baz", "{", "}")`` returns ``true``. @@ -974,10 +977,10 @@ var GlobsMatch = &Builtin{ The set of regex symbols is limited for this builtin: only ` + "`.`, `*`, `+`, `[`, `-`, `]` and `\\` are treated as special symbols.", Decl: types.NewFunction( types.Args( - types.Named("glob1", types.S), - types.Named("glob2", types.S), + types.Named("glob1", types.S).Description("first glob-style regular expression"), + types.Named("glob2", types.S).Description("second glob-style regular expression"), ), - types.Named("result", types.B), + types.Named("result", types.B).Description("true if the intersection of `glob1` and `glob2` matches a non-empty set of non-empty strings"), ), } @@ -993,12 +996,12 @@ var AnyPrefixMatch = &Builtin{ types.Args( types.Named("search", types.NewAny( types.S, - types.NewSet(types.S), + types.SetOfStr, types.NewArray(nil, types.S), )).Description("search string(s)"), types.Named("base", types.NewAny( types.S, - types.NewSet(types.S), + types.SetOfStr, types.NewArray(nil, types.S), )).Description("base string(s)"), ), @@ -1014,12 +1017,12 @@ var AnySuffixMatch = &Builtin{ types.Args( types.Named("search", types.NewAny( types.S, - types.NewSet(types.S), + types.SetOfStr, types.NewArray(nil, types.S), )).Description("search string(s)"), types.Named("base", types.NewAny( types.S, - types.NewSet(types.S), + types.SetOfStr, types.NewArray(nil, types.S), )).Description("base string(s)"), ), @@ -1033,13 +1036,13 @@ var Concat = &Builtin{ Description: "Joins a set or array of strings with a delimiter.", Decl: types.NewFunction( types.Args( - types.Named("delimiter", types.S), + types.Named("delimiter", types.S).Description("string to use as a delimiter"), types.Named("collection", types.NewAny( - types.NewSet(types.S), + types.SetOfStr, types.NewArray(nil, types.S), )).Description("strings to join"), ), - types.Named("output", types.S), + types.Named("output", types.S).Description("the joined string"), ), Categories: stringsCat, } @@ -1088,7 +1091,7 @@ var Substring = &Builtin{ Description: "Returns the portion of a string for a given `offset` and a `length`. If `length < 0`, `output` is the remainder of the string.", Decl: types.NewFunction( types.Args( - types.Named("value", types.S), + types.Named("value", types.S).Description("string to extract substring from"), types.Named("offset", types.N).Description("offset, must be positive"), types.Named("length", types.N).Description("length of the substring starting from `offset`"), ), @@ -1215,7 +1218,7 @@ The old string comparisons are done in argument order.`, ).Description("replacement pairs"), types.Named("value", types.S).Description("string to replace substring matches in"), ), - types.Named("output", types.S), + types.Named("output", types.S).Description("string with replaced substrings"), ), } @@ -1228,7 +1231,7 @@ var RegexReplace = &Builtin{ types.Named("pattern", types.S).Description("regex pattern to be applied"), types.Named("value", types.S).Description("regex value"), ), - types.Named("output", types.S), + types.Named("output", types.S).Description("string with replaced substrings"), ), } @@ -1327,9 +1330,9 @@ var StringReverse = &Builtin{ Description: "Reverses a given string.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("string to reverse"), ), - types.Named("y", types.S), + types.Named("y", types.S).Description("reversed string"), ), Categories: stringsCat, } @@ -1359,8 +1362,8 @@ var RandIntn = &Builtin{ Description: "Returns a random integer between `0` and `n` (`n` exclusive). If `n` is `0`, then `y` is always `0`. For any given argument pair (`str`, `n`), the output will be consistent throughout a query evaluation.", Decl: types.NewFunction( types.Args( - types.Named("str", types.S), - types.Named("n", types.N), + types.Named("str", types.S).Description("seed string for the random number"), + types.Named("n", types.N).Description("upper bound of the random number (exclusive)"), ), types.Named("y", types.N).Description("random integer in the range `[0, abs(n))`"), ), @@ -1373,8 +1376,8 @@ var NumbersRange = &Builtin{ Description: "Returns an array of numbers in the given (inclusive) range. If `a==b`, then `range == [a]`; if `a > b`, then `range` is in descending order.", Decl: types.NewFunction( types.Args( - types.Named("a", types.N), - types.Named("b", types.N), + types.Named("a", types.N).Description("the start of the range"), + types.Named("b", types.N).Description("the end of the range (inclusive)"), ), types.Named("range", types.NewArray(nil, types.N)).Description("the range between `a` and `b`"), ), @@ -1389,9 +1392,9 @@ var NumbersRangeStep = &Builtin{ `, Decl: types.NewFunction( types.Args( - types.Named("a", types.N), - types.Named("b", types.N), - types.Named("step", types.N), + types.Named("a", types.N).Description("the start of the range"), + types.Named("b", types.N).Description("the end of the range (inclusive)"), + types.Named("step", types.N).Description("the step between numbers in the range"), ), types.Named("range", types.NewArray(nil, types.N)).Description("the range between `a` and `b` in `step` increments"), ), @@ -1403,12 +1406,16 @@ var NumbersRangeStep = &Builtin{ var UnitsParse = &Builtin{ Name: "units.parse", - Description: `Converts strings like "10G", "5K", "4M", "1500m" and the like into a number. -This number can be a non-integer, such as 1.5, 0.22, etc. Supports standard metric decimal and -binary SI units (e.g., K, Ki, M, Mi, G, Gi etc.) m, K, M, G, T, P, and E are treated as decimal -units and Ki, Mi, Gi, Ti, Pi, and Ei are treated as binary units. + Description: `Converts strings like "10G", "5K", "4M", "1500m", and the like into a number. +This number can be a non-integer, such as 1.5, 0.22, etc. Scientific notation is supported, +allowing values such as "1e-3K" (1) or "2.5e6M" (2.5 million M). + +Supports standard metric decimal and binary SI units (e.g., K, Ki, M, Mi, G, Gi, etc.) where +m, K, M, G, T, P, and E are treated as decimal units and Ki, Mi, Gi, Ti, Pi, and Ei are treated as +binary units. -Note that 'm' and 'M' are case-sensitive, to allow distinguishing between "milli" and "mega" units respectively. Other units are case-insensitive.`, +Note that 'm' and 'M' are case-sensitive to allow distinguishing between "milli" and "mega" units +respectively. Other units are case-insensitive.`, Decl: types.NewFunction( types.Args( types.Named("x", types.S).Description("the unit to parse"), @@ -1419,10 +1426,14 @@ Note that 'm' and 'M' are case-sensitive, to allow distinguishing between "milli var UnitsParseBytes = &Builtin{ Name: "units.parse_bytes", - Description: `Converts strings like "10GB", "5K", "4mb" into an integer number of bytes. -Supports standard byte units (e.g., KB, KiB, etc.) KB, MB, GB, and TB are treated as decimal -units and KiB, MiB, GiB, and TiB are treated as binary units. The bytes symbol (b/B) in the -unit is optional and omitting it wil give the same result (e.g. Mi and MiB).`, + Description: `Converts strings like "10GB", "5K", "4mb", or "1e6KB" into an integer number of bytes. + +Supports standard byte units (e.g., KB, KiB, etc.) where KB, MB, GB, and TB are treated as decimal +units, and KiB, MiB, GiB, and TiB are treated as binary units. Scientific notation is supported, +enabling values like "1.5e3MB" (1500MB) or "2e6GiB" (2 million GiB). + +The bytes symbol (b/B) in the unit is optional; omitting it will yield the same result (e.g., "Mi" +and "MiB" are equivalent).`, Decl: types.NewFunction( types.Args( types.Named("x", types.S).Description("the byte unit to parse"), @@ -1443,7 +1454,7 @@ var UUIDRFC4122 = &Builtin{ Description: "Returns a new UUIDv4.", Decl: types.NewFunction( types.Args( - types.Named("k", types.S), + types.Named("k", types.S).Description("seed string"), ), types.Named("output", types.S).Description("a version 4 UUID; for any given `k`, the output will be consistent throughout a query evaluation"), ), @@ -1456,7 +1467,7 @@ var UUIDParse = &Builtin{ Categories: nil, Decl: types.NewFunction( types.Args( - types.Named("uuid", types.S), + types.Named("uuid", types.S).Description("UUID string to parse"), ), types.Named("result", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))).Description("Properties of UUID if valid (version, variant, etc). Undefined otherwise."), ), @@ -1479,7 +1490,7 @@ var JSONFilter = &Builtin{ types.Named("object", types.NewObject( nil, types.NewDynamicProperty(types.A, types.A), - )), + )).Description("object to filter"), types.Named("paths", types.NewAny( types.NewArray( nil, @@ -1517,7 +1528,7 @@ var JSONRemove = &Builtin{ types.Named("object", types.NewObject( nil, types.NewDynamicProperty(types.A, types.A), - )), + )).Description("object to remove paths from"), types.Named("paths", types.NewAny( types.NewArray( nil, @@ -1553,7 +1564,7 @@ var JSONPatch = &Builtin{ "Additionally works on sets, where a value contained in the set is considered to be its path.", Decl: types.NewFunction( types.Args( - types.Named("object", types.A), // TODO(sr): types.A? + types.Named("object", types.A).Description("the object to patch"), // TODO(sr): types.A? types.Named("patches", types.NewArray( nil, types.NewObject( @@ -1563,7 +1574,7 @@ var JSONPatch = &Builtin{ }, types.NewDynamicProperty(types.A, types.A), ), - )), + )).Description("the JSON patches to apply"), ), types.Named("output", types.A).Description("result obtained after consecutively applying all patch operations in `patches`"), ), @@ -1589,15 +1600,13 @@ var ObjectSubset = &Builtin{ types.Named("super", types.NewAny(types.NewObject( nil, types.NewDynamicProperty(types.A, types.A), - ), - types.NewSet(types.A), + ), types.SetOfAny, types.NewArray(nil, types.A), )).Description("object to test if sub is a subset of"), types.Named("sub", types.NewAny(types.NewObject( nil, types.NewDynamicProperty(types.A, types.A), - ), - types.NewSet(types.A), + ), types.SetOfAny, types.NewArray(nil, types.A), )).Description("object to test if super is a superset of"), ), @@ -1614,11 +1623,11 @@ var ObjectUnion = &Builtin{ types.Named("a", types.NewObject( nil, types.NewDynamicProperty(types.A, types.A), - )), + )).Description("left-hand object"), types.Named("b", types.NewObject( nil, types.NewDynamicProperty(types.A, types.A), - )), + )).Description("right-hand object"), ), types.Named("output", types.A).Description("a new object which is the result of an asymmetric recursive union of two objects where conflicts are resolved by choosing the key from the right-hand object `b`"), ), // TODO(sr): types.A? ^^^^^^^ (also below) @@ -1633,7 +1642,7 @@ var ObjectUnionN = &Builtin{ types.Named("objects", types.NewArray( nil, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)), - )), + )).Description("list of objects to merge"), ), types.Named("output", types.A).Description("asymmetric recursive union of all objects in `objects`, merged from left to right, where conflicts are resolved by choosing the key from the right-hand object"), ), @@ -1650,7 +1659,7 @@ var ObjectRemove = &Builtin{ )).Description("object to remove keys from"), types.Named("keys", types.NewAny( types.NewArray(nil, types.A), - types.NewSet(types.A), + types.SetOfAny, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)), )).Description("keys to remove from x"), ), @@ -1670,9 +1679,9 @@ var ObjectFilter = &Builtin{ )).Description("object to filter keys"), types.Named("keys", types.NewAny( types.NewArray(nil, types.A), - types.NewSet(types.A), + types.SetOfAny, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)), - )), + )).Description("keys to keep in `object`"), ), types.Named("filtered", types.A).Description("remaining data from `object` with only keys specified in `keys`"), ), @@ -1701,7 +1710,7 @@ var ObjectKeys = &Builtin{ types.Args( types.Named("object", types.NewObject(nil, types.NewDynamicProperty(types.A, types.A))).Description("object to get keys from"), ), - types.Named("value", types.NewSet(types.A)).Description("set of `object`'s keys"), + types.Named("value", types.SetOfAny).Description("set of `object`'s keys"), ), } @@ -1772,7 +1781,7 @@ var Base64Encode = &Builtin{ Description: "Serializes the input string into base64 encoding.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("string to encode"), ), types.Named("y", types.S).Description("base64 serialization of `x`"), ), @@ -1784,7 +1793,7 @@ var Base64Decode = &Builtin{ Description: "Deserializes the base64 encoded input string.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("string to decode"), ), types.Named("y", types.S).Description("base64 deserialization of `x`"), ), @@ -1796,7 +1805,7 @@ var Base64IsValid = &Builtin{ Description: "Verifies the input string is base64 encoded.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("string to check"), ), types.Named("result", types.B).Description("`true` if `x` is valid base64 encoded value, `false` otherwise"), ), @@ -1808,7 +1817,7 @@ var Base64UrlEncode = &Builtin{ Description: "Serializes the input string into base64url encoding.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("string to encode"), ), types.Named("y", types.S).Description("base64url serialization of `x`"), ), @@ -1820,7 +1829,7 @@ var Base64UrlEncodeNoPad = &Builtin{ Description: "Serializes the input string into base64url encoding without padding.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("string to encode"), ), types.Named("y", types.S).Description("base64url serialization of `x`"), ), @@ -1832,7 +1841,7 @@ var Base64UrlDecode = &Builtin{ Description: "Deserializes the base64url encoded input string.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("string to decode"), ), types.Named("y", types.S).Description("base64url deserialization of `x`"), ), @@ -1844,7 +1853,7 @@ var URLQueryDecode = &Builtin{ Description: "Decodes a URL-encoded input string.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("the URL-encoded string"), ), types.Named("y", types.S).Description("URL-encoding deserialization of `x`"), ), @@ -1856,7 +1865,7 @@ var URLQueryEncode = &Builtin{ Description: "Encodes the input string into a URL-encoded string.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("the string to encode"), ), types.Named("y", types.S).Description("URL-encoding serialization of `x`"), ), @@ -1875,7 +1884,12 @@ var URLQueryEncodeObject = &Builtin{ types.NewAny( types.S, types.NewArray(nil, types.S), - types.NewSet(types.S)))))), + types.SetOfStr, + ), + ), + ), + ).Description("the object to encode"), + ), types.Named("y", types.S).Description("the URL-encoded serialization of `object`"), ), Categories: encoding, @@ -1937,7 +1951,7 @@ var HexEncode = &Builtin{ Description: "Serializes the input string using hex-encoding.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("string to encode"), ), types.Named("y", types.S).Description("serialization of `x` using hex-encoding"), ), @@ -2219,7 +2233,7 @@ var ParseRFC3339Nanos = &Builtin{ Description: "Returns the time in nanoseconds parsed from the string in RFC3339 format. `undefined` if the result would be outside the valid time range that can fit within an `int64`.", Decl: types.NewFunction( types.Args( - types.Named("value", types.S), + types.Named("value", types.S).Description("input string to parse in RFC3339 format"), ), types.Named("ns", types.N).Description("`value` in nanoseconds since epoch"), ), @@ -2300,9 +2314,9 @@ var AddDate = &Builtin{ Decl: types.NewFunction( types.Args( types.Named("ns", types.N).Description("nanoseconds since the epoch"), - types.Named("years", types.N), - types.Named("months", types.N), - types.Named("days", types.N), + types.Named("years", types.N).Description("number of years to add"), + types.Named("months", types.N).Description("number of months to add"), + types.Named("days", types.N).Description("number of days to add"), ), types.Named("output", types.N).Description("nanoseconds since the epoch representing the input time, with years, months and days added"), ), @@ -2316,11 +2330,11 @@ var Diff = &Builtin{ types.Named("ns1", types.NewAny( types.N, types.NewArray([]types.Type{types.N, types.S}, nil), - )), + )).Description("nanoseconds since the epoch; or a two-element array of the nanoseconds, and a timezone string"), types.Named("ns2", types.NewAny( types.N, types.NewArray([]types.Type{types.N, types.S}, nil), - )), + )).Description("nanoseconds since the epoch; or a two-element array of the nanoseconds, and a timezone string"), ), types.Named("output", types.NewArray([]types.Type{types.N, types.N, types.N, types.N, types.N, types.N}, nil)).Description("difference between `ns1` and `ns2` (in their supplied timezones, if supplied, or UTC) as array of numbers: `[years, months, days, hours, minutes, seconds]`"), ), @@ -2440,7 +2454,7 @@ var CryptoMd5 = &Builtin{ Description: "Returns a string representing the input string hashed with the MD5 function", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("input string"), ), types.Named("y", types.S).Description("MD5-hash of `x`"), ), @@ -2451,7 +2465,7 @@ var CryptoSha1 = &Builtin{ Description: "Returns a string representing the input string hashed with the SHA1 function", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("input string"), ), types.Named("y", types.S).Description("SHA1-hash of `x`"), ), @@ -2462,7 +2476,7 @@ var CryptoSha256 = &Builtin{ Description: "Returns a string representing the input string hashed with the SHA256 function", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("input string"), ), types.Named("y", types.S).Description("SHA256-hash of `x`"), ), @@ -2539,7 +2553,7 @@ var WalkBuiltin = &Builtin{ Description: "Generates `[path, value]` tuples for all nested documents of `x` (recursively). Queries can use `walk` to traverse documents nested under `x`.", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("value to walk"), ), types.Named("output", types.NewArray( []types.Type{ @@ -2562,13 +2576,13 @@ var ReachableBuiltin = &Builtin{ types.NewDynamicProperty( types.A, types.NewAny( - types.NewSet(types.A), + types.SetOfAny, types.NewArray(nil, types.A)), )), ).Description("object containing a set or array of neighboring vertices"), - types.Named("initial", types.NewAny(types.NewSet(types.A), types.NewArray(nil, types.A))).Description("set or array of root vertices"), + types.Named("initial", types.NewAny(types.SetOfAny, types.NewArray(nil, types.A))).Description("set or array of root vertices"), ), - types.Named("output", types.NewSet(types.A)).Description("set of vertices reachable from the `initial` vertices in the directed `graph`"), + types.Named("output", types.SetOfAny).Description("set of vertices reachable from the `initial` vertices in the directed `graph`"), ), } @@ -2582,11 +2596,11 @@ var ReachablePathsBuiltin = &Builtin{ types.NewDynamicProperty( types.A, types.NewAny( - types.NewSet(types.A), + types.SetOfAny, types.NewArray(nil, types.A)), )), ).Description("object containing a set or array of root vertices"), - types.Named("initial", types.NewAny(types.NewSet(types.A), types.NewArray(nil, types.A))).Description("initial paths"), // TODO(sr): copied. is that correct? + types.Named("initial", types.NewAny(types.SetOfAny, types.NewArray(nil, types.A))).Description("initial paths"), // TODO(sr): copied. is that correct? ), types.Named("output", types.NewSet(types.NewArray(nil, types.A))).Description("paths reachable from the `initial` vertices in the directed `graph`"), ), @@ -2602,7 +2616,7 @@ var IsNumber = &Builtin{ Description: "Returns `true` if the input value is a number.", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("input value"), ), types.Named("result", types.B).Description("`true` if `x` is a number, `false` otherwise."), ), @@ -2614,7 +2628,7 @@ var IsString = &Builtin{ Description: "Returns `true` if the input value is a string.", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("input value"), ), types.Named("result", types.B).Description("`true` if `x` is a string, `false` otherwise."), ), @@ -2626,7 +2640,7 @@ var IsBoolean = &Builtin{ Description: "Returns `true` if the input value is a boolean.", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("input value"), ), types.Named("result", types.B).Description("`true` if `x` is an boolean, `false` otherwise."), ), @@ -2638,7 +2652,7 @@ var IsArray = &Builtin{ Description: "Returns `true` if the input value is an array.", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("input value"), ), types.Named("result", types.B).Description("`true` if `x` is an array, `false` otherwise."), ), @@ -2650,7 +2664,7 @@ var IsSet = &Builtin{ Description: "Returns `true` if the input value is a set.", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("input value"), ), types.Named("result", types.B).Description("`true` if `x` is a set, `false` otherwise."), ), @@ -2662,7 +2676,7 @@ var IsObject = &Builtin{ Description: "Returns true if the input value is an object", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("input value"), ), types.Named("result", types.B).Description("`true` if `x` is an object, `false` otherwise."), ), @@ -2674,7 +2688,7 @@ var IsNull = &Builtin{ Description: "Returns `true` if the input value is null.", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("input value"), ), types.Named("result", types.B).Description("`true` if `x` is null, `false` otherwise."), ), @@ -2691,7 +2705,7 @@ var TypeNameBuiltin = &Builtin{ Description: "Returns the type of its input value.", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("input value"), ), types.Named("type", types.S).Description(`one of "null", "boolean", "number", "string", "array", "object", "set"`), ), @@ -2708,9 +2722,11 @@ var HTTPSend = &Builtin{ Description: "Returns a HTTP response to the given HTTP request.", Decl: types.NewFunction( types.Args( - types.Named("request", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))), + types.Named("request", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))). + Description("the HTTP request object"), ), - types.Named("response", types.NewObject(nil, types.NewDynamicProperty(types.A, types.A))), + types.Named("response", types.NewObject(nil, types.NewDynamicProperty(types.A, types.A))). + Description("the HTTP response object"), ), Nondeterministic: true, } @@ -2725,8 +2741,10 @@ var GraphQLParse = &Builtin{ Description: "Returns AST objects for a given GraphQL query and schema after validating the query against the schema. Returns undefined if errors were encountered during parsing or validation. The query and/or schema can be either GraphQL strings or AST objects from the other GraphQL builtin functions.", Decl: types.NewFunction( types.Args( - types.Named("query", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))), - types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))), + types.Named("query", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))). + Description("the GraphQL query"), + types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))). + Description("the GraphQL schema"), ), types.Named("output", types.NewArray([]types.Type{ types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)), @@ -2741,8 +2759,10 @@ var GraphQLParseAndVerify = &Builtin{ Description: "Returns a boolean indicating success or failure alongside the parsed ASTs for a given GraphQL query and schema after validating the query against the schema. The query and/or schema can be either GraphQL strings or AST objects from the other GraphQL builtin functions.", Decl: types.NewFunction( types.Args( - types.Named("query", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))), - types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))), + types.Named("query", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))). + Description("the GraphQL query"), + types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))). + Description("the GraphQL schema"), ), types.Named("output", types.NewArray([]types.Type{ types.B, @@ -2759,7 +2779,7 @@ var GraphQLParseQuery = &Builtin{ Description: "Returns an AST object for a GraphQL query.", Decl: types.NewFunction( types.Args( - types.Named("query", types.S), + types.Named("query", types.S).Description("GraphQL query string"), ), types.Named("output", types.NewObject(nil, types.NewDynamicProperty(types.A, types.A))).Description("AST object for the GraphQL query."), ), @@ -2772,7 +2792,7 @@ var GraphQLParseSchema = &Builtin{ Description: "Returns an AST object for a GraphQL schema.", Decl: types.NewFunction( types.Args( - types.Named("schema", types.S), + types.Named("schema", types.S).Description("GraphQL schema string"), ), types.Named("output", types.NewObject(nil, types.NewDynamicProperty(types.A, types.A))).Description("AST object for the GraphQL schema."), ), @@ -2785,8 +2805,10 @@ var GraphQLIsValid = &Builtin{ Description: "Checks that a GraphQL query is valid against a given schema. The query and/or schema can be either GraphQL strings or AST objects from the other GraphQL builtin functions.", Decl: types.NewFunction( types.Args( - types.Named("query", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))), - types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))), + types.Named("query", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))). + Description("the GraphQL query"), + types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))). + Description("the GraphQL schema"), ), types.Named("output", types.B).Description("`true` if the query is valid under the given schema. `false` otherwise."), ), @@ -2799,7 +2821,8 @@ var GraphQLSchemaIsValid = &Builtin{ Description: "Checks that the input is a valid GraphQL schema. The schema can be either a GraphQL string or an AST object from the other GraphQL builtin functions.", Decl: types.NewFunction( types.Args( - types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))), + types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))). + Description("the schema to verify"), ), types.Named("output", types.B).Description("`true` if the schema is a valid GraphQL schema. `false` otherwise."), ), @@ -2869,11 +2892,14 @@ var ProvidersAWSSignReqObj = &Builtin{ Description: "Signs an HTTP request object for Amazon Web Services. Currently implements [AWS Signature Version 4 request signing](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html) by the `Authorization` header method.", Decl: types.NewFunction( types.Args( - types.Named("request", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))), - types.Named("aws_config", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))), - types.Named("time_ns", types.N), + types.Named("request", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))). + Description("HTTP request object"), + types.Named("aws_config", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))). + Description("AWS configuration object"), + types.Named("time_ns", types.N).Description("nanoseconds since the epoch"), ), - types.Named("signed_request", types.NewObject(nil, types.NewDynamicProperty(types.A, types.A))), + types.Named("signed_request", types.NewObject(nil, types.NewDynamicProperty(types.A, types.A))). + Description("HTTP request object with `Authorization` header"), ), Categories: providersAWSCat, } @@ -2890,7 +2916,8 @@ var RegoParseModule = &Builtin{ types.Named("filename", types.S).Description("file name to attach to AST nodes' locations"), types.Named("rego", types.S).Description("Rego module"), ), - types.Named("output", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))), // TODO(tsandall): import AST schema + types.Named("output", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))). + Description("AST object for the Rego module"), ), } @@ -2958,12 +2985,12 @@ var GlobMatch = &Builtin{ Description: "Parses and matches strings against the glob notation. Not to be confused with `regex.globs_match`.", Decl: types.NewFunction( types.Args( - types.Named("pattern", types.S), + types.Named("pattern", types.S).Description("glob pattern"), types.Named("delimiters", types.NewAny( types.NewArray(nil, types.S), types.NewNull(), )).Description("glob pattern delimiters, e.g. `[\".\", \":\"]`, defaults to `[\".\"]` if unset. If `delimiters` is `null`, glob match without delimiter."), - types.Named("match", types.S), + types.Named("match", types.S).Description("string to match against `pattern`"), ), types.Named("result", types.B).Description("true if `match` can be found in `pattern` which is separated by `delimiters`"), ), @@ -2974,7 +3001,7 @@ var GlobQuoteMeta = &Builtin{ Description: "Returns a string which represents a version of the pattern where all asterisks have been escaped.", Decl: types.NewFunction( types.Args( - types.Named("pattern", types.S), + types.Named("pattern", types.S).Description("glob pattern"), ), types.Named("output", types.S).Description("the escaped string of `pattern`"), ), @@ -2990,10 +3017,10 @@ var NetCIDRIntersects = &Builtin{ Description: "Checks if a CIDR intersects with another CIDR (e.g. `192.168.0.0/16` overlaps with `192.168.1.0/24`). Supports both IPv4 and IPv6 notations.", Decl: types.NewFunction( types.Args( - types.Named("cidr1", types.S), - types.Named("cidr2", types.S), + types.Named("cidr1", types.S).Description("first CIDR"), + types.Named("cidr2", types.S).Description("second CIDR"), ), - types.Named("result", types.B), + types.Named("result", types.B).Description("`true` if `cidr1` intersects with `cidr2`"), ), } @@ -3002,9 +3029,9 @@ var NetCIDRExpand = &Builtin{ Description: "Expands CIDR to set of hosts (e.g., `net.cidr_expand(\"192.168.0.0/30\")` generates 4 hosts: `{\"192.168.0.0\", \"192.168.0.1\", \"192.168.0.2\", \"192.168.0.3\"}`).", Decl: types.NewFunction( types.Args( - types.Named("cidr", types.S), + types.Named("cidr", types.S).Description("CIDR to expand"), ), - types.Named("hosts", types.NewSet(types.S)).Description("set of IP addresses the CIDR `cidr` expands to"), + types.Named("hosts", types.SetOfStr).Description("set of IP addresses the CIDR `cidr` expands to"), ), } @@ -3013,10 +3040,10 @@ var NetCIDRContains = &Builtin{ Description: "Checks if a CIDR or IP is contained within another CIDR. `output` is `true` if `cidr_or_ip` (e.g. `127.0.0.64/26` or `127.0.0.1`) is contained within `cidr` (e.g. `127.0.0.1/24`) and `false` otherwise. Supports both IPv4 and IPv6 notations.", Decl: types.NewFunction( types.Args( - types.Named("cidr", types.S), - types.Named("cidr_or_ip", types.S), + types.Named("cidr", types.S).Description("CIDR to check against"), + types.Named("cidr_or_ip", types.S).Description("CIDR or IP to check"), ), - types.Named("result", types.B), + types.Named("result", types.B).Description("`true` if `cidr_or_ip` is contained within `cidr`"), ), } @@ -3026,8 +3053,8 @@ var NetCIDRContainsMatches = &Builtin{ "This function is similar to `net.cidr_contains` except it allows callers to pass collections of CIDRs or IPs as arguments and returns the matches (as opposed to a boolean result indicating a match between two CIDRs/IPs).", Decl: types.NewFunction( types.Args( - types.Named("cidrs", netCidrContainsMatchesOperandType), - types.Named("cidrs_or_ips", netCidrContainsMatchesOperandType), + types.Named("cidrs", netCidrContainsMatchesOperandType).Description("CIDRs to check against"), + types.Named("cidrs_or_ips", netCidrContainsMatchesOperandType).Description("CIDRs or IPs to check"), ), types.Named("output", types.NewSet(types.NewArray([]types.Type{types.A, types.A}, nil))).Description("tuples identifying matches where `cidrs_or_ips` are contained within `cidrs`"), ), @@ -3042,10 +3069,10 @@ Supports both IPv4 and IPv6 notations. IPv6 inputs need a prefix length (e.g. "/ types.Args( types.Named("addrs", types.NewAny( types.NewArray(nil, types.NewAny(types.S)), - types.NewSet(types.S), + types.SetOfStr, )).Description("CIDRs or IP addresses"), ), - types.Named("output", types.NewSet(types.S)).Description("smallest possible set of CIDRs obtained after merging the provided list of IP addresses and subnets in `addrs`"), + types.Named("output", types.SetOfStr).Description("smallest possible set of CIDRs obtained after merging the provided list of IP addresses and subnets in `addrs`"), ), } @@ -3054,9 +3081,9 @@ var NetCIDRIsValid = &Builtin{ Description: "Parses an IPv4/IPv6 CIDR and returns a boolean indicating if the provided CIDR is valid.", Decl: types.NewFunction( types.Args( - types.Named("cidr", types.S), + types.Named("cidr", types.S).Description("CIDR to validate"), ), - types.Named("result", types.B), + types.Named("result", types.B).Description("`true` if `cidr` is a valid CIDR"), ), } @@ -3087,7 +3114,7 @@ var NetLookupIPAddr = &Builtin{ types.Args( types.Named("name", types.S).Description("domain name to resolve"), ), - types.Named("addrs", types.NewSet(types.S)).Description("IP addresses (v4 and v6) that `name` resolves to"), + types.Named("addrs", types.SetOfStr).Description("IP addresses (v4 and v6) that `name` resolves to"), ), Nondeterministic: true, } @@ -3101,7 +3128,7 @@ var SemVerIsValid = &Builtin{ Description: "Validates that the input is a valid SemVer string.", Decl: types.NewFunction( types.Args( - types.Named("vsn", types.A), + types.Named("vsn", types.A).Description("input to validate"), ), types.Named("result", types.B).Description("`true` if `vsn` is a valid SemVer; `false` otherwise"), ), @@ -3112,8 +3139,8 @@ var SemVerCompare = &Builtin{ Description: "Compares valid SemVer formatted version strings.", Decl: types.NewFunction( types.Args( - types.Named("a", types.S), - types.Named("b", types.S), + types.Named("a", types.S).Description("first version string"), + types.Named("b", types.S).Description("second version string"), ), types.Named("result", types.N).Description("`-1` if `a < b`; `1` if `a > b`; `0` if `a == b`"), ), @@ -3137,7 +3164,12 @@ var Print = &Builtin{ // The compiler rewrites print() calls to refer to the internal implementation. var InternalPrint = &Builtin{ Name: "internal.print", - Decl: types.NewFunction([]types.Type{types.NewArray(nil, types.NewSet(types.A))}, nil), + Decl: types.NewFunction([]types.Type{types.NewArray(nil, types.SetOfAny)}, nil), +} + +var InternalTestCase = &Builtin{ + Name: "internal.test_case", + Decl: types.NewFunction([]types.Type{types.NewArray(nil, types.A)}, nil), } /** @@ -3149,10 +3181,10 @@ var SetDiff = &Builtin{ Name: "set_diff", Decl: types.NewFunction( types.Args( - types.NewSet(types.A), - types.NewSet(types.A), + types.SetOfAny, + types.SetOfAny, ), - types.NewSet(types.A), + types.SetOfAny, ), deprecated: true, } @@ -3189,7 +3221,7 @@ var CastSet = &Builtin{ Name: "cast_set", Decl: types.NewFunction( types.Args(types.A), - types.NewSet(types.A), + types.SetOfAny, ), deprecated: true, } @@ -3255,7 +3287,7 @@ var All = &Builtin{ Decl: types.NewFunction( types.Args( types.NewAny( - types.NewSet(types.A), + types.SetOfAny, types.NewArray(nil, types.A), ), ), @@ -3271,7 +3303,7 @@ var Any = &Builtin{ Decl: types.NewFunction( types.Args( types.NewAny( - types.NewSet(types.A), + types.SetOfAny, types.NewArray(nil, types.A), ), ), @@ -3364,12 +3396,12 @@ func (b *Builtin) Ref() Ref { // IsTargetPos returns true if a variable in the i-th position will be bound by // evaluating the call expression. func (b *Builtin) IsTargetPos(i int) bool { - return len(b.Decl.FuncArgs().Args) == i + return b.Decl.Arity() == i } func init() { BuiltinMap = map[string]*Builtin{} - for _, b := range DefaultBuiltins { + for _, b := range &DefaultBuiltins { RegisterBuiltin(b) } } diff --git a/vendor/github.com/open-policy-agent/opa/ast/capabilities.go b/vendor/github.com/open-policy-agent/opa/v1/ast/capabilities.go similarity index 82% rename from vendor/github.com/open-policy-agent/opa/ast/capabilities.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/capabilities.go index 3b95d79e57..7744a4ca26 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/capabilities.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/capabilities.go @@ -11,13 +11,14 @@ import ( "fmt" "io" "os" + "slices" "sort" "strings" - caps "github.com/open-policy-agent/opa/capabilities" "github.com/open-policy-agent/opa/internal/semver" "github.com/open-policy-agent/opa/internal/wasm/sdk/opa/capabilities" - "github.com/open-policy-agent/opa/util" + caps "github.com/open-policy-agent/opa/v1/capabilities" + "github.com/open-policy-agent/opa/v1/util" ) // VersonIndex contains an index from built-in function name, language feature, @@ -52,6 +53,7 @@ var minVersionIndex = func() VersionIndex { // heads, they wouldn't be able to parse them. const FeatureRefHeadStringPrefixes = "rule_head_ref_string_prefixes" const FeatureRefHeads = "rule_head_refs" +const FeatureRegoV1 = "rego_v1" const FeatureRegoV1Import = "rego_v1_import" // Capabilities defines a structure containing data that describes the capabilities @@ -83,8 +85,30 @@ type WasmABIVersion struct { Minor int `json:"minor_version"` } +type CapabilitiesOptions struct { + regoVersion RegoVersion +} + +func newCapabilitiesOptions(opts []CapabilitiesOption) CapabilitiesOptions { + co := CapabilitiesOptions{} + for _, opt := range opts { + opt(&co) + } + return co +} + +type CapabilitiesOption func(*CapabilitiesOptions) + +func CapabilitiesRegoVersion(regoVersion RegoVersion) CapabilitiesOption { + return func(o *CapabilitiesOptions) { + o.regoVersion = regoVersion + } +} + // CapabilitiesForThisVersion returns the capabilities of this version of OPA. -func CapabilitiesForThisVersion() *Capabilities { +func CapabilitiesForThisVersion(opts ...CapabilitiesOption) *Capabilities { + co := newCapabilitiesOptions(opts) + f := &Capabilities{} for _, vers := range capabilities.ABIVersions() { @@ -93,21 +117,36 @@ func CapabilitiesForThisVersion() *Capabilities { f.Builtins = make([]*Builtin, len(Builtins)) copy(f.Builtins, Builtins) - sort.Slice(f.Builtins, func(i, j int) bool { - return f.Builtins[i].Name < f.Builtins[j].Name + + slices.SortFunc(f.Builtins, func(a, b *Builtin) int { + return strings.Compare(a.Name, b.Name) }) - for kw := range futureKeywords { - f.FutureKeywords = append(f.FutureKeywords, kw) - } - sort.Strings(f.FutureKeywords) + switch co.regoVersion { + case RegoV0, RegoV0CompatV1: + for kw := range allFutureKeywords { + f.FutureKeywords = append(f.FutureKeywords, kw) + } + + f.Features = []string{ + FeatureRefHeadStringPrefixes, + FeatureRefHeads, + FeatureRegoV1Import, + FeatureRegoV1, // Included in v0 capabilities to allow v1 bundles in --v0-compatible mode + } + default: + for kw := range futureKeywords { + f.FutureKeywords = append(f.FutureKeywords, kw) + } - f.Features = []string{ - FeatureRefHeadStringPrefixes, - FeatureRefHeads, - FeatureRegoV1Import, + f.Features = []string{ + FeatureRegoV1, + } } + sort.Strings(f.FutureKeywords) + sort.Strings(f.Features) + return f } @@ -208,12 +247,7 @@ func (c *Capabilities) MinimumCompatibleVersion() (string, bool) { } func (c *Capabilities) ContainsFeature(feature string) bool { - for _, f := range c.Features { - if f == feature { - return true - } - } - return false + return slices.Contains(c.Features, feature) } // addBuiltinSorted inserts a built-in into c in sorted order. An existing built-in with the same name diff --git a/vendor/github.com/open-policy-agent/opa/ast/check.go b/vendor/github.com/open-policy-agent/opa/v1/ast/check.go similarity index 92% rename from vendor/github.com/open-policy-agent/opa/ast/check.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/check.go index 03d31123cf..ecfb320649 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/check.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/check.go @@ -9,8 +9,8 @@ import ( "sort" "strings" - "github.com/open-policy-agent/opa/types" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/types" + "github.com/open-policy-agent/opa/v1/util" ) type varRewriter func(Ref) Ref @@ -39,8 +39,6 @@ type typeChecker struct { // newTypeChecker returns a new typeChecker object that has no errors. func newTypeChecker() *typeChecker { return &typeChecker{ - builtins: make(map[string]*Builtin), - schemaTypes: make(map[string]types.Type), exprCheckers: map[string]exprChecker{ "eq": checkExprEq, }, @@ -62,6 +60,7 @@ func (tc *typeChecker) copy() *typeChecker { return newTypeChecker(). WithVarRewriter(tc.varRewriter). WithSchemaSet(tc.ss). + WithSchemaTypes(tc.schemaTypes). WithAllowNet(tc.allowNet). WithInputType(tc.input). WithAllowUndefinedFunctionCalls(tc.allowUndefinedFuncs). @@ -84,6 +83,11 @@ func (tc *typeChecker) WithSchemaSet(ss *SchemaSet) *typeChecker { return tc } +func (tc *typeChecker) WithSchemaTypes(schemaTypes map[string]types.Type) *typeChecker { + tc.schemaTypes = schemaTypes + return tc +} + func (tc *typeChecker) WithAllowNet(hosts []string) *typeChecker { tc.allowNet = hosts return tc @@ -124,6 +128,7 @@ func (tc *typeChecker) CheckBody(env *TypeEnv, body Body) (*TypeEnv, Errors) { errors := []*Error{} env = tc.newEnv(env) + vis := newRefChecker(env, tc.varRewriter) WalkExprs(body, func(expr *Expr) bool { @@ -134,7 +139,8 @@ func (tc *typeChecker) CheckBody(env *TypeEnv, body Body) (*TypeEnv, Errors) { hasClosureErrors := len(closureErrs) > 0 - vis := newRefChecker(env, tc.varRewriter) + // reset errors from previous iteration + vis.errs = nil NewGenericVisitor(vis.Visit).Walk(expr) for _, err := range vis.errs { errors = append(errors, err) @@ -200,6 +206,10 @@ func (tc *typeChecker) checkClosures(env *TypeEnv, expr *Expr) Errors { } func (tc *typeChecker) getSchemaType(schemaAnnot *SchemaAnnotation, rule *Rule) (types.Type, *Error) { + if tc.schemaTypes == nil { + tc.schemaTypes = make(map[string]types.Type) + } + if refType, exists := tc.schemaTypes[schemaAnnot.Schema.String()]; exists { return refType, nil } @@ -266,7 +276,7 @@ func (tc *typeChecker) checkRule(env *TypeEnv, as *AnnotationSet, rule *Rule) { if len(rule.Head.Args) > 0 { // If args are not referred to in body, infer as any. WalkVars(rule.Head.Args, func(v Var) bool { - if cpy.Get(v) == nil { + if cpy.GetByValue(v) == nil { cpy.tree.PutOne(v, types.A) } return false @@ -274,8 +284,8 @@ func (tc *typeChecker) checkRule(env *TypeEnv, as *AnnotationSet, rule *Rule) { // 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]) + for i := range len(rule.Head.Args) { + args[i] = cpy.GetByValue(rule.Head.Args[i].Value) } f := types.NewFunction(args, cpy.Get(rule.Head.Value)) @@ -284,7 +294,7 @@ func (tc *typeChecker) checkRule(env *TypeEnv, as *AnnotationSet, rule *Rule) { } else { switch rule.Head.RuleKind() { case SingleValue: - typeV := cpy.Get(rule.Head.Value) + typeV := cpy.GetByValue(rule.Head.Value.Value) if !path.IsGround() { // e.g. store object[string: whatever] at data.p.q.r, not data.p.q.r[x] or data.p.q.r[x].y[z] objPath := path.DynamicSuffix() @@ -293,16 +303,14 @@ func (tc *typeChecker) checkRule(env *TypeEnv, as *AnnotationSet, rule *Rule) { var err error tpe, err = nestedObject(cpy, objPath, typeV) if err != nil { - tc.err([]*Error{NewError(TypeErr, rule.Head.Location, err.Error())}) + tc.err([]*Error{NewError(TypeErr, rule.Head.Location, err.Error())}) //nolint:govet tpe = nil } - } else { - if typeV != nil { - tpe = typeV - } + } else if typeV != nil { + tpe = typeV } case MultiValue: - typeK := cpy.Get(rule.Head.Key) + typeK := cpy.GetByValue(rule.Head.Key.Value) if typeK != nil { tpe = types.NewSet(typeK) } @@ -331,7 +339,7 @@ func nestedObject(env *TypeEnv, path Ref, tpe types.Type) (types.Type, error) { } var dynamicProperty *types.DynamicProperty - typeK := env.Get(k) + typeK := env.GetByValue(k.Value) if typeK == nil { return nil, nil } @@ -353,7 +361,7 @@ func (tc *typeChecker) checkExpr(env *TypeEnv, expr *Expr) *Error { // If the type checker wasn't provided with a required capabilities // structure then just skip. In some cases, type checking might be run // without the need to record what builtins are required. - if tc.required != nil { + if tc.required != nil && tc.builtins != nil { if bi, ok := tc.builtins[operator]; ok { tc.required.addBuiltinSorted(bi) } @@ -381,7 +389,7 @@ func (tc *typeChecker) checkExprBuiltin(env *TypeEnv, expr *Expr) *Error { // type checker relies on reordering (in particular for references to local // vars). name := expr.Operator() - tpe := env.Get(name) + tpe := env.GetByRef(name) if tpe == nil { if tc.allowUndefinedFuncs { @@ -421,7 +429,7 @@ func (tc *typeChecker) checkExprBuiltin(env *TypeEnv, expr *Expr) *Error { if !unify1(env, args[i], fargs.Arg(i), false) { post := make([]types.Type, len(args)) for i := range args { - post[i] = env.Get(args[i]) + post[i] = env.GetByValue(args[i].Value) } return newArgError(expr.Location, name, "invalid argument(s)", post, namedFargs) } @@ -433,18 +441,17 @@ func (tc *typeChecker) checkExprBuiltin(env *TypeEnv, expr *Expr) *Error { func checkExprEq(env *TypeEnv, expr *Expr) *Error { pre := getArgTypes(env, expr.Operands()) - exp := Equality.Decl.FuncArgs() - if len(pre) < len(exp.Args) { - return newArgError(expr.Location, expr.Operator(), "too few arguments", pre, exp) + if len(pre) < Equality.Decl.Arity() { + return newArgError(expr.Location, expr.Operator(), "too few arguments", pre, Equality.Decl.FuncArgs()) } - if len(exp.Args) < len(pre) { - return newArgError(expr.Location, expr.Operator(), "too many arguments", pre, exp) + if Equality.Decl.Arity() < len(pre) { + return newArgError(expr.Location, expr.Operator(), "too many arguments", pre, Equality.Decl.FuncArgs()) } a, b := expr.Operand(0), expr.Operand(1) - typeA, typeB := env.Get(a), env.Get(b) + typeA, typeB := env.GetByValue(a.Value), env.GetByValue(b.Value) if !unify2(env, a, typeA, b, typeB) { err := NewError(TypeErr, expr.Location, "match error") @@ -464,7 +471,7 @@ func (tc *typeChecker) checkExprWith(env *TypeEnv, expr *Expr, i int) *Error { } target, value := expr.With[i].Target, expr.With[i].Value - targetType, valueType := env.Get(target), env.Get(value) + targetType, valueType := env.GetByValue(target.Value), env.GetByValue(value.Value) if t, ok := targetType.(*types.Function); ok { // built-in function replacement switch v := valueType.(type) { @@ -500,7 +507,7 @@ func unify2(env *TypeEnv, a *Term, typeA types.Type, b *Term, typeB types.Type) case Var: switch b.Value.(type) { case Var: - return unify1(env, a, types.A, false) && unify1(env, b, env.Get(a), false) + return unify1(env, a, types.A, false) && unify1(env, b, env.GetByValue(a.Value), false) case *Array: return unify2Array(env, b, a) case *object: @@ -516,15 +523,15 @@ func unify2Array(env *TypeEnv, a *Term, b *Term) bool { switch bv := b.Value.(type) { case *Array: if arr.Len() == bv.Len() { - for i := 0; i < arr.Len(); i++ { - if !unify2(env, arr.Elem(i), env.Get(arr.Elem(i)), bv.Elem(i), env.Get(bv.Elem(i))) { + for i := range arr.Len() { + if !unify2(env, arr.Elem(i), env.GetByValue(arr.Elem(i).Value), bv.Elem(i), env.GetByValue(bv.Elem(i).Value)) { return false } } return true } case Var: - return unify1(env, a, types.A, false) && unify1(env, b, env.Get(a), false) + return unify1(env, a, types.A, false) && unify1(env, b, env.GetByValue(a.Value), false) } return false } @@ -536,14 +543,14 @@ func unify2Object(env *TypeEnv, a *Term, b *Term) bool { cv := obj.Intersect(bv) if obj.Len() == bv.Len() && bv.Len() == len(cv) { for i := range cv { - if !unify2(env, cv[i][1], env.Get(cv[i][1]), cv[i][2], env.Get(cv[i][2])) { + if !unify2(env, cv[i][1], env.GetByValue(cv[i][1].Value), cv[i][2], env.GetByValue(cv[i][2].Value)) { return false } } return true } case Var: - return unify1(env, a, types.A, false) && unify1(env, b, env.Get(a), false) + return unify1(env, a, types.A, false) && unify1(env, b, env.GetByValue(a.Value), false) } return false } @@ -556,7 +563,7 @@ func unify1(env *TypeEnv, term *Term, tpe types.Type, union bool) bool { return unify1Array(env, v, tpe, union) case types.Any: if types.Compare(tpe, types.A) == 0 { - for i := 0; i < v.Len(); i++ { + for i := range v.Len() { unify1(env, v.Elem(i), types.A, true) } return true @@ -606,22 +613,22 @@ func unify1(env *TypeEnv, term *Term, tpe types.Type, union bool) bool { } return false case Ref, *ArrayComprehension, *ObjectComprehension, *SetComprehension: - return unifies(env.Get(v), tpe) + return unifies(env.GetByValue(v), tpe) case Var: if !union { - if exist := env.Get(v); exist != nil { + if exist := env.GetByValue(v); exist != nil { return unifies(exist, tpe) } env.tree.PutOne(term.Value, tpe) } else { - env.tree.PutOne(term.Value, types.Or(env.Get(v), tpe)) + env.tree.PutOne(term.Value, types.Or(env.GetByValue(v), tpe)) } return true default: if !IsConstant(v) { panic("unreachable") } - return unifies(env.Get(term), tpe) + return unifies(env.GetByValue(term.Value), tpe) } } @@ -629,7 +636,7 @@ func unify1Array(env *TypeEnv, val *Array, tpe *types.Array, union bool) bool { if val.Len() != tpe.Len() && tpe.Dynamic() == nil { return false } - for i := 0; i < val.Len(); i++ { + for i := range val.Len() { if !unify1(env, val.Elem(i), tpe.Select(i), union) { return false } @@ -684,7 +691,6 @@ func rewriteVarsNop(node Ref) Ref { } func newRefChecker(env *TypeEnv, f varRewriter) *refChecker { - if f == nil { f = rewriteVarsNop } @@ -724,8 +730,8 @@ func (rc *refChecker) Visit(x interface{}) bool { } func (rc *refChecker) checkApply(curr *TypeEnv, ref Ref) *Error { - switch tpe := curr.Get(ref).(type) { - case *types.Function: // NOTE(sr): We don't support first-class functions, except for `with`. + if tpe, ok := curr.GetByRef(ref).(*types.Function); ok { + // NOTE(sr): We don't support first-class functions, except for `with`. return newRefErrUnsupported(ref[0].Location, rc.varRewriter(ref), len(ref)-1, tpe) } @@ -747,19 +753,19 @@ func (rc *refChecker) checkRef(curr *TypeEnv, node *typeTreeNode, ref Ref, idx i switch head.Value.(type) { case Var, String: // OK default: - have := rc.env.Get(head.Value) + have := rc.env.GetByValue(head.Value) return newRefErrInvalid(ref[0].Location, rc.varRewriter(ref), idx, have, types.S, getOneOfForNode(node)) } } - if v, ok := head.Value.(Var); ok && idx != 0 { + if _, ok := head.Value.(Var); ok && idx != 0 { tpe := types.Keys(rc.env.getRefRecExtent(node)) - if exist := rc.env.Get(v); exist != nil { + if exist := rc.env.GetByValue(head.Value); exist != nil { if !unifies(tpe, exist) { return newRefErrInvalid(ref[0].Location, rc.varRewriter(ref), idx, exist, tpe, getOneOfForNode(node)) } } else { - rc.env.tree.PutOne(v, tpe) + rc.env.tree.PutOne(head.Value, tpe) } } @@ -773,8 +779,8 @@ func (rc *refChecker) checkRef(curr *TypeEnv, node *typeTreeNode, ref Ref, idx i case RootDocumentNames.Contains(ref[0]): if idx != 0 { - node.Children().Iter(func(_, child util.T) bool { - _ = rc.checkRef(curr, child.(*typeTreeNode), ref, idx+1) // ignore error + node.Children().Iter(func(_ Value, child *typeTreeNode) bool { + _ = rc.checkRef(curr, child, ref, idx+1) // ignore error return false }) return nil @@ -809,7 +815,7 @@ func (rc *refChecker) checkRefLeaf(tpe types.Type, ref Ref, idx int) *Error { switch value := head.Value.(type) { case Var: - if exist := rc.env.Get(value); exist != nil { + if exist := rc.env.GetByValue(value); exist != nil { if !unifies(exist, keys) { return newRefErrInvalid(ref[0].Location, rc.varRewriter(ref), idx, exist, keys, getOneOfForType(tpe)) } @@ -940,7 +946,7 @@ func unifiesArrays(a, b *types.Array) bool { func unifiesArraysStatic(a, b *types.Array) bool { if a.Len() != 0 { - for i := 0; i < a.Len(); i++ { + for i := range a.Len() { if !unifies(a.Select(i), b.Select(i)) { return false } @@ -995,7 +1001,7 @@ type ArgErrDetail struct { func (d *ArgErrDetail) Lines() []string { lines := make([]string, 2) lines[0] = "have: " + formatArgs(d.Have) - lines[1] = "want: " + fmt.Sprint(d.Want) + lines[1] = "want: " + d.Want.String() return lines } @@ -1061,7 +1067,7 @@ func (r *RefErrInvalidDetail) Lines() []string { lines := []string{r.Ref.String()} offset := len(r.Ref[:r.Pos].String()) + 1 pad := strings.Repeat(" ", offset) - lines = append(lines, fmt.Sprintf("%s^", pad)) + lines = append(lines, pad+"^") if r.Have != nil { lines = append(lines, fmt.Sprintf("%shave (type): %v", pad, r.Have)) } else { @@ -1119,8 +1125,8 @@ func newArgError(loc *Location, builtinName Ref, msg string, have []types.Type, } func getOneOfForNode(node *typeTreeNode) (result []Value) { - node.Children().Iter(func(k, _ util.T) bool { - result = append(result, k.(Value)) + node.Children().Iter(func(k Value, _ *typeTreeNode) bool { + result = append(result, k) return false }) @@ -1310,7 +1316,7 @@ func processAnnotation(ss *SchemaSet, annot *SchemaAnnotation, rule *Rule, allow tpe, err := loadSchema(schema, allowNet) if err != nil { - return nil, NewError(TypeErr, rule.Location, err.Error()) + return nil, NewError(TypeErr, rule.Location, err.Error()) //nolint:govet } return tpe, nil diff --git a/vendor/github.com/open-policy-agent/opa/ast/compare.go b/vendor/github.com/open-policy-agent/opa/v1/ast/compare.go similarity index 84% rename from vendor/github.com/open-policy-agent/opa/ast/compare.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/compare.go index 3bb6f2a75d..452c6365a3 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/compare.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/compare.go @@ -151,14 +151,7 @@ func Compare(a, b interface{}) int { } return 1 case Var: - b := b.(Var) - if a.Equal(b) { - return 0 - } - if a < b { - return -1 - } - return 1 + return VarCompare(a, b.(Var)) case Ref: b := b.(Ref) return termSliceCompare(a, b) @@ -181,7 +174,7 @@ func Compare(a, b interface{}) int { if cmp := Compare(a.Term, b.Term); cmp != 0 { return cmp } - return Compare(a.Body, b.Body) + return a.Body.Compare(b.Body) case *ObjectComprehension: b := b.(*ObjectComprehension) if cmp := Compare(a.Key, b.Key); cmp != 0 { @@ -190,13 +183,13 @@ func Compare(a, b interface{}) int { if cmp := Compare(a.Value, b.Value); cmp != 0 { return cmp } - return Compare(a.Body, b.Body) + return a.Body.Compare(b.Body) case *SetComprehension: b := b.(*SetComprehension) if cmp := Compare(a.Term, b.Term); cmp != 0 { return cmp } - return Compare(a.Body, b.Body) + return a.Body.Compare(b.Body) case Call: b := b.(Call) return termSliceCompare(a, b) @@ -243,7 +236,7 @@ func Compare(a, b interface{}) int { type termSlice []*Term func (s termSlice) Less(i, j int) bool { return Compare(s[i].Value, s[j].Value) < 0 } -func (s termSlice) Swap(i, j int) { x := s[i]; s[i] = s[j]; s[j] = x } +func (s termSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s termSlice) Len() int { return len(s) } func sortOrder(x interface{}) int { @@ -307,7 +300,7 @@ func importsCompare(a, b []*Import) int { if len(b) < minLen { minLen = len(b) } - for i := 0; i < minLen; i++ { + for i := range minLen { if cmp := a[i].Compare(b[i]); cmp != 0 { return cmp } @@ -326,7 +319,7 @@ func annotationsCompare(a, b []*Annotations) int { if len(b) < minLen { minLen = len(b) } - for i := 0; i < minLen; i++ { + for i := range minLen { if cmp := a[i].Compare(b[i]); cmp != 0 { return cmp } @@ -345,7 +338,7 @@ func rulesCompare(a, b []*Rule) int { if len(b) < minLen { minLen = len(b) } - for i := 0; i < minLen; i++ { + for i := range minLen { if cmp := a[i].Compare(b[i]); cmp != 0 { return cmp } @@ -364,7 +357,7 @@ func termSliceCompare(a, b []*Term) int { if len(b) < minLen { minLen = len(b) } - for i := 0; i < minLen; i++ { + for i := range minLen { if cmp := Compare(a[i], b[i]); cmp != 0 { return cmp } @@ -382,7 +375,7 @@ func withSliceCompare(a, b []*With) int { if len(b) < minLen { minLen = len(b) } - for i := 0; i < minLen; i++ { + for i := range minLen { if cmp := Compare(a[i], b[i]); cmp != 0 { return cmp } @@ -394,3 +387,58 @@ func withSliceCompare(a, b []*With) int { } return 0 } + +func VarCompare(a, b Var) int { + if a == b { + return 0 + } + if a < b { + return -1 + } + return 1 +} + +func TermValueCompare(a, b *Term) int { + return a.Value.Compare(b.Value) +} + +func TermValueEqual(a, b *Term) bool { + return ValueEqual(a.Value, b.Value) +} + +func ValueEqual(a, b Value) bool { + // TODO(ae): why doesn't this work the same? + // + // case interface{ Equal(Value) bool }: + // return v.Equal(b) + // + // When put on top, golangci-lint even flags the other cases as unreachable.. + // but TestTopdownVirtualCache will have failing test cases when we replace + // the other cases with the above one.. 🤔 + switch v := a.(type) { + case Null: + return v.Equal(b) + case Boolean: + return v.Equal(b) + case Number: + return v.Equal(b) + case String: + return v.Equal(b) + case Var: + return v.Equal(b) + case Ref: + return v.Equal(b) + case *Array: + return v.Equal(b) + } + + return a.Compare(b) == 0 +} + +func RefCompare(a, b Ref) int { + return termSliceCompare(a, b) +} + +func RefEqual(a, b Ref) bool { + return termSliceEqual(a, b) +} diff --git a/vendor/github.com/open-policy-agent/opa/ast/compile.go b/vendor/github.com/open-policy-agent/opa/v1/ast/compile.go similarity index 94% rename from vendor/github.com/open-policy-agent/opa/ast/compile.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/compile.go index 9025f862b2..13855692cd 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/compile.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/compile.go @@ -8,16 +8,18 @@ import ( "errors" "fmt" "io" + "maps" + "slices" "sort" "strconv" "strings" - "github.com/open-policy-agent/opa/ast/location" "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" + "github.com/open-policy-agent/opa/v1/ast/location" + "github.com/open-policy-agent/opa/v1/metrics" + "github.com/open-policy-agent/opa/v1/types" + "github.com/open-policy-agent/opa/v1/util" ) // CompileErrorLimitDefault is the default number errors a compiler will allow before @@ -117,16 +119,17 @@ type Compiler struct { // with the key being the generated name and value being the original. RewrittenVars map[Var]Var - // Capabliities required by the modules that were compiled. + // Capabilities required by the modules that were compiled. Required *Capabilities localvargen *localVarGenerator moduleLoader ModuleLoader - ruleIndices *util.HashMap + ruleIndices *util.HasherMap[Ref, RuleIndex] stages []stage maxErrs int sorted []string // list of sorted module names pathExists func([]string) (bool, error) + pathConflictCheckRoots []string after map[string][]CompilerStageDefinition metrics metrics.Metrics capabilities *Capabilities // user-supplied capabilities @@ -149,6 +152,11 @@ type Compiler struct { allowUndefinedFuncCalls bool // don't error on calls to unknown functions. evalMode CompilerEvalMode // rewriteTestRulesForTracing bool // rewrite test rules to capture dynamic values for tracing. + defaultRegoVersion RegoVersion +} + +func (c *Compiler) DefaultRegoVersion() RegoVersion { + return c.defaultRegoVersion } // CompilerStage defines the interface for stages in the compiler. @@ -295,21 +303,17 @@ type stage struct { func NewCompiler() *Compiler { c := &Compiler{ - Modules: map[string]*Module{}, - RewrittenVars: map[Var]Var{}, - Required: &Capabilities{}, - ruleIndices: util.NewHashMap(func(a, b util.T) bool { - r1, r2 := a.(Ref), b.(Ref) - return r1.Equal(r2) - }, func(x util.T) int { - return x.(Ref).Hash() - }), + Modules: map[string]*Module{}, + RewrittenVars: map[Var]Var{}, + Required: &Capabilities{}, + ruleIndices: util.NewHasherMap[Ref, RuleIndex](RefEqual), maxErrs: CompileErrorLimitDefault, after: map[string][]CompilerStageDefinition{}, unsafeBuiltinsMap: map[string]struct{}{}, deprecatedBuiltinsMap: map[string]struct{}{}, comprehensionIndices: map[*Term]*ComprehensionIndex{}, debug: debug.Discard(), + defaultRegoVersion: DefaultRegoVersion, } c.ModuleTree = NewModuleTree(nil) @@ -326,7 +330,7 @@ func NewCompiler() *Compiler { {"InitLocalVarGen", "compile_stage_init_local_var_gen", c.initLocalVarGen}, {"RewriteRuleHeadRefs", "compile_stage_rewrite_rule_head_refs", c.rewriteRuleHeadRefs}, {"CheckKeywordOverrides", "compile_stage_check_keyword_overrides", c.checkKeywordOverrides}, - {"CheckDuplicateImports", "compile_stage_check_duplicate_imports", c.checkDuplicateImports}, + {"CheckDuplicateImports", "compile_stage_check_imports", c.checkImports}, {"RemoveImports", "compile_stage_remove_imports", c.removeImports}, {"SetModuleTree", "compile_stage_set_module_tree", c.setModuleTree}, {"SetRuleTree", "compile_stage_set_rule_tree", c.setRuleTree}, // depends on RewriteRuleHeadRefs @@ -383,6 +387,15 @@ func (c *Compiler) WithPathConflictsCheck(fn func([]string) (bool, error)) *Comp return c } +// WithPathConflictsCheckRoots enables checking path conflicts from the specified root instead +// of the top root node. Limiting conflict checks to a known set of roots, such as bundle roots, +// improves performance. Each root has the format of a "/"-delimited string, excluding the "data" +// root document. +func (c *Compiler) WithPathConflictsCheckRoots(rootPaths []string) *Compiler { + c.pathConflictCheckRoots = rootPaths + return c +} + // WithStageAfter registers a stage to run during compilation after // the named stage. func (c *Compiler) WithStageAfter(after string, stage CompilerStageDefinition) *Compiler { @@ -422,24 +435,21 @@ func (c *Compiler) WithDebug(sink io.Writer) *Compiler { return c } -// WithBuiltins is deprecated. Use WithCapabilities instead. +// WithBuiltins is deprecated. +// Deprecated: Use WithCapabilities instead. func (c *Compiler) WithBuiltins(builtins map[string]*Builtin) *Compiler { - c.customBuiltins = make(map[string]*Builtin) - for k, v := range builtins { - c.customBuiltins[k] = v - } + c.customBuiltins = maps.Clone(builtins) return c } -// WithUnsafeBuiltins is deprecated. Use WithCapabilities instead. +// WithUnsafeBuiltins is deprecated. +// Deprecated: Use WithCapabilities instead. func (c *Compiler) WithUnsafeBuiltins(unsafeBuiltins map[string]struct{}) *Compiler { - for name := range unsafeBuiltins { - c.unsafeBuiltinsMap[name] = struct{}{} - } + maps.Copy(c.unsafeBuiltinsMap, unsafeBuiltins) return c } -// WithStrict enables strict mode in the compiler. +// WithStrict toggles strict mode in the compiler. func (c *Compiler) WithStrict(strict bool) *Compiler { c.strict = strict return c @@ -544,7 +554,7 @@ func (c *Compiler) ComprehensionIndex(term *Term) *ComprehensionIndex { // otherwise, the ref is used to perform a ruleset lookup. func (c *Compiler) GetArity(ref Ref) int { if bi := c.builtins[ref.String()]; bi != nil { - return len(bi.Decl.FuncArgs().Args) + return bi.Decl.Arity() } rules := c.GetRulesExact(ref) if len(rules) == 0 { @@ -652,7 +662,7 @@ func (c *Compiler) GetRulesWithPrefix(ref Ref) (rules []*Rule) { return rules } -func extractRules(s []util.T) []*Rule { +func extractRules(s []any) []*Rule { rules := make([]*Rule, len(s)) for i := range s { rules[i] = s[i].(*Rule) @@ -795,7 +805,7 @@ func (c *Compiler) GetRulesDynamicWithOpts(ref Ref, opts RulesOptions) []*Rule { } // Utility: add all rule values to the set. -func insertRules(set map[*Rule]struct{}, rules []util.T) { +func insertRules(set map[*Rule]struct{}, rules []any) { for _, rule := range rules { set[rule.(*Rule)] = struct{}{} } @@ -810,7 +820,7 @@ func (c *Compiler) RuleIndex(path Ref) RuleIndex { if !ok { return nil } - return r.(RuleIndex) + return r } // PassesTypeCheck determines whether the given body passes type checking @@ -840,7 +850,7 @@ func (c *Compiler) PassesTypeCheckRules(rules []*Rule) Errors { tpe, err := loadSchema(schema, allowNet) if err != nil { - return Errors{NewError(TypeErr, nil, err.Error())} + return Errors{NewError(TypeErr, nil, err.Error())} //nolint:govet } c.inputType = tpe } @@ -892,6 +902,13 @@ func (c *Compiler) WithModuleLoader(f ModuleLoader) *Compiler { return c } +// WithDefaultRegoVersion sets the default Rego version to use when a module doesn't specify one; +// such as when it's hand-crafted instead of parsed. +func (c *Compiler) WithDefaultRegoVersion(regoVersion RegoVersion) *Compiler { + c.defaultRegoVersion = regoVersion + return c +} + func (c *Compiler) counterAdd(name string, n uint64) { if c.metrics == nil { return @@ -949,6 +966,13 @@ func (c *Compiler) buildComprehensionIndices() { } } +var ( + keywordsTerm = StringTerm("keywords") + pathTerm = StringTerm("path") + annotationsTerm = StringTerm("annotations") + futureKeywordsPrefix = Ref{FutureRootDocument, keywordsTerm} +) + // buildRequiredCapabilities updates the required capabilities on the compiler // to include any keyword and feature dependencies present in the modules. The // built-in function dependencies will have already been added by the type @@ -958,62 +982,81 @@ func (c *Compiler) buildRequiredCapabilities() { features := map[string]struct{}{} // extract required keywords from modules + keywords := map[string]struct{}{} - futureKeywordsPrefix := Ref{FutureRootDocument, StringTerm("keywords")} + for _, name := range c.sorted { for _, imp := range c.imports[name] { + mod := c.Modules[name] path := imp.Path.Value.(Ref) switch { case path.Equal(RegoV1CompatibleRef): - features[FeatureRegoV1Import] = struct{}{} + if !c.moduleIsRegoV1(mod) { + features[FeatureRegoV1Import] = struct{}{} + } case path.HasPrefix(futureKeywordsPrefix): if len(path) == 2 { - for kw := range futureKeywords { - keywords[kw] = struct{}{} + if c.moduleIsRegoV1(mod) { + for kw := range futureKeywords { + keywords[kw] = struct{}{} + } + } else { + for kw := range allFutureKeywords { + keywords[kw] = struct{}{} + } } } else { - keywords[string(path[2].Value.(String))] = struct{}{} + kw := string(path[2].Value.(String)) + if c.moduleIsRegoV1(mod) { + for allowedKw := range futureKeywords { + if kw == allowedKw { + keywords[kw] = struct{}{} + break + } + } + } else { + for allowedKw := range allFutureKeywords { + if kw == allowedKw { + keywords[kw] = struct{}{} + break + } + } + } } } } } - c.Required.FutureKeywords = stringMapToSortedSlice(keywords) + c.Required.FutureKeywords = util.KeysSorted(keywords) // extract required features from modules for _, name := range c.sorted { - for _, rule := range c.Modules[name].Rules { - refLen := len(rule.Head.Reference) - if refLen >= 3 { - if refLen > len(rule.Head.Reference.ConstantPrefix()) { - features[FeatureRefHeads] = struct{}{} - } else { - features[FeatureRefHeadStringPrefixes] = struct{}{} + mod := c.Modules[name] + + if c.moduleIsRegoV1(mod) { + features[FeatureRegoV1] = struct{}{} + } else { + for _, rule := range mod.Rules { + refLen := len(rule.Head.Reference) + if refLen >= 3 { + if refLen > len(rule.Head.Reference.ConstantPrefix()) { + features[FeatureRefHeads] = struct{}{} + } else { + features[FeatureRefHeadStringPrefixes] = struct{}{} + } } } } } - c.Required.Features = stringMapToSortedSlice(features) + c.Required.Features = util.KeysSorted(features) for i, bi := range c.Required.Builtins { c.Required.Builtins[i] = bi.Minimal() } } -func stringMapToSortedSlice(xs map[string]struct{}) []string { - if len(xs) == 0 { - return nil - } - s := make([]string, 0, len(xs)) - for k := range xs { - s = append(s, k) - } - sort.Strings(s) - return s -} - // checkRecursion ensures that there are no recursive definitions, i.e., there are // no cycles in the Graph. func (c *Compiler) checkRecursion() { @@ -1056,21 +1099,21 @@ func (c *Compiler) checkRuleConflicts() { } kinds := make(map[RuleKind]struct{}, len(node.Values)) - defaultRules := 0 completeRules := 0 partialRules := 0 arities := make(map[int]struct{}, len(node.Values)) name := "" var conflicts []Ref + defaultRules := make([]*Rule, 0) for _, rule := range node.Values { r := rule.(*Rule) ref := r.Ref() - name = rw(ref.Copy()).String() // varRewriter operates in-place + name = rw(ref.CopyNonGround()).String() // varRewriter operates in-place kinds[r.Head.RuleKind()] = struct{}{} arities[len(r.Head.Args)] = struct{}{} if r.Default { - defaultRules++ + defaultRules = append(defaultRules, r) } // Single-value rules may not have any other rules in their extent. @@ -1108,7 +1151,7 @@ func (c *Compiler) checkRuleConflicts() { // data.p.q[r][s] { r := input.r; s := input.s } // data.p[q].r.s { q := input.q } - if r.Ref().IsGround() && len(node.Children) > 0 { + if ref.IsGround() && len(node.Children) > 0 { conflicts = node.flattenChildren() } @@ -1126,8 +1169,21 @@ func (c *Compiler) checkRuleConflicts() { case len(kinds) > 1 || len(arities) > 1 || (completeRules >= 1 && partialRules >= 1): c.err(NewError(TypeErr, node.Values[0].(*Rule).Loc(), "conflicting rules %v found", name)) - case defaultRules > 1: - c.err(NewError(TypeErr, node.Values[0].(*Rule).Loc(), "multiple default rules %s found", name)) + case len(defaultRules) > 1: + + defaultRuleLocations := strings.Builder{} + defaultRuleLocations.WriteString(defaultRules[0].Loc().String()) + for i := 1; i < len(defaultRules); i++ { + defaultRuleLocations.WriteString(", ") + defaultRuleLocations.WriteString(defaultRules[i].Loc().String()) + } + + c.err(NewError( + TypeErr, + defaultRules[0].Module.Package.Loc(), + "multiple default rules %s found at %s", + name, defaultRuleLocations.String()), + ) } return false @@ -1158,7 +1214,7 @@ func (c *Compiler) checkRuleConflicts() { continue // don't self-conflict } msg := fmt.Sprintf("%v conflicts with rule %v defined at %v", childMod.Package, rule.Head.Ref(), rule.Loc()) - c.err(NewError(TypeErr, mod.Package.Loc(), msg)) + c.err(NewError(TypeErr, mod.Package.Loc(), msg)) //nolint:govet } } } @@ -1290,7 +1346,7 @@ func compileSchema(goSchema interface{}, allowNet []string) (*gojsonschema.Schem if goSchema != nil { refLoader = gojsonschema.NewGoLoader(goSchema) } else { - return nil, fmt.Errorf("no schema as input to compile") + return nil, errors.New("no schema as input to compile") } schemasCompiled, err := sl.Compile(refLoader) if err != nil { @@ -1309,13 +1365,13 @@ func mergeSchemas(schemas ...*gojsonschema.SubSchema) (*gojsonschema.SubSchema, if len(schemas[i].PropertiesChildren) > 0 { if !schemas[i].Types.Contains("object") { if err := schemas[i].Types.Add("object"); err != nil { - return nil, fmt.Errorf("unable to set the type in schemas") + return nil, errors.New("unable to set the type in schemas") } } } else if len(schemas[i].ItemsChildren) > 0 { if !schemas[i].Types.Contains("array") { if err := schemas[i].Types.Add("array"); err != nil { - return nil, fmt.Errorf("unable to set the type in schemas") + return nil, errors.New("unable to set the type in schemas") } } } @@ -1327,12 +1383,12 @@ func mergeSchemas(schemas ...*gojsonschema.SubSchema) (*gojsonschema.SubSchema, } else if result.Types.Contains("object") && len(result.PropertiesChildren) > 0 && schemas[i].Types.Contains("object") && len(schemas[i].PropertiesChildren) > 0 { result.PropertiesChildren = append(result.PropertiesChildren, schemas[i].PropertiesChildren...) } else if result.Types.Contains("array") && len(result.ItemsChildren) > 0 && schemas[i].Types.Contains("array") && len(schemas[i].ItemsChildren) > 0 { - for j := 0; j < len(schemas[i].ItemsChildren); j++ { + for j := range len(schemas[i].ItemsChildren) { if len(result.ItemsChildren)-1 < j && !(len(schemas[i].ItemsChildren)-1 < j) { result.ItemsChildren = append(result.ItemsChildren, schemas[i].ItemsChildren[j]) } if result.ItemsChildren[j].Types.String() != schemas[i].ItemsChildren[j].Types.String() { - return nil, fmt.Errorf("unable to merge these schemas") + return nil, errors.New("unable to merge these schemas") } } } @@ -1421,7 +1477,7 @@ func (parser *schemaParser) parseSchemaWithPropertyKey(schema interface{}, prope } return parser.parseSchema(objectOrArrayResult) } else if subSchema.Types.String() != allOfResult.Types.String() { - return nil, fmt.Errorf("unable to merge these schemas") + return nil, errors.New("unable to merge these schemas") } } return parser.parseSchema(allOfResult) @@ -1542,6 +1598,10 @@ func (c *Compiler) checkTypes() { } func (c *Compiler) checkUnsafeBuiltins() { + if len(c.unsafeBuiltinsMap) == 0 { + return + } + for _, name := range c.sorted { errs := checkUnsafeBuiltins(c.unsafeBuiltinsMap, c.Modules[name]) for _, err := range errs { @@ -1551,6 +1611,17 @@ func (c *Compiler) checkUnsafeBuiltins() { } func (c *Compiler) checkDeprecatedBuiltins() { + checkNeeded := false + for _, b := range c.Required.Builtins { + if _, found := c.deprecatedBuiltinsMap[b.Name]; found { + checkNeeded = true + break + } + } + if !checkNeeded { + return + } + for _, name := range c.sorted { mod := c.Modules[name] if c.strict || mod.regoV1Compatible() { @@ -1639,7 +1710,7 @@ func (c *Compiler) init() { if schema := c.schemaSet.Get(SchemaRootRef); schema != nil { tpe, err := loadSchema(schema, c.capabilities.AllowNet) if err != nil { - c.err(NewError(TypeErr, nil, err.Error())) + c.err(NewError(TypeErr, nil, err.Error())) //nolint:govet } else { c.inputType = tpe } @@ -1662,13 +1733,9 @@ func (c *Compiler) err(err *Error) { c.Errors = append(c.Errors, err) } -func (c *Compiler) getExports() *util.HashMap { +func (c *Compiler) getExports() *util.HasherMap[Ref, []Ref] { - rules := util.NewHashMap(func(a, b util.T) bool { - return a.(Ref).Equal(b.(Ref)) - }, func(v util.T) int { - return v.(Ref).Hash() - }) + rules := util.NewHasherMap[Ref, []Ref](RefEqual) for _, name := range c.sorted { mod := c.Modules[name] @@ -1681,30 +1748,52 @@ func (c *Compiler) getExports() *util.HashMap { return rules } -func hashMapAdd(rules *util.HashMap, pkg, rule Ref) { +func refSliceEqual(a, b []Ref) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if !a[i].Equal(b[i]) { + return false + } + } + return true +} + +func hashMapAdd(rules *util.HasherMap[Ref, []Ref], pkg, rule Ref) { prev, ok := rules.Get(pkg) if !ok { rules.Put(pkg, []Ref{rule}) return } - for _, p := range prev.([]Ref) { + for _, p := range prev { if p.Equal(rule) { return } } - rules.Put(pkg, append(prev.([]Ref), rule)) + rules.Put(pkg, append(prev, rule)) } func (c *Compiler) GetAnnotationSet() *AnnotationSet { return c.annotationSet } -func (c *Compiler) checkDuplicateImports() { +func (c *Compiler) checkImports() { modules := make([]*Module, 0, len(c.Modules)) + supportsRegoV1Import := c.capabilities.ContainsFeature(FeatureRegoV1Import) || + c.capabilities.ContainsFeature(FeatureRegoV1) + for _, name := range c.sorted { mod := c.Modules[name] - if c.strict || mod.regoV1Compatible() { + + for _, imp := range mod.Imports { + if !supportsRegoV1Import && RegoV1CompatibleRef.Equal(imp.Path.Value) { + c.err(NewError(CompileErr, imp.Loc(), "rego.v1 import is not supported")) + } + } + + if c.strict || c.moduleIsRegoV1Compatible(mod) { modules = append(modules, mod) } } @@ -1718,7 +1807,7 @@ func (c *Compiler) checkDuplicateImports() { func (c *Compiler) checkKeywordOverrides() { for _, name := range c.sorted { mod := c.Modules[name] - if c.strict || mod.regoV1Compatible() { + if c.strict || c.moduleIsRegoV1Compatible(mod) { errs := checkRootDocumentOverrides(mod) for _, err := range errs { c.err(err) @@ -1727,6 +1816,34 @@ func (c *Compiler) checkKeywordOverrides() { } } +func (c *Compiler) moduleIsRegoV1(mod *Module) bool { + if mod.regoVersion == RegoUndefined { + switch c.defaultRegoVersion { + case RegoUndefined: + c.err(NewError(CompileErr, mod.Package.Loc(), "cannot determine rego version for module")) + return false + case RegoV1: + return true + } + return false + } + return mod.regoVersion == RegoV1 +} + +func (c *Compiler) moduleIsRegoV1Compatible(mod *Module) bool { + if mod.regoVersion == RegoUndefined { + switch c.defaultRegoVersion { + case RegoUndefined: + c.err(NewError(CompileErr, mod.Package.Loc(), "cannot determine rego version for module")) + return false + case RegoV1, RegoV0CompatV1: + return true + } + return false + } + return mod.regoV1Compatible() +} + // resolveAllRefs resolves references in expressions to their fully qualified values. // // For instance, given the following module: @@ -1753,7 +1870,7 @@ func (c *Compiler) resolveAllRefs() { var ruleExports []Ref if x, ok := rules.Get(mod.Package.Path); ok { - ruleExports = x.([]Ref) + ruleExports = x } globals := getGlobals(mod.Package, ruleExports, mod.Imports) @@ -1761,7 +1878,7 @@ func (c *Compiler) resolveAllRefs() { WalkRules(mod, func(rule *Rule) bool { err := resolveRefsInRule(globals, rule) if err != nil { - c.err(NewError(CompileErr, rule.Location, err.Error())) + c.err(NewError(CompileErr, rule.Location, err.Error())) //nolint:govet } return false }) @@ -1786,7 +1903,7 @@ func (c *Compiler) resolveAllRefs() { parsed, err := c.moduleLoader(c.Modules) if err != nil { - c.err(NewError(CompileErr, nil, err.Error())) + c.err(NewError(CompileErr, nil, err.Error())) //nolint:govet return } @@ -1859,6 +1976,9 @@ func (c *Compiler) rewriteRuleHeadRefs() { cannotSpeakStringPrefixRefs = false case FeatureRefHeads: cannotSpeakGeneralRefs = false + case FeatureRegoV1: + cannotSpeakStringPrefixRefs = false + cannotSpeakGeneralRefs = false } } @@ -2110,8 +2230,10 @@ func containsPrintCall(x interface{}) bool { return found } +var printRef = Print.Ref() + func isPrintCall(x *Expr) bool { - return x.IsCall() && x.Operator().Equal(Print.Ref()) + return x.IsCall() && x.Operator().Equal(printRef) } // rewriteRefsInHead will rewrite rules so that the head does not contain any @@ -2346,8 +2468,8 @@ func getPrimaryRuleAnnotations(as *AnnotationSet, rule *Rule) *Annotations { } // Sort by annotation location; chain must start with annotations declared closest to rule, then going outward - sort.SliceStable(annots, func(i, j int) bool { - return annots[i].Location.Compare(annots[j].Location) > 0 + slices.SortStableFunc(annots, func(a, b *Annotations) int { + return -a.Location.Compare(b.Location) }) return annots[0] @@ -2401,12 +2523,15 @@ func rewriteRegoMetadataCalls(metadataChainVar *Var, metadataRuleVar *Var, body return errs } +var regoMetadataChainRef = RegoMetadataChain.Ref() +var regoMetadataRuleRef = RegoMetadataRule.Ref() + func isRegoMetadataChainCall(x *Expr) bool { - return x.IsCall() && x.Operator().Equal(RegoMetadataChain.Ref()) + return x.IsCall() && x.Operator().Equal(regoMetadataChainRef) } func isRegoMetadataRuleCall(x *Expr) bool { - return x.IsCall() && x.Operator().Equal(RegoMetadataRule.Ref()) + return x.IsCall() && x.Operator().Equal(regoMetadataRuleRef) } func createMetadataChain(chain []*AnnotationsRef) (*Term, *Error) { @@ -2416,14 +2541,14 @@ func createMetadataChain(chain []*AnnotationsRef) (*Term, *Error) { p := link.Path.toArray(). Slice(1, -1) // Dropping leading 'data' element of path obj := NewObject( - Item(StringTerm("path"), NewTerm(p)), + Item(pathTerm, NewTerm(p)), ) if link.Annotations != nil { annotObj, err := link.Annotations.toObject() if err != nil { return nil, err } - obj.Insert(StringTerm("annotations"), NewTerm(*annotObj)) + obj.Insert(annotationsTerm, NewTerm(*annotObj)) } metaArray = metaArray.Append(NewTerm(obj)) } @@ -2538,9 +2663,7 @@ func (c *Compiler) rewriteLocalVarsInRule(rule *Rule, unusedArgs VarSet, argsSta // For rewritten vars use the collection of all variables that // were in the stack at some point in time. - for k, v := range stack.rewritten { - c.RewrittenVars[k] = v - } + maps.Copy(c.RewrittenVars, stack.rewritten) rule.Body = body @@ -2608,9 +2731,7 @@ func (xform *rewriteNestedHeadVarLocalTransform) Visit(x interface{}) bool { stop = true } - for k, v := range stack.rewritten { - xform.RewrittenVars[k] = v - } + maps.Copy(xform.RewrittenVars, stack.rewritten) return stop } @@ -2677,7 +2798,7 @@ func (vis *ruleArgLocalRewriter) Visit(x interface{}) Visitor { Walk(vis, vcpy) return k, vcpy, nil }); err != nil { - vis.errs = append(vis.errs, NewError(CompileErr, t.Location, err.Error())) + vis.errs = append(vis.errs, NewError(CompileErr, t.Location, err.Error())) //nolint:govet } else { t.Value = cpy } @@ -2896,7 +3017,7 @@ func (qc *queryCompiler) resolveRefs(qctx *QueryContext, body Body) (Body, error var ruleExports []Ref rules := qc.compiler.getExports() if exist, ok := rules.Get(pkg.Path); ok { - ruleExports = exist.([]Ref) + ruleExports = exist } globals = getGlobals(qctx.Package, ruleExports, qctx.Imports) @@ -2909,7 +3030,7 @@ func (qc *queryCompiler) resolveRefs(qctx *QueryContext, body Body) (Body, error return resolveRefsInBody(globals, ignore, body), nil } -func (qc *queryCompiler) rewriteComprehensionTerms(_ *QueryContext, body Body) (Body, error) { +func (*queryCompiler) rewriteComprehensionTerms(_ *QueryContext, body Body) (Body, error) { gen := newLocalVarGenerator("q", body) f := newEqualityFactory(gen) node, err := rewriteComprehensionTerms(f, body) @@ -2919,13 +3040,13 @@ func (qc *queryCompiler) rewriteComprehensionTerms(_ *QueryContext, body Body) ( return node.(Body), nil } -func (qc *queryCompiler) rewriteDynamicTerms(_ *QueryContext, body Body) (Body, error) { +func (*queryCompiler) rewriteDynamicTerms(_ *QueryContext, body Body) (Body, error) { gen := newLocalVarGenerator("q", body) f := newEqualityFactory(gen) return rewriteDynamics(f, body), nil } -func (qc *queryCompiler) rewriteExprTerms(_ *QueryContext, body Body) (Body, error) { +func (*queryCompiler) rewriteExprTerms(_ *QueryContext, body Body) (Body, error) { gen := newLocalVarGenerator("q", body) return rewriteExprTermsInBody(gen, body), nil } @@ -2937,13 +3058,12 @@ func (qc *queryCompiler) rewriteLocalVars(_ *QueryContext, body Body) (Body, err if len(err) != 0 { return nil, err } - qc.rewritten = make(map[Var]Var, len(stack.rewritten)) - for k, v := range stack.rewritten { - // The vars returned during the rewrite will include all seen vars, - // even if they're not declared with an assignment operation. We don't - // want to include these inside the rewritten set though. - qc.rewritten[k] = v - } + + // The vars returned during the rewrite will include all seen vars, + // even if they're not declared with an assignment operation. We don't + // want to include these inside the rewritten set though. + qc.rewritten = maps.Clone(stack.rewritten) + return body, nil } @@ -3171,9 +3291,7 @@ func getComprehensionIndex(dbg debug.Debug, arity func(Ref) int, candidates VarS result = append(result, NewTerm(v)) } - sort.Slice(result, func(i, j int) bool { - return result[i].Value.Compare(result[j].Value) < 0 - }) + slices.SortFunc(result, TermValueCompare) debugRes := make([]*Term, len(result)) for i, r := range result { @@ -3298,12 +3416,7 @@ func NewModuleTree(mods map[string]*Module) *ModuleTreeNode { root := &ModuleTreeNode{ Children: map[Value]*ModuleTreeNode{}, } - names := make([]string, 0, len(mods)) - for name := range mods { - names = append(names, name) - } - sort.Strings(names) - for _, name := range names { + for _, name := range util.KeysSorted(mods) { m := mods[name] node := root for i, x := range m.Package.Path { @@ -3380,7 +3493,7 @@ func (n *ModuleTreeNode) DepthFirst(f func(*ModuleTreeNode) bool) { // rule path. type TreeNode struct { Key Value - Values []util.T + Values []any Children map[Value]*TreeNode Sorted []Value Hide bool @@ -3432,10 +3545,8 @@ func (n *TreeNode) add(path Ref, rule *Rule) { } node.Children[sub.Key] = sub node.Sorted = append(node.Sorted, sub.Key) - } else { - if rule != nil { - node.Values = append(node.Values, rule) - } + } else if rule != nil { + node.Values = append(node.Values, rule) } } @@ -3500,9 +3611,7 @@ func (n *TreeNode) DepthFirst(f func(*TreeNode) bool) { } func (n *TreeNode) sort() { - sort.Slice(n.Sorted, func(i, j int) bool { - return n.Sorted[i].Compare(n.Sorted[j]) < 0 - }) + slices.SortFunc(n.Sorted, Value.Compare) } func treeNodeFromRef(ref Ref, rule *Rule) *TreeNode { @@ -3513,7 +3622,7 @@ func treeNodeFromRef(ref Ref, rule *Rule) *TreeNode { Children: nil, } if rule != nil { - node.Values = []util.T{rule} + node.Values = []any{rule} } for i := len(ref) - 2; i >= 0; i-- { @@ -3540,9 +3649,7 @@ func (n *TreeNode) flattenChildren() []Ref { }) } - sort.Slice(ret.s, func(i, j int) bool { - return ret.s[i].Compare(ret.s[j]) < 0 - }) + slices.SortFunc(ret.s, RefCompare) return ret.s } @@ -3780,8 +3887,8 @@ func (vs unsafeVars) Vars() (result []unsafeVarLoc) { }) } - sort.Slice(result, func(i, j int) bool { - return result[i].Loc.Compare(result[j].Loc) < 0 + slices.SortFunc(result, func(a, b unsafeVarLoc) int { + return a.Loc.Compare(b.Loc) }) return result @@ -4125,6 +4232,9 @@ func (f *equalityFactory) Generate(other *Term) *Expr { return expr } +// TODO: Move to internal package? +const LocalVarPrefix = "__local" + type localVarGenerator struct { exclude VarSet suffix string @@ -4149,7 +4259,7 @@ func newLocalVarGenerator(suffix string, node interface{}) *localVarGenerator { func (l *localVarGenerator) Generate() Var { for { - result := Var("__local" + l.suffix + strconv.Itoa(l.next) + "__") + result := Var(LocalVarPrefix + l.suffix + strconv.Itoa(l.next) + "__") l.next++ if !l.exclude.Contains(result) { return result @@ -4305,7 +4415,7 @@ func resolveRefsInExpr(globals map[Var]*usedRef, ignore *declaredVarStack, expr cpy.Terms = resolveRefsInTerm(globals, ignore, ts) case []*Term: buf := make([]*Term, len(ts)) - for i := 0; i < len(ts); i++ { + for i := range ts { buf[i] = resolveRefsInTerm(globals, ignore, ts[i]) } cpy.Terms = buf @@ -4410,7 +4520,7 @@ func resolveRefsInTerm(globals map[Var]*usedRef, ignore *declaredVarStack, term func resolveRefsInTermArray(globals map[Var]*usedRef, ignore *declaredVarStack, terms *Array) []*Term { cpy := make([]*Term, terms.Len()) - for i := 0; i < terms.Len(); i++ { + for i := range terms.Len() { cpy[i] = resolveRefsInTerm(globals, ignore, terms.Elem(i)) } return cpy @@ -4418,7 +4528,7 @@ func resolveRefsInTermArray(globals map[Var]*usedRef, ignore *declaredVarStack, func resolveRefsInTermSlice(globals map[Var]*usedRef, ignore *declaredVarStack, terms []*Term) []*Term { cpy := make([]*Term, len(terms)) - for i := 0; i < len(terms); i++ { + for i := range terms { cpy[i] = resolveRefsInTerm(globals, ignore, terms[i]) } return cpy @@ -4692,7 +4802,7 @@ func rewriteDynamicsOne(original *Expr, f *equalityFactory, term *Term, result B connectGeneratedExprs(original, generated) return result, result[len(result)-1].Operand(0) case *Array: - for i := 0; i < v.Len(); i++ { + for i := range v.Len() { var t *Term result, t = rewriteDynamicsOne(original, f, v.Elem(i), result) v.set(i, t) @@ -4769,7 +4879,7 @@ func rewriteExprTermsInHead(gen *localVarGenerator, rule *Rule) { func rewriteExprTermsInBody(gen *localVarGenerator, body Body) Body { cpy := make(Body, 0, len(body)) - for i := 0; i < len(body); i++ { + for i := range body { for _, expr := range expandExpr(gen, body[i]) { cpy.Append(expr) } @@ -4922,7 +5032,7 @@ func expandExprRef(gen *localVarGenerator, v []*Term) (support []*Expr) { } func expandExprTermArray(gen *localVarGenerator, arr *Array) (support []*Expr) { - for i := 0; i < arr.Len(); i++ { + for i := range arr.Len() { extras, v := expandExprTerm(gen, arr.Elem(i)) arr.set(i, v) support = append(support, extras...) @@ -4993,23 +5103,13 @@ func (s *localDeclaredVars) Copy() *localDeclaredVars { for i := range s.vars { stack.vars = append(stack.vars, newDeclaredVarSet()) - for k, v := range s.vars[i].vs { - stack.vars[0].vs[k] = v - } - for k, v := range s.vars[i].reverse { - stack.vars[0].reverse[k] = v - } - for k, v := range s.vars[i].count { - stack.vars[0].count[k] = v - } - for k, v := range s.vars[i].occurrence { - stack.vars[0].occurrence[k] = v - } + maps.Copy(stack.vars[0].vs, s.vars[i].vs) + maps.Copy(stack.vars[0].reverse, s.vars[i].reverse) + maps.Copy(stack.vars[0].occurrence, s.vars[i].occurrence) + maps.Copy(stack.vars[0].count, s.vars[i].count) } - for k, v := range s.rewritten { - stack.rewritten[k] = v - } + maps.Copy(stack.rewritten, s.rewritten) return stack } @@ -5258,7 +5358,7 @@ func rewriteEveryStatement(g *localVarGenerator, stack *localDeclaredVars, expr if v := every.Key.Value.(Var); !v.IsWildcard() { gv, err := rewriteDeclaredVar(g, stack, v, declaredVar) if err != nil { - return nil, append(errs, NewError(CompileErr, every.Loc(), err.Error())) + return nil, append(errs, NewError(CompileErr, every.Loc(), err.Error())) //nolint:govet } every.Key.Value = gv } @@ -5270,7 +5370,7 @@ func rewriteEveryStatement(g *localVarGenerator, stack *localDeclaredVars, expr if v := every.Value.Value.(Var); !v.IsWildcard() { gv, err := rewriteDeclaredVar(g, stack, v, declaredVar) if err != nil { - return nil, append(errs, NewError(CompileErr, every.Loc(), err.Error())) + return nil, append(errs, NewError(CompileErr, every.Loc(), err.Error())) //nolint:govet } every.Value.Value = gv } @@ -5288,7 +5388,7 @@ func rewriteSomeDeclStatement(g *localVarGenerator, stack *localDeclaredVars, ex switch v := decl.Symbols[i].Value.(type) { case Var: if _, err := rewriteDeclaredVar(g, stack, v, declaredVar); err != nil { - return nil, append(errs, NewError(CompileErr, decl.Loc(), err.Error())) + return nil, append(errs, NewError(CompileErr, decl.Loc(), err.Error())) //nolint:govet } case Call: var key, val, container *Term @@ -5316,7 +5416,7 @@ func rewriteSomeDeclStatement(g *localVarGenerator, stack *localDeclaredVars, ex for _, v0 := range outputVarsForExprEq(e, container.Vars()).Sorted() { if _, err := rewriteDeclaredVar(g, stack, v0, declaredVar); err != nil { - return nil, append(errs, NewError(CompileErr, decl.Loc(), err.Error())) + return nil, append(errs, NewError(CompileErr, decl.Loc(), err.Error())) //nolint:govet } } return rewriteDeclaredVarsInExpr(g, stack, e, errs, strict) @@ -5370,7 +5470,7 @@ func rewriteDeclaredAssignment(g *localVarGenerator, stack *localDeclaredVars, e switch v := t.Value.(type) { case Var: if gv, err := rewriteDeclaredVar(g, stack, v, assignedVar); err != nil { - errs = append(errs, NewError(CompileErr, t.Location, err.Error())) + errs = append(errs, NewError(CompileErr, t.Location, err.Error())) //nolint:govet } else { t.Value = gv } @@ -5385,14 +5485,14 @@ func rewriteDeclaredAssignment(g *localVarGenerator, stack *localDeclaredVars, e case Ref: if RootDocumentRefs.Contains(t) { if gv, err := rewriteDeclaredVar(g, stack, v[0].Value.(Var), assignedVar); err != nil { - errs = append(errs, NewError(CompileErr, t.Location, err.Error())) + errs = append(errs, NewError(CompileErr, t.Location, err.Error())) //nolint:govet } else { t.Value = gv } return true } } - errs = append(errs, NewError(CompileErr, t.Location, "cannot assign to %v", TypeName(t.Value))) + errs = append(errs, NewError(CompileErr, t.Location, "cannot assign to %v", ValueName(t.Value))) return true } @@ -5614,7 +5714,7 @@ func validateWith(c *Compiler, unsafeBuiltinsMap map[string]struct{}, expr *Expr case isDataRef(target): ref := target.Value.(Ref) targetNode := c.RuleTree - for i := 0; i < len(ref)-1; i++ { + for i := range len(ref) - 1 { child := targetNode.Child(ref[i].Value) if child == nil { break @@ -5763,7 +5863,7 @@ func safetyErrorSlice(unsafe unsafeVars, rewritten map[Var]Var) (result Errors) v = w } if !v.IsGenerated() { - if _, ok := futureKeywords[string(v)]; ok { + if _, ok := allFutureKeywords[string(v)]; ok { result = append(result, NewError(UnsafeVarErr, pair.Loc, "var %[1]v is unsafe (hint: `import future.keywords.%[1]v` to import a future keyword)", v)) continue @@ -5781,8 +5881,8 @@ func safetyErrorSlice(unsafe unsafeVars, rewritten map[Var]Var) (result Errors) // the latter are not meaningful to the user.) pairs := unsafe.Slice() - sort.Slice(pairs, func(i, j int) bool { - return pairs[i].Expr.Location.Compare(pairs[j].Expr.Location) < 0 + slices.SortFunc(pairs, func(a, b unsafePair) int { + return a.Expr.Location.Compare(b.Expr.Location) }) // Report at most one error per generated variable. @@ -5849,12 +5949,7 @@ func newRefSet(x ...Ref) *refSet { // ContainsPrefix returns true if r is prefixed by any of the existing refs in the set. func (rs *refSet) ContainsPrefix(r Ref) bool { - for i := range rs.s { - if r.HasPrefix(rs.s[i]) { - return true - } - } - return false + return slices.ContainsFunc(rs.s, r.HasPrefix) } // AddPrefix inserts r into the set if r is not prefixed by any existing @@ -5879,8 +5974,6 @@ func (rs *refSet) Sorted() []*Term { for i := range rs.s { terms[i] = NewTerm(rs.s[i]) } - sort.Slice(terms, func(i, j int) bool { - return terms[i].Value.Compare(terms[j].Value) < 0 - }) + slices.SortFunc(terms, TermValueCompare) return terms } diff --git a/vendor/github.com/open-policy-agent/opa/ast/compilehelper.go b/vendor/github.com/open-policy-agent/opa/v1/ast/compilehelper.go similarity index 92% rename from vendor/github.com/open-policy-agent/opa/ast/compilehelper.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/compilehelper.go index dd48884f9d..7d81d45e6d 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/compilehelper.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/compilehelper.go @@ -31,7 +31,9 @@ func CompileModulesWithOpt(modules map[string]string, opts CompileOpts) (*Compil parsed[f] = pm } - compiler := NewCompiler().WithEnablePrintStatements(opts.EnablePrintStatements) + compiler := NewCompiler(). + WithDefaultRegoVersion(opts.ParserOptions.RegoVersion). + WithEnablePrintStatements(opts.EnablePrintStatements) compiler.Compile(parsed) if compiler.Failed() { diff --git a/vendor/github.com/open-policy-agent/opa/ast/compilemetrics.go b/vendor/github.com/open-policy-agent/opa/v1/ast/compilemetrics.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/ast/compilemetrics.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/compilemetrics.go diff --git a/vendor/github.com/open-policy-agent/opa/ast/conflicts.go b/vendor/github.com/open-policy-agent/opa/v1/ast/conflicts.go similarity index 63% rename from vendor/github.com/open-policy-agent/opa/ast/conflicts.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/conflicts.go index c2713ad576..685cc6b694 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/conflicts.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/conflicts.go @@ -5,6 +5,7 @@ package ast import ( + "slices" "strings" ) @@ -18,8 +19,33 @@ func CheckPathConflicts(c *Compiler, exists func([]string) (bool, error)) Errors return nil } - for _, node := range root.Children { - errs = append(errs, checkDocumentConflicts(node, exists, nil)...) + if len(c.pathConflictCheckRoots) == 0 || slices.Contains(c.pathConflictCheckRoots, "") { + for _, child := range root.Children { + errs = append(errs, checkDocumentConflicts(child, exists, nil)...) + } + return errs + } + + for _, rootPath := range c.pathConflictCheckRoots { + // traverse AST from `path` to go to the new root + paths := strings.Split(rootPath, "/") + node := root + for _, key := range paths { + node = node.Child(String(key)) + if node == nil { + break + } + } + + if node == nil { + // could not find the node from the AST (e.g. `path` is from a data file) + // then no conflict is possible + continue + } + + for _, child := range node.Children { + errs = append(errs, checkDocumentConflicts(child, exists, paths)...) + } } return errs diff --git a/vendor/github.com/open-policy-agent/opa/ast/doc.go b/vendor/github.com/open-policy-agent/opa/v1/ast/doc.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/ast/doc.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/doc.go diff --git a/vendor/github.com/open-policy-agent/opa/ast/env.go b/vendor/github.com/open-policy-agent/opa/v1/ast/env.go similarity index 85% rename from vendor/github.com/open-policy-agent/opa/ast/env.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/env.go index c767aafefb..9bffd03e0a 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/env.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/env.go @@ -8,8 +8,8 @@ import ( "fmt" "strings" - "github.com/open-policy-agent/opa/types" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/types" + "github.com/open-policy-agent/opa/v1/util" ) // TypeEnv contains type info for static analysis such as type checking. @@ -29,29 +29,38 @@ func newTypeEnv(f func() *typeChecker) *TypeEnv { } // Get returns the type of x. +// Deprecated: Use GetByValue or GetByRef instead, as they are more efficient. func (env *TypeEnv) Get(x interface{}) types.Type { - if term, ok := x.(*Term); ok { x = term.Value } - switch x := x.(type) { + if v, ok := x.(Value); ok { + return env.GetByValue(v) + } + + panic("unreachable") +} + +// GetByValue returns the type of v. +func (env *TypeEnv) GetByValue(v Value) types.Type { + switch x := v.(type) { // Scalars. case Null: - return types.NewNull() + return types.Nl case Boolean: - return types.NewBoolean() + return types.B case Number: - return types.NewNumber() + return types.N case String: - return types.NewString() + return types.S // Composites. case *Array: static := make([]types.Type, x.Len()) for i := range static { - tpe := env.Get(x.Elem(i).Value) + tpe := env.GetByValue(x.Elem(i).Value) static[i] = tpe } @@ -63,7 +72,7 @@ func (env *TypeEnv) Get(x interface{}) types.Type { return types.NewArray(static, dynamic) case *lazyObj: - return env.Get(x.force()) + return env.GetByValue(x.force()) case *object: static := []*types.StaticProperty{} var dynamic *types.DynamicProperty @@ -72,14 +81,14 @@ func (env *TypeEnv) Get(x interface{}) types.Type { if IsConstant(k.Value) { kjson, err := JSON(k.Value) if err == nil { - tpe := env.Get(v) + tpe := env.GetByValue(v.Value) static = append(static, types.NewStaticProperty(kjson, tpe)) return } } // Can't handle it as a static property, fallback to dynamic - typeK := env.Get(k.Value) - typeV := env.Get(v.Value) + typeK := env.GetByValue(k.Value) + typeV := env.GetByValue(v.Value) dynamic = types.NewDynamicProperty(typeK, typeV) }) @@ -92,8 +101,7 @@ func (env *TypeEnv) Get(x interface{}) types.Type { case Set: var tpe types.Type x.Foreach(func(elem *Term) { - other := env.Get(elem.Value) - tpe = types.Or(tpe, other) + tpe = types.Or(tpe, env.GetByValue(elem.Value)) }) if tpe == nil { tpe = types.A @@ -104,47 +112,46 @@ func (env *TypeEnv) Get(x interface{}) types.Type { case *ArrayComprehension: cpy, errs := env.newChecker().CheckBody(env, x.Body) if len(errs) == 0 { - return types.NewArray(nil, cpy.Get(x.Term)) + return types.NewArray(nil, cpy.GetByValue(x.Term.Value)) } return nil case *ObjectComprehension: 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 types.NewObject(nil, types.NewDynamicProperty(cpy.GetByValue(x.Key.Value), cpy.GetByValue(x.Value.Value))) } return nil case *SetComprehension: cpy, errs := env.newChecker().CheckBody(env, x.Body) if len(errs) == 0 { - return types.NewSet(cpy.Get(x.Term)) + return types.NewSet(cpy.GetByValue(x.Term.Value)) } return nil // Refs. case Ref: - return env.getRef(x) + return env.GetByRef(x) // Vars. case Var: - if node := env.tree.Child(x); node != nil { + if node := env.tree.Child(v); node != nil { return node.Value() } if env.next != nil { - return env.next.Get(x) + return env.next.GetByValue(v) } return nil // Calls. case Call: return nil - - default: - panic("unreachable") } -} -func (env *TypeEnv) getRef(ref Ref) types.Type { + return env.Get(v) +} +// GetByRef returns the type of the value referred to by ref. +func (env *TypeEnv) GetByRef(ref Ref) types.Type { node := env.tree.Child(ref[0].Value) if node == nil { return env.getRefFallback(ref) @@ -156,7 +163,7 @@ func (env *TypeEnv) getRef(ref Ref) types.Type { func (env *TypeEnv) getRefFallback(ref Ref) types.Type { if env.next != nil { - return env.next.Get(ref) + return env.next.GetByRef(ref) } if RootDocumentNames.Contains(ref[0]) { @@ -200,10 +207,7 @@ func (env *TypeEnv) getRefRecExtent(node *typeTreeNode) types.Type { children := []*types.StaticProperty{} - node.Children().Iter(func(k, v util.T) bool { - key := k.(Value) - child := v.(*typeTreeNode) - + node.Children().Iter(func(key Value, child *typeTreeNode) bool { tpe := env.getRefRecExtent(child) // NOTE(sr): Converting to Golang-native types here is an extension of what we did @@ -237,14 +241,14 @@ func (env *TypeEnv) wrap() *TypeEnv { type typeTreeNode struct { key Value value types.Type - children *util.HashMap + children *util.HasherMap[Value, *typeTreeNode] } func newTypeTree() *typeTreeNode { return &typeTreeNode{ key: nil, value: nil, - children: util.NewHashMap(valueEq, valueHash), + children: util.NewHasherMap[Value, *typeTreeNode](ValueEqual), } } @@ -253,10 +257,10 @@ func (n *typeTreeNode) Child(key Value) *typeTreeNode { if !ok { return nil } - return value.(*typeTreeNode) + return value } -func (n *typeTreeNode) Children() *util.HashMap { +func (n *typeTreeNode) Children() *util.HasherMap[Value, *typeTreeNode] { return n.children } @@ -267,7 +271,7 @@ func (n *typeTreeNode) Get(path Ref) types.Type { if !ok { return nil } - curr = child.(*typeTreeNode) + curr = child } return curr.Value() } @@ -285,7 +289,7 @@ func (n *typeTreeNode) PutOne(key Value, tpe types.Type) { child.key = key n.children.Put(key, child) } else { - child = c.(*typeTreeNode) + child = c } child.value = tpe @@ -302,7 +306,7 @@ func (n *typeTreeNode) Put(path Ref, tpe types.Type) { child.key = term.Value curr.children.Put(child.key, child) } else { - child = c.(*typeTreeNode) + child = c } curr = child @@ -324,8 +328,7 @@ func (n *typeTreeNode) Insert(path Ref, tpe types.Type, env *TypeEnv) { child.key = term.Value curr.children.Put(child.key, child) } else { - child = c.(*typeTreeNode) - + child = c if child.value != nil && i+1 < len(path) { // If child has an object value, merge the new value into it. if o, ok := child.value.(*types.Object); ok { @@ -426,13 +429,12 @@ func (n *typeTreeNode) String() string { b.WriteString(v.String()) } - n.children.Iter(func(_, v util.T) bool { - if child, ok := v.(*typeTreeNode); ok { - b.WriteString("\n\t+ ") - s := child.String() - s = strings.ReplaceAll(s, "\n", "\n\t") - b.WriteString(s) - } + n.children.Iter(func(_ Value, child *typeTreeNode) bool { + b.WriteString("\n\t+ ") + s := child.String() + s = strings.ReplaceAll(s, "\n", "\n\t") + b.WriteString(s) + return false }) @@ -444,7 +446,7 @@ func insertIntoObject(o *types.Object, path Ref, tpe types.Type, env *TypeEnv) ( return o, nil } - key := env.Get(path[0].Value) + key := env.GetByValue(path[0].Value) if len(path) == 1 { var dynamicProps *types.DynamicProperty @@ -472,8 +474,8 @@ func insertIntoObject(o *types.Object, path Ref, tpe types.Type, env *TypeEnv) ( func (n *typeTreeNode) Leafs() map[*Ref]types.Type { leafs := map[*Ref]types.Type{} - n.children.Iter(func(_, v util.T) bool { - collectLeafs(v.(*typeTreeNode), nil, leafs) + n.children.Iter(func(_ Value, v *typeTreeNode) bool { + collectLeafs(v, nil, leafs) return false }) return leafs @@ -485,8 +487,8 @@ func collectLeafs(n *typeTreeNode, path Ref, leafs map[*Ref]types.Type) { leafs[&nPath] = n.Value() return } - n.children.Iter(func(_, v util.T) bool { - collectLeafs(v.(*typeTreeNode), nPath, leafs) + n.children.Iter(func(_ Value, v *typeTreeNode) bool { + collectLeafs(v, nPath, leafs) return false }) } diff --git a/vendor/github.com/open-policy-agent/opa/ast/errors.go b/vendor/github.com/open-policy-agent/opa/v1/ast/errors.go similarity index 87% rename from vendor/github.com/open-policy-agent/opa/ast/errors.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/errors.go index 066dfcdd68..c7aab71141 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/errors.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/errors.go @@ -6,7 +6,8 @@ package ast import ( "fmt" - "sort" + "slices" + "strconv" "strings" ) @@ -35,15 +36,12 @@ func (e Errors) Error() string { // Sort sorts the error slice by location. If the locations are equal then the // error message is compared. func (e Errors) Sort() { - sort.Slice(e, func(i, j int) bool { - a := e[i] - b := e[j] - + slices.SortFunc(e, func(a, b *Error) int { if cmp := a.Location.Compare(b.Location); cmp != 0 { - return cmp < 0 + return cmp } - return a.Error() < b.Error() + return strings.Compare(a.Error(), b.Error()) }) } @@ -62,6 +60,9 @@ const ( // RecursionErr indicates recursion was found during compilation. RecursionErr = "rego_recursion_error" + + // FormatErr indicates an error occurred during formatting. + FormatErr = "rego_format_error" ) // IsError returns true if err is an AST error with code. @@ -92,9 +93,9 @@ func (e *Error) Error() string { if e.Location != nil { if len(e.Location.File) > 0 { - prefix += e.Location.File + ":" + fmt.Sprint(e.Location.Row) + prefix += e.Location.File + ":" + strconv.Itoa(e.Location.Row) } else { - prefix += fmt.Sprint(e.Location.Row) + ":" + fmt.Sprint(e.Location.Col) + prefix += strconv.Itoa(e.Location.Row) + ":" + strconv.Itoa(e.Location.Col) } } diff --git a/vendor/github.com/open-policy-agent/opa/ast/index.go b/vendor/github.com/open-policy-agent/opa/v1/ast/index.go similarity index 82% rename from vendor/github.com/open-policy-agent/opa/ast/index.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/index.go index cb0cbea323..722b70e57e 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/index.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/index.go @@ -6,10 +6,12 @@ package ast import ( "fmt" + "slices" "sort" "strings" + "sync" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/util" ) // RuleIndex defines the interface for rule indices. @@ -32,10 +34,10 @@ type RuleIndex interface { // IndexResult contains the result of an index lookup. type IndexResult struct { - Kind RuleKind Rules []*Rule Else map[*Rule][]*Rule Default *Rule + Kind RuleKind EarlyExit bool OnlyGroundRefs bool } @@ -44,7 +46,6 @@ type IndexResult struct { func NewIndexResult(kind RuleKind) *IndexResult { return &IndexResult{ Kind: kind, - Else: map[*Rule][]*Rule{}, } } @@ -54,7 +55,6 @@ func (ir *IndexResult) Empty() bool { } type baseDocEqIndex struct { - skipIndexing Set isVirtual func(Ref) bool root *trieNode defaultRule *Rule @@ -62,9 +62,18 @@ type baseDocEqIndex struct { onlyGroundRefs bool } +var ( + equalityRef = Equality.Ref() + equalRef = Equal.Ref() + globMatchRef = GlobMatch.Ref() + internalPrintRef = InternalPrint.Ref() + internalTestCaseRef = InternalTestCase.Ref() + + skipIndexing = NewSet(NewTerm(internalPrintRef), NewTerm(internalTestCaseRef)) +) + func newBaseDocEqIndex(isVirtual func(Ref) bool) *baseDocEqIndex { return &baseDocEqIndex{ - skipIndexing: NewSet(NewTerm(InternalPrint.Ref())), isVirtual: isVirtual, root: newTrieNodeImpl(), onlyGroundRefs: true, @@ -90,15 +99,15 @@ func (i *baseDocEqIndex) Build(rules []*Rule) bool { i.onlyGroundRefs = rule.Head.Reference.IsGround() } var skip bool - for _, expr := range rule.Body { - if op := expr.OperatorTerm(); op != nil && i.skipIndexing.Contains(op) { + for i := range rule.Body { + if op := rule.Body[i].OperatorTerm(); op != nil && skipIndexing.Contains(op) { skip = true break } } if !skip { - for _, expr := range rule.Body { - indices.Update(rule, expr) + for i := range rule.Body { + indices.Update(rule, rule.Body[i]) } } return false @@ -130,28 +139,49 @@ func (i *baseDocEqIndex) Build(rules []*Rule) bool { } func (i *baseDocEqIndex) Lookup(resolver ValueResolver) (*IndexResult, error) { + tr := ttrPool.Get().(*trieTraversalResult) - tr := newTrieTraversalResult() + defer func() { + clear(tr.unordered) + tr.ordering = tr.ordering[:0] + tr.multiple = false + tr.exist = nil + + ttrPool.Put(tr) + }() err := i.root.Traverse(resolver, tr) if err != nil { return nil, err } - result := NewIndexResult(i.kind) + result := IndexResultPool.Get() + + result.Kind = i.kind result.Default = i.defaultRule result.OnlyGroundRefs = i.onlyGroundRefs - result.Rules = make([]*Rule, 0, len(tr.ordering)) + + if result.Rules == nil { + result.Rules = make([]*Rule, 0, len(tr.ordering)) + } else { + result.Rules = result.Rules[:0] + } + + clear(result.Else) for _, pos := range tr.ordering { - sort.Slice(tr.unordered[pos], func(i, j int) bool { - return tr.unordered[pos][i].prio[1] < tr.unordered[pos][j].prio[1] + slices.SortFunc(tr.unordered[pos], func(a, b *ruleNode) int { + return a.prio[1] - b.prio[1] }) nodes := tr.unordered[pos] root := nodes[0].rule result.Rules = append(result.Rules, root) if len(nodes) > 1 { + if result.Else == nil { + result.Else = map[*Rule][]*Rule{} + } + result.Else[root] = make([]*Rule, len(nodes)-1) for i := 1; i < len(nodes); i++ { result.Else[root][i-1] = nodes[i].rule @@ -159,7 +189,26 @@ func (i *baseDocEqIndex) Lookup(resolver ValueResolver) (*IndexResult, error) { } } - result.EarlyExit = tr.values.Len() == 1 && tr.values.Slice()[0].IsGround() + if !tr.multiple { + // even when the indexer hasn't seen multiple values, the rule itself could be one + // where early exit shouldn't be applied. + var lastValue Value + for i := range result.Rules { + if result.Rules[i].Head.DocKind() != CompleteDoc { + tr.multiple = true + break + } + if result.Rules[i].Head.Value != nil { + if lastValue != nil && !ValueEqual(lastValue, result.Rules[i].Head.Value.Value) { + tr.multiple = true + break + } + lastValue = result.Rules[i].Head.Value.Value + } + } + } + + result.EarlyExit = !tr.multiple return result, nil } @@ -177,13 +226,17 @@ func (i *baseDocEqIndex) AllRules(_ ValueResolver) (*IndexResult, error) { result.Rules = make([]*Rule, 0, len(tr.ordering)) for _, pos := range tr.ordering { - sort.Slice(tr.unordered[pos], func(i, j int) bool { - return tr.unordered[pos][i].prio[1] < tr.unordered[pos][j].prio[1] + slices.SortFunc(tr.unordered[pos], func(a, b *ruleNode) int { + return a.prio[1] - b.prio[1] }) nodes := tr.unordered[pos] root := nodes[0].rule result.Rules = append(result.Rules, root) if len(nodes) > 1 { + if result.Else == nil { + result.Else = map[*Rule][]*Rule{} + } + result.Else[root] = make([]*Rule, len(nodes)-1) for i := 1; i < len(nodes); i++ { result.Else[root][i-1] = nodes[i].rule @@ -191,7 +244,7 @@ func (i *baseDocEqIndex) AllRules(_ ValueResolver) (*IndexResult, error) { } } - result.EarlyExit = tr.values.Len() == 1 && tr.values.Slice()[0].IsGround() + result.EarlyExit = !tr.multiple return result, nil } @@ -220,7 +273,7 @@ type refindex struct { type refindices struct { isVirtual func(Ref) bool rules map[*Rule][]*refindex - frequency *util.HashMap + frequency *util.HasherMap[Ref, int] sorted []Ref } @@ -228,12 +281,7 @@ func newrefindices(isVirtual func(Ref) bool) *refindices { return &refindices{ isVirtual: isVirtual, rules: map[*Rule][]*refindex{}, - frequency: util.NewHashMap(func(a, b util.T) bool { - r1, r2 := a.(Ref), b.(Ref) - return r1.Equal(r2) - }, func(x util.T) int { - return x.(Ref).Hash() - }), + frequency: util.NewHasherMap[Ref, int](RefEqual), } } @@ -255,17 +303,17 @@ func (i *refindices) Update(rule *Rule, expr *Expr) { op := expr.Operator() switch { - case op.Equal(Equality.Ref()): + case op.Equal(equalityRef): i.updateEq(rule, expr) - case op.Equal(Equal.Ref()) && len(expr.Operands()) == 2: + case op.Equal(equalRef) && len(expr.Operands()) == 2: // NOTE(tsandall): if equal() is called with more than two arguments the // output value is being captured in which case the indexer cannot // exclude the rule if the equal() call would return false (because the // false value must still be produced.) i.updateEq(rule, expr) - case op.Equal(GlobMatch.Ref()) && len(expr.Operands()) == 3: + case op.Equal(globMatchRef) && len(expr.Operands()) == 3: // NOTE(sr): Same as with equal() above -- 4 operands means the output // of `glob.match` is captured and the rule can thus not be excluded. i.updateGlobMatch(rule, expr) @@ -281,9 +329,9 @@ func (i *refindices) Sorted() []Ref { counts := make([]int, 0, i.frequency.Len()) i.sorted = make([]Ref, 0, i.frequency.Len()) - i.frequency.Iter(func(k, v util.T) bool { - counts = append(counts, v.(int)) - i.sorted = append(i.sorted, k.(Ref)) + i.frequency.Iter(func(k Ref, v int) bool { + counts = append(counts, v) + i.sorted = append(i.sorted, k) return false }) @@ -354,7 +402,7 @@ func (i *refindices) updateGlobMatch(rule *Rule, expr *Expr) { if ref == nil { for j, arg := range args { if arg.Equal(match) { - ref = Ref{FunctionArgRootDocument, IntNumberTerm(j)} + ref = Ref{FunctionArgRootDocument, InternedIntNumberTerm(j)} } } } @@ -384,7 +432,7 @@ func (i *refindices) insert(rule *Rule, index *refindex) { count = 0 } - i.frequency.Put(index.Ref, count.(int)+1) + i.frequency.Put(index.Ref, count+1) for pos, other := range i.rules[rule] { if other.Ref.Equal(index.Ref) { @@ -412,13 +460,19 @@ type trieWalker interface { type trieTraversalResult struct { unordered map[int][]*ruleNode ordering []int - values Set + exist *Term + multiple bool +} + +var ttrPool = sync.Pool{ + New: func() any { + return newTrieTraversalResult() + }, } func newTrieTraversalResult() *trieTraversalResult { return &trieTraversalResult{ unordered: map[int][]*ruleNode{}, - values: NewSet(), } } @@ -431,21 +485,30 @@ func (tr *trieTraversalResult) Add(t *trieNode) { } tr.unordered[root] = append(nodes, node) } - if t.values != nil { - t.values.Foreach(func(v *Term) { tr.values.Add(v) }) + if t.multiple { + tr.multiple = true + } + if tr.multiple || t.value == nil { + return } + if t.value.IsGround() && tr.exist == nil || tr.exist.Equal(t.value) { + tr.exist = t.value + return + } + tr.multiple = true } type trieNode struct { ref Ref - values Set mappers []*valueMapper next *trieNode any *trieNode undefined *trieNode - scalars *util.HashMap + scalars *util.HasherMap[Value, *trieNode] array *trieNode rules []*ruleNode + value *Term + multiple bool } func (node *trieNode) String() string { @@ -468,9 +531,7 @@ func (node *trieNode) String() string { } if node.scalars.Len() > 0 { buf := make([]string, 0, node.scalars.Len()) - node.scalars.Iter(func(k, v util.T) bool { - key := k.(Value) - val := v.(*trieNode) + node.scalars.Iter(func(key Value, val *trieNode) bool { buf = append(buf, fmt.Sprintf("scalar(%v):%p", key, val)) return false }) @@ -483,10 +544,8 @@ func (node *trieNode) String() string { if len(node.mappers) > 0 { flags = append(flags, fmt.Sprintf("%d mapper(s)", len(node.mappers))) } - if node.values != nil { - if l := node.values.Len(); l > 0 { - flags = append(flags, fmt.Sprintf("%d value(s)", l)) - } + if node.value != nil { + flags = append(flags, "value exists") } return strings.Join(flags, " ") } @@ -494,13 +553,12 @@ func (node *trieNode) String() string { func (node *trieNode) append(prio [2]int, rule *Rule) { node.rules = append(node.rules, &ruleNode{prio, rule}) - if node.values != nil && rule.Head.Value != nil { - node.values.Add(rule.Head.Value) - return + if node.value != nil && rule.Head.Value != nil && !node.value.Equal(rule.Head.Value) { + node.multiple = true } - if node.values == nil && rule.Head.DocKind() == CompleteDoc { - node.values = NewSet(rule.Head.Value) + if node.value == nil && rule.Head.DocKind() == CompleteDoc { + node.value = rule.Head.Value } } @@ -511,7 +569,7 @@ type ruleNode struct { func newTrieNodeImpl() *trieNode { return &trieNode{ - scalars: util.NewHashMap(valueEq, valueHash), + scalars: util.NewHasherMap[Value, *trieNode](ValueEqual), } } @@ -527,8 +585,7 @@ func (node *trieNode) Do(walker trieWalker) { node.undefined.Do(next) } - node.scalars.Iter(func(_, v util.T) bool { - child := v.(*trieNode) + node.scalars.Iter(func(_ Value, child *trieNode) bool { child.Do(next) return false }) @@ -594,7 +651,7 @@ func (node *trieNode) insertValue(value Value) *trieNode { child = newTrieNodeImpl() node.scalars.Put(value, child) } - return child.(*trieNode) + return child case *Array: if node.array == nil { node.array = newTrieNodeImpl() @@ -623,7 +680,7 @@ func (node *trieNode) insertArray(arr *Array) *trieNode { child = newTrieNodeImpl() node.scalars.Put(head, child) } - return child.(*trieNode).insertArray(arr.Slice(1, -1)) + return child.insertArray(arr.Slice(1, -1)) } panic("illegal value") @@ -688,7 +745,7 @@ func (node *trieNode) traverseValue(resolver ValueResolver, tr *trieTraversalRes if !ok { return nil } - return child.(*trieNode).Traverse(resolver, tr) + return child.Traverse(resolver, tr) } return nil @@ -713,11 +770,16 @@ func (node *trieNode) traverseArray(resolver ValueResolver, tr *trieTraversalRes return nil } - child, ok := node.scalars.Get(head) - if !ok { - return nil + switch head := head.(type) { + case Null, Boolean, Number, String: + child, ok := node.scalars.Get(head) + if !ok { + return nil + } + return child.traverseArray(resolver, tr, arr.Slice(1, -1)) } - return child.(*trieNode).traverseArray(resolver, tr, arr.Slice(1, -1)) + + panic("illegal value") } func (node *trieNode) traverseUnknown(resolver ValueResolver, tr *trieTraversalResult) error { @@ -743,12 +805,8 @@ func (node *trieNode) traverseUnknown(resolver ValueResolver, tr *trieTraversalR } var iterErr error - node.scalars.Iter(func(_, v util.T) bool { - child := v.(*trieNode) - if iterErr = child.traverseUnknown(resolver, tr); iterErr != nil { - return true - } - return false + node.scalars.Iter(func(_ Value, child *trieNode) bool { + return child.traverseUnknown(resolver, tr) != nil }) return iterErr @@ -762,9 +820,9 @@ func eqOperandsToRefAndValue(isVirtual func(Ref) bool, args []*Term, a, b *Term) switch v := a.Value.(type) { case Var: for i, arg := range args { - if arg.Value.Compare(v) == 0 { + if arg.Value.Compare(a.Value) == 0 { if bval, ok := indexValue(b); ok { - return &refindex{Ref: Ref{FunctionArgRootDocument, IntNumberTerm(i)}, Value: bval}, true + return &refindex{Ref: Ref{FunctionArgRootDocument, InternedIntNumberTerm(i)}, Value: bval}, true } } } @@ -825,7 +883,7 @@ func globDelimiterToString(delim *Term) (string, bool) { if arr.Len() == 0 { result = "." } else { - for i := 0; i < arr.Len(); i++ { + for i := range arr.Len() { term := arr.Elem(i) s, ok := term.Value.(String) if !ok { @@ -838,6 +896,8 @@ func globDelimiterToString(delim *Term) (string, bool) { return result, true } +var globwildcard = VarTerm("$globwildcard") + func globPatternToArray(pattern *Term, delim string) *Term { s, ok := pattern.Value.(String) @@ -850,7 +910,7 @@ func globPatternToArray(pattern *Term, delim string) *Term { for i := range parts { if parts[i] == "*" { - arr[i] = VarTerm("$globwildcard") + arr[i] = globwildcard } else { var escaped bool for _, c := range parts[i] { diff --git a/vendor/github.com/open-policy-agent/opa/ast/internal/scanner/scanner.go b/vendor/github.com/open-policy-agent/opa/v1/ast/internal/scanner/scanner.go similarity index 91% rename from vendor/github.com/open-policy-agent/opa/ast/internal/scanner/scanner.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/internal/scanner/scanner.go index a0200ac18d..d70253bc5c 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/internal/scanner/scanner.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/internal/scanner/scanner.go @@ -10,7 +10,8 @@ import ( "unicode" "unicode/utf8" - "github.com/open-policy-agent/opa/ast/internal/tokens" + "github.com/open-policy-agent/opa/v1/ast/internal/tokens" + "github.com/open-policy-agent/opa/v1/util" ) const bom = 0xFEFF @@ -18,31 +19,31 @@ const bom = 0xFEFF // Scanner is used to tokenize an input stream of // Rego source code. type Scanner struct { + keywords map[string]tokens.Token + bs []byte + errors []Error + tabs []int offset int row int col int - bs []byte - curr rune width int - errors []Error - keywords map[string]tokens.Token - tabs []int + curr rune regoV1Compatible bool } // Error represents a scanner error. type Error struct { - Pos Position Message string + Pos Position } // Position represents a point in the scanned source code. type Position struct { + Tabs []int // positions of any tabs preceding Col Offset int // start offset in bytes End int // end offset in bytes Row int // line number computed in bytes Col int // column number computed in bytes - Tabs []int // positions of any tabs preceding Col } // New returns an initialized scanner that will scan @@ -100,8 +101,8 @@ func (s *Scanner) Keyword(lit string) tokens.Token { func (s *Scanner) AddKeyword(kw string, tok tokens.Token) { s.keywords[kw] = tok - switch tok { - case tokens.Every: // importing 'every' means also importing 'in' + if tok == tokens.Every { + // importing 'every' means also importing 'in' s.keywords["in"] = tokens.In } } @@ -164,7 +165,21 @@ func (s *Scanner) Scan() (tokens.Token, Position, string, []Error) { var lit string if s.isWhitespace() { - lit = string(s.curr) + // string(rune) is an unnecessary heap allocation in this case as we know all + // the possible whitespace values, and can simply translate to string ourselves + switch s.curr { + case ' ': + lit = " " + case '\t': + lit = "\t" + case '\n': + lit = "\n" + case '\r': + lit = "\r" + default: + // unreachable unless isWhitespace changes + lit = string(s.curr) + } s.next() tok = tokens.Whitespace } else if isLetter(s.curr) { @@ -270,7 +285,8 @@ func (s *Scanner) scanIdentifier() string { for isLetter(s.curr) || isDigit(s.curr) { s.next() } - return string(s.bs[start : s.offset-1]) + + return util.ByteSliceToString(s.bs[start : s.offset-1]) } func (s *Scanner) scanNumber() string { @@ -321,7 +337,7 @@ func (s *Scanner) scanNumber() string { } } - return string(s.bs[start : s.offset-1]) + return util.ByteSliceToString(s.bs[start : s.offset-1]) } func (s *Scanner) scanString() string { @@ -355,7 +371,7 @@ func (s *Scanner) scanString() string { } } - return string(s.bs[start : s.offset-1]) + return util.ByteSliceToString(s.bs[start : s.offset-1]) } func (s *Scanner) scanRawString() string { @@ -370,7 +386,8 @@ func (s *Scanner) scanRawString() string { break } } - return string(s.bs[start : s.offset-1]) + + return util.ByteSliceToString(s.bs[start : s.offset-1]) } func (s *Scanner) scanComment() string { @@ -381,9 +398,10 @@ func (s *Scanner) scanComment() string { end := s.offset - 1 // Trim carriage returns that precede the newline if s.offset > 1 && s.bs[s.offset-2] == '\r' { - end = end - 1 + end -= 1 } - return string(s.bs[start:end]) + + return util.ByteSliceToString(s.bs[start:end]) } func (s *Scanner) next() { @@ -413,7 +431,7 @@ func (s *Scanner) next() { if s.curr == '\n' { s.row++ s.col = 0 - s.tabs = []int{} + s.tabs = s.tabs[:0] } else { s.col++ if s.curr == '\t' { diff --git a/vendor/github.com/open-policy-agent/opa/ast/internal/tokens/tokens.go b/vendor/github.com/open-policy-agent/opa/v1/ast/internal/tokens/tokens.go similarity index 93% rename from vendor/github.com/open-policy-agent/opa/ast/internal/tokens/tokens.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/internal/tokens/tokens.go index 623ed7ed21..4033ba81ae 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/internal/tokens/tokens.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/internal/tokens/tokens.go @@ -4,12 +4,14 @@ package tokens +import "maps" + // Token represents a single Rego source code token // for use by the Parser. -type Token int +type Token uint8 func (t Token) String() string { - if t < 0 || int(t) >= len(strings) { + if int(t) >= len(strings) { return "unknown" } return strings[t] @@ -137,11 +139,7 @@ var keywords = map[string]Token{ // Keywords returns a copy of the default string -> Token keyword map. func Keywords() map[string]Token { - cpy := make(map[string]Token, len(keywords)) - for k, v := range keywords { - cpy[k] = v - } - return cpy + return maps.Clone(keywords) } // IsKeyword returns if a token is a keyword diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/interning.go b/vendor/github.com/open-policy-agent/opa/v1/ast/interning.go new file mode 100644 index 0000000000..012cffb9a9 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/interning.go @@ -0,0 +1,1120 @@ +// Copyright 2024 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 "strconv" + +// NOTE! Great care must be taken **not** to modify the terms returned +// from these functions, as they are shared across all callers. + +var ( + booleanTrueTerm = &Term{Value: Boolean(true)} + booleanFalseTerm = &Term{Value: Boolean(false)} + + // since this is by far the most common negative number + minusOneTerm = &Term{Value: Number("-1")} + + InternedNullTerm = &Term{Value: Null{}} + + InternedEmptyString = StringTerm("") + InternedEmptyObject = ObjectTerm() +) + +// InternedBooleanTerm returns an interned term with the given boolean value. +func InternedBooleanTerm(b bool) *Term { + if b { + return booleanTrueTerm + } + + return booleanFalseTerm +} + +// InternedIntNumberTerm returns a term with the given integer value. The term is +// cached between -1 to 512, and for values outside of that range, this function +// is equivalent to ast.IntNumberTerm. +func InternedIntNumberTerm(i int) *Term { + if i >= 0 && i < len(intNumberTerms) { + return intNumberTerms[i] + } + + if i == -1 { + return minusOneTerm + } + + return &Term{Value: Number(strconv.Itoa(i))} +} + +// InternedIntFromString returns a term with the given integer value if the string +// maps to an interned term. If the string does not map to an interned term, nil is +// returned. +func InternedIntNumberTermFromString(s string) *Term { + if term, ok := stringToIntNumberTermMap[s]; ok { + return term + } + + return nil +} + +// HasInternedIntNumberTerm returns true if the given integer value maps to an interned +// term, otherwise false. +func HasInternedIntNumberTerm(i int) bool { + return i >= -1 && i < len(intNumberTerms) +} + +func InternedStringTerm(s string) *Term { + if term, ok := internedStringTerms[s]; ok { + return term + } + + return StringTerm(s) +} + +var internedStringTerms = map[string]*Term{ + "": InternedEmptyString, + "0": StringTerm("0"), + "1": StringTerm("1"), + "2": StringTerm("2"), + "3": StringTerm("3"), + "4": StringTerm("4"), + "5": StringTerm("5"), + "6": StringTerm("6"), + "7": StringTerm("7"), + "8": StringTerm("8"), + "9": StringTerm("9"), + "10": StringTerm("10"), +} + +var stringToIntNumberTermMap = map[string]*Term{ + "-1": minusOneTerm, + "0": intNumberTerms[0], + "1": intNumberTerms[1], + "2": intNumberTerms[2], + "3": intNumberTerms[3], + "4": intNumberTerms[4], + "5": intNumberTerms[5], + "6": intNumberTerms[6], + "7": intNumberTerms[7], + "8": intNumberTerms[8], + "9": intNumberTerms[9], + "10": intNumberTerms[10], + "11": intNumberTerms[11], + "12": intNumberTerms[12], + "13": intNumberTerms[13], + "14": intNumberTerms[14], + "15": intNumberTerms[15], + "16": intNumberTerms[16], + "17": intNumberTerms[17], + "18": intNumberTerms[18], + "19": intNumberTerms[19], + "20": intNumberTerms[20], + "21": intNumberTerms[21], + "22": intNumberTerms[22], + "23": intNumberTerms[23], + "24": intNumberTerms[24], + "25": intNumberTerms[25], + "26": intNumberTerms[26], + "27": intNumberTerms[27], + "28": intNumberTerms[28], + "29": intNumberTerms[29], + "30": intNumberTerms[30], + "31": intNumberTerms[31], + "32": intNumberTerms[32], + "33": intNumberTerms[33], + "34": intNumberTerms[34], + "35": intNumberTerms[35], + "36": intNumberTerms[36], + "37": intNumberTerms[37], + "38": intNumberTerms[38], + "39": intNumberTerms[39], + "40": intNumberTerms[40], + "41": intNumberTerms[41], + "42": intNumberTerms[42], + "43": intNumberTerms[43], + "44": intNumberTerms[44], + "45": intNumberTerms[45], + "46": intNumberTerms[46], + "47": intNumberTerms[47], + "48": intNumberTerms[48], + "49": intNumberTerms[49], + "50": intNumberTerms[50], + "51": intNumberTerms[51], + "52": intNumberTerms[52], + "53": intNumberTerms[53], + "54": intNumberTerms[54], + "55": intNumberTerms[55], + "56": intNumberTerms[56], + "57": intNumberTerms[57], + "58": intNumberTerms[58], + "59": intNumberTerms[59], + "60": intNumberTerms[60], + "61": intNumberTerms[61], + "62": intNumberTerms[62], + "63": intNumberTerms[63], + "64": intNumberTerms[64], + "65": intNumberTerms[65], + "66": intNumberTerms[66], + "67": intNumberTerms[67], + "68": intNumberTerms[68], + "69": intNumberTerms[69], + "70": intNumberTerms[70], + "71": intNumberTerms[71], + "72": intNumberTerms[72], + "73": intNumberTerms[73], + "74": intNumberTerms[74], + "75": intNumberTerms[75], + "76": intNumberTerms[76], + "77": intNumberTerms[77], + "78": intNumberTerms[78], + "79": intNumberTerms[79], + "80": intNumberTerms[80], + "81": intNumberTerms[81], + "82": intNumberTerms[82], + "83": intNumberTerms[83], + "84": intNumberTerms[84], + "85": intNumberTerms[85], + "86": intNumberTerms[86], + "87": intNumberTerms[87], + "88": intNumberTerms[88], + "89": intNumberTerms[89], + "90": intNumberTerms[90], + "91": intNumberTerms[91], + "92": intNumberTerms[92], + "93": intNumberTerms[93], + "94": intNumberTerms[94], + "95": intNumberTerms[95], + "96": intNumberTerms[96], + "97": intNumberTerms[97], + "98": intNumberTerms[98], + "99": intNumberTerms[99], + "100": intNumberTerms[100], + "101": intNumberTerms[101], + "102": intNumberTerms[102], + "103": intNumberTerms[103], + "104": intNumberTerms[104], + "105": intNumberTerms[105], + "106": intNumberTerms[106], + "107": intNumberTerms[107], + "108": intNumberTerms[108], + "109": intNumberTerms[109], + "110": intNumberTerms[110], + "111": intNumberTerms[111], + "112": intNumberTerms[112], + "113": intNumberTerms[113], + "114": intNumberTerms[114], + "115": intNumberTerms[115], + "116": intNumberTerms[116], + "117": intNumberTerms[117], + "118": intNumberTerms[118], + "119": intNumberTerms[119], + "120": intNumberTerms[120], + "121": intNumberTerms[121], + "122": intNumberTerms[122], + "123": intNumberTerms[123], + "124": intNumberTerms[124], + "125": intNumberTerms[125], + "126": intNumberTerms[126], + "127": intNumberTerms[127], + "128": intNumberTerms[128], + "129": intNumberTerms[129], + "130": intNumberTerms[130], + "131": intNumberTerms[131], + "132": intNumberTerms[132], + "133": intNumberTerms[133], + "134": intNumberTerms[134], + "135": intNumberTerms[135], + "136": intNumberTerms[136], + "137": intNumberTerms[137], + "138": intNumberTerms[138], + "139": intNumberTerms[139], + "140": intNumberTerms[140], + "141": intNumberTerms[141], + "142": intNumberTerms[142], + "143": intNumberTerms[143], + "144": intNumberTerms[144], + "145": intNumberTerms[145], + "146": intNumberTerms[146], + "147": intNumberTerms[147], + "148": intNumberTerms[148], + "149": intNumberTerms[149], + "150": intNumberTerms[150], + "151": intNumberTerms[151], + "152": intNumberTerms[152], + "153": intNumberTerms[153], + "154": intNumberTerms[154], + "155": intNumberTerms[155], + "156": intNumberTerms[156], + "157": intNumberTerms[157], + "158": intNumberTerms[158], + "159": intNumberTerms[159], + "160": intNumberTerms[160], + "161": intNumberTerms[161], + "162": intNumberTerms[162], + "163": intNumberTerms[163], + "164": intNumberTerms[164], + "165": intNumberTerms[165], + "166": intNumberTerms[166], + "167": intNumberTerms[167], + "168": intNumberTerms[168], + "169": intNumberTerms[169], + "170": intNumberTerms[170], + "171": intNumberTerms[171], + "172": intNumberTerms[172], + "173": intNumberTerms[173], + "174": intNumberTerms[174], + "175": intNumberTerms[175], + "176": intNumberTerms[176], + "177": intNumberTerms[177], + "178": intNumberTerms[178], + "179": intNumberTerms[179], + "180": intNumberTerms[180], + "181": intNumberTerms[181], + "182": intNumberTerms[182], + "183": intNumberTerms[183], + "184": intNumberTerms[184], + "185": intNumberTerms[185], + "186": intNumberTerms[186], + "187": intNumberTerms[187], + "188": intNumberTerms[188], + "189": intNumberTerms[189], + "190": intNumberTerms[190], + "191": intNumberTerms[191], + "192": intNumberTerms[192], + "193": intNumberTerms[193], + "194": intNumberTerms[194], + "195": intNumberTerms[195], + "196": intNumberTerms[196], + "197": intNumberTerms[197], + "198": intNumberTerms[198], + "199": intNumberTerms[199], + "200": intNumberTerms[200], + "201": intNumberTerms[201], + "202": intNumberTerms[202], + "203": intNumberTerms[203], + "204": intNumberTerms[204], + "205": intNumberTerms[205], + "206": intNumberTerms[206], + "207": intNumberTerms[207], + "208": intNumberTerms[208], + "209": intNumberTerms[209], + "210": intNumberTerms[210], + "211": intNumberTerms[211], + "212": intNumberTerms[212], + "213": intNumberTerms[213], + "214": intNumberTerms[214], + "215": intNumberTerms[215], + "216": intNumberTerms[216], + "217": intNumberTerms[217], + "218": intNumberTerms[218], + "219": intNumberTerms[219], + "220": intNumberTerms[220], + "221": intNumberTerms[221], + "222": intNumberTerms[222], + "223": intNumberTerms[223], + "224": intNumberTerms[224], + "225": intNumberTerms[225], + "226": intNumberTerms[226], + "227": intNumberTerms[227], + "228": intNumberTerms[228], + "229": intNumberTerms[229], + "230": intNumberTerms[230], + "231": intNumberTerms[231], + "232": intNumberTerms[232], + "233": intNumberTerms[233], + "234": intNumberTerms[234], + "235": intNumberTerms[235], + "236": intNumberTerms[236], + "237": intNumberTerms[237], + "238": intNumberTerms[238], + "239": intNumberTerms[239], + "240": intNumberTerms[240], + "241": intNumberTerms[241], + "242": intNumberTerms[242], + "243": intNumberTerms[243], + "244": intNumberTerms[244], + "245": intNumberTerms[245], + "246": intNumberTerms[246], + "247": intNumberTerms[247], + "248": intNumberTerms[248], + "249": intNumberTerms[249], + "250": intNumberTerms[250], + "251": intNumberTerms[251], + "252": intNumberTerms[252], + "253": intNumberTerms[253], + "254": intNumberTerms[254], + "255": intNumberTerms[255], + "256": intNumberTerms[256], + "257": intNumberTerms[257], + "258": intNumberTerms[258], + "259": intNumberTerms[259], + "260": intNumberTerms[260], + "261": intNumberTerms[261], + "262": intNumberTerms[262], + "263": intNumberTerms[263], + "264": intNumberTerms[264], + "265": intNumberTerms[265], + "266": intNumberTerms[266], + "267": intNumberTerms[267], + "268": intNumberTerms[268], + "269": intNumberTerms[269], + "270": intNumberTerms[270], + "271": intNumberTerms[271], + "272": intNumberTerms[272], + "273": intNumberTerms[273], + "274": intNumberTerms[274], + "275": intNumberTerms[275], + "276": intNumberTerms[276], + "277": intNumberTerms[277], + "278": intNumberTerms[278], + "279": intNumberTerms[279], + "280": intNumberTerms[280], + "281": intNumberTerms[281], + "282": intNumberTerms[282], + "283": intNumberTerms[283], + "284": intNumberTerms[284], + "285": intNumberTerms[285], + "286": intNumberTerms[286], + "287": intNumberTerms[287], + "288": intNumberTerms[288], + "289": intNumberTerms[289], + "290": intNumberTerms[290], + "291": intNumberTerms[291], + "292": intNumberTerms[292], + "293": intNumberTerms[293], + "294": intNumberTerms[294], + "295": intNumberTerms[295], + "296": intNumberTerms[296], + "297": intNumberTerms[297], + "298": intNumberTerms[298], + "299": intNumberTerms[299], + "300": intNumberTerms[300], + "301": intNumberTerms[301], + "302": intNumberTerms[302], + "303": intNumberTerms[303], + "304": intNumberTerms[304], + "305": intNumberTerms[305], + "306": intNumberTerms[306], + "307": intNumberTerms[307], + "308": intNumberTerms[308], + "309": intNumberTerms[309], + "310": intNumberTerms[310], + "311": intNumberTerms[311], + "312": intNumberTerms[312], + "313": intNumberTerms[313], + "314": intNumberTerms[314], + "315": intNumberTerms[315], + "316": intNumberTerms[316], + "317": intNumberTerms[317], + "318": intNumberTerms[318], + "319": intNumberTerms[319], + "320": intNumberTerms[320], + "321": intNumberTerms[321], + "322": intNumberTerms[322], + "323": intNumberTerms[323], + "324": intNumberTerms[324], + "325": intNumberTerms[325], + "326": intNumberTerms[326], + "327": intNumberTerms[327], + "328": intNumberTerms[328], + "329": intNumberTerms[329], + "330": intNumberTerms[330], + "331": intNumberTerms[331], + "332": intNumberTerms[332], + "333": intNumberTerms[333], + "334": intNumberTerms[334], + "335": intNumberTerms[335], + "336": intNumberTerms[336], + "337": intNumberTerms[337], + "338": intNumberTerms[338], + "339": intNumberTerms[339], + "340": intNumberTerms[340], + "341": intNumberTerms[341], + "342": intNumberTerms[342], + "343": intNumberTerms[343], + "344": intNumberTerms[344], + "345": intNumberTerms[345], + "346": intNumberTerms[346], + "347": intNumberTerms[347], + "348": intNumberTerms[348], + "349": intNumberTerms[349], + "350": intNumberTerms[350], + "351": intNumberTerms[351], + "352": intNumberTerms[352], + "353": intNumberTerms[353], + "354": intNumberTerms[354], + "355": intNumberTerms[355], + "356": intNumberTerms[356], + "357": intNumberTerms[357], + "358": intNumberTerms[358], + "359": intNumberTerms[359], + "360": intNumberTerms[360], + "361": intNumberTerms[361], + "362": intNumberTerms[362], + "363": intNumberTerms[363], + "364": intNumberTerms[364], + "365": intNumberTerms[365], + "366": intNumberTerms[366], + "367": intNumberTerms[367], + "368": intNumberTerms[368], + "369": intNumberTerms[369], + "370": intNumberTerms[370], + "371": intNumberTerms[371], + "372": intNumberTerms[372], + "373": intNumberTerms[373], + "374": intNumberTerms[374], + "375": intNumberTerms[375], + "376": intNumberTerms[376], + "377": intNumberTerms[377], + "378": intNumberTerms[378], + "379": intNumberTerms[379], + "380": intNumberTerms[380], + "381": intNumberTerms[381], + "382": intNumberTerms[382], + "383": intNumberTerms[383], + "384": intNumberTerms[384], + "385": intNumberTerms[385], + "386": intNumberTerms[386], + "387": intNumberTerms[387], + "388": intNumberTerms[388], + "389": intNumberTerms[389], + "390": intNumberTerms[390], + "391": intNumberTerms[391], + "392": intNumberTerms[392], + "393": intNumberTerms[393], + "394": intNumberTerms[394], + "395": intNumberTerms[395], + "396": intNumberTerms[396], + "397": intNumberTerms[397], + "398": intNumberTerms[398], + "399": intNumberTerms[399], + "400": intNumberTerms[400], + "401": intNumberTerms[401], + "402": intNumberTerms[402], + "403": intNumberTerms[403], + "404": intNumberTerms[404], + "405": intNumberTerms[405], + "406": intNumberTerms[406], + "407": intNumberTerms[407], + "408": intNumberTerms[408], + "409": intNumberTerms[409], + "410": intNumberTerms[410], + "411": intNumberTerms[411], + "412": intNumberTerms[412], + "413": intNumberTerms[413], + "414": intNumberTerms[414], + "415": intNumberTerms[415], + "416": intNumberTerms[416], + "417": intNumberTerms[417], + "418": intNumberTerms[418], + "419": intNumberTerms[419], + "420": intNumberTerms[420], + "421": intNumberTerms[421], + "422": intNumberTerms[422], + "423": intNumberTerms[423], + "424": intNumberTerms[424], + "425": intNumberTerms[425], + "426": intNumberTerms[426], + "427": intNumberTerms[427], + "428": intNumberTerms[428], + "429": intNumberTerms[429], + "430": intNumberTerms[430], + "431": intNumberTerms[431], + "432": intNumberTerms[432], + "433": intNumberTerms[433], + "434": intNumberTerms[434], + "435": intNumberTerms[435], + "436": intNumberTerms[436], + "437": intNumberTerms[437], + "438": intNumberTerms[438], + "439": intNumberTerms[439], + "440": intNumberTerms[440], + "441": intNumberTerms[441], + "442": intNumberTerms[442], + "443": intNumberTerms[443], + "444": intNumberTerms[444], + "445": intNumberTerms[445], + "446": intNumberTerms[446], + "447": intNumberTerms[447], + "448": intNumberTerms[448], + "449": intNumberTerms[449], + "450": intNumberTerms[450], + "451": intNumberTerms[451], + "452": intNumberTerms[452], + "453": intNumberTerms[453], + "454": intNumberTerms[454], + "455": intNumberTerms[455], + "456": intNumberTerms[456], + "457": intNumberTerms[457], + "458": intNumberTerms[458], + "459": intNumberTerms[459], + "460": intNumberTerms[460], + "461": intNumberTerms[461], + "462": intNumberTerms[462], + "463": intNumberTerms[463], + "464": intNumberTerms[464], + "465": intNumberTerms[465], + "466": intNumberTerms[466], + "467": intNumberTerms[467], + "468": intNumberTerms[468], + "469": intNumberTerms[469], + "470": intNumberTerms[470], + "471": intNumberTerms[471], + "472": intNumberTerms[472], + "473": intNumberTerms[473], + "474": intNumberTerms[474], + "475": intNumberTerms[475], + "476": intNumberTerms[476], + "477": intNumberTerms[477], + "478": intNumberTerms[478], + "479": intNumberTerms[479], + "480": intNumberTerms[480], + "481": intNumberTerms[481], + "482": intNumberTerms[482], + "483": intNumberTerms[483], + "484": intNumberTerms[484], + "485": intNumberTerms[485], + "486": intNumberTerms[486], + "487": intNumberTerms[487], + "488": intNumberTerms[488], + "489": intNumberTerms[489], + "490": intNumberTerms[490], + "491": intNumberTerms[491], + "492": intNumberTerms[492], + "493": intNumberTerms[493], + "494": intNumberTerms[494], + "495": intNumberTerms[495], + "496": intNumberTerms[496], + "497": intNumberTerms[497], + "498": intNumberTerms[498], + "499": intNumberTerms[499], + "500": intNumberTerms[500], + "501": intNumberTerms[501], + "502": intNumberTerms[502], + "503": intNumberTerms[503], + "504": intNumberTerms[504], + "505": intNumberTerms[505], + "506": intNumberTerms[506], + "507": intNumberTerms[507], + "508": intNumberTerms[508], + "509": intNumberTerms[509], + "510": intNumberTerms[510], + "511": intNumberTerms[511], + "512": intNumberTerms[512], +} + +var intNumberTerms = [...]*Term{ + {Value: Number("0")}, + {Value: Number("1")}, + {Value: Number("2")}, + {Value: Number("3")}, + {Value: Number("4")}, + {Value: Number("5")}, + {Value: Number("6")}, + {Value: Number("7")}, + {Value: Number("8")}, + {Value: Number("9")}, + {Value: Number("10")}, + {Value: Number("11")}, + {Value: Number("12")}, + {Value: Number("13")}, + {Value: Number("14")}, + {Value: Number("15")}, + {Value: Number("16")}, + {Value: Number("17")}, + {Value: Number("18")}, + {Value: Number("19")}, + {Value: Number("20")}, + {Value: Number("21")}, + {Value: Number("22")}, + {Value: Number("23")}, + {Value: Number("24")}, + {Value: Number("25")}, + {Value: Number("26")}, + {Value: Number("27")}, + {Value: Number("28")}, + {Value: Number("29")}, + {Value: Number("30")}, + {Value: Number("31")}, + {Value: Number("32")}, + {Value: Number("33")}, + {Value: Number("34")}, + {Value: Number("35")}, + {Value: Number("36")}, + {Value: Number("37")}, + {Value: Number("38")}, + {Value: Number("39")}, + {Value: Number("40")}, + {Value: Number("41")}, + {Value: Number("42")}, + {Value: Number("43")}, + {Value: Number("44")}, + {Value: Number("45")}, + {Value: Number("46")}, + {Value: Number("47")}, + {Value: Number("48")}, + {Value: Number("49")}, + {Value: Number("50")}, + {Value: Number("51")}, + {Value: Number("52")}, + {Value: Number("53")}, + {Value: Number("54")}, + {Value: Number("55")}, + {Value: Number("56")}, + {Value: Number("57")}, + {Value: Number("58")}, + {Value: Number("59")}, + {Value: Number("60")}, + {Value: Number("61")}, + {Value: Number("62")}, + {Value: Number("63")}, + {Value: Number("64")}, + {Value: Number("65")}, + {Value: Number("66")}, + {Value: Number("67")}, + {Value: Number("68")}, + {Value: Number("69")}, + {Value: Number("70")}, + {Value: Number("71")}, + {Value: Number("72")}, + {Value: Number("73")}, + {Value: Number("74")}, + {Value: Number("75")}, + {Value: Number("76")}, + {Value: Number("77")}, + {Value: Number("78")}, + {Value: Number("79")}, + {Value: Number("80")}, + {Value: Number("81")}, + {Value: Number("82")}, + {Value: Number("83")}, + {Value: Number("84")}, + {Value: Number("85")}, + {Value: Number("86")}, + {Value: Number("87")}, + {Value: Number("88")}, + {Value: Number("89")}, + {Value: Number("90")}, + {Value: Number("91")}, + {Value: Number("92")}, + {Value: Number("93")}, + {Value: Number("94")}, + {Value: Number("95")}, + {Value: Number("96")}, + {Value: Number("97")}, + {Value: Number("98")}, + {Value: Number("99")}, + {Value: Number("100")}, + {Value: Number("101")}, + {Value: Number("102")}, + {Value: Number("103")}, + {Value: Number("104")}, + {Value: Number("105")}, + {Value: Number("106")}, + {Value: Number("107")}, + {Value: Number("108")}, + {Value: Number("109")}, + {Value: Number("110")}, + {Value: Number("111")}, + {Value: Number("112")}, + {Value: Number("113")}, + {Value: Number("114")}, + {Value: Number("115")}, + {Value: Number("116")}, + {Value: Number("117")}, + {Value: Number("118")}, + {Value: Number("119")}, + {Value: Number("120")}, + {Value: Number("121")}, + {Value: Number("122")}, + {Value: Number("123")}, + {Value: Number("124")}, + {Value: Number("125")}, + {Value: Number("126")}, + {Value: Number("127")}, + {Value: Number("128")}, + {Value: Number("129")}, + {Value: Number("130")}, + {Value: Number("131")}, + {Value: Number("132")}, + {Value: Number("133")}, + {Value: Number("134")}, + {Value: Number("135")}, + {Value: Number("136")}, + {Value: Number("137")}, + {Value: Number("138")}, + {Value: Number("139")}, + {Value: Number("140")}, + {Value: Number("141")}, + {Value: Number("142")}, + {Value: Number("143")}, + {Value: Number("144")}, + {Value: Number("145")}, + {Value: Number("146")}, + {Value: Number("147")}, + {Value: Number("148")}, + {Value: Number("149")}, + {Value: Number("150")}, + {Value: Number("151")}, + {Value: Number("152")}, + {Value: Number("153")}, + {Value: Number("154")}, + {Value: Number("155")}, + {Value: Number("156")}, + {Value: Number("157")}, + {Value: Number("158")}, + {Value: Number("159")}, + {Value: Number("160")}, + {Value: Number("161")}, + {Value: Number("162")}, + {Value: Number("163")}, + {Value: Number("164")}, + {Value: Number("165")}, + {Value: Number("166")}, + {Value: Number("167")}, + {Value: Number("168")}, + {Value: Number("169")}, + {Value: Number("170")}, + {Value: Number("171")}, + {Value: Number("172")}, + {Value: Number("173")}, + {Value: Number("174")}, + {Value: Number("175")}, + {Value: Number("176")}, + {Value: Number("177")}, + {Value: Number("178")}, + {Value: Number("179")}, + {Value: Number("180")}, + {Value: Number("181")}, + {Value: Number("182")}, + {Value: Number("183")}, + {Value: Number("184")}, + {Value: Number("185")}, + {Value: Number("186")}, + {Value: Number("187")}, + {Value: Number("188")}, + {Value: Number("189")}, + {Value: Number("190")}, + {Value: Number("191")}, + {Value: Number("192")}, + {Value: Number("193")}, + {Value: Number("194")}, + {Value: Number("195")}, + {Value: Number("196")}, + {Value: Number("197")}, + {Value: Number("198")}, + {Value: Number("199")}, + {Value: Number("200")}, + {Value: Number("201")}, + {Value: Number("202")}, + {Value: Number("203")}, + {Value: Number("204")}, + {Value: Number("205")}, + {Value: Number("206")}, + {Value: Number("207")}, + {Value: Number("208")}, + {Value: Number("209")}, + {Value: Number("210")}, + {Value: Number("211")}, + {Value: Number("212")}, + {Value: Number("213")}, + {Value: Number("214")}, + {Value: Number("215")}, + {Value: Number("216")}, + {Value: Number("217")}, + {Value: Number("218")}, + {Value: Number("219")}, + {Value: Number("220")}, + {Value: Number("221")}, + {Value: Number("222")}, + {Value: Number("223")}, + {Value: Number("224")}, + {Value: Number("225")}, + {Value: Number("226")}, + {Value: Number("227")}, + {Value: Number("228")}, + {Value: Number("229")}, + {Value: Number("230")}, + {Value: Number("231")}, + {Value: Number("232")}, + {Value: Number("233")}, + {Value: Number("234")}, + {Value: Number("235")}, + {Value: Number("236")}, + {Value: Number("237")}, + {Value: Number("238")}, + {Value: Number("239")}, + {Value: Number("240")}, + {Value: Number("241")}, + {Value: Number("242")}, + {Value: Number("243")}, + {Value: Number("244")}, + {Value: Number("245")}, + {Value: Number("246")}, + {Value: Number("247")}, + {Value: Number("248")}, + {Value: Number("249")}, + {Value: Number("250")}, + {Value: Number("251")}, + {Value: Number("252")}, + {Value: Number("253")}, + {Value: Number("254")}, + {Value: Number("255")}, + {Value: Number("256")}, + {Value: Number("257")}, + {Value: Number("258")}, + {Value: Number("259")}, + {Value: Number("260")}, + {Value: Number("261")}, + {Value: Number("262")}, + {Value: Number("263")}, + {Value: Number("264")}, + {Value: Number("265")}, + {Value: Number("266")}, + {Value: Number("267")}, + {Value: Number("268")}, + {Value: Number("269")}, + {Value: Number("270")}, + {Value: Number("271")}, + {Value: Number("272")}, + {Value: Number("273")}, + {Value: Number("274")}, + {Value: Number("275")}, + {Value: Number("276")}, + {Value: Number("277")}, + {Value: Number("278")}, + {Value: Number("279")}, + {Value: Number("280")}, + {Value: Number("281")}, + {Value: Number("282")}, + {Value: Number("283")}, + {Value: Number("284")}, + {Value: Number("285")}, + {Value: Number("286")}, + {Value: Number("287")}, + {Value: Number("288")}, + {Value: Number("289")}, + {Value: Number("290")}, + {Value: Number("291")}, + {Value: Number("292")}, + {Value: Number("293")}, + {Value: Number("294")}, + {Value: Number("295")}, + {Value: Number("296")}, + {Value: Number("297")}, + {Value: Number("298")}, + {Value: Number("299")}, + {Value: Number("300")}, + {Value: Number("301")}, + {Value: Number("302")}, + {Value: Number("303")}, + {Value: Number("304")}, + {Value: Number("305")}, + {Value: Number("306")}, + {Value: Number("307")}, + {Value: Number("308")}, + {Value: Number("309")}, + {Value: Number("310")}, + {Value: Number("311")}, + {Value: Number("312")}, + {Value: Number("313")}, + {Value: Number("314")}, + {Value: Number("315")}, + {Value: Number("316")}, + {Value: Number("317")}, + {Value: Number("318")}, + {Value: Number("319")}, + {Value: Number("320")}, + {Value: Number("321")}, + {Value: Number("322")}, + {Value: Number("323")}, + {Value: Number("324")}, + {Value: Number("325")}, + {Value: Number("326")}, + {Value: Number("327")}, + {Value: Number("328")}, + {Value: Number("329")}, + {Value: Number("330")}, + {Value: Number("331")}, + {Value: Number("332")}, + {Value: Number("333")}, + {Value: Number("334")}, + {Value: Number("335")}, + {Value: Number("336")}, + {Value: Number("337")}, + {Value: Number("338")}, + {Value: Number("339")}, + {Value: Number("340")}, + {Value: Number("341")}, + {Value: Number("342")}, + {Value: Number("343")}, + {Value: Number("344")}, + {Value: Number("345")}, + {Value: Number("346")}, + {Value: Number("347")}, + {Value: Number("348")}, + {Value: Number("349")}, + {Value: Number("350")}, + {Value: Number("351")}, + {Value: Number("352")}, + {Value: Number("353")}, + {Value: Number("354")}, + {Value: Number("355")}, + {Value: Number("356")}, + {Value: Number("357")}, + {Value: Number("358")}, + {Value: Number("359")}, + {Value: Number("360")}, + {Value: Number("361")}, + {Value: Number("362")}, + {Value: Number("363")}, + {Value: Number("364")}, + {Value: Number("365")}, + {Value: Number("366")}, + {Value: Number("367")}, + {Value: Number("368")}, + {Value: Number("369")}, + {Value: Number("370")}, + {Value: Number("371")}, + {Value: Number("372")}, + {Value: Number("373")}, + {Value: Number("374")}, + {Value: Number("375")}, + {Value: Number("376")}, + {Value: Number("377")}, + {Value: Number("378")}, + {Value: Number("379")}, + {Value: Number("380")}, + {Value: Number("381")}, + {Value: Number("382")}, + {Value: Number("383")}, + {Value: Number("384")}, + {Value: Number("385")}, + {Value: Number("386")}, + {Value: Number("387")}, + {Value: Number("388")}, + {Value: Number("389")}, + {Value: Number("390")}, + {Value: Number("391")}, + {Value: Number("392")}, + {Value: Number("393")}, + {Value: Number("394")}, + {Value: Number("395")}, + {Value: Number("396")}, + {Value: Number("397")}, + {Value: Number("398")}, + {Value: Number("399")}, + {Value: Number("400")}, + {Value: Number("401")}, + {Value: Number("402")}, + {Value: Number("403")}, + {Value: Number("404")}, + {Value: Number("405")}, + {Value: Number("406")}, + {Value: Number("407")}, + {Value: Number("408")}, + {Value: Number("409")}, + {Value: Number("410")}, + {Value: Number("411")}, + {Value: Number("412")}, + {Value: Number("413")}, + {Value: Number("414")}, + {Value: Number("415")}, + {Value: Number("416")}, + {Value: Number("417")}, + {Value: Number("418")}, + {Value: Number("419")}, + {Value: Number("420")}, + {Value: Number("421")}, + {Value: Number("422")}, + {Value: Number("423")}, + {Value: Number("424")}, + {Value: Number("425")}, + {Value: Number("426")}, + {Value: Number("427")}, + {Value: Number("428")}, + {Value: Number("429")}, + {Value: Number("430")}, + {Value: Number("431")}, + {Value: Number("432")}, + {Value: Number("433")}, + {Value: Number("434")}, + {Value: Number("435")}, + {Value: Number("436")}, + {Value: Number("437")}, + {Value: Number("438")}, + {Value: Number("439")}, + {Value: Number("440")}, + {Value: Number("441")}, + {Value: Number("442")}, + {Value: Number("443")}, + {Value: Number("444")}, + {Value: Number("445")}, + {Value: Number("446")}, + {Value: Number("447")}, + {Value: Number("448")}, + {Value: Number("449")}, + {Value: Number("450")}, + {Value: Number("451")}, + {Value: Number("452")}, + {Value: Number("453")}, + {Value: Number("454")}, + {Value: Number("455")}, + {Value: Number("456")}, + {Value: Number("457")}, + {Value: Number("458")}, + {Value: Number("459")}, + {Value: Number("460")}, + {Value: Number("461")}, + {Value: Number("462")}, + {Value: Number("463")}, + {Value: Number("464")}, + {Value: Number("465")}, + {Value: Number("466")}, + {Value: Number("467")}, + {Value: Number("468")}, + {Value: Number("469")}, + {Value: Number("470")}, + {Value: Number("471")}, + {Value: Number("472")}, + {Value: Number("473")}, + {Value: Number("474")}, + {Value: Number("475")}, + {Value: Number("476")}, + {Value: Number("477")}, + {Value: Number("478")}, + {Value: Number("479")}, + {Value: Number("480")}, + {Value: Number("481")}, + {Value: Number("482")}, + {Value: Number("483")}, + {Value: Number("484")}, + {Value: Number("485")}, + {Value: Number("486")}, + {Value: Number("487")}, + {Value: Number("488")}, + {Value: Number("489")}, + {Value: Number("490")}, + {Value: Number("491")}, + {Value: Number("492")}, + {Value: Number("493")}, + {Value: Number("494")}, + {Value: Number("495")}, + {Value: Number("496")}, + {Value: Number("497")}, + {Value: Number("498")}, + {Value: Number("499")}, + {Value: Number("500")}, + {Value: Number("501")}, + {Value: Number("502")}, + {Value: Number("503")}, + {Value: Number("504")}, + {Value: Number("505")}, + {Value: Number("506")}, + {Value: Number("507")}, + {Value: Number("508")}, + {Value: Number("509")}, + {Value: Number("510")}, + {Value: Number("511")}, + {Value: Number("512")}, +} diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/json/json.go b/vendor/github.com/open-policy-agent/opa/v1/ast/json/json.go new file mode 100644 index 0000000000..9081fe7039 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/json/json.go @@ -0,0 +1,106 @@ +// Copyright 2023 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. + +// This package provides options for JSON marshalling of AST nodes, and location +// data in particular. Since location data occupies a significant portion of the +// AST when included, it is excluded by default. The options provided here allow +// changing that behavior — either for all nodes or for specific types. Since +// JSONMarshaller implementations have access only to the node being marshaled, +// our options are to either attach these settings to *all* nodes in the AST, or +// to provide them via global state. The former is perhaps a little more elegant, +// and is what we went with initially. The cost of attaching these settings to +// every node however turned out to be non-negligible, and given that the number +// of users who have an interest in AST serialization are likely to be few, we +// have since switched to using global state, as provided here. Note that this +// is mostly to provide an equivalent feature to what we had before, should +// anyone depend on that. Users who need fine-grained control over AST +// serialization are recommended to use external libraries for that purpose, +// such as `github.com/json-iterator/go`. +package json + +import "sync" + +// Options defines the options for JSON operations, +// currently only marshaling can be configured +type Options struct { + MarshalOptions MarshalOptions +} + +// MarshalOptions defines the options for JSON marshaling, +// currently only toggling the marshaling of location information is supported +type MarshalOptions struct { + // IncludeLocation toggles the marshaling of location information + IncludeLocation NodeToggle + // IncludeLocationText additionally/optionally includes the text of the location + IncludeLocationText bool + // ExcludeLocationFile additionally/optionally excludes the file of the location + // Note that this is inverted (i.e. not "include" as the default needs to remain false) + ExcludeLocationFile bool +} + +// NodeToggle is a generic struct to allow the toggling of +// settings for different ast node types +type NodeToggle struct { + Term bool + Package bool + Comment bool + Import bool + Rule bool + Head bool + Expr bool + SomeDecl bool + Every bool + With bool + Annotations bool + AnnotationsRef bool +} + +// configuredJSONOptions synchronizes access to the global JSON options +type configuredJSONOptions struct { + options Options + lock sync.RWMutex +} + +var options = &configuredJSONOptions{ + options: Defaults(), +} + +// SetOptions sets the global options for marshalling AST nodes to JSON +func SetOptions(opts Options) { + options.lock.Lock() + defer options.lock.Unlock() + options.options = opts +} + +// GetOptions returns (a copy of) the global options for marshalling AST nodes to JSON +func GetOptions() Options { + options.lock.RLock() + defer options.lock.RUnlock() + return options.options +} + +// Defaults returns the default JSON options, which is to exclude location +// information in serialized JSON AST. +func Defaults() Options { + return Options{ + MarshalOptions: MarshalOptions{ + IncludeLocation: NodeToggle{ + Term: false, + Package: false, + Comment: false, + Import: false, + Rule: false, + Head: false, + Expr: false, + SomeDecl: false, + Every: false, + With: false, + Annotations: false, + AnnotationsRef: false, + }, + IncludeLocationText: false, + ExcludeLocationFile: false, + }, + } +} diff --git a/vendor/github.com/open-policy-agent/opa/ast/location/location.go b/vendor/github.com/open-policy-agent/opa/v1/ast/location/location.go similarity index 91% rename from vendor/github.com/open-policy-agent/opa/ast/location/location.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/location/location.go index 92226df3f0..716aad6930 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/location/location.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/location/location.go @@ -7,7 +7,7 @@ import ( "errors" "fmt" - astJSON "github.com/open-policy-agent/opa/ast/json" + astJSON "github.com/open-policy-agent/opa/v1/ast/json" ) // Location records a position in source code @@ -18,9 +18,6 @@ type Location struct { Col int `json:"col"` // The column in the row. Offset int `json:"-"` // The byte offset for the location in the source. - // JSONOptions specifies options for marshaling and unmarshalling of locations - JSONOptions astJSON.Options - Tabs []int `json:"-"` // The column offsets of tabs in the source. } @@ -98,7 +95,8 @@ func (loc *Location) Compare(other *Location) int { func (loc *Location) MarshalJSON() ([]byte, error) { // structs are used here to preserve the field ordering of the original Location struct - if loc.JSONOptions.MarshalOptions.ExcludeLocationFile { + jsonOptions := astJSON.GetOptions().MarshalOptions + if jsonOptions.ExcludeLocationFile { data := struct { Row int `json:"row"` Col int `json:"col"` @@ -108,7 +106,7 @@ func (loc *Location) MarshalJSON() ([]byte, error) { Col: loc.Col, } - if loc.JSONOptions.MarshalOptions.IncludeLocationText { + if jsonOptions.IncludeLocationText { data.Text = loc.Text } @@ -126,7 +124,7 @@ func (loc *Location) MarshalJSON() ([]byte, error) { File: loc.File, } - if loc.JSONOptions.MarshalOptions.IncludeLocationText { + if jsonOptions.IncludeLocationText { data.Text = loc.Text } diff --git a/vendor/github.com/open-policy-agent/opa/ast/map.go b/vendor/github.com/open-policy-agent/opa/v1/ast/map.go similarity index 75% rename from vendor/github.com/open-policy-agent/opa/ast/map.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/map.go index b0cc9eb60f..d0aa43755f 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/map.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/map.go @@ -7,21 +7,20 @@ package ast import ( "encoding/json" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/util" ) // ValueMap represents a key/value map between AST term values. Any type of term // can be used as a key in the map. type ValueMap struct { - hashMap *util.HashMap + hashMap *util.TypedHashMap[Value, Value] } // NewValueMap returns a new ValueMap. func NewValueMap() *ValueMap { - vs := &ValueMap{ - hashMap: util.NewHashMap(valueEq, valueHash), + return &ValueMap{ + hashMap: util.NewTypedHashMap(ValueEqual, ValueEqual, Value.Hash, Value.Hash, nil), } - return vs } // MarshalJSON provides a custom marshaller for the ValueMap which @@ -31,7 +30,7 @@ func (vs *ValueMap) MarshalJSON() ([]byte, error) { vs.Iter(func(k Value, v Value) bool { tmp = append(tmp, map[string]interface{}{ "name": k.String(), - "type": TypeName(v), + "type": ValueName(v), "value": v, }) return false @@ -39,23 +38,13 @@ func (vs *ValueMap) MarshalJSON() ([]byte, error) { return json.Marshal(tmp) } -// Copy returns a shallow copy of the ValueMap. -func (vs *ValueMap) Copy() *ValueMap { - if vs == nil { - return nil - } - cpy := NewValueMap() - cpy.hashMap = vs.hashMap.Copy() - return cpy -} - // Equal returns true if this ValueMap equals the other. func (vs *ValueMap) Equal(other *ValueMap) bool { if vs == nil { return other == nil || other.Len() == 0 } if other == nil { - return vs == nil || vs.Len() == 0 + return vs.Len() == 0 } return vs.hashMap.Equal(other.hashMap) } @@ -72,7 +61,7 @@ func (vs *ValueMap) Len() int { func (vs *ValueMap) Get(k Value) Value { if vs != nil { if v, ok := vs.hashMap.Get(k); ok { - return v.(Value) + return v } } return nil @@ -92,11 +81,7 @@ func (vs *ValueMap) Iter(iter func(Value, Value) bool) bool { if vs == nil { return false } - return vs.hashMap.Iter(func(kt, vt util.T) bool { - k := kt.(Value) - v := vt.(Value) - return iter(k, v) - }) + return vs.hashMap.Iter(iter) } // Put inserts a key k into the map with value v. @@ -121,13 +106,3 @@ func (vs *ValueMap) String() string { } return vs.hashMap.String() } - -func valueHash(v util.T) int { - return v.(Value).Hash() -} - -func valueEq(a, b util.T) bool { - av := a.(Value) - bv := b.(Value) - return av.Compare(bv) == 0 -} diff --git a/vendor/github.com/open-policy-agent/opa/ast/parser.go b/vendor/github.com/open-policy-agent/opa/v1/ast/parser.go similarity index 92% rename from vendor/github.com/open-policy-agent/opa/ast/parser.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/parser.go index 09ede2baec..66779b8d75 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/parser.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/parser.go @@ -7,6 +7,7 @@ package ast import ( "bytes" "encoding/json" + "errors" "fmt" "io" "math/big" @@ -19,10 +20,10 @@ import ( "gopkg.in/yaml.v3" - "github.com/open-policy-agent/opa/ast/internal/scanner" - "github.com/open-policy-agent/opa/ast/internal/tokens" - astJSON "github.com/open-policy-agent/opa/ast/json" - "github.com/open-policy-agent/opa/ast/location" + "github.com/open-policy-agent/opa/v1/ast/internal/scanner" + "github.com/open-policy-agent/opa/v1/ast/internal/tokens" + astJSON "github.com/open-policy-agent/opa/v1/ast/json" + "github.com/open-policy-agent/opa/v1/ast/location" ) var RegoV1CompatibleRef = Ref{VarTerm("rego"), StringTerm("v1")} @@ -30,11 +31,12 @@ var RegoV1CompatibleRef = Ref{VarTerm("rego"), StringTerm("v1")} // RegoVersion defines the Rego syntax requirements for a module. type RegoVersion int -const DefaultRegoVersion = RegoVersion(0) +const DefaultRegoVersion = RegoV1 const ( + RegoUndefined RegoVersion = iota // RegoV0 is the default, original Rego syntax. - RegoV0 RegoVersion = iota + RegoV0 // RegoV0CompatV1 requires modules to comply with both the RegoV0 and RegoV1 syntax (as when 'rego.v1' is imported in a module). // Shortly, RegoV1 compatibility is required, but 'rego.v1' or 'future.keywords' must also be imported. RegoV0CompatV1 @@ -132,7 +134,7 @@ func (c parsedTermCache) String() string { s.WriteRune('{') var e *parsedTermCacheItem for e = c.m; e != nil; e = e.next { - s.WriteString(fmt.Sprintf("%v", e)) + s.WriteString(e.String()) } s.WriteRune('}') return s.String() @@ -149,15 +151,16 @@ type ParserOptions struct { AllFutureKeywords bool FutureKeywords []string SkipRules bool - JSONOptions *astJSON.Options // RegoVersion is the version of Rego to parse for. RegoVersion RegoVersion unreleasedKeywords bool // TODO(sr): cleanup } // EffectiveRegoVersion returns the effective RegoVersion to use for parsing. -// Deprecated: Use RegoVersion instead. func (po *ParserOptions) EffectiveRegoVersion() RegoVersion { + if po.RegoVersion == RegoUndefined { + return DefaultRegoVersion + } return po.RegoVersion } @@ -234,10 +237,11 @@ func (p *Parser) WithSkipRules(skip bool) *Parser { return p } -// WithJSONOptions sets the Options which will be set on nodes to configure -// their JSON marshaling behavior. -func (p *Parser) WithJSONOptions(jsonOptions *astJSON.Options) *Parser { - p.po.JSONOptions = jsonOptions +// WithJSONOptions sets the JSON options on the parser (now a no-op). +// +// Deprecated: Use SetOptions in the json package instead, where a longer description +// of why this is deprecated also can be found. +func (p *Parser) WithJSONOptions(_ *astJSON.Options) *Parser { return p } @@ -280,7 +284,7 @@ func (p *Parser) parsedTermCachePush(t *Term, s0 *state) { func (p *Parser) futureParser() *Parser { q := *p q.s = p.save() - q.s.s = p.s.s.WithKeywords(futureKeywords) + q.s.s = p.s.s.WithKeywords(allFutureKeywords) q.cache = parsedTermCache{} return &q } @@ -298,7 +302,7 @@ func (p *Parser) presentParser() (*Parser, map[string]tokens.Token) { var cpy map[string]tokens.Token q := *p q.s = p.save() - q.s.s, cpy = p.s.s.WithoutKeywords(futureKeywords) + q.s.s, cpy = p.s.s.WithoutKeywords(allFutureKeywords) q.cache = parsedTermCache{} return &q, cpy } @@ -309,30 +313,45 @@ func (p *Parser) presentParser() (*Parser, map[string]tokens.Token) { func (p *Parser) Parse() ([]Statement, []*Comment, Errors) { if p.po.Capabilities == nil { - p.po.Capabilities = CapabilitiesForThisVersion() + p.po.Capabilities = CapabilitiesForThisVersion(CapabilitiesRegoVersion(p.po.RegoVersion)) } allowedFutureKeywords := map[string]tokens.Token{} - if p.po.RegoVersion == RegoV1 { - // RegoV1 includes all future keywords in the default language definition - for k, v := range futureKeywords { + if p.po.EffectiveRegoVersion() == RegoV1 { + if !p.po.Capabilities.ContainsFeature(FeatureRegoV1) { + return nil, nil, Errors{ + &Error{ + Code: ParseErr, + Message: "illegal capabilities: rego_v1 feature required for parsing v1 Rego", + Location: nil, + }, + } + } + + // rego-v1 includes all v0 future keywords in the default language definition + for k, v := range futureKeywordsV0 { allowedFutureKeywords[k] = v } - // For sake of error reporting, we still need to check that keywords in capabilities are known, for _, kw := range p.po.Capabilities.FutureKeywords { - if _, ok := futureKeywords[kw]; !ok { - return nil, nil, Errors{ - &Error{ - Code: ParseErr, - Message: fmt.Sprintf("illegal capabilities: unknown keyword: %v", kw), - Location: nil, - }, + if tok, ok := futureKeywords[kw]; ok { + allowedFutureKeywords[kw] = tok + } else { + // For sake of error reporting, we still need to check that keywords in capabilities are known in v0 + if _, ok := futureKeywordsV0[kw]; !ok { + return nil, nil, Errors{ + &Error{ + Code: ParseErr, + Message: fmt.Sprintf("illegal capabilities: unknown keyword: %v", kw), + Location: nil, + }, + } } } } - // and that explicitly requested future keywords are known. + + // Check that explicitly requested future keywords are known. for _, kw := range p.po.FutureKeywords { if _, ok := allowedFutureKeywords[kw]; !ok { return nil, nil, Errors{ @@ -347,7 +366,7 @@ func (p *Parser) Parse() ([]Statement, []*Comment, Errors) { } else { for _, kw := range p.po.Capabilities.FutureKeywords { var ok bool - allowedFutureKeywords[kw], ok = futureKeywords[kw] + allowedFutureKeywords[kw], ok = allFutureKeywords[kw] if !ok { return nil, nil, Errors{ &Error{ @@ -358,6 +377,13 @@ func (p *Parser) Parse() ([]Statement, []*Comment, Errors) { } } } + + if p.po.Capabilities.ContainsFeature(FeatureRegoV1) { + // rego-v1 includes all v0 future keywords in the default language definition + for k, v := range futureKeywordsV0 { + allowedFutureKeywords[k] = v + } + } } var err error @@ -373,7 +399,7 @@ func (p *Parser) Parse() ([]Statement, []*Comment, Errors) { } selected := map[string]tokens.Token{} - if p.po.AllFutureKeywords || p.po.RegoVersion == RegoV1 { + if p.po.AllFutureKeywords || p.po.EffectiveRegoVersion() == RegoV1 { for kw, tok := range allowedFutureKeywords { selected[kw] = tok } @@ -394,7 +420,7 @@ func (p *Parser) Parse() ([]Statement, []*Comment, Errors) { } p.s.s = p.s.s.WithKeywords(selected) - if p.po.RegoVersion == RegoV1 { + if p.po.EffectiveRegoVersion() == RegoV1 { for kw, tok := range allowedFutureKeywords { p.s.s.AddKeyword(kw, tok) } @@ -469,19 +495,6 @@ func (p *Parser) Parse() ([]Statement, []*Comment, Errors) { stmts = p.parseAnnotations(stmts) } - if p.po.JSONOptions != nil { - for i := range stmts { - vis := NewGenericVisitor(func(x interface{}) bool { - if x, ok := x.(customJSON); ok { - x.setJSONOptions(*p.po.JSONOptions) - } - return false - }) - - vis.Walk(stmts[i]) - } - } - return stmts, p.s.comments, p.s.errors } @@ -505,7 +518,7 @@ func parseAnnotations(comments []*Comment) ([]*Annotations, Errors) { var curr *metadataParser var blocks []*metadataParser - for i := 0; i < len(comments); i++ { + for i := range comments { if curr != nil { if comments[i].Location.Row == comments[i-1].Location.Row+1 && comments[i].Location.Col == 1 { curr.Append(comments[i]) @@ -566,7 +579,7 @@ func (p *Parser) parsePackage() *Package { pkg.Path[0] = DefaultRootDocument.Copy().SetLocation(v[0].Location) first, ok := v[0].Value.(Var) if !ok { - p.errorf(v[0].Location, "unexpected %v token: expecting var", TypeName(v[0].Value)) + p.errorf(v[0].Location, "unexpected %v token: expecting var", ValueName(v[0].Value)) return nil } pkg.Path[1] = StringTerm(string(first)).SetLocation(v[0].Location) @@ -575,7 +588,7 @@ func (p *Parser) parsePackage() *Package { case String: pkg.Path[i] = v[i-1] default: - p.errorf(v[i-1].Location, "unexpected %v token: expecting string", TypeName(v[i-1].Value)) + p.errorf(v[i-1].Location, "unexpected %v token: expecting string", ValueName(v[i-1].Value)) return nil } } @@ -618,7 +631,7 @@ func (p *Parser) parseImport() *Import { case Ref: for i := 1; i < len(v); i++ { if _, ok := v[i].Value.(String); !ok { - p.errorf(v[i].Location, "unexpected %v token: expecting string", TypeName(v[i].Value)) + p.errorf(v[i].Location, "unexpected %v token: expecting string", ValueName(v[i].Value)) return nil } } @@ -713,7 +726,9 @@ func (p *Parser) parseRules() []*Rule { // p[x] if ... becomes a single-value rule p[x] if hasIf && !usesContains && len(rule.Head.Ref()) == 2 { - if !rule.Head.Ref()[1].IsGround() && len(rule.Head.Args) == 0 { + v := rule.Head.Ref()[1] + _, isRef := v.Value.(Ref) + if (!v.IsGround() || isRef) && len(rule.Head.Args) == 0 { rule.Head.Key = rule.Head.Ref()[1] } @@ -946,9 +961,8 @@ func (p *Parser) parseHead(defaultRule bool) (*Head, bool) { switch x := ref.Value.(type) { case Var: - // Modify the code to add the location to the head ref - // and set the head ref's jsonOptions. - head = VarHead(x, ref.Location, p.po.JSONOptions) + // TODO + head = VarHead(x, ref.Location, nil) case Ref: head = RefHead(x) case Call: @@ -1353,6 +1367,11 @@ func (p *Parser) parseTermInfixCallInList() *Term { return p.parseTermIn(nil, false, p.s.loc.Offset) } +// use static references to avoid allocations, and +// copy them to the call term only when needed +var memberWithKeyRef = MemberWithKey.Ref() +var memberRef = Member.Ref() + func (p *Parser) parseTermIn(lhs *Term, keyVal bool, offset int) *Term { // NOTE(sr): `in` is a bit special: besides `lhs in rhs`, it also // supports `key, val in rhs`, so it can have an optional second lhs. @@ -1365,7 +1384,8 @@ func (p *Parser) parseTermIn(lhs *Term, keyVal bool, offset int) *Term { s := p.save() p.scan() if mhs := p.parseTermRelation(nil, offset); mhs != nil { - if op := p.parseTermOpName(MemberWithKey.Ref(), tokens.In); op != nil { + + if op := p.parseTermOpName(memberWithKeyRef, tokens.In); op != nil { if rhs := p.parseTermRelation(nil, p.s.loc.Offset); rhs != nil { call := p.setLoc(CallTerm(op, lhs, mhs, rhs), lhs.Location, offset, p.s.lastEnd) switch p.s.tok { @@ -1379,7 +1399,7 @@ func (p *Parser) parseTermIn(lhs *Term, keyVal bool, offset int) *Term { } p.restore(s) } - if op := p.parseTermOpName(Member.Ref(), tokens.In); op != nil { + if op := p.parseTermOpName(memberRef, tokens.In); op != nil { if rhs := p.parseTermRelation(nil, p.s.loc.Offset); rhs != nil { call := p.setLoc(CallTerm(op, lhs, rhs), lhs.Location, offset, p.s.lastEnd) switch p.s.tok { @@ -1616,12 +1636,15 @@ func (p *Parser) parseNumber() *Term { // Note: Use the original string, do *not* round trip from // the big.Float as it can cause precision loss. - r := NumberTerm(json.Number(s)).SetLocation(loc) - return r + return NumberTerm(json.Number(s)).SetLocation(loc) } func (p *Parser) parseString() *Term { if p.s.lit[0] == '"' { + if p.s.lit == "\"\"" { + return NewTerm(InternedEmptyString.Value).SetLocation(p.s.Loc()) + } + var s string err := json.Unmarshal([]byte(p.s.lit), &s) if err != nil { @@ -1687,7 +1710,7 @@ func (p *Parser) parseRef(head *Term, offset int) (term *Term) { case Var, *Array, Object, Set, *ArrayComprehension, *ObjectComprehension, *SetComprehension, Call: // ok default: - p.errorf(loc, "illegal ref (head cannot be %v)", TypeName(h)) + p.errorf(loc, "illegal ref (head cannot be %v)", ValueName(h)) } ref := []*Term{head} @@ -2044,7 +2067,7 @@ func (p *Parser) parseTermPairList(end tokens.Token, r [][2]*Term) [][2]*Term { func (p *Parser) parseTermOp(values ...tokens.Token) *Term { for i := range values { if p.s.tok == values[i] { - r := RefTerm(VarTerm(fmt.Sprint(p.s.tok)).SetLocation(p.s.Loc())).SetLocation(p.s.Loc()) + r := RefTerm(VarTerm(p.s.tok.String()).SetLocation(p.s.Loc())).SetLocation(p.s.Loc()) p.scan() return r } @@ -2055,10 +2078,11 @@ func (p *Parser) parseTermOp(values ...tokens.Token) *Term { func (p *Parser) parseTermOpName(ref Ref, values ...tokens.Token) *Term { for i := range values { if p.s.tok == values[i] { - for _, r := range ref { + cp := ref.Copy() + for _, r := range cp { r.SetLocation(p.s.Loc()) } - t := RefTerm(ref...) + t := RefTerm(cp...) t.SetLocation(p.s.Loc()) p.scan() return t @@ -2088,7 +2112,7 @@ func (p *Parser) genwildcard() string { } func (p *Parser) error(loc *location.Location, reason string) { - p.errorf(loc, reason) + p.errorf(loc, reason) //nolint:govet } func (p *Parser) errorf(loc *location.Location, f string, a ...interface{}) { @@ -2136,8 +2160,7 @@ func (p *Parser) illegal(note string, a ...interface{}) { tokType := "token" if tokens.IsKeyword(p.s.tok) { tokType = "keyword" - } - if _, ok := futureKeywords[p.s.tok.String()]; ok { + } else if _, ok := allFutureKeywords[p.s.tok.String()]; ok { tokType = "keyword" } @@ -2288,7 +2311,7 @@ func (p *Parser) validateDefaultRuleArgs(rule *Rule) bool { switch v := x.Value.(type) { case Var: // do nothing default: - p.error(rule.Loc(), fmt.Sprintf("illegal default rule (arguments cannot contain %v)", TypeName(v))) + p.error(rule.Loc(), fmt.Sprintf("illegal default rule (arguments cannot contain %v)", ValueName(v))) valid = false return true } @@ -2338,7 +2361,7 @@ 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") + return nil, errors.New("expected METADATA block, found whitespace") } if err := yaml.Unmarshal(b.buf.Bytes(), &raw); err != nil { @@ -2387,7 +2410,7 @@ func (b *metadataParser) Parse() (*Annotations, error) { a.Path, err = ParseRef(k) if err != nil { - return nil, fmt.Errorf("invalid document reference") + return nil, errors.New("invalid document reference") } switch v := v.(type) { @@ -2487,7 +2510,7 @@ func unwrapPair(pair map[string]interface{}) (string, interface{}) { return "", nil } -var errInvalidSchemaRef = fmt.Errorf("invalid schema reference") +var errInvalidSchemaRef = errors.New("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 @@ -2526,7 +2549,7 @@ func parseRelatedResource(rr interface{}) (*RelatedResourceAnnotation, error) { } return &RelatedResourceAnnotation{Ref: *u}, nil } - return nil, fmt.Errorf("ref URL may not be empty string") + return nil, errors.New("ref URL may not be empty string") case map[string]interface{}: description := strings.TrimSpace(getSafeString(rr, "description")) ref := strings.TrimSpace(getSafeString(rr, "ref")) @@ -2537,10 +2560,10 @@ func parseRelatedResource(rr interface{}) (*RelatedResourceAnnotation, error) { } return &RelatedResourceAnnotation{Description: description, Ref: *u}, nil } - return nil, fmt.Errorf("'ref' value required in object") + return nil, errors.New("'ref' value required in object") } - return nil, fmt.Errorf("invalid value type, must be string or map") + return nil, errors.New("invalid value type, must be string or map") } func parseAuthor(a interface{}) (*AuthorAnnotation, error) { @@ -2558,10 +2581,10 @@ func parseAuthor(a interface{}) (*AuthorAnnotation, error) { if len(name) > 0 || len(email) > 0 { return &AuthorAnnotation{name, email}, nil } - return nil, fmt.Errorf("'name' and/or 'email' values required in object") + return nil, errors.New("'name' and/or 'email' values required in object") } - return nil, fmt.Errorf("invalid value type, must be string or map") + return nil, errors.New("invalid value type, must be string or map") } func getSafeString(m map[string]interface{}, k string) string { @@ -2583,7 +2606,7 @@ func parseAuthorString(s string) (*AuthorAnnotation, error) { parts := strings.Fields(s) if len(parts) == 0 { - return nil, fmt.Errorf("author is an empty string") + return nil, errors.New("author is an empty string") } namePartCount := len(parts) @@ -2593,7 +2616,7 @@ func parseAuthorString(s string) (*AuthorAnnotation, error) { strings.HasSuffix(trailing, emailSuffix) { email = trailing[len(emailPrefix):] email = email[0 : len(email)-len(emailSuffix)] - namePartCount = namePartCount - 1 + namePartCount -= 1 } name := strings.Join(parts[0:namePartCount], " ") @@ -2619,7 +2642,7 @@ func convertYAMLMapKeyTypes(x any, path []string) (any, error) { return result, nil case []any: for i := range x { - x[i], err = convertYAMLMapKeyTypes(x[i], append(path, fmt.Sprintf("%d", i))) + x[i], err = convertYAMLMapKeyTypes(x[i], append(path, strconv.Itoa(i))) if err != nil { return nil, err } @@ -2632,22 +2655,40 @@ func convertYAMLMapKeyTypes(x any, path []string) (any, error) { // futureKeywords is the source of truth for future keywords that will // eventually become standard keywords inside of Rego. -var futureKeywords = map[string]tokens.Token{ +var futureKeywords = map[string]tokens.Token{} + +// futureKeywordsV0 is the source of truth for future keywords that were +// not yet a standard part of Rego in v0, and required importing. +var futureKeywordsV0 = map[string]tokens.Token{ "in": tokens.In, "every": tokens.Every, "contains": tokens.Contains, "if": tokens.If, } +var allFutureKeywords map[string]tokens.Token + func IsFutureKeyword(s string) bool { - _, ok := futureKeywords[s] - return ok + return IsFutureKeywordForRegoVersion(s, RegoV1) +} + +func IsFutureKeywordForRegoVersion(s string, v RegoVersion) bool { + var yes bool + + switch v { + case RegoV0, RegoV0CompatV1: + _, yes = futureKeywordsV0[s] + case RegoV1: + _, yes = futureKeywords[s] + } + + return yes } func (p *Parser) futureImport(imp *Import, allowedFutureKeywords map[string]tokens.Token) { path := imp.Path.Value.(Ref) - if len(path) == 1 || !path[1].Equal(StringTerm("keywords")) { + if len(path) == 1 || !path[1].Equal(keywordsTerm) { p.errorf(imp.Path.Location, "invalid import, must be `future.keywords`") return } @@ -2657,11 +2698,6 @@ func (p *Parser) futureImport(imp *Import, allowedFutureKeywords map[string]toke return } - if p.s.s.RegoV1Compatible() { - p.errorf(imp.Path.Location, "the `%s` import implies `future.keywords`, these are therefore mutually exclusive", RegoV1CompatibleRef) - return - } - kwds := make([]string, 0, len(allowedFutureKeywords)) for k := range allowedFutureKeywords { kwds = append(kwds, k) @@ -2691,7 +2727,7 @@ func (p *Parser) futureImport(imp *Import, allowedFutureKeywords map[string]toke } func (p *Parser) regoV1Import(imp *Import) { - if !p.po.Capabilities.ContainsFeature(FeatureRegoV1Import) { + if !p.po.Capabilities.ContainsFeature(FeatureRegoV1Import) && !p.po.Capabilities.ContainsFeature(FeatureRegoV1) { p.errorf(imp.Path.Location, "invalid import, `%s` is not supported by current capabilities", RegoV1CompatibleRef) return } @@ -2704,7 +2740,7 @@ func (p *Parser) regoV1Import(imp *Import) { return } - if p.po.RegoVersion == RegoV1 { + if p.po.EffectiveRegoVersion() == RegoV1 { // We're parsing for Rego v1, where the 'rego.v1' import is a no-op. return } @@ -2715,19 +2751,23 @@ func (p *Parser) regoV1Import(imp *Import) { } // import all future keywords with the rego.v1 import - kwds := make([]string, 0, len(futureKeywords)) - for k := range futureKeywords { + kwds := make([]string, 0, len(futureKeywordsV0)) + for k := range futureKeywordsV0 { kwds = append(kwds, k) } - if p.s.s.HasKeyword(futureKeywords) && !p.s.s.RegoV1Compatible() { - // We have imported future keywords, but they didn't come from another `rego.v1` import. - p.errorf(imp.Path.Location, "the `%s` import implies `future.keywords`, these are therefore mutually exclusive", RegoV1CompatibleRef) - return - } - p.s.s.SetRegoV1Compatible() for _, kw := range kwds { - p.s.s.AddKeyword(kw, futureKeywords[kw]) + p.s.s.AddKeyword(kw, futureKeywordsV0[kw]) + } +} + +func init() { + allFutureKeywords = map[string]tokens.Token{} + for k, v := range futureKeywords { + allFutureKeywords[k] = v + } + for k, v := range futureKeywordsV0 { + allFutureKeywords[k] = v } } diff --git a/vendor/github.com/open-policy-agent/opa/ast/parser_ext.go b/vendor/github.com/open-policy-agent/opa/v1/ast/parser_ext.go similarity index 88% rename from vendor/github.com/open-policy-agent/opa/ast/parser_ext.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/parser_ext.go index 83c87e47b1..dec06f1969 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/parser_ext.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/parser_ext.go @@ -17,8 +17,7 @@ import ( "strings" "unicode" - "github.com/open-policy-agent/opa/ast/internal/tokens" - astJSON "github.com/open-policy-agent/opa/ast/json" + "github.com/open-policy-agent/opa/v1/ast/internal/tokens" ) // MustParseBody returns a parsed body. @@ -156,7 +155,7 @@ func MustParseTerm(input string) *Term { func ParseRuleFromBody(module *Module, body Body) (*Rule, error) { if len(body) != 1 { - return nil, fmt.Errorf("multiple expressions cannot be used for rule head") + return nil, errors.New("multiple expressions cannot be used for rule head") } return ParseRuleFromExpr(module, body[0]) @@ -167,11 +166,11 @@ func ParseRuleFromBody(module *Module, body Body) (*Rule, error) { func ParseRuleFromExpr(module *Module, expr *Expr) (*Rule, error) { if len(expr.With) > 0 { - return nil, fmt.Errorf("expressions using with keyword cannot be used for rule head") + return nil, errors.New("expressions using with keyword cannot be used for rule head") } if expr.Negated { - return nil, fmt.Errorf("negated expressions cannot be used for rule head") + return nil, errors.New("negated expressions cannot be used for rule head") } if _, ok := expr.Terms.(*SomeDecl); ok { @@ -186,7 +185,7 @@ func ParseRuleFromExpr(module *Module, expr *Expr) (*Rule, error) { } return ParsePartialSetDocRuleFromTerm(module, term) default: - return nil, fmt.Errorf("%v cannot be used for rule name", TypeName(v)) + return nil, fmt.Errorf("%v cannot be used for rule name", ValueName(v)) } } @@ -208,7 +207,7 @@ func ParseRuleFromExpr(module *Module, expr *Expr) (*Rule, error) { } if _, ok := BuiltinMap[expr.Operator().String()]; ok { - return nil, fmt.Errorf("rule name conflicts with built-in function") + return nil, errors.New("rule name conflicts with built-in function") } return ParseRuleFromCallExpr(module, expr.Terms.([]*Term)) @@ -266,32 +265,28 @@ func ParseCompleteDocRuleFromEqExpr(module *Module, lhs, rhs *Term) (*Rule, erro if v, ok := lhs.Value.(Var); ok { // Modify the code to add the location to the head ref - // and set the head ref's jsonOptions. - head = VarHead(v, lhs.Location, &lhs.jsonOptions) + head = VarHead(v, lhs.Location, nil) } else if r, ok := lhs.Value.(Ref); ok { // groundness ? if _, ok := r[0].Value.(Var); !ok { return nil, fmt.Errorf("invalid rule head: %v", r) } head = RefHead(r) if len(r) > 1 && !r[len(r)-1].IsGround() { - return nil, fmt.Errorf("ref not ground") + return nil, errors.New("ref not ground") } } else { - return nil, fmt.Errorf("%v cannot be used for rule name", TypeName(lhs.Value)) + return nil, fmt.Errorf("%v cannot be used for rule name", ValueName(lhs.Value)) } head.Value = rhs head.Location = lhs.Location - head.setJSONOptions(lhs.jsonOptions) body := NewBody(NewExpr(BooleanTerm(true).SetLocation(rhs.Location)).SetLocation(rhs.Location)) - setJSONOptions(body, &rhs.jsonOptions) return &Rule{ Location: lhs.Location, Head: head, Body: body, Module: module, - jsonOptions: lhs.jsonOptions, generatedBody: true, }, nil } @@ -299,7 +294,7 @@ func ParseCompleteDocRuleFromEqExpr(module *Module, lhs, rhs *Term) (*Rule, erro func ParseCompleteDocRuleWithDotsFromTerm(module *Module, term *Term) (*Rule, error) { ref, ok := term.Value.(Ref) if !ok { - return nil, fmt.Errorf("%v cannot be used for rule name", TypeName(term.Value)) + return nil, fmt.Errorf("%v cannot be used for rule name", ValueName(term.Value)) } if _, ok := ref[0].Value.(Var); !ok { @@ -308,18 +303,14 @@ func ParseCompleteDocRuleWithDotsFromTerm(module *Module, term *Term) (*Rule, er head := RefHead(ref, BooleanTerm(true).SetLocation(term.Location)) head.generatedValue = true head.Location = term.Location - head.jsonOptions = term.jsonOptions body := NewBody(NewExpr(BooleanTerm(true).SetLocation(term.Location)).SetLocation(term.Location)) - setJSONOptions(body, &term.jsonOptions) return &Rule{ Location: term.Location, Head: head, Body: body, Module: module, - - jsonOptions: term.jsonOptions, }, nil } @@ -328,7 +319,7 @@ func ParseCompleteDocRuleWithDotsFromTerm(module *Module, term *Term) (*Rule, er func ParsePartialObjectDocRuleFromEqExpr(module *Module, lhs, rhs *Term) (*Rule, error) { ref, ok := lhs.Value.(Ref) if !ok { - return nil, fmt.Errorf("%v cannot be used as rule name", TypeName(lhs.Value)) + return nil, fmt.Errorf("%v cannot be used as rule name", ValueName(lhs.Value)) } if _, ok := ref[0].Value.(Var); !ok { @@ -341,17 +332,14 @@ func ParsePartialObjectDocRuleFromEqExpr(module *Module, lhs, rhs *Term) (*Rule, head.Key = ref[1] } head.Location = rhs.Location - head.jsonOptions = rhs.jsonOptions body := NewBody(NewExpr(BooleanTerm(true).SetLocation(rhs.Location)).SetLocation(rhs.Location)) - setJSONOptions(body, &rhs.jsonOptions) rule := &Rule{ - Location: rhs.Location, - Head: head, - Body: body, - Module: module, - jsonOptions: rhs.jsonOptions, + Location: rhs.Location, + Head: head, + Body: body, + Module: module, } return rule, nil @@ -363,7 +351,7 @@ func ParsePartialSetDocRuleFromTerm(module *Module, term *Term) (*Rule, error) { ref, ok := term.Value.(Ref) if !ok || len(ref) == 1 { - return nil, fmt.Errorf("%vs cannot be used for rule head", TypeName(term.Value)) + return nil, fmt.Errorf("%vs cannot be used for rule head", ValueName(term.Value)) } if _, ok := ref[0].Value.(Var); !ok { return nil, fmt.Errorf("invalid rule head: %v", ref) @@ -373,25 +361,21 @@ func ParsePartialSetDocRuleFromTerm(module *Module, term *Term) (*Rule, error) { if len(ref) == 2 { v, ok := ref[0].Value.(Var) if !ok { - return nil, fmt.Errorf("%vs cannot be used for rule head", TypeName(term.Value)) + return nil, fmt.Errorf("%vs cannot be used for rule head", ValueName(term.Value)) } // Modify the code to add the location to the head ref - // and set the head ref's jsonOptions. - head = VarHead(v, ref[0].Location, &ref[0].jsonOptions) + head = VarHead(v, ref[0].Location, nil) head.Key = ref[1] } head.Location = term.Location - head.jsonOptions = term.jsonOptions body := NewBody(NewExpr(BooleanTerm(true).SetLocation(term.Location)).SetLocation(term.Location)) - setJSONOptions(body, &term.jsonOptions) rule := &Rule{ - Location: term.Location, - Head: head, - Body: body, - Module: module, - jsonOptions: term.jsonOptions, + Location: term.Location, + Head: head, + Body: body, + Module: module, } return rule, nil @@ -403,12 +387,12 @@ func ParseRuleFromCallEqExpr(module *Module, lhs, rhs *Term) (*Rule, error) { call, ok := lhs.Value.(Call) if !ok { - return nil, fmt.Errorf("must be call") + return nil, errors.New("must be call") } ref, ok := call[0].Value.(Ref) if !ok { - return nil, fmt.Errorf("%vs cannot be used in function signature", TypeName(call[0].Value)) + return nil, fmt.Errorf("%vs cannot be used in function signature", ValueName(call[0].Value)) } if _, ok := ref[0].Value.(Var); !ok { return nil, fmt.Errorf("invalid rule head: %v", ref) @@ -417,17 +401,14 @@ func ParseRuleFromCallEqExpr(module *Module, lhs, rhs *Term) (*Rule, error) { head := RefHead(ref, rhs) head.Location = lhs.Location head.Args = Args(call[1:]) - head.jsonOptions = lhs.jsonOptions body := NewBody(NewExpr(BooleanTerm(true).SetLocation(rhs.Location)).SetLocation(rhs.Location)) - setJSONOptions(body, &rhs.jsonOptions) rule := &Rule{ - Location: lhs.Location, - Head: head, - Body: body, - Module: module, - jsonOptions: lhs.jsonOptions, + Location: lhs.Location, + Head: head, + Body: body, + Module: module, } return rule, nil @@ -438,7 +419,7 @@ func ParseRuleFromCallEqExpr(module *Module, lhs, rhs *Term) (*Rule, error) { func ParseRuleFromCallExpr(module *Module, terms []*Term) (*Rule, error) { if len(terms) <= 1 { - return nil, fmt.Errorf("rule argument list must take at least one argument") + return nil, errors.New("rule argument list must take at least one argument") } loc := terms[0].Location @@ -449,17 +430,14 @@ func ParseRuleFromCallExpr(module *Module, terms []*Term) (*Rule, error) { head := RefHead(ref, BooleanTerm(true).SetLocation(loc)) head.Location = loc head.Args = terms[1:] - head.jsonOptions = terms[0].jsonOptions body := NewBody(NewExpr(BooleanTerm(true).SetLocation(loc)).SetLocation(loc)) - setJSONOptions(body, &terms[0].jsonOptions) rule := &Rule{ - Location: loc, - Head: head, - Module: module, - Body: body, - jsonOptions: terms[0].jsonOptions, + Location: loc, + Head: head, + Module: module, + Body: body, } return rule, nil } @@ -622,7 +600,7 @@ func ParseStatement(input string) (Statement, error) { return nil, err } if len(stmts) != 1 { - return nil, fmt.Errorf("expected exactly one statement") + return nil, errors.New("expected exactly one statement") } return stmts[0], nil } @@ -633,7 +611,7 @@ func ParseStatementWithOpts(input string, popts ParserOptions) (Statement, error return nil, err } if len(stmts) != 1 { - return nil, fmt.Errorf("expected exactly one statement") + return nil, errors.New("expected exactly one statement") } return stmts[0], nil } @@ -655,7 +633,6 @@ func ParseStatementsWithOpts(filename, input string, popts ParserOptions) ([]Sta WithAllFutureKeywords(popts.AllFutureKeywords). WithCapabilities(popts.Capabilities). WithSkipRules(popts.SkipRules). - WithJSONOptions(popts.JSONOptions). WithRegoVersion(popts.RegoVersion). withUnreleasedKeywords(popts.unreleasedKeywords) @@ -689,7 +666,12 @@ func parseModule(filename string, stmts []Statement, comments []*Comment, regoCo // The comments slice only holds comments that were not their own statements. mod.Comments = append(mod.Comments, comments...) - mod.regoVersion = regoCompatibilityMode + + if regoCompatibilityMode == RegoUndefined { + mod.regoVersion = DefaultRegoVersion + } else { + mod.regoVersion = regoCompatibilityMode + } for i, stmt := range stmts[1:] { switch stmt := stmt.(type) { @@ -704,7 +686,7 @@ func parseModule(filename string, stmts []Statement, comments []*Comment, regoCo case Body: rule, err := ParseRuleFromBody(mod, stmt) if err != nil { - errs = append(errs, NewError(ParseErr, stmt[0].Location, err.Error())) + errs = append(errs, NewError(ParseErr, stmt[0].Location, err.Error())) //nolint:govet continue } rule.generatedBody = true @@ -772,16 +754,6 @@ func setRuleModule(rule *Rule, module *Module) { } } -func setJSONOptions(x interface{}, jsonOptions *astJSON.Options) { - vis := NewGenericVisitor(func(x interface{}) bool { - if x, ok := x.(customJSON); ok { - x.setJSONOptions(*jsonOptions) - } - return false - }) - vis.Walk(x) -} - // ParserErrorDetail holds additional details for parser errors. type ParserErrorDetail struct { Line string `json:"line"` diff --git a/vendor/github.com/open-policy-agent/opa/ast/policy.go b/vendor/github.com/open-policy-agent/opa/v1/ast/policy.go similarity index 90% rename from vendor/github.com/open-policy-agent/opa/ast/policy.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/policy.go index 43e9bba4a3..978de9441b 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/policy.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/policy.go @@ -8,21 +8,14 @@ import ( "bytes" "encoding/json" "fmt" - "math/rand" + "slices" "strings" - "time" - "github.com/open-policy-agent/opa/ast/internal/tokens" - astJSON "github.com/open-policy-agent/opa/ast/json" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/ast/internal/tokens" + astJSON "github.com/open-policy-agent/opa/v1/ast/json" + "github.com/open-policy-agent/opa/v1/util" ) -// Initialize seed for term hashing. This is intentionally placed before the -// root document sets are constructed to ensure they use the same hash seed as -// 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()) - // DefaultRootDocument is the default root document. // // All package directives inside source files are implicitly prefixed with the @@ -84,7 +77,7 @@ var RootDocumentRefs = NewSet( // SystemDocumentKey is the name of the top-level key that identifies the system // document. -var SystemDocumentKey = String("system") +const SystemDocumentKey = String("system") // ReservedVars is the set of names that refer to implicitly ground vars. var ReservedVars = NewVarSet( @@ -97,7 +90,7 @@ var Wildcard = &Term{Value: Var("_")} // WildcardPrefix is the special character that all wildcard variables are // prefixed with when the statement they are contained in is parsed. -var WildcardPrefix = "$" +const WildcardPrefix = "$" // Keywords contains strings that map to language keywords. var Keywords = KeywordsForRegoVersion(DefaultRegoVersion) @@ -213,8 +206,6 @@ type ( // TODO: these fields have inconsistent JSON keys with other structs in this package. Text []byte Location *Location - - jsonOptions astJSON.Options } // Package represents the namespace of the documents produced @@ -222,8 +213,6 @@ type ( Package struct { Path Ref `json:"path"` Location *Location `json:"location,omitempty"` - - jsonOptions astJSON.Options } // Import represents a dependency on a document outside of the policy @@ -232,8 +221,6 @@ type ( Path *Term `json:"path"` Alias Var `json:"alias,omitempty"` Location *Location `json:"location,omitempty"` - - jsonOptions astJSON.Options } // Rule represents a rule as defined in the language. Rules define the @@ -253,7 +240,6 @@ type ( Module *Module `json:"-"` generatedBody bool - jsonOptions astJSON.Options } // Head represents the head of a rule. @@ -268,7 +254,6 @@ type ( keywords []tokens.Token generatedValue bool - jsonOptions astJSON.Options } // Args represents zero or more arguments to a rule. @@ -287,7 +272,6 @@ type ( Negated bool `json:"negated,omitempty"` Location *Location `json:"location,omitempty"` - jsonOptions astJSON.Options generatedFrom *Expr generates []*Expr } @@ -296,8 +280,6 @@ type ( SomeDecl struct { Symbols []*Term `json:"symbols"` Location *Location `json:"location,omitempty"` - - jsonOptions astJSON.Options } Every struct { @@ -306,8 +288,6 @@ type ( Domain *Term `json:"domain"` Body Body `json:"body"` Location *Location `json:"location,omitempty"` - - jsonOptions astJSON.Options } // With represents a modifier on an expression. @@ -315,11 +295,14 @@ type ( Target *Term `json:"target"` Value *Term `json:"value"` Location *Location `json:"location,omitempty"` - - jsonOptions astJSON.Options } ) +// SetModuleRegoVersion sets the RegoVersion for the Module. +func SetModuleRegoVersion(mod *Module, v RegoVersion) { + mod.regoVersion = v +} + // Compare returns an integer indicating whether mod is less than, equal to, // or greater than other. func (mod *Module) Compare(other *Module) int { @@ -509,19 +492,10 @@ func (c *Comment) Equal(other *Comment) bool { return c.Location.Equal(other.Location) && bytes.Equal(c.Text, other.Text) } -func (c *Comment) setJSONOptions(opts astJSON.Options) { - // Note: this is not used for location since Comments use default JSON marshaling - // behavior with struct field names in JSON. - c.jsonOptions = opts - if c.Location != nil { - c.Location.JSONOptions = opts - } -} - // Compare returns an integer indicating whether pkg is less than, equal to, // or greater than other. func (pkg *Package) Compare(other *Package) int { - return Compare(pkg.Path, other.Path) + return termSliceCompare(pkg.Path, other.Path) } // Copy returns a deep copy of pkg. @@ -562,19 +536,12 @@ func (pkg *Package) String() string { return fmt.Sprintf("package %v", path) } -func (pkg *Package) setJSONOptions(opts astJSON.Options) { - pkg.jsonOptions = opts - if pkg.Location != nil { - pkg.Location.JSONOptions = opts - } -} - func (pkg *Package) MarshalJSON() ([]byte, error) { data := map[string]interface{}{ "path": pkg.Path, } - if pkg.jsonOptions.MarshalOptions.IncludeLocation.Package { + if astJSON.GetOptions().MarshalOptions.IncludeLocation.Package { if pkg.Location != nil { data["location"] = pkg.Location } @@ -620,7 +587,8 @@ func (imp *Import) Compare(other *Import) int { if cmp := Compare(imp.Path, other.Path); cmp != 0 { return cmp } - return Compare(imp.Alias, other.Alias) + + return VarCompare(imp.Alias, other.Alias) } // Copy returns a deep copy of imp. @@ -670,18 +638,11 @@ func (imp *Import) Name() Var { func (imp *Import) String() string { buf := []string{"import", imp.Path.String()} if len(imp.Alias) > 0 { - buf = append(buf, "as "+imp.Alias.String()) + buf = append(buf, "as", imp.Alias.String()) } return strings.Join(buf, " ") } -func (imp *Import) setJSONOptions(opts astJSON.Options) { - imp.jsonOptions = opts - if imp.Location != nil { - imp.Location.JSONOptions = opts - } -} - func (imp *Import) MarshalJSON() ([]byte, error) { data := map[string]interface{}{ "path": imp.Path, @@ -691,7 +652,7 @@ func (imp *Import) MarshalJSON() ([]byte, error) { data["alias"] = imp.Alias } - if imp.jsonOptions.MarshalOptions.IncludeLocation.Import { + if astJSON.GetOptions().MarshalOptions.IncludeLocation.Import { if imp.Location != nil { data["location"] = imp.Location } @@ -714,8 +675,11 @@ func (rule *Rule) Compare(other *Rule) int { if cmp := rule.Head.Compare(other.Head); cmp != 0 { return cmp } - if cmp := util.Compare(rule.Default, other.Default); cmp != 0 { - return cmp + if rule.Default != other.Default { + if !rule.Default { + return -1 + } + return 1 } if cmp := rule.Body.Compare(other.Body); cmp != 0 { return cmp @@ -734,9 +698,11 @@ func (rule *Rule) Copy() *Rule { cpy.Head = rule.Head.Copy() cpy.Body = rule.Body.Copy() - cpy.Annotations = make([]*Annotations, len(rule.Annotations)) - for i, a := range rule.Annotations { - cpy.Annotations[i] = a.Copy(&cpy) + if len(cpy.Annotations) > 0 { + cpy.Annotations = make([]*Annotations, len(rule.Annotations)) + for i, a := range rule.Annotations { + cpy.Annotations[i] = a.Copy(&cpy) + } } if cpy.Else != nil { @@ -784,13 +750,24 @@ func (rule *Rule) Ref() Ref { } func (rule *Rule) String() string { - return rule.stringWithOpts(toStringOpts{}) + regoVersion := DefaultRegoVersion + if rule.Module != nil { + regoVersion = rule.Module.RegoVersion() + } + return rule.stringWithOpts(toStringOpts{regoVersion: regoVersion}) } type toStringOpts struct { regoVersion RegoVersion } +func (o toStringOpts) RegoVersion() RegoVersion { + if o.regoVersion == RegoUndefined { + return DefaultRegoVersion + } + return o.regoVersion +} + func (rule *Rule) stringWithOpts(opts toStringOpts) string { buf := []string{} if rule.Default { @@ -798,13 +775,11 @@ func (rule *Rule) stringWithOpts(opts toStringOpts) string { } buf = append(buf, rule.Head.stringWithOpts(opts)) if !rule.Default { - switch opts.regoVersion { + switch opts.RegoVersion() { case RegoV1, RegoV0CompatV1: buf = append(buf, "if") } - buf = append(buf, "{") - buf = append(buf, rule.Body.String()) - buf = append(buf, "}") + buf = append(buf, "{", rule.Body.String(), "}") } if rule.Else != nil { buf = append(buf, rule.Else.elseString(opts)) @@ -816,13 +791,6 @@ func (rule *Rule) isFunction() bool { return len(rule.Head.Args) > 0 } -func (rule *Rule) setJSONOptions(opts astJSON.Options) { - rule.jsonOptions = opts - if rule.Location != nil { - rule.Location.JSONOptions = opts - } -} - func (rule *Rule) MarshalJSON() ([]byte, error) { data := map[string]interface{}{ "head": rule.Head, @@ -837,7 +805,7 @@ func (rule *Rule) MarshalJSON() ([]byte, error) { data["else"] = rule.Else } - if rule.jsonOptions.MarshalOptions.IncludeLocation.Rule { + if astJSON.GetOptions().MarshalOptions.IncludeLocation.Rule { if rule.Location != nil { data["location"] = rule.Location } @@ -857,18 +825,15 @@ func (rule *Rule) elseString(opts toStringOpts) string { value := rule.Head.Value if value != nil { - buf = append(buf, "=") - buf = append(buf, value.String()) + buf = append(buf, "=", value.String()) } - switch opts.regoVersion { + switch opts.RegoVersion() { case RegoV1, RegoV0CompatV1: buf = append(buf, "if") } - buf = append(buf, "{") - buf = append(buf, rule.Body.String()) - buf = append(buf, "}") + buf = append(buf, "{", rule.Body.String(), "}") if rule.Else != nil { buf = append(buf, rule.Else.elseString(opts)) @@ -898,14 +863,11 @@ func NewHead(name Var, args ...*Term) *Head { return head } -// VarHead creates a head object, initializes its Name, Location, and Options, -// and returns the new head. -func VarHead(name Var, location *Location, jsonOpts *astJSON.Options) *Head { +// VarHead creates a head object, initializes its Name and Location and returns the new head. +// NOTE: The JSON options argument is no longer used, and kept only for backwards compatibility. +func VarHead(name Var, location *Location, _ *astJSON.Options) *Head { h := NewHead(name) h.Reference[0].Location = location - if jsonOpts != nil { - h.Reference[0].setJSONOptions(*jsonOpts) - } return h } @@ -924,7 +886,7 @@ func RefHead(ref Ref, args ...*Term) *Head { } // DocKind represents the collection of document types that can be produced by rules. -type DocKind int +type DocKind byte const ( // CompleteDoc represents a document that is completely defined by the rule. @@ -944,11 +906,13 @@ func (head *Head) DocKind() DocKind { return PartialObjectDoc } return PartialSetDoc + } else if head.HasDynamicRef() { + return PartialObjectDoc } return CompleteDoc } -type RuleKind int +type RuleKind byte const ( SingleValue = iota @@ -1005,7 +969,7 @@ func (head *Head) Compare(other *Head) int { if cmp := Compare(head.Reference, other.Reference); cmp != 0 { return cmp } - if cmp := Compare(head.Name, other.Name); cmp != 0 { + if cmp := VarCompare(head.Name, other.Name); cmp != 0 { return cmp } if cmp := Compare(head.Key, other.Key); cmp != 0 { @@ -1043,7 +1007,7 @@ func (head *Head) stringWithOpts(opts toStringOpts) string { case len(head.Args) != 0: buf.WriteString(head.Args.String()) case len(head.Reference) == 1 && head.Key != nil: - switch opts.regoVersion { + switch opts.RegoVersion() { case RegoV0: buf.WriteRune('[') buf.WriteString(head.Key.String()) @@ -1068,26 +1032,10 @@ func (head *Head) stringWithOpts(opts toStringOpts) string { return buf.String() } -func (head *Head) setJSONOptions(opts astJSON.Options) { - head.jsonOptions = opts - if head.Location != nil { - head.Location.JSONOptions = opts - } -} - func (head *Head) MarshalJSON() ([]byte, error) { var loc *Location - includeLoc := head.jsonOptions.MarshalOptions.IncludeLocation - if includeLoc.Head { - if head.Location != nil { - loc = head.Location - } - - for _, term := range head.Reference { - if term.Location != nil { - term.jsonOptions.MarshalOptions.IncludeLocation.Term = includeLoc.Term - } - } + if astJSON.GetOptions().MarshalOptions.IncludeLocation.Head && head.Location != nil { + loc = head.Location } // NOTE(sr): we do this to override the rendering of `head.Reference`. @@ -1139,8 +1087,7 @@ func (head *Head) SetLoc(loc *Location) { func (head *Head) HasDynamicRef() bool { pos := head.Reference.Dynamic() - // Ref is dynamic if it has one non-constant term that isn't the first or last term or if it's a partial set rule. - return pos > 0 && (pos < len(head.Reference)-1 || head.RuleKind() == MultiValue) + return pos > 0 && (pos < len(head.Reference)) } // Copy returns a deep copy of a. @@ -1225,7 +1172,7 @@ func (body Body) Compare(other Body) int { if len(other) < minLen { minLen = len(other) } - for i := 0; i < minLen; i++ { + for i := range minLen { if cmp := body[i].Compare(other[i]); cmp != 0 { return cmp } @@ -1250,12 +1197,7 @@ func (body Body) Copy() Body { // Contains returns true if this body contains the given expression. func (body Body) Contains(x *Expr) bool { - for _, e := range body { - if e.Equal(x) { - return true - } - } - return false + return slices.ContainsFunc(body, x.Equal) } // Equal returns true if this Body is equal to the other Body. @@ -1335,6 +1277,16 @@ func (expr *Expr) Complement() *Expr { return &cpy } +// ComplementNoWith returns a copy of this expression with the negation flag flipped +// and the with modifier removed. This is the same as calling .Complement().NoWith() +// but without making an intermediate copy. +func (expr *Expr) ComplementNoWith() *Expr { + cpy := *expr + cpy.Negated = !cpy.Negated + cpy.With = nil + return &cpy +} + // Equal returns true if this Expr equals the other Expr. func (expr *Expr) Equal(other *Expr) bool { return expr.Compare(other) == 0 @@ -1425,9 +1377,11 @@ func (expr *Expr) sortOrder() int { func (expr *Expr) CopyWithoutTerms() *Expr { cpy := *expr - cpy.With = make([]*With, len(expr.With)) - for i := range expr.With { - cpy.With[i] = expr.With[i].Copy() + if expr.With != nil { + cpy.With = make([]*With, len(expr.With)) + for i := range expr.With { + cpy.With[i] = expr.With[i].Copy() + } } return &cpy @@ -1442,11 +1396,7 @@ func (expr *Expr) Copy() *Expr { case *SomeDecl: cpy.Terms = ts.Copy() case []*Term: - cpyTs := make([]*Term, len(ts)) - for i := range ts { - cpyTs[i] = ts[i].Copy() - } - cpy.Terms = cpyTs + cpy.Terms = termSliceCopy(ts) case *Term: cpy.Terms = ts.Copy() case *Every: @@ -1627,13 +1577,6 @@ func (expr *Expr) String() string { return strings.Join(buf, " ") } -func (expr *Expr) setJSONOptions(opts astJSON.Options) { - expr.jsonOptions = opts - if expr.Location != nil { - expr.Location.JSONOptions = opts - } -} - func (expr *Expr) MarshalJSON() ([]byte, error) { data := map[string]interface{}{ "terms": expr.Terms, @@ -1652,7 +1595,7 @@ func (expr *Expr) MarshalJSON() ([]byte, error) { data["negated"] = true } - if expr.jsonOptions.MarshalOptions.IncludeLocation.Expr { + if astJSON.GetOptions().MarshalOptions.IncludeLocation.Expr { if expr.Location != nil { data["location"] = expr.Location } @@ -1766,19 +1709,12 @@ func (d *SomeDecl) Hash() int { return termSliceHash(d.Symbols) } -func (d *SomeDecl) setJSONOptions(opts astJSON.Options) { - d.jsonOptions = opts - if d.Location != nil { - d.Location.JSONOptions = opts - } -} - func (d *SomeDecl) MarshalJSON() ([]byte, error) { data := map[string]interface{}{ "symbols": d.Symbols, } - if d.jsonOptions.MarshalOptions.IncludeLocation.SomeDecl { + if astJSON.GetOptions().MarshalOptions.IncludeLocation.SomeDecl { if d.Location != nil { data["location"] = d.Location } @@ -1843,13 +1779,6 @@ func (q *Every) KeyValueVars() VarSet { return vis.vars } -func (q *Every) setJSONOptions(opts astJSON.Options) { - q.jsonOptions = opts - if q.Location != nil { - q.Location.JSONOptions = opts - } -} - func (q *Every) MarshalJSON() ([]byte, error) { data := map[string]interface{}{ "key": q.Key, @@ -1858,7 +1787,7 @@ func (q *Every) MarshalJSON() ([]byte, error) { "body": q.Body, } - if q.jsonOptions.MarshalOptions.IncludeLocation.Every { + if astJSON.GetOptions().MarshalOptions.IncludeLocation.Every { if q.Location != nil { data["location"] = q.Location } @@ -1925,20 +1854,13 @@ func (w *With) SetLoc(loc *Location) { w.Location = loc } -func (w *With) setJSONOptions(opts astJSON.Options) { - w.jsonOptions = opts - if w.Location != nil { - w.Location.JSONOptions = opts - } -} - func (w *With) MarshalJSON() ([]byte, error) { data := map[string]interface{}{ "target": w.Target, "value": w.Value, } - if w.jsonOptions.MarshalOptions.IncludeLocation.With { + if astJSON.GetOptions().MarshalOptions.IncludeLocation.With { if w.Location != nil { data["location"] = w.Location } diff --git a/vendor/github.com/open-policy-agent/opa/ast/pretty.go b/vendor/github.com/open-policy-agent/opa/v1/ast/pretty.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/ast/pretty.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/pretty.go diff --git a/vendor/github.com/open-policy-agent/opa/ast/rego_v1.go b/vendor/github.com/open-policy-agent/opa/v1/ast/rego_v1.go similarity index 96% rename from vendor/github.com/open-policy-agent/opa/ast/rego_v1.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/rego_v1.go index b64dfce7be..8b757ecc3c 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/rego_v1.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/rego_v1.go @@ -3,7 +3,7 @@ package ast import ( "fmt" - "github.com/open-policy-agent/opa/ast/internal/tokens" + "github.com/open-policy-agent/opa/v1/ast/internal/tokens" ) func checkDuplicateImports(modules []*Module) (errors Errors) { @@ -192,7 +192,7 @@ func checkRegoV1Rule(rule *Rule, opts RegoCheckOptions) Errors { var errs Errors if opts.NoKeywordsAsRuleNames && IsKeywordInRegoVersion(rule.Head.Name.String(), RegoV1) { - errs = append(errs, NewError(ParseErr, rule.Location, fmt.Sprintf("%s keyword cannot be used for rule name", rule.Head.Name.String()))) + errs = append(errs, NewError(ParseErr, rule.Location, "%s keyword cannot be used for rule name", rule.Head.Name.String())) } if opts.RequireRuleBodyOrValue && rule.generatedBody && rule.Head.generatedValue { errs = append(errs, NewError(ParseErr, rule.Location, "%s must have value assignment and/or body declaration", t)) diff --git a/vendor/github.com/open-policy-agent/opa/ast/schema.go b/vendor/github.com/open-policy-agent/opa/v1/ast/schema.go similarity index 58% rename from vendor/github.com/open-policy-agent/opa/ast/schema.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/schema.go index 8c96ac624e..3f9e2001d5 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/schema.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/schema.go @@ -7,47 +7,38 @@ package ast import ( "fmt" - "github.com/open-policy-agent/opa/types" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/types" + "github.com/open-policy-agent/opa/v1/util" ) // SchemaSet holds a map from a path to a schema. type SchemaSet struct { - m *util.HashMap + m *util.HasherMap[Ref, any] } // 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), + m: util.NewHasherMap[Ref, any](RefEqual), } } // Put inserts a raw schema into the set. -func (ss *SchemaSet) Put(path Ref, raw interface{}) { +func (ss *SchemaSet) Put(path Ref, raw any) { 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 +func (ss *SchemaSet) Get(path Ref) any { + if ss != nil { + if x, ok := ss.m.Get(path); ok { + return x + } } - return x + return nil } -func loadSchema(raw interface{}, allowNet []string) (types.Type, error) { +func loadSchema(raw any, allowNet []string) (types.Type, error) { jsonSchema, err := compileSchema(raw, allowNet) if err != nil { diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/strings.go b/vendor/github.com/open-policy-agent/opa/v1/ast/strings.go new file mode 100644 index 0000000000..40d66753f5 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/strings.go @@ -0,0 +1,54 @@ +// Copyright 2016 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 ( + "reflect" + "strings" +) + +// TypeName returns a human readable name for the AST element type. +func TypeName(x interface{}) string { + if _, ok := x.(*lazyObj); ok { + return "object" + } + return strings.ToLower(reflect.Indirect(reflect.ValueOf(x)).Type().Name()) +} + +// ValueName returns a human readable name for the AST Value type. +// This is preferrable over calling TypeName when the argument is known to be +// a Value, as this doesn't require reflection (= heap allocations). +func ValueName(x Value) string { + switch x.(type) { + case String: + return "string" + case Boolean: + return "boolean" + case Number: + return "number" + case Null: + return "null" + case Var: + return "var" + case Object: + return "object" + case Set: + return "set" + case Ref: + return "ref" + case Call: + return "call" + case *Array: + return "array" + case *ArrayComprehension: + return "arraycomprehension" + case *ObjectComprehension: + return "objectcomprehension" + case *SetComprehension: + return "setcomprehension" + } + + return TypeName(x) +} diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/syncpools.go b/vendor/github.com/open-policy-agent/opa/v1/ast/syncpools.go new file mode 100644 index 0000000000..cb150d39b5 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/syncpools.go @@ -0,0 +1,69 @@ +package ast + +import ( + "strings" + "sync" +) + +type termPtrPool struct { + pool sync.Pool +} + +type stringBuilderPool struct { + pool sync.Pool +} + +type indexResultPool struct { + pool sync.Pool +} + +func (p *termPtrPool) Get() *Term { + return p.pool.Get().(*Term) +} + +func (p *termPtrPool) Put(t *Term) { + p.pool.Put(t) +} + +func (p *stringBuilderPool) Get() *strings.Builder { + return p.pool.Get().(*strings.Builder) +} + +func (p *stringBuilderPool) Put(sb *strings.Builder) { + sb.Reset() + p.pool.Put(sb) +} + +func (p *indexResultPool) Get() *IndexResult { + return p.pool.Get().(*IndexResult) +} + +func (p *indexResultPool) Put(x *IndexResult) { + if x != nil { + p.pool.Put(x) + } +} + +var TermPtrPool = &termPtrPool{ + pool: sync.Pool{ + New: func() any { + return &Term{} + }, + }, +} + +var sbPool = &stringBuilderPool{ + pool: sync.Pool{ + New: func() any { + return &strings.Builder{} + }, + }, +} + +var IndexResultPool = &indexResultPool{ + pool: sync.Pool{ + New: func() any { + return &IndexResult{} + }, + }, +} diff --git a/vendor/github.com/open-policy-agent/opa/ast/term.go b/vendor/github.com/open-policy-agent/opa/v1/ast/term.go similarity index 87% rename from vendor/github.com/open-policy-agent/opa/ast/term.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/term.go index ce8ee4853d..e0fda51e89 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/term.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/term.go @@ -15,19 +15,19 @@ import ( "math/big" "net/url" "regexp" - "sort" + "slices" "strconv" "strings" "sync" - "github.com/OneOfOne/xxhash" + "github.com/cespare/xxhash/v2" - astJSON "github.com/open-policy-agent/opa/ast/json" - "github.com/open-policy-agent/opa/ast/location" - "github.com/open-policy-agent/opa/util" + astJSON "github.com/open-policy-agent/opa/v1/ast/json" + "github.com/open-policy-agent/opa/v1/ast/location" + "github.com/open-policy-agent/opa/v1/util" ) -var errFindNotFound = fmt.Errorf("find: not found") +var errFindNotFound = errors.New("find: not found") // Location records a position in source code. type Location = location.Location @@ -56,11 +56,16 @@ type Value interface { // InterfaceToValue converts a native Go value x to a Value. func InterfaceToValue(x interface{}) (Value, error) { switch x := x.(type) { + case Value: + return x, nil case nil: - return Null{}, nil + return NullValue, nil case bool: - return Boolean(x), nil + return InternedBooleanTerm(x).Value, nil case json.Number: + if interned := InternedIntNumberTermFromString(string(x)); interned != nil { + return interned.Value, nil + } return Number(x), nil case int64: return int64Number(x), nil @@ -72,42 +77,43 @@ func InterfaceToValue(x interface{}) (Value, error) { return intNumber(x), nil case string: return String(x), nil - case []interface{}: - r := make([]*Term, len(x)) + case []any: + r := util.NewPtrSlice[Term](len(x)) for i, e := range x { e, err := InterfaceToValue(e) if err != nil { return nil, err } - r[i] = &Term{Value: e} + r[i].Value = e } return NewArray(r...), nil - case map[string]interface{}: - r := newobject(len(x)) + case []string: + r := util.NewPtrSlice[Term](len(x)) + for i, e := range x { + r[i].Value = String(e) + } + return NewArray(r...), nil + case map[string]any: + kvs := util.NewPtrSlice[Term](len(x) * 2) + idx := 0 for k, v := range x { - k, err := InterfaceToValue(k) - if err != nil { - return nil, err - } + kvs[idx].Value = String(k) v, err := InterfaceToValue(v) if err != nil { return nil, err } - r.Insert(NewTerm(k), NewTerm(v)) + kvs[idx+1].Value = v + idx += 2 } - return r, nil + tuples := make([][2]*Term, len(kvs)/2) + for i := 0; i < len(kvs); i += 2 { + tuples[i/2] = *(*[2]*Term)(kvs[i : i+2]) + } + return NewObject(tuples...), nil case map[string]string: r := newobject(len(x)) for k, v := range x { - k, err := InterfaceToValue(k) - if err != nil { - return nil, err - } - v, err := InterfaceToValue(v) - if err != nil { - return nil, err - } - r.Insert(NewTerm(k), NewTerm(v)) + r.Insert(StringTerm(k), StringTerm(v)) } return r, nil default: @@ -130,7 +136,7 @@ func ValueFromReader(r io.Reader) (Value, error) { // As converts v into a Go native type referred to by x. func As(v Value, x interface{}) error { - return util.NewJSONDecoder(bytes.NewBufferString(v.String())).Decode(x) + return util.NewJSONDecoder(strings.NewReader(v.String())).Decode(x) } // Resolver defines the interface for resolving references to native Go values. @@ -182,7 +188,7 @@ func valueToInterface(v Value, resolver Resolver, opt JSONOpt) (interface{}, err return string(v), nil case *Array: buf := []interface{}{} - for i := 0; i < v.Len(); i++ { + for i := range v.Len() { x1, err := valueToInterface(v.Elem(i).Value, resolver, opt) if err != nil { return nil, err @@ -294,8 +300,6 @@ func MustInterfaceToValue(x interface{}) Value { type Term struct { Value Value `json:"value"` // the value of the Term as represented in Go Location *Location `json:"location,omitempty"` // the location of the Term in the source - - jsonOptions astJSON.Options } // NewTerm returns a new Term object. @@ -326,7 +330,6 @@ func (term *Term) SetLoc(loc *Location) { // Copy returns a deep copy of term. func (term *Term) Copy() *Term { - if term == nil { return nil } @@ -358,7 +361,7 @@ func (term *Term) Copy() *Term { } // Equal returns true if this term equals the other term. Equality is -// defined for each kind of term. +// defined for each kind of term, and does not compare the Location. func (term *Term) Equal(other *Term) bool { if term == nil && other != nil { return false @@ -370,24 +373,7 @@ func (term *Term) Equal(other *Term) bool { return true } - // TODO(tsandall): This early-exit avoids allocations for types that have - // Equal() functions that just use == underneath. We should revisit the - // other types and implement Equal() functions that do not require - // allocations. - switch v := term.Value.(type) { - case Null: - return v.Equal(other.Value) - case Boolean: - return v.Equal(other.Value) - case Number: - return v.Equal(other.Value) - case String: - return v.Equal(other.Value) - case Var: - return v.Equal(other.Value) - } - - return term.Value.Compare(other.Value) == 0 + return ValueEqual(term.Value, other.Value) } // Get returns a value referred to by name from the term. @@ -420,22 +406,16 @@ func (term *Term) IsGround() bool { return term.Value.IsGround() } -func (term *Term) setJSONOptions(opts astJSON.Options) { - term.jsonOptions = opts - if term.Location != nil { - term.Location.JSONOptions = opts - } -} - // MarshalJSON returns the JSON encoding of the term. // // Specialized marshalling logic is required to include a type hint for Value. func (term *Term) MarshalJSON() ([]byte, error) { d := map[string]interface{}{ - "type": TypeName(term.Value), + "type": ValueName(term.Value), "value": term.Value, } - if term.jsonOptions.MarshalOptions.IncludeLocation.Term { + jsonOptions := astJSON.GetOptions().MarshalOptions + if jsonOptions.IncludeLocation.Term { if term.Location != nil { d["location"] = term.Location } @@ -544,13 +524,7 @@ func ContainsClosures(v interface{}) bool { // IsScalar returns true if the AST value is a scalar. func IsScalar(v Value) bool { switch v.(type) { - case String: - return true - case Number: - return true - case Boolean: - return true - case Null: + case String, Number, Boolean, Null: return true } return false @@ -559,13 +533,15 @@ func IsScalar(v Value) bool { // Null represents the null value defined by JSON. type Null struct{} +var NullValue Value = Null{} + // NullTerm creates a new Term with a Null value. func NullTerm() *Term { - return &Term{Value: Null{}} + return &Term{Value: NullValue} } // Equal returns true if the other term Value is also Null. -func (null Null) Equal(other Value) bool { +func (Null) Equal(other Value) bool { switch other.(type) { case Null: return true @@ -576,20 +552,23 @@ func (null Null) Equal(other Value) bool { // Compare compares null to other, return <0, 0, or >0 if it is less than, equal to, // or greater than other. -func (null Null) Compare(other Value) int { - return Compare(null, other) +func (Null) Compare(other Value) int { + if _, ok := other.(Null); ok { + return 0 + } + return -1 } // Find returns the current value or a not found error. -func (null Null) Find(path Ref) (Value, error) { +func (Null) Find(path Ref) (Value, error) { if len(path) == 0 { - return null, nil + return NullValue, nil } return nil, errFindNotFound } // Hash returns the hash code for the Value. -func (null Null) Hash() int { +func (Null) Hash() int { return 0 } @@ -598,7 +577,7 @@ func (Null) IsGround() bool { return true } -func (null Null) String() string { +func (Null) String() string { return "null" } @@ -607,7 +586,10 @@ type Boolean bool // BooleanTerm creates a new Term with a Boolean value. func BooleanTerm(b bool) *Term { - return &Term{Value: Boolean(b)} + if b { + return &Term{Value: InternedBooleanTerm(true).Value} + } + return &Term{Value: InternedBooleanTerm(false).Value} } // Equal returns true if the other Value is a Boolean and is equal. @@ -623,13 +605,26 @@ func (bol Boolean) Equal(other Value) bool { // Compare compares bol to other, return <0, 0, or >0 if it is less than, equal to, // or greater than other. func (bol Boolean) Compare(other Value) int { - return Compare(bol, other) + switch other := other.(type) { + case Boolean: + if bol == other { + return 0 + } + if !bol { + return -1 + } + return 1 + case Null: + return 1 + } + + return -1 } // Find returns the current value or a not found error. func (bol Boolean) Find(path Ref) (Value, error) { if len(path) == 0 { - return bol, nil + return InternedBooleanTerm(bool(bol)).Value, nil } return nil, errFindNotFound } @@ -679,7 +674,14 @@ func FloatNumberTerm(f float64) *Term { func (num Number) Equal(other Value) bool { switch other := other.(type) { case Number: - return Compare(num, other) == 0 + if n1, ok1 := num.Int64(); ok1 { + n2, ok2 := other.Int64() + if ok1 && ok2 && n1 == n2 { + return true + } + } + + return num.Compare(other) == 0 default: return false } @@ -688,6 +690,21 @@ func (num Number) Equal(other Value) bool { // Compare compares num to other, return <0, 0, or >0 if it is less than, equal to, // or greater than other. func (num Number) Compare(other Value) int { + // Optimize for the common case, as calling Compare allocates on heap. + if otherNum, yes := other.(Number); yes { + if ai, ok := num.Int64(); ok { + if bi, ok := otherNum.Int64(); ok { + if ai == bi { + return 0 + } + if ai < bi { + return -1 + } + return 1 + } + } + } + return Compare(num, other) } @@ -704,7 +721,7 @@ func (num Number) Hash() int { f, err := json.Number(num).Float64() if err != nil { bs := []byte(num) - h := xxhash.Checksum64(bs) + h := xxhash.Sum64(bs) return int(h) } return int(f) @@ -785,6 +802,19 @@ func (str String) Equal(other Value) bool { // Compare compares str to other, return <0, 0, or >0 if it is less than, equal to, // or greater than other. func (str String) Compare(other Value) int { + // Optimize for the common case of one string being compared to another by + // using a direct comparison of values. This avoids the allocation performed + // when calling Compare and its interface{} argument conversion. + if otherStr, ok := other.(String); ok { + if str == otherStr { + return 0 + } + if str < otherStr { + return -1 + } + return 1 + } + return Compare(str, other) } @@ -807,8 +837,7 @@ func (str String) String() string { // Hash returns the hash code for the Value. func (str String) Hash() int { - h := xxhash.ChecksumString64S(string(str), hashSeed0) - return int(h) + return int(xxhash.Sum64String(string(str))) } // Var represents a variable as defined by the language. @@ -833,6 +862,9 @@ func (v Var) Equal(other Value) bool { // Compare compares v to other, return <0, 0, or >0 if it is less than, equal to, // or greater than other. func (v Var) Compare(other Value) int { + if otherVar, ok := other.(Var); ok { + return strings.Compare(string(v), string(otherVar)) + } return Compare(v, other) } @@ -846,8 +878,7 @@ func (v Var) Find(path Ref) (Value, error) { // Hash returns the hash code for the Value. func (v Var) Hash() int { - h := xxhash.ChecksumString64S(string(v), hashSeed0) - return int(h) + return int(xxhash.Sum64String(string(v))) } // IsGround always returns false. @@ -984,14 +1015,50 @@ func (ref Ref) Copy() Ref { return termSliceCopy(ref) } +// CopyNonGround returns a new ref with deep copies of the non-ground parts and shallow +// copies of the ground parts. This is a *much* cheaper operation than Copy for operations +// that only intend to modify (e.g. plug) the non-ground parts. The head element of the ref +// is always shallow copied. +func (ref Ref) CopyNonGround() Ref { + cpy := make(Ref, len(ref)) + cpy[0] = ref[0] + + for i := 1; i < len(ref); i++ { + if ref[i].Value.IsGround() { + cpy[i] = ref[i] + } else { + cpy[i] = ref[i].Copy() + } + } + + return cpy +} + // Equal returns true if ref is equal to other. func (ref Ref) Equal(other Value) bool { - return Compare(ref, other) == 0 + switch o := other.(type) { + case Ref: + if len(ref) == len(o) { + for i := range ref { + if !ref[i].Equal(o[i]) { + return false + } + } + + return true + } + } + + return false } // Compare compares ref to other, return <0, 0, or >0 if it is less than, equal to, // or greater than other. func (ref Ref) Compare(other Value) int { + if o, ok := other.(Ref); ok { + return termSliceCompare(ref, o) + } + return Compare(ref, other) } @@ -1023,32 +1090,32 @@ func (ref Ref) HasPrefix(other Ref) bool { // ConstantPrefix returns the constant portion of the ref starting from the head. func (ref Ref) ConstantPrefix() Ref { - ref = ref.Copy() - i := ref.Dynamic() if i < 0 { - return ref + return ref.Copy() } - return ref[:i] + return ref[:i].Copy() } func (ref Ref) StringPrefix() Ref { - r := ref.Copy() - for i := 1; i < len(ref); i++ { - switch r[i].Value.(type) { + switch ref[i].Value.(type) { case String: // pass default: // cut off - return r[:i] + return ref[:i].Copy() } } - return r + return ref.Copy() } // GroundPrefix returns the ground portion of the ref starting from the head. By // definition, the head of the reference is always ground. func (ref Ref) GroundPrefix() Ref { + if ref.IsGround() { + return ref + } + prefix := make(Ref, 0, len(ref)) for i, x := range ref { @@ -1096,7 +1163,7 @@ func (ref Ref) Ptr() (string, error) { if str, ok := term.Value.(String); ok { parts = append(parts, url.PathEscape(string(str))) } else { - return "", fmt.Errorf("invalid path value type") + return "", errors.New("invalid path value type") } } return strings.Join(parts, "/"), nil @@ -1112,22 +1179,34 @@ func (ref Ref) String() string { if len(ref) == 0 { return "" } - buf := []string{ref[0].Value.String()} - path := ref[1:] - for _, p := range path { + + sb := sbPool.Get() + defer sbPool.Put(sb) + + sb.Grow(10 * len(ref)) + + sb.WriteString(ref[0].Value.String()) + + for _, p := range ref[1:] { switch p := p.Value.(type) { case String: str := string(p) - if varRegexp.MatchString(str) && len(buf) > 0 && !IsKeyword(str) { - buf = append(buf, "."+str) + if varRegexp.MatchString(str) && !IsKeyword(str) { + sb.WriteByte('.') + sb.WriteString(str) } else { - buf = append(buf, "["+p.String()+"]") + sb.WriteString(`["`) + sb.WriteString(str) + sb.WriteString(`"]`) } default: - buf = append(buf, "["+p.String()+"]") + sb.WriteByte('[') + sb.WriteString(p.String()) + sb.WriteByte(']') } } - return strings.Join(buf, "") + + return sb.String() } // OutputVars returns a VarSet containing variables that would be bound by evaluating @@ -1193,12 +1272,38 @@ func (arr *Array) Copy() *Array { // Equal returns true if arr is equal to other. func (arr *Array) Equal(other Value) bool { - return Compare(arr, other) == 0 + if arr == other { + return true + } + + if other, ok := other.(*Array); ok && len(arr.elems) == len(other.elems) { + for i := range arr.elems { + if !arr.elems[i].Equal(other.elems[i]) { + return false + } + } + return true + } + + return false } // Compare compares arr to other, return <0, 0, or >0 if it is less than, equal to, // or greater than other. func (arr *Array) Compare(other Value) int { + if b, ok := other.(*Array); ok { + return termSliceCompare(arr.elems, b.elems) + } + + sortA := sortOrder(arr) + sortB := sortOrder(other) + + if sortA < sortB { + return -1 + } else if sortB < sortA { + return 1 + } + return Compare(arr, other) } @@ -1218,7 +1323,15 @@ func (arr *Array) Find(path Ref) (Value, error) { if i < 0 || i >= arr.Len() { return nil, errFindNotFound } - return arr.Elem(i).Value.Find(path[1:]) + + term := arr.Elem(i) + // Using Find on scalar values costs an allocation (type -> Value conversion) + // and since we already have the Value here, we can avoid that. + if len(path) == 1 && IsScalar(term.Value) { + return term.Value, nil + } + + return term.Value.Find(path[1:]) } // Get returns the element at pos or nil if not possible. @@ -1246,7 +1359,9 @@ func (arr *Array) Sorted() *Array { for i := range cpy { cpy[i] = arr.elems[i] } - sort.Sort(termSlice(cpy)) + + slices.SortFunc(cpy, TermValueCompare) + a := NewArray(cpy...) a.hashs = arr.hashs return a @@ -1271,16 +1386,21 @@ func (arr *Array) MarshalJSON() ([]byte, error) { } func (arr *Array) String() string { - var b strings.Builder - b.WriteRune('[') + sb := sbPool.Get() + sb.Grow(len(arr.elems) * 16) + + defer sbPool.Put(sb) + + sb.WriteByte('[') for i, e := range arr.elems { if i > 0 { - b.WriteString(", ") + sb.WriteString(", ") } - b.WriteString(e.String()) + sb.WriteString(e.String()) } - b.WriteRune(']') - return b.String() + sb.WriteByte(']') + + return sb.String() } // Len returns the number of elements in the array. @@ -1350,21 +1470,19 @@ func (arr *Array) Iter(f func(*Term) error) error { // Until calls f on each element in arr. If f returns true, iteration stops. func (arr *Array) Until(f func(*Term) bool) bool { - err := arr.Iter(func(t *Term) error { - if f(t) { - return errStop + for _, term := range arr.elems { + if f(term) { + return true } - return nil - }) - return err != nil + } + return false } // Foreach calls f on each element in arr. func (arr *Array) Foreach(f func(*Term)) { - _ = arr.Iter(func(t *Term) error { - f(t) - return nil - }) // ignore error + for _, term := range arr.elems { + f(term) + } } // Append appends a term to arr, returning the appended array. @@ -1399,8 +1517,8 @@ type Set interface { // NewSet returns a new Set containing t. func NewSet(t ...*Term) Set { s := newset(len(t)) - for i := range t { - s.Add(t[i]) + for _, term := range t { + s.insert(term, false) } return s } @@ -1415,7 +1533,7 @@ func newset(n int) *set { keys: keys, hash: 0, ground: true, - sortGuard: new(sync.Once), + sortGuard: sync.Once{}, } } @@ -1428,19 +1546,24 @@ func SetTerm(t ...*Term) *Term { } type set struct { - elems map[int]*Term - keys []*Term - hash int - ground bool - sortGuard *sync.Once // Prevents race condition around sorting. + elems map[int]*Term + keys []*Term + hash int + ground bool + // Prevents race condition around sorting. + // We can avoid (the allocation cost of) using a pointer here as all + // methods of `set` use a pointer receiver, and the `sync.Once` value + // is never copied. + sortGuard sync.Once } // Copy returns a deep copy of s. func (s *set) Copy() Set { - cpy := newset(s.Len()) - s.Foreach(func(x *Term) { - cpy.Add(x.Copy()) - }) + terms := make([]*Term, len(s.keys)) + for i := range s.keys { + terms[i] = s.keys[i].Copy() + } + cpy := NewSet(terms...).(*set) cpy.hash = s.hash cpy.ground = s.ground return cpy @@ -1460,21 +1583,27 @@ func (s *set) String() string { if s.Len() == 0 { return "set()" } - var b strings.Builder - b.WriteRune('{') + + sb := sbPool.Get() + sb.Grow(s.Len() * 16) + + defer sbPool.Put(sb) + + sb.WriteByte('{') for i := range s.sortedKeys() { if i > 0 { - b.WriteString(", ") + sb.WriteString(", ") } - b.WriteString(s.keys[i].Value.String()) + sb.WriteString(s.keys[i].Value.String()) } - b.WriteRune('}') - return b.String() + sb.WriteByte('}') + + return sb.String() } func (s *set) sortedKeys() []*Term { s.sortGuard.Do(func() { - sort.Sort(termSlice(s.keys)) + slices.SortFunc(s.keys, TermValueCompare) }) return s.keys } @@ -1506,13 +1635,14 @@ func (s *set) Find(path Ref) (Value, error) { // Diff returns elements in s that are not in other. func (s *set) Diff(other Set) Set { - r := NewSet() - s.Foreach(func(x *Term) { - if !other.Contains(x) { - r.Add(x) + terms := make([]*Term, 0, len(s.keys)) + for _, term := range s.sortedKeys() { + if !other.Contains(term) { + terms = append(terms, term) } - }) - return r + } + + return NewSet(terms...) } // Intersect returns the set containing elements in both s and other. @@ -1527,79 +1657,68 @@ func (s *set) Intersect(other Set) Set { n = m } - r := newset(n) - ss.Foreach(func(x *Term) { - if so.Contains(x) { - r.Add(x) + terms := make([]*Term, 0, n) + for _, term := range ss.sortedKeys() { + if so.Contains(term) { + terms = append(terms, term) } - }) - return r + } + + return NewSet(terms...) } // Union returns the set containing all elements of s and other. func (s *set) Union(other Set) Set { r := NewSet() - s.Foreach(func(x *Term) { - r.Add(x) - }) - other.Foreach(func(x *Term) { - r.Add(x) - }) + s.Foreach(r.Add) + other.Foreach(r.Add) return r } // Add updates s to include t. func (s *set) Add(t *Term) { - s.insert(t) + s.insert(t, true) } // Iter calls f on each element in s. If f returns an error, iteration stops // and the return value is the error. func (s *set) Iter(f func(*Term) error) error { - for i := range s.sortedKeys() { - if err := f(s.keys[i]); err != nil { + for _, term := range s.sortedKeys() { + if err := f(term); err != nil { return err } } return nil } -var errStop = errors.New("stop") - // Until calls f on each element in s. If f returns true, iteration stops. func (s *set) Until(f func(*Term) bool) bool { - err := s.Iter(func(t *Term) error { - if f(t) { - return errStop + for _, term := range s.sortedKeys() { + if f(term) { + return true } - return nil - }) - return err != nil + } + return false } // Foreach calls f on each element in s. func (s *set) Foreach(f func(*Term)) { - _ = s.Iter(func(t *Term) error { - f(t) - return nil - }) // ignore error + for _, term := range s.sortedKeys() { + f(term) + } } // Map returns a new Set obtained by applying f to each value in s. func (s *set) Map(f func(*Term) (*Term, error)) (Set, error) { - set := NewSet() - err := s.Iter(func(x *Term) error { + mapped := make([]*Term, 0, len(s.keys)) + for _, x := range s.sortedKeys() { term, err := f(x) if err != nil { - return err + return nil, err } - set.Add(term) - return nil - }) - if err != nil { - return nil, err + mapped = append(mapped, term) } - return set, nil + return NewSet(mapped...), nil } // Reduce returns a Term produced by applying f to each value in s. The first @@ -1649,7 +1768,7 @@ func (s *set) Slice() []*Term { // NOTE(philipc): We assume a many-readers, single-writer model here. // This method should NOT be used concurrently, or else we risk data races. -func (s *set) insert(x *Term) { +func (s *set) insert(x *Term, resetSortGuard bool) { hash := x.Hash() insertHash := hash // This `equal` utility is duplicated and manually inlined a number of @@ -1741,9 +1860,15 @@ func (s *set) insert(x *Term) { s.elems[insertHash] = x // O(1) insertion, but we'll have to re-sort the keys later. s.keys = append(s.keys, x) - // Reset the sync.Once instance. - // See https://github.com/golang/go/issues/25955 for why we do it this way. - s.sortGuard = new(sync.Once) + + if resetSortGuard { + // Reset the sync.Once instance. + // See https://github.com/golang/go/issues/25955 for why we do it this way. + // Note that this will always be the case when external code calls insert via + // Add, or otherwise. Internal code may however benefit from not having to + // re-create this pointer when it's known not to be needed. + s.sortGuard = sync.Once{} + } s.hash += hash s.ground = s.ground && x.IsGround() @@ -1865,7 +1990,7 @@ type Object interface { func NewObject(t ...[2]*Term) Object { obj := newobject(len(t)) for i := range t { - obj.Insert(t[i][0], t[i][1]) + obj.insert(t[i][0], t[i][1], false) } return obj } @@ -2011,7 +2136,8 @@ func (l *lazyObj) Keys() []*Term { for k := range l.native { ret = append(ret, StringTerm(k)) } - sort.Sort(termSlice(ret)) + slices.SortFunc(ret, TermValueCompare) + return ret } @@ -2065,7 +2191,7 @@ type object struct { ground int // number of key and value grounds. Counting is // required to support insert's key-value replace. hash int - sortGuard *sync.Once // Prevents race condition around sorting. + sortGuard sync.Once // Prevents race condition around sorting. } func newobject(n int) *object { @@ -2078,7 +2204,7 @@ func newobject(n int) *object { keys: keys, ground: 0, hash: 0, - sortGuard: new(sync.Once), + sortGuard: sync.Once{}, } } @@ -2091,7 +2217,7 @@ type objectElem struct { type objectElemSlice []*objectElem func (s objectElemSlice) Less(i, j int) bool { return Compare(s[i].key.Value, s[j].key.Value) < 0 } -func (s objectElemSlice) Swap(i, j int) { x := s[i]; s[i] = s[j]; s[j] = x } +func (s objectElemSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s objectElemSlice) Len() int { return len(s) } // Item is a helper for constructing an tuple containing two Terms @@ -2102,7 +2228,9 @@ func Item(key, value *Term) [2]*Term { func (obj *object) sortedKeys() objectElemSlice { obj.sortGuard.Do(func() { - sort.Sort(obj.keys) + slices.SortFunc(obj.keys, func(a, b *objectElem) int { + return a.key.Value.Compare(b.key.Value) + }) }) return obj.keys } @@ -2129,7 +2257,7 @@ func (obj *object) Compare(other Value) int { if len(b.keys) < len(akeys) { minLen = len(bkeys) } - for i := 0; i < minLen; i++ { + for i := range minLen { keysCmp := Compare(akeys[i].key, bkeys[i].key) if keysCmp < 0 { return -1 @@ -2158,15 +2286,21 @@ func (obj *object) Find(path Ref) (Value, error) { if len(path) == 0 { return obj, nil } - value := obj.Get(path[0]) - if value == nil { + term := obj.Get(path[0]) + if term == nil { return nil, errFindNotFound } - return value.Value.Find(path[1:]) + // Using Find on scalar values costs an allocation (type -> Value conversion) + // and since we already have the Value here, we can avoid that. + if len(path) == 1 && IsScalar(term.Value) { + return term.Value, nil + } + + return term.Value.Find(path[1:]) } func (obj *object) Insert(k, v *Term) { - obj.insert(k, v) + obj.insert(k, v, true) } // Get returns the value of k in obj if k exists, otherwise nil. @@ -2198,12 +2332,12 @@ func (obj *object) Copy() Object { // Diff returns a new Object that contains only the key/value pairs that exist in obj. func (obj *object) Diff(other Object) Object { - r := NewObject() - obj.Foreach(func(k, v *Term) { - if other.Get(k) == nil { - r.Insert(k, v) + r := newobject(obj.Len()) + for _, node := range obj.sortedKeys() { + if other.Get(node.key) == nil { + r.insert(node.key, node.value, false) } - }) + } return r } @@ -2235,38 +2369,34 @@ func (obj *object) Iter(f func(*Term, *Term) error) error { // 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) { - return errStop + for _, node := range obj.sortedKeys() { + if f(node.key, node.value) { + return true } - return nil - }) - return err != nil + } + return false } // 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 { - f(k, v) - return nil - }) // ignore error + for _, node := range obj.sortedKeys() { + f(node.key, node.value) + } } // Map returns a new Object constructed by mapping each element in the object -// using the function f. +// using the function f. If f returns an error, the error is returned by Map. +// If f return a nil key, the element is skipped. func (obj *object) Map(f func(*Term, *Term) (*Term, *Term, error)) (Object, error) { cpy := newobject(obj.Len()) - err := obj.Iter(func(k, v *Term) error { - var err error - k, v, err = f(k, v) + for _, node := range obj.sortedKeys() { + k, v, err := f(node.key, node.value) if err != nil { - return err + return nil, err + } + if k != nil { + cpy.insert(k, v, false) } - cpy.insert(k, v) - return nil - }) - if err != nil { - return nil, err } return cpy, nil } @@ -2300,7 +2430,7 @@ func (obj *object) MarshalJSON() ([]byte, error) { // overlapping keys between obj and other, the values of associated with the keys are merged. Only // objects can be merged with other objects. If the values cannot be merged, the second turn value // will be false. -func (obj object) Merge(other Object) (Object, bool) { +func (obj *object) Merge(other Object) (Object, bool) { return obj.MergeWith(other, func(v1, v2 *Term) (*Term, bool) { obj1, ok1 := v1.Value.(Object) obj2, ok2 := v2.Value.(Object) @@ -2319,7 +2449,7 @@ func (obj object) Merge(other Object) (Object, bool) { // If there are overlapping keys between obj and other, the conflictResolver // is called. The conflictResolver can return a merged value and a boolean // indicating if the merge has failed and should stop. -func (obj object) MergeWith(other Object, conflictResolver func(v1, v2 *Term) (*Term, bool)) (Object, bool) { +func (obj *object) MergeWith(other Object, conflictResolver func(v1, v2 *Term) (*Term, bool)) (Object, bool) { result := NewObject() stop := obj.Until(func(k, v *Term) bool { v2 := other.Get(k) @@ -2362,24 +2492,29 @@ func (obj *object) Filter(filter Object) (Object, error) { } // Len returns the number of elements in the object. -func (obj object) Len() int { +func (obj *object) Len() int { return len(obj.keys) } -func (obj object) String() string { - var b strings.Builder - b.WriteRune('{') +func (obj *object) String() string { + sb := sbPool.Get() + sb.Grow(obj.Len() * 32) + + defer sbPool.Put(sb) + + sb.WriteByte('{') for i, elem := range obj.sortedKeys() { if i > 0 { - b.WriteString(", ") + sb.WriteString(", ") } - b.WriteString(elem.key.String()) - b.WriteString(": ") - b.WriteString(elem.value.String()) + sb.WriteString(elem.key.String()) + sb.WriteString(": ") + sb.WriteString(elem.value.String()) } - b.WriteRune('}') - return b.String() + sb.WriteByte('}') + + return sb.String() } func (obj *object) get(k *Term) *objectElem { @@ -2395,10 +2530,10 @@ func (obj *object) get(k *Term) *objectElem { case Null, Boolean, String, Var: equal = func(y Value) bool { return x == y } case Number: - if xi, err := json.Number(x).Int64(); err == nil { + if xi, ok := x.Int64(); ok { equal = func(y Value) bool { if y, ok := y.(Number); ok { - if yi, err := json.Number(y).Int64(); err == nil { + if yi, ok := y.Int64(); ok { return xi == yi } } @@ -2472,7 +2607,7 @@ func (obj *object) get(k *Term) *objectElem { // NOTE(philipc): We assume a many-readers, single-writer model here. // This method should NOT be used concurrently, or else we risk data races. -func (obj *object) insert(k, v *Term) { +func (obj *object) insert(k, v *Term, resetSortGuard bool) { hash := k.Hash() head := obj.elems[hash] // This `equal` utility is duplicated and manually inlined a number of @@ -2579,9 +2714,16 @@ func (obj *object) insert(k, v *Term) { obj.elems[hash] = elem // O(1) insertion, but we'll have to re-sort the keys later. obj.keys = append(obj.keys, elem) - // Reset the sync.Once instance. - // See https://github.com/golang/go/issues/25955 for why we do it this way. - obj.sortGuard = new(sync.Once) + + if resetSortGuard { + // Reset the sync.Once instance. + // See https://github.com/golang/go/issues/25955 for why we do it this way. + // Note that this will always be the case when external code calls insert via + // Add, or otherwise. Internal code may however benefit from not having to + // re-create this when it's known not to be needed. + obj.sortGuard = sync.Once{} + } + obj.hash += hash + v.Hash() if k.IsGround() { @@ -2606,7 +2748,7 @@ func (obj *object) rehash() { } func filterObject(o Value, filter Value) (Value, error) { - if filter.Compare(Null{}) == 0 { + if (Null{}).Equal(filter) { return o, nil } @@ -2620,7 +2762,7 @@ func filterObject(o Value, filter Value) (Value, error) { return o, nil case *Array: values := NewArray() - for i := 0; i < v.Len(); i++ { + for i := range v.Len() { subFilter := filteredObj.Get(StringTerm(strconv.Itoa(i))) if subFilter != nil { filteredValue, err := filterObject(v.Elem(i).Value, subFilter.Value) @@ -2632,18 +2774,17 @@ func filterObject(o Value, filter Value) (Value, error) { } return values, nil case Set: - values := NewSet() - err := v.Iter(func(t *Term) error { + terms := make([]*Term, 0, v.Len()) + for _, t := range v.Slice() { if filteredObj.Get(t) != nil { filteredValue, err := filterObject(t.Value, filteredObj.Get(t).Value) if err != nil { - return err + return nil, err } - values.Add(NewTerm(filteredValue)) + terms = append(terms, NewTerm(filteredValue)) } - return nil - }) - return values, err + } + return NewSet(terms...), nil case *object: values := NewObject() @@ -2895,7 +3036,7 @@ func (c Call) Compare(other Value) int { } // Find returns the current value or a not found error. -func (c Call) Find(Ref) (Value, error) { +func (Call) Find(Ref) (Value, error) { return nil, errFindNotFound } @@ -2982,7 +3123,7 @@ func unmarshalBody(b []interface{}) (Body, error) { } return buf, nil unmarshal_error: - return nil, fmt.Errorf("ast: unable to unmarshal body") + return nil, errors.New("ast: unable to unmarshal body") } func unmarshalExpr(expr *Expr, v map[string]interface{}) error { @@ -3119,7 +3260,7 @@ func unmarshalTermSlice(s []interface{}) ([]*Term, error) { } return nil, err } - return nil, fmt.Errorf("ast: unable to unmarshal term") + return nil, errors.New("ast: unable to unmarshal term") } return buf, nil } @@ -3128,7 +3269,7 @@ func unmarshalTermSliceValue(d map[string]interface{}) ([]*Term, error) { if s, ok := d["value"].([]interface{}); ok { return unmarshalTermSlice(s) } - return nil, fmt.Errorf(`ast: unable to unmarshal term (expected {"value": [...], "type": ...} where type is one of: ref, array, or set)`) + return nil, errors.New(`ast: unable to unmarshal term (expected {"value": [...], "type": ...} where type is one of: ref, array, or set)`) } func unmarshalWith(i interface{}) (*With, error) { @@ -3148,14 +3289,14 @@ func unmarshalWith(i interface{}) (*With, error) { } return nil, err } - return nil, fmt.Errorf(`ast: unable to unmarshal with modifier (expected {"target": {...}, "value": {...}})`) + return nil, errors.New(`ast: unable to unmarshal with modifier (expected {"target": {...}, "value": {...}})`) } func unmarshalValue(d map[string]interface{}) (Value, error) { v := d["value"] switch d["type"] { case "null": - return Null{}, nil + return NullValue, nil case "boolean": if b, ok := v.(bool); ok { return Boolean(b), nil @@ -3182,11 +3323,7 @@ func unmarshalValue(d map[string]interface{}) (Value, error) { } case "set": if s, err := unmarshalTermSliceValue(d); err == nil { - set := NewSet() - for _, x := range s { - set.Add(x) - } - return set, nil + return NewSet(s...), nil } case "object": if s, ok := v.([]interface{}); ok { @@ -3270,5 +3407,5 @@ func unmarshalValue(d map[string]interface{}) (Value, error) { } } unmarshal_error: - return nil, fmt.Errorf("ast: unable to unmarshal term") + return nil, errors.New("ast: unable to unmarshal term") } diff --git a/vendor/github.com/open-policy-agent/opa/ast/transform.go b/vendor/github.com/open-policy-agent/opa/v1/ast/transform.go similarity index 99% rename from vendor/github.com/open-policy-agent/opa/ast/transform.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/transform.go index 391a164860..e8c9ddcab1 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/transform.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/transform.go @@ -234,7 +234,7 @@ func Transform(t Transformer, x interface{}) (interface{}, error) { return k, v, nil }) case *Array: - for i := 0; i < y.Len(); i++ { + for i := range y.Len() { v, err := transformTerm(t, y.Elem(i)) if err != nil { return nil, err diff --git a/vendor/github.com/open-policy-agent/opa/ast/unify.go b/vendor/github.com/open-policy-agent/opa/v1/ast/unify.go similarity index 98% rename from vendor/github.com/open-policy-agent/opa/ast/unify.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/unify.go index 60244974a9..3af52815f7 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/unify.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/unify.go @@ -135,7 +135,7 @@ func (u *unifier) unify(a *Term, b *Term) { } case *Array: if a.Len() == b.Len() { - for i := 0; i < a.Len(); i++ { + for i := range a.Len() { u.unify(a.Elem(i), b.Elem(i)) } } @@ -226,7 +226,7 @@ func (u *unifier) unifyAll(a Var, b Value) { } } -func (u *unifier) varVisitor() *VarVisitor { +func (*unifier) varVisitor() *VarVisitor { return NewVarVisitor().WithParams(VarVisitorParams{ SkipRefHead: true, SkipObjectKeys: true, diff --git a/vendor/github.com/open-policy-agent/opa/ast/varset.go b/vendor/github.com/open-policy-agent/opa/v1/ast/varset.go similarity index 71% rename from vendor/github.com/open-policy-agent/opa/ast/varset.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/varset.go index 14f531494b..bccb035e30 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/varset.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/varset.go @@ -6,7 +6,9 @@ package ast import ( "fmt" - "sort" + "slices" + + "github.com/open-policy-agent/opa/v1/util" ) // VarSet represents a set of variables. @@ -14,13 +16,18 @@ type VarSet map[Var]struct{} // NewVarSet returns a new VarSet containing the specified variables. func NewVarSet(vs ...Var) VarSet { - s := VarSet{} + s := make(VarSet, len(vs)) for _, v := range vs { s.Add(v) } return s } +// NewVarSet returns a new VarSet containing the specified variables. +func NewVarSetOfSize(size int) VarSet { + return make(VarSet, size) +} + // Add updates the set to include the variable "v". func (s VarSet) Add(v Var) { s[v] = struct{}{} @@ -34,7 +41,7 @@ func (s VarSet) Contains(v Var) bool { // Copy returns a shallow copy of the VarSet. func (s VarSet) Copy() VarSet { - cpy := VarSet{} + cpy := NewVarSetOfSize(len(s)) for v := range s { cpy.Add(v) } @@ -43,7 +50,13 @@ func (s VarSet) Copy() VarSet { // Diff returns a VarSet containing variables in s that are not in vs. func (s VarSet) Diff(vs VarSet) VarSet { - r := VarSet{} + i := 0 + for v := range s { + if !vs.Contains(v) { + i++ + } + } + r := NewVarSetOfSize(i) for v := range s { if !vs.Contains(v) { r.Add(v) @@ -54,15 +67,26 @@ func (s VarSet) Diff(vs VarSet) VarSet { // Equal returns true if s contains exactly the same elements as vs. func (s VarSet) Equal(vs VarSet) bool { - if len(s.Diff(vs)) > 0 { + if len(s) != len(vs) { return false } - return len(vs.Diff(s)) == 0 + for v := range s { + if !vs.Contains(v) { + return false + } + } + return true } // Intersect returns a VarSet containing variables in s that are in vs. func (s VarSet) Intersect(vs VarSet) VarSet { - r := VarSet{} + i := 0 + for v := range s { + if vs.Contains(v) { + i++ + } + } + r := NewVarSetOfSize(i) for v := range s { if vs.Contains(v) { r.Add(v) @@ -71,15 +95,13 @@ func (s VarSet) Intersect(vs VarSet) VarSet { return r } -// Sorted returns a sorted slice of vars from s. +// Sorted returns a new sorted slice of vars from s. func (s VarSet) Sorted() []Var { sorted := make([]Var, 0, len(s)) for v := range s { sorted = append(sorted, v) } - sort.Slice(sorted, func(i, j int) bool { - return sorted[i].Compare(sorted[j]) < 0 - }) + slices.SortFunc(sorted, VarCompare) return sorted } @@ -91,10 +113,5 @@ func (s VarSet) Update(vs VarSet) { } func (s VarSet) String() string { - tmp := make([]string, 0, len(s)) - for v := range s { - tmp = append(tmp, string(v)) - } - sort.Strings(tmp) - return fmt.Sprintf("%v", tmp) + return fmt.Sprintf("%v", util.KeysSorted(s)) } diff --git a/vendor/github.com/open-policy-agent/opa/ast/version_index.json b/vendor/github.com/open-policy-agent/opa/v1/ast/version_index.json similarity index 99% rename from vendor/github.com/open-policy-agent/opa/ast/version_index.json rename to vendor/github.com/open-policy-agent/opa/v1/ast/version_index.json index 718df220f9..eecb68c772 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/version_index.json +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/version_index.json @@ -497,6 +497,13 @@ "PreRelease": "", "Metadata": "" }, + "internal.test_case": { + "Major": 1, + "Minor": 2, + "Patch": 0, + "PreRelease": "", + "Metadata": "" + }, "intersection": { "Major": 0, "Minor": 17, @@ -1395,6 +1402,13 @@ } }, "features": { + "rego_v1": { + "Major": 1, + "Minor": 0, + "Patch": 0, + "PreRelease": "", + "Metadata": "" + }, "rego_v1_import": { "Major": 0, "Minor": 59, diff --git a/vendor/github.com/open-policy-agent/opa/ast/visit.go b/vendor/github.com/open-policy-agent/opa/v1/ast/visit.go similarity index 99% rename from vendor/github.com/open-policy-agent/opa/ast/visit.go rename to vendor/github.com/open-policy-agent/opa/v1/ast/visit.go index d83c31149e..0115c4f455 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/visit.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/visit.go @@ -357,14 +357,14 @@ func (vis *GenericVisitor) Walk(x interface{}) { vis.Walk(x.Get(k)) }) case Object: - x.Foreach(func(k, _ *Term) { + for _, k := range x.Keys() { vis.Walk(k) vis.Walk(x.Get(k)) - }) + } case *Array: - x.Foreach(func(t *Term) { - vis.Walk(t) - }) + for i := range x.Len() { + vis.Walk(x.Elem(i)) + } case Set: xSlice := x.Slice() for i := range xSlice { diff --git a/vendor/github.com/open-policy-agent/opa/bundle/bundle.go b/vendor/github.com/open-policy-agent/opa/v1/bundle/bundle.go similarity index 94% rename from vendor/github.com/open-policy-agent/opa/bundle/bundle.go rename to vendor/github.com/open-policy-agent/opa/v1/bundle/bundle.go index 0e159384ef..d6bf846fc4 100644 --- a/vendor/github.com/open-policy-agent/opa/bundle/bundle.go +++ b/vendor/github.com/open-policy-agent/opa/v1/bundle/bundle.go @@ -22,13 +22,13 @@ import ( "strings" "github.com/gobwas/glob" - "github.com/open-policy-agent/opa/ast" - astJSON "github.com/open-policy-agent/opa/ast/json" - "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/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/ast" + astJSON "github.com/open-policy-agent/opa/v1/ast/json" + "github.com/open-policy-agent/opa/v1/format" + "github.com/open-policy-agent/opa/v1/metrics" + "github.com/open-policy-agent/opa/v1/util" ) // Common file extensions and file names. @@ -67,8 +67,9 @@ type Bundle struct { // Raw contains raw bytes representing the bundle's content type Raw struct { - Path string - Value []byte + Path string + Value []byte + module *ModuleFile } // Patch contains an array of objects wherein each object represents the patch operation to be @@ -266,7 +267,7 @@ func (m Manifest) equalWasmResolversAndRoots(other Manifest) bool { return false } - for i := 0; i < len(m.WasmResolvers); i++ { + for i := range len(m.WasmResolvers) { if !m.WasmResolvers[i].Equal(&other.WasmResolvers[i]) { return false } @@ -297,7 +298,7 @@ func (wr *WasmResolver) Equal(other *WasmResolver) bool { return false } - for i := 0; i < annotLen; i++ { + for i := range annotLen { if wr.Annotations[i].Compare(other.Annotations[i]) != 0 { return false } @@ -332,7 +333,7 @@ func (m *Manifest) validateAndInjectDefaults(b Bundle) error { roots[i] = strings.Trim(roots[i], "/") } - for i := 0; i < len(roots)-1; i++ { + for i := range len(roots) - 1 { for j := i + 1; j < len(roots); j++ { if RootPathsOverlap(roots[i], roots[j]) { return fmt.Errorf("manifest has overlapped roots: '%v' and '%v'", roots[i], roots[j]) @@ -444,7 +445,6 @@ type Reader struct { verificationConfig *VerificationConfig skipVerify bool processAnnotations bool - jsonOptions *astJSON.Options capabilities *ast.Capabilities files map[string]FileInfo // files in the bundle signature payload sizeLimitBytes int64 @@ -517,9 +517,11 @@ func (r *Reader) WithCapabilities(caps *ast.Capabilities) *Reader { return r } -// WithJSONOptions sets the JSONOptions to use when parsing policy files -func (r *Reader) WithJSONOptions(opts *astJSON.Options) *Reader { - r.jsonOptions = opts +// WithJSONOptions sets the JSON options on the parser (now a no-op). +// +// Deprecated: Use SetOptions in the json package instead, where a longer description +// of why this is deprecated also can be found. +func (r *Reader) WithJSONOptions(*astJSON.Options) *Reader { return r } @@ -571,7 +573,6 @@ func (r *Reader) ParserOptions() ast.ParserOptions { return ast.ParserOptions{ ProcessAnnotation: r.processAnnotations, Capabilities: r.capabilities, - JSONOptions: r.jsonOptions, RegoVersion: r.regoVersion, } } @@ -633,15 +634,6 @@ func (r *Reader) Read() (Bundle, error) { fullPath := r.fullPath(path) bs := buf.Bytes() - if r.lazyLoadingMode { - p := fullPath - if r.name != "" { - p = modulePathWithPrefix(r.name, fullPath) - } - - raw = append(raw, Raw{Path: p, Value: bs}) - } - // Modules are parsed after we've had a chance to read the manifest mf := ModuleFile{ URL: f.URL(), @@ -650,6 +642,15 @@ func (r *Reader) Read() (Bundle, error) { Raw: bs, } modules = append(modules, mf) + + if r.lazyLoadingMode { + p := fullPath + if r.name != "" { + p = modulePathWithPrefix(r.name, fullPath) + } + + raw = append(raw, Raw{Path: p, Value: bs, module: &mf}) + } } else if filepath.Base(path) == WasmFile { bundle.WasmModules = append(bundle.WasmModules, WasmModuleFile{ URL: f.URL(), @@ -711,11 +712,14 @@ func (r *Reader) Read() (Bundle, error) { // Parse modules popts := r.ParserOptions() - popts.RegoVersion = bundle.RegoVersion(popts.RegoVersion) + popts.RegoVersion = bundle.RegoVersion(popts.EffectiveRegoVersion()) for _, mf := range modules { modulePopts := popts - if modulePopts.RegoVersion, err = bundle.RegoVersionForFile(mf.RelativePath, popts.RegoVersion); err != nil { + if regoVersion, err := bundle.RegoVersionForFile(mf.RelativePath, popts.EffectiveRegoVersion()); err != nil { return bundle, err + } else if regoVersion != ast.RegoUndefined { + // We don't expect ast.RegoUndefined here, but don't override configured rego-version if we do just to be extra protective + modulePopts.RegoVersion = regoVersion } r.metrics.Timer(metrics.RegoModuleParse).Start() mf.Parsed, err = ast.ParseModuleWithOpts(mf.Path, string(mf.Raw), modulePopts) @@ -728,19 +732,19 @@ func (r *Reader) Read() (Bundle, error) { if bundle.Type() == DeltaBundleType { if len(bundle.Data) != 0 { - return bundle, fmt.Errorf("delta bundle expected to contain only patch file but data files found") + return bundle, errors.New("delta bundle expected to contain only patch file but data files found") } if len(bundle.Modules) != 0 { - return bundle, fmt.Errorf("delta bundle expected to contain only patch file but policy files found") + return bundle, errors.New("delta bundle expected to contain only patch file but policy files found") } if len(bundle.WasmModules) != 0 { - return bundle, fmt.Errorf("delta bundle expected to contain only patch file but wasm files found") + return bundle, errors.New("delta bundle expected to contain only patch file but wasm files found") } if r.persist { - return bundle, fmt.Errorf("'persist' property is true in config. persisting delta bundle to disk is not supported") + return bundle, errors.New("'persist' property is true in config. persisting delta bundle to disk is not supported") } } @@ -762,7 +766,7 @@ func (r *Reader) Read() (Bundle, error) { for _, r := range bundle.Manifest.WasmResolvers { epMap[r.Module] = append(epMap[r.Module], r.Entrypoint) } - for i := 0; i < len(bundle.WasmModules); i++ { + for i := range len(bundle.WasmModules) { entrypoints := epMap[bundle.WasmModules[i].Path] for _, entrypoint := range entrypoints { ref, err := ast.PtrRef(ast.DefaultRootDocument, entrypoint) @@ -815,12 +819,12 @@ func (r *Reader) checkSignaturesAndDescriptors(signatures SignaturesConfig) erro } if signatures.isEmpty() && r.verificationConfig != nil && r.verificationConfig.KeyID != "" { - return fmt.Errorf("bundle missing .signatures.json file") + return errors.New("bundle missing .signatures.json file") } if !signatures.isEmpty() { if r.verificationConfig == nil { - return fmt.Errorf("verification key not provided") + return errors.New("verification key not provided") } // verify the JWT signatures included in the `.signatures.json` file @@ -1082,9 +1086,9 @@ func hashBundleFiles(hash SignatureHasher, b *Bundle) ([]FileInfo, error) { } // FormatModules formats Rego modules -// Modules will be formatted to comply with rego-v0, but Rego compatibility of individual parsed modules will be respected (e.g. if 'rego.v1' is imported). +// Modules will be formatted to comply with [ast.DefaultRegoVersion], but Rego compatibility of individual parsed modules will be respected (e.g. if 'rego.v1' is imported). func (b *Bundle) FormatModules(useModulePath bool) error { - return b.FormatModulesForRegoVersion(ast.RegoV0, true, useModulePath) + return b.FormatModulesForRegoVersion(ast.DefaultRegoVersion, true, useModulePath) } // FormatModulesForRegoVersion formats Rego modules to comply with a given Rego version @@ -1216,6 +1220,19 @@ func (b *Bundle) RegoVersionForFile(path string, def ast.RegoVersion) (ast.RegoV return def, fmt.Errorf("unknown bundle rego-version %d for file '%s'", *version, path) } +func (m *Manifest) RegoVersionForFile(path string) (ast.RegoVersion, error) { + v, err := m.numericRegoVersionForFile(path) + if err != nil { + return ast.RegoUndefined, err + } + + if v == nil { + return ast.RegoUndefined, nil + } + + return ast.RegoVersionFromInt(*v), nil +} + func (m *Manifest) numericRegoVersionForFile(path string) (*int, error) { var version *int @@ -1336,7 +1353,7 @@ func (b *Bundle) readData(key []string) *interface{} { node := b.Data - for i := 0; i < len(key)-1; i++ { + for i := range len(key) - 1 { child, ok := node[key[i]] if !ok { @@ -1372,7 +1389,7 @@ func mktree(path []string, value interface{}) (map[string]interface{}, error) { // For 0 length path the value is the full tree. obj, ok := value.(map[string]interface{}) if !ok { - return nil, fmt.Errorf("root value must be object") + return nil, errors.New("root value must be object") } return obj, nil } @@ -1393,7 +1410,7 @@ func mktree(path []string, value interface{}) (map[string]interface{}, error) { // 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.) func Merge(bundles []*Bundle) (*Bundle, error) { - return MergeWithRegoVersion(bundles, ast.RegoV0, false) + return MergeWithRegoVersion(bundles, ast.DefaultRegoVersion, false) } // MergeWithRegoVersion creates a merged bundle from the provided bundles, similar to Merge. @@ -1410,6 +1427,10 @@ func MergeWithRegoVersion(bundles []*Bundle, regoVersion ast.RegoVersion, usePat return nil, errors.New("expected at least one bundle") } + if regoVersion == ast.RegoUndefined { + regoVersion = ast.DefaultRegoVersion + } + if len(bundles) == 1 { result := bundles[0] // We respect the bundle rego-version, defaulting to the provided rego version if not set. @@ -1490,11 +1511,20 @@ func bundleRegoVersions(bundle *Bundle, regoVersion ast.RegoVersion, usePath boo if err != nil { return nil, err } - // only record the rego version if it's different from one applied globally to the result bundle - if v != regoVersion { - // We store the rego version by the absolute path to the bundle root, as this will be the - possibly new - path - // to the module inside the merged bundle. - fileRegoVersions[bundleAbsolutePath(m, usePath)] = v.Int() + + // only record the rego version if it's different from the one applied globally to the result bundle + if v != ast.RegoUndefined { + if regoVersion == ast.RegoUndefined { + // We store the rego version by the absolute path to the bundle root, as this will be the - possibly new - path + // to the module inside the merged bundle. + fileRegoVersions[bundleAbsolutePath(m, usePath)] = v.Int() + } else { + vInt := v.Int() + gVInt := regoVersion.Int() + if vInt != gVInt { + fileRegoVersions[bundleAbsolutePath(m, usePath)] = vInt + } + } } } diff --git a/vendor/github.com/open-policy-agent/opa/bundle/file.go b/vendor/github.com/open-policy-agent/opa/v1/bundle/file.go similarity index 95% rename from vendor/github.com/open-policy-agent/opa/bundle/file.go rename to vendor/github.com/open-policy-agent/opa/v1/bundle/file.go index 80b1a87eb1..12e159254c 100644 --- a/vendor/github.com/open-policy-agent/opa/bundle/file.go +++ b/vendor/github.com/open-policy-agent/opa/v1/bundle/file.go @@ -13,9 +13,9 @@ import ( "strings" "sync" - "github.com/open-policy-agent/opa/loader/filter" + "github.com/open-policy-agent/opa/v1/loader/filter" - "github.com/open-policy-agent/opa/storage" + "github.com/open-policy-agent/opa/v1/storage" ) const maxSizeLimitBytesErrMsg = "bundle file %s size (%d bytes) exceeds configured size_limit_bytes (%d bytes)" @@ -438,15 +438,11 @@ func (it *iterator) Next() (*storage.Update, error) { for _, item := range it.raw { f := file{name: item.Path} - fpath := strings.TrimLeft(normalizePath(filepath.Dir(f.name)), "/.") - if strings.HasSuffix(f.name, RegoExt) { - fpath = strings.Trim(normalizePath(f.name), "/") + p, err := getFileStoragePath(f.name) + if err != nil { + return nil, err } - p, ok := storage.ParsePathEscaped("/" + fpath) - if !ok { - return nil, fmt.Errorf("storage path invalid: %v", f.name) - } f.path = p f.raw = item.Value @@ -506,3 +502,16 @@ func getdepth(path string, isDir bool) int { basePath := strings.Trim(filepath.Dir(filepath.ToSlash(path)), "/") return len(strings.Split(basePath, "/")) } + +func getFileStoragePath(path string) (storage.Path, error) { + fpath := strings.TrimLeft(normalizePath(filepath.Dir(path)), "/.") + if strings.HasSuffix(path, RegoExt) { + fpath = strings.Trim(normalizePath(path), "/") + } + + p, ok := storage.ParsePathEscaped("/" + fpath) + if !ok { + return nil, fmt.Errorf("storage path invalid: %v", path) + } + return p, nil +} diff --git a/vendor/github.com/open-policy-agent/opa/bundle/filefs.go b/vendor/github.com/open-policy-agent/opa/v1/bundle/filefs.go similarity index 98% rename from vendor/github.com/open-policy-agent/opa/bundle/filefs.go rename to vendor/github.com/open-policy-agent/opa/v1/bundle/filefs.go index a3a0dbf204..7ab3de989c 100644 --- a/vendor/github.com/open-policy-agent/opa/bundle/filefs.go +++ b/vendor/github.com/open-policy-agent/opa/v1/bundle/filefs.go @@ -10,7 +10,7 @@ import ( "path/filepath" "sync" - "github.com/open-policy-agent/opa/loader/filter" + "github.com/open-policy-agent/opa/v1/loader/filter" ) const ( diff --git a/vendor/github.com/open-policy-agent/opa/bundle/hash.go b/vendor/github.com/open-policy-agent/opa/v1/bundle/hash.go similarity index 96% rename from vendor/github.com/open-policy-agent/opa/bundle/hash.go rename to vendor/github.com/open-policy-agent/opa/v1/bundle/hash.go index 021801bb0a..ab6fcd0f38 100644 --- a/vendor/github.com/open-policy-agent/opa/bundle/hash.go +++ b/vendor/github.com/open-policy-agent/opa/v1/bundle/hash.go @@ -14,8 +14,9 @@ import ( "fmt" "hash" "io" - "sort" "strings" + + "github.com/open-policy-agent/opa/v1/util" ) // HashingAlgorithm represents a subset of hashing algorithms implemented in Go @@ -97,13 +98,7 @@ func walk(v interface{}, h io.Writer) { case map[string]interface{}: _, _ = h.Write([]byte("{")) - var keys []string - for k := range x { - keys = append(keys, k) - } - sort.Strings(keys) - - for i, key := range keys { + for i, key := range util.KeysSorted(x) { if i > 0 { _, _ = h.Write([]byte(",")) } diff --git a/vendor/github.com/open-policy-agent/opa/bundle/keys.go b/vendor/github.com/open-policy-agent/opa/v1/bundle/keys.go similarity index 97% rename from vendor/github.com/open-policy-agent/opa/bundle/keys.go rename to vendor/github.com/open-policy-agent/opa/v1/bundle/keys.go index 810bee4b72..aad30a675a 100644 --- a/vendor/github.com/open-policy-agent/opa/bundle/keys.go +++ b/vendor/github.com/open-policy-agent/opa/v1/bundle/keys.go @@ -12,9 +12,9 @@ import ( "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/v1/keys" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/util" ) const ( diff --git a/vendor/github.com/open-policy-agent/opa/bundle/sign.go b/vendor/github.com/open-policy-agent/opa/v1/bundle/sign.go similarity index 96% rename from vendor/github.com/open-policy-agent/opa/bundle/sign.go rename to vendor/github.com/open-policy-agent/opa/v1/bundle/sign.go index cf9a3e183a..710e296860 100644 --- a/vendor/github.com/open-policy-agent/opa/bundle/sign.go +++ b/vendor/github.com/open-policy-agent/opa/v1/bundle/sign.go @@ -101,11 +101,9 @@ func generatePayload(files []FileInfo, sc *SigningConfig, keyID string) ([]byte, for claim, value := range claims { payload[claim] = value } - } else { - if keyID != "" { - // keyid claim is deprecated but include it for backwards compatibility. - payload["keyid"] = keyID - } + } else if keyID != "" { + // keyid claim is deprecated but include it for backwards compatibility. + payload["keyid"] = keyID } return json.Marshal(payload) } diff --git a/vendor/github.com/open-policy-agent/opa/bundle/store.go b/vendor/github.com/open-policy-agent/opa/v1/bundle/store.go similarity index 84% rename from vendor/github.com/open-policy-agent/opa/bundle/store.go rename to vendor/github.com/open-policy-agent/opa/v1/bundle/store.go index 9a49f025e8..363f7664d7 100644 --- a/vendor/github.com/open-policy-agent/opa/bundle/store.go +++ b/vendor/github.com/open-policy-agent/opa/v1/bundle/store.go @@ -8,21 +8,24 @@ import ( "context" "encoding/base64" "encoding/json" + "errors" "fmt" "path/filepath" "strings" - "github.com/open-policy-agent/opa/ast" iCompiler "github.com/open-policy-agent/opa/internal/compiler" "github.com/open-policy-agent/opa/internal/json/patch" - "github.com/open-policy-agent/opa/metrics" - "github.com/open-policy-agent/opa/storage" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/metrics" + "github.com/open-policy-agent/opa/v1/storage" + "github.com/open-policy-agent/opa/v1/util" ) // BundlesBasePath is the storage path used for storing bundle metadata var BundlesBasePath = storage.MustParsePath("/system/bundles") +var ModulesInfoBasePath = storage.MustParsePath("/system/modules") + // Note: As needed these helpers could be memoized. // ManifestStoragePath is the storage path used for the given named bundle manifest. @@ -59,6 +62,14 @@ func metadataPath(name string) storage.Path { return append(BundlesBasePath, name, "manifest", "metadata") } +func moduleRegoVersionPath(id string) storage.Path { + return append(ModulesInfoBasePath, strings.Trim(id, "/"), "rego_version") +} + +func moduleInfoPath(id string) storage.Path { + return append(ModulesInfoBasePath, strings.Trim(id, "/")) +} + func read(ctx context.Context, store storage.Store, txn storage.Transaction, path storage.Path) (interface{}, error) { value, err := store.Read(ctx, txn, path) if err != nil { @@ -84,7 +95,7 @@ func ReadBundleNamesFromStore(ctx context.Context, store storage.Store, txn stor bundleMap, ok := value.(map[string]interface{}) if !ok { - return nil, fmt.Errorf("corrupt manifest roots") + return nil, errors.New("corrupt manifest roots") } bundles := make([]string, len(bundleMap)) @@ -166,6 +177,16 @@ func eraseWasmModulesFromStore(ctx context.Context, store storage.Store, txn sto return suppressNotFound(err) } +func eraseModuleRegoVersionsFromStore(ctx context.Context, store storage.Store, txn storage.Transaction, modules []string) error { + for _, module := range modules { + err := store.Write(ctx, txn, storage.RemoveOp, moduleInfoPath(module), nil) + if err := suppressNotFound(err); err != nil { + 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) @@ -176,14 +197,14 @@ func ReadWasmMetadataFromStore(ctx context.Context, store storage.Store, txn sto bs, err := json.Marshal(value) if err != nil { - return nil, fmt.Errorf("corrupt wasm manifest data") + return nil, errors.New("corrupt wasm manifest data") } var wasmMetadata []WasmResolver err = util.UnmarshalJSON(bs, &wasmMetadata) if err != nil { - return nil, fmt.Errorf("corrupt wasm manifest data") + return nil, errors.New("corrupt wasm manifest data") } return wasmMetadata, nil @@ -199,14 +220,14 @@ func ReadWasmModulesFromStore(ctx context.Context, store storage.Store, txn stor encodedModules, ok := value.(map[string]interface{}) if !ok { - return nil, fmt.Errorf("corrupt wasm modules") + return nil, errors.New("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") + return nil, errors.New("corrupt wasm modules") } bs, err := base64.StdEncoding.DecodeString(encStr) if err != nil { @@ -228,7 +249,7 @@ func ReadBundleRootsFromStore(ctx context.Context, store storage.Store, txn stor sl, ok := value.([]interface{}) if !ok { - return nil, fmt.Errorf("corrupt manifest roots") + return nil, errors.New("corrupt manifest roots") } roots := make([]string, len(sl)) @@ -236,7 +257,7 @@ func ReadBundleRootsFromStore(ctx context.Context, store storage.Store, txn stor for i := range sl { roots[i], ok = sl[i].(string) if !ok { - return nil, fmt.Errorf("corrupt manifest root") + return nil, errors.New("corrupt manifest root") } } @@ -258,7 +279,7 @@ func readRevisionFromStore(ctx context.Context, store storage.Store, txn storage str, ok := value.(string) if !ok { - return "", fmt.Errorf("corrupt manifest revision") + return "", errors.New("corrupt manifest revision") } return str, nil @@ -279,7 +300,7 @@ func readMetadataFromStore(ctx context.Context, store storage.Store, txn storage data, ok := value.(map[string]interface{}) if !ok { - return nil, fmt.Errorf("corrupt manifest metadata") + return nil, errors.New("corrupt manifest metadata") } return data, nil @@ -300,7 +321,7 @@ func readEtagFromStore(ctx context.Context, store storage.Store, txn storage.Tra str, ok := value.(string) if !ok { - return "", fmt.Errorf("corrupt bundle etag") + return "", errors.New("corrupt bundle etag") } return str, nil @@ -426,7 +447,7 @@ func activateBundles(opts *ActivateOpts) error { p := getNormalizedPath(path) if len(p) == 0 { - return fmt.Errorf("root value must be object") + return errors.New("root value must be object") } // verify valid YAML or JSON value @@ -475,7 +496,7 @@ func activateBundles(opts *ActivateOpts) error { return err } - if err := writeDataAndModules(opts.Ctx, opts.Store, opts.Txn, opts.TxnCtx, snapshotBundles, opts.legacy); err != nil { + if err := writeDataAndModules(opts.Ctx, opts.Store, opts.Txn, opts.TxnCtx, snapshotBundles, opts.legacy, opts.ParserOptions.RegoVersion); err != nil { return err } @@ -626,7 +647,7 @@ func eraseBundles(ctx context.Context, store storage.Store, txn storage.Transact return nil, err } - remaining, err := erasePolicies(ctx, store, txn, parserOpts, roots) + remaining, removed, err := erasePolicies(ctx, store, txn, parserOpts, roots) if err != nil { return nil, err } @@ -649,6 +670,11 @@ func eraseBundles(ctx context.Context, store storage.Store, txn storage.Transact } } + err = eraseModuleRegoVersionsFromStore(ctx, store, txn, removed) + if err != nil { + return nil, err + } + return remaining, nil } @@ -668,44 +694,103 @@ func eraseData(ctx context.Context, store storage.Store, txn storage.Transaction return nil } -func erasePolicies(ctx context.Context, store storage.Store, txn storage.Transaction, parserOpts ast.ParserOptions, roots map[string]struct{}) (map[string]*ast.Module, error) { +type moduleInfo struct { + RegoVersion ast.RegoVersion `json:"rego_version"` +} + +func readModuleInfoFromStore(ctx context.Context, store storage.Store, txn storage.Transaction) (map[string]moduleInfo, error) { + value, err := read(ctx, store, txn, ModulesInfoBasePath) + if suppressNotFound(err) != nil { + return nil, err + } + + if value == nil { + return nil, nil + } + + if m, ok := value.(map[string]any); ok { + versions := make(map[string]moduleInfo, len(m)) + + for k, v := range m { + if m0, ok := v.(map[string]any); ok { + if ver, ok := m0["rego_version"]; ok { + if vs, ok := ver.(json.Number); ok { + i, err := vs.Int64() + if err != nil { + return nil, errors.New("corrupt rego version") + } + versions[k] = moduleInfo{RegoVersion: ast.RegoVersionFromInt(int(i))} + } + } + } + } + return versions, nil + } + + return nil, errors.New("corrupt rego version") +} + +func erasePolicies(ctx context.Context, store storage.Store, txn storage.Transaction, parserOpts ast.ParserOptions, roots map[string]struct{}) (map[string]*ast.Module, []string, error) { ids, err := store.ListPolicies(ctx, txn) if err != nil { - return nil, err + return nil, nil, err + } + + modulesInfo, err := readModuleInfoFromStore(ctx, store, txn) + if err != nil { + return nil, nil, fmt.Errorf("failed to read module info from store: %w", err) + } + + getRegoVersion := func(modId string) (ast.RegoVersion, bool) { + info, ok := modulesInfo[modId] + if !ok { + return ast.RegoUndefined, false + } + return info.RegoVersion, true } remaining := map[string]*ast.Module{} + var removed []string for _, id := range ids { bs, err := store.GetPolicy(ctx, txn, id) if err != nil { - return nil, err + return nil, nil, err } - module, err := ast.ParseModuleWithOpts(id, string(bs), parserOpts) + + parserOptsCpy := parserOpts + if regoVersion, ok := getRegoVersion(id); ok { + parserOptsCpy.RegoVersion = regoVersion + } + + module, err := ast.ParseModuleWithOpts(id, string(bs), parserOptsCpy) if err != nil { - return nil, err + return nil, nil, err } path, err := module.Package.Path.Ptr() if err != nil { - return nil, err + return nil, nil, err } deleted := false for root := range roots { if RootPathsContain([]string{root}, path) { if err := store.DeletePolicy(ctx, txn, id); err != nil { - return nil, err + return nil, nil, err } deleted = true break } } - if !deleted { + + if deleted { + removed = append(removed, id) + } else { remaining[id] = module } } - return remaining, nil + return remaining, removed, nil } func writeManifestToStore(opts *ActivateOpts, name string, manifest Manifest) error { @@ -732,7 +817,31 @@ func writeEtagToStore(opts *ActivateOpts, name, etag string) error { return nil } -func writeDataAndModules(ctx context.Context, store storage.Store, txn storage.Transaction, txnCtx *storage.Context, bundles map[string]*Bundle, legacy bool) error { +func writeModuleRegoVersionToStore(ctx context.Context, store storage.Store, txn storage.Transaction, b *Bundle, + mf ModuleFile, storagePath string, runtimeRegoVersion ast.RegoVersion) error { + + var regoVersion ast.RegoVersion + if mf.Parsed != nil { + regoVersion = mf.Parsed.RegoVersion() + } + + if regoVersion == ast.RegoUndefined { + var err error + regoVersion, err = b.RegoVersionForFile(mf.Path, runtimeRegoVersion) + if err != nil { + return fmt.Errorf("failed to get rego version for module '%s' in bundle: %w", mf.Path, err) + } + } + + if regoVersion != ast.RegoUndefined && regoVersion != runtimeRegoVersion { + if err := write(ctx, store, txn, moduleRegoVersionPath(storagePath), regoVersion.Int()); err != nil { + return fmt.Errorf("failed to write rego version for module '%s': %w", storagePath, err) + } + } + return nil +} + +func writeDataAndModules(ctx context.Context, store storage.Store, txn storage.Transaction, txnCtx *storage.Context, bundles map[string]*Bundle, legacy bool, runtimeRegoVersion ast.RegoVersion) error { params := storage.WriteParams params.Context = txnCtx @@ -758,6 +867,10 @@ func writeDataAndModules(ctx context.Context, store storage.Store, txn storage.T if err := store.UpsertPolicy(ctx, txn, path, mf.Raw); err != nil { return err } + + if err := writeModuleRegoVersionToStore(ctx, store, txn, b, mf, path, runtimeRegoVersion); err != nil { + return err + } } } else { params.BasePaths = *b.Manifest.Roots @@ -766,6 +879,23 @@ func writeDataAndModules(ctx context.Context, store storage.Store, txn storage.T if err != nil { return fmt.Errorf("store truncate failed for bundle '%s': %v", name, err) } + + for _, f := range b.Raw { + if strings.HasSuffix(f.Path, RegoExt) { + p, err := getFileStoragePath(f.Path) + if err != nil { + return fmt.Errorf("failed get storage path for module '%s' in bundle '%s': %w", f.Path, name, err) + } + + if m := f.module; m != nil { + // 'f.module.Path' contains the module's path as it relates to the bundle root, and can be used for looking up the rego-version. + // 'f.Path' can differ, based on how the bundle reader was initialized. + if err := writeModuleRegoVersionToStore(ctx, store, txn, b, *m, p.String(), runtimeRegoVersion); err != nil { + return err + } + } + } + } } } @@ -890,7 +1020,7 @@ func lookup(path storage.Path, data map[string]interface{}) (interface{}, bool) if len(path) == 0 { return data, true } - for i := 0; i < len(path)-1; i++ { + for i := range len(path) - 1 { value, ok := data[path[i]] if !ok { return nil, false @@ -964,7 +1094,7 @@ func applyPatches(ctx context.Context, store storage.Store, txn storage.Transact // construct patch path path, ok := patch.ParsePatchPathEscaped("/" + strings.Trim(pat.Path, "/")) if !ok { - return fmt.Errorf("error parsing patch path") + return errors.New("error parsing patch path") } var op storage.PatchOp diff --git a/vendor/github.com/open-policy-agent/opa/bundle/verify.go b/vendor/github.com/open-policy-agent/opa/v1/bundle/verify.go similarity index 95% rename from vendor/github.com/open-policy-agent/opa/bundle/verify.go rename to vendor/github.com/open-policy-agent/opa/v1/bundle/verify.go index e85be835be..0645d3aafb 100644 --- a/vendor/github.com/open-policy-agent/opa/bundle/verify.go +++ b/vendor/github.com/open-policy-agent/opa/v1/bundle/verify.go @@ -10,12 +10,13 @@ import ( "encoding/base64" "encoding/hex" "encoding/json" + "errors" "fmt" "github.com/open-policy-agent/opa/internal/jwx/jwa" "github.com/open-policy-agent/opa/internal/jwx/jws" "github.com/open-policy-agent/opa/internal/jwx/jws/verify" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/util" ) const defaultVerifierID = "_default" @@ -60,11 +61,11 @@ func (*DefaultVerifier) VerifyBundleSignature(sc SignaturesConfig, bvc *Verifica files := make(map[string]FileInfo) if len(sc.Signatures) == 0 { - return files, fmt.Errorf(".signatures.json: missing JWT (expected exactly one)") + return files, errors.New(".signatures.json: missing JWT (expected exactly one)") } if len(sc.Signatures) > 1 { - return files, fmt.Errorf(".signatures.json: multiple JWTs not supported (expected exactly one)") + return files, errors.New(".signatures.json: multiple JWTs not supported (expected exactly one)") } for _, token := range sc.Signatures { @@ -120,7 +121,7 @@ func verifyJWTSignature(token string, bvc *VerificationConfig) (*DecodedSignatur } if keyID == "" { - return nil, fmt.Errorf("verification key ID is empty") + return nil, errors.New("verification key ID is empty") } // now that we have the keyID, fetch the actual key @@ -148,7 +149,7 @@ func verifyJWTSignature(token string, bvc *VerificationConfig) (*DecodedSignatur } if ds.Scope != scope { - return nil, fmt.Errorf("scope mismatch") + return nil, errors.New("scope mismatch") } return &ds, nil } diff --git a/vendor/github.com/open-policy-agent/opa/v1/capabilities/capabilities.go b/vendor/github.com/open-policy-agent/opa/v1/capabilities/capabilities.go new file mode 100644 index 0000000000..5b0bb1ea52 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/capabilities/capabilities.go @@ -0,0 +1,18 @@ +// 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. + +//go:build go1.16 +// +build go1.16 + +package capabilities + +import ( + v0 "github.com/open-policy-agent/opa/capabilities" +) + +// FS contains the embedded capabilities/ directory of the built version, +// which has all the capabilities of previous versions: +// "v0.18.0.json" contains the capabilities JSON of version v0.18.0, etc + +var FS = v0.FS diff --git a/vendor/github.com/open-policy-agent/opa/config/config.go b/vendor/github.com/open-policy-agent/opa/v1/config/config.go similarity index 96% rename from vendor/github.com/open-policy-agent/opa/config/config.go rename to vendor/github.com/open-policy-agent/opa/v1/config/config.go index 87ab109113..490f90b905 100644 --- a/vendor/github.com/open-policy-agent/opa/config/config.go +++ b/vendor/github.com/open-policy-agent/opa/v1/config/config.go @@ -7,6 +7,7 @@ package config import ( "encoding/json" + "errors" "fmt" "os" "path/filepath" @@ -14,10 +15,10 @@ import ( "sort" "strings" - "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/internal/ref" - "github.com/open-policy-agent/opa/util" - "github.com/open-policy-agent/opa/version" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/util" + "github.com/open-policy-agent/opa/v1/version" ) // Config represents the configuration file that OPA can be started with. @@ -98,7 +99,7 @@ func (c Config) PluginNames() (result []string) { // PluginsEnabled returns true if one or more plugin features are enabled. // -// Deprecated. Use PluginNames instead. +// Deprecated: Use PluginNames instead. func (c Config) PluginsEnabled() bool { return c.Bundle != nil || c.Bundles != nil || c.DecisionLogs != nil || c.Status != nil || len(c.Plugins) > 0 } @@ -243,7 +244,7 @@ func removeCryptoKeys(x interface{}) error { func removeKey(x interface{}, keys ...string) error { val, ok := x.(map[string]interface{}) if !ok { - return fmt.Errorf("type assertion error") + return errors.New("type assertion error") } for _, key := range keys { diff --git a/vendor/github.com/open-policy-agent/opa/format/format.go b/vendor/github.com/open-policy-agent/opa/v1/format/format.go similarity index 56% rename from vendor/github.com/open-policy-agent/opa/format/format.go rename to vendor/github.com/open-policy-agent/opa/v1/format/format.go index 43e5594669..2b0f2af15a 100644 --- a/vendor/github.com/open-policy-agent/opa/format/format.go +++ b/vendor/github.com/open-policy-agent/opa/v1/format/format.go @@ -7,15 +7,17 @@ package format import ( "bytes" + "errors" "fmt" "regexp" + "slices" "sort" "strings" "unicode" - "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/internal/future" - "github.com/open-policy-agent/opa/types" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/types" ) // Opts lets you control the code formatting via `AstWithOpts()`. @@ -31,6 +33,17 @@ type Opts struct { // ParserOptions is the parser options used when parsing the module to be formatted. ParserOptions *ast.ParserOptions + + // DropV0Imports instructs the formatter to drop all v0 imports from the module; i.e. 'rego.v1' and 'future.keywords' imports. + // Imports are only removed if [Opts.RegoVersion] makes them redundant. + DropV0Imports bool +} + +func (o Opts) effectiveRegoVersion() ast.RegoVersion { + if o.RegoVersion == ast.RegoUndefined { + return ast.DefaultRegoVersion + } + return o.RegoVersion } // defaultLocationFile is the file name used in `Ast()` for terms @@ -46,15 +59,19 @@ func Source(filename string, src []byte) ([]byte, error) { } func SourceWithOpts(filename string, src []byte, opts Opts) ([]byte, error) { + regoVersion := opts.effectiveRegoVersion() + var parserOpts ast.ParserOptions if opts.ParserOptions != nil { parserOpts = *opts.ParserOptions - } else { - if opts.RegoVersion == ast.RegoV1 { - // If the rego version is V1, we need to parse it as such, to allow for future keywords not being imported. - // Otherwise, we'll default to the default rego-version. - parserOpts.RegoVersion = ast.RegoV1 - } + } else if regoVersion == ast.RegoV1 { + // If the rego version is V1, we need to parse it as such, to allow for future keywords not being imported. + // Otherwise, we'll default to the default rego-version. + parserOpts.RegoVersion = ast.RegoV1 + } + + if parserOpts.RegoVersion == ast.RegoUndefined { + parserOpts.RegoVersion = ast.DefaultRegoVersion } module, err := ast.ParseModuleWithOpts(filename, string(src), parserOpts) @@ -62,15 +79,15 @@ func SourceWithOpts(filename string, src []byte, opts Opts) ([]byte, error) { return nil, err } - if opts.RegoVersion == ast.RegoV0CompatV1 || opts.RegoVersion == ast.RegoV1 { + if regoVersion == ast.RegoV0CompatV1 || regoVersion == ast.RegoV1 { checkOpts := ast.NewRegoCheckOptions() // The module is parsed as v0, so we need to disable checks that will be automatically amended by the AstWithOpts call anyways. checkOpts.RequireIfKeyword = false checkOpts.RequireContainsKeyword = false checkOpts.RequireRuleBodyOrValue = false - errors := ast.CheckRegoV1WithOptions(module, checkOpts) - if len(errors) > 0 { - return nil, errors + errs := ast.CheckRegoV1WithOptions(module, checkOpts) + if len(errs) > 0 { + return nil, errs } } @@ -83,7 +100,7 @@ func SourceWithOpts(filename string, src []byte, opts Opts) ([]byte, error) { } // MustAst is a helper function to format a Rego AST element. If any errors -// occurs this function will panic. This is mostly used for test +// occur this function will panic. This is mostly used for test func MustAst(x interface{}) []byte { bs, err := Ast(x) if err != nil { @@ -93,7 +110,7 @@ func MustAst(x interface{}) []byte { } // MustAstWithOpts is a helper function to format a Rego AST element. If any errors -// occurs this function will panic. This is mostly used for test +// occur this function will panic. This is mostly used for test func MustAstWithOpts(x interface{}, opts Opts) []byte { bs, err := AstWithOpts(x, opts) if err != nil { @@ -127,6 +144,7 @@ type fmtOpts struct { refHeads bool regoV1 bool + regoV1Imported bool futureKeywords []string } @@ -154,12 +172,16 @@ func AstWithOpts(x interface{}, opts Opts) ([]byte, error) { o := fmtOpts{} - if opts.RegoVersion == ast.RegoV0CompatV1 || opts.RegoVersion == ast.RegoV1 { + regoVersion := opts.effectiveRegoVersion() + if regoVersion == ast.RegoV0CompatV1 || regoVersion == ast.RegoV1 { o.regoV1 = true o.ifs = true o.contains = true } + memberRef := ast.Member.Ref() + memberWithKeyRef := ast.MemberWithKey.Ref() + // Preprocess the AST. Set any required defaults and calculate // values required for printing the formatted output. ast.WalkNodes(x, func(x ast.Node) bool { @@ -173,7 +195,7 @@ func AstWithOpts(x interface{}, opts Opts) ([]byte, error) { case *ast.Expr: switch { - case n.IsCall() && ast.Member.Ref().Equal(n.Operator()) || ast.MemberWithKey.Ref().Equal(n.Operator()): + case n.IsCall() && memberRef.Equal(n.Operator()) || memberWithKeyRef.Equal(n.Operator()): extraFutureKeywordImports["in"] = struct{}{} case n.IsEvery(): extraFutureKeywordImports["every"] = struct{}{} @@ -186,6 +208,7 @@ func AstWithOpts(x interface{}, opts Opts) ([]byte, error) { switch { case isRegoV1Compatible(n): + o.regoV1Imported = true o.contains = true o.ifs = true case future.IsAllFutureKeywords(n): @@ -220,43 +243,83 @@ func AstWithOpts(x interface{}, opts Opts) ([]byte, error) { switch x := x.(type) { case *ast.Module: - if opts.RegoVersion == ast.RegoV1 { + if regoVersion == ast.RegoV1 && opts.DropV0Imports { x.Imports = filterRegoV1Import(x.Imports) - } else if opts.RegoVersion == ast.RegoV0CompatV1 { + } else if regoVersion == ast.RegoV0CompatV1 { x.Imports = ensureRegoV1Import(x.Imports) } - if opts.RegoVersion == ast.RegoV0CompatV1 || opts.RegoVersion == ast.RegoV1 || moduleIsRegoV1Compatible(x) { - x.Imports = future.FilterFutureImports(x.Imports) + regoV1Imported := moduleIsRegoV1Compatible(x) + if regoVersion == ast.RegoV0CompatV1 || regoVersion == ast.RegoV1 || regoV1Imported { + if !opts.DropV0Imports && !regoV1Imported { + for _, kw := range o.futureKeywords { + x.Imports = ensureFutureKeywordImport(x.Imports, kw) + } + } else { + x.Imports = future.FilterFutureImports(x.Imports) + } } else { for kw := range extraFutureKeywordImports { x.Imports = ensureFutureKeywordImport(x.Imports, kw) } } - w.writeModule(x) + err := w.writeModule(x) + if err != nil { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, &ast.Location{}, err.Error())) + } case *ast.Package: - w.writePackage(x, nil) + _, err := w.writePackage(x, nil) + if err != nil { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, &ast.Location{}, err.Error())) + } case *ast.Import: - w.writeImports([]*ast.Import{x}, nil) + _, err := w.writeImports([]*ast.Import{x}, nil) + if err != nil { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, &ast.Location{}, err.Error())) + } case *ast.Rule: - w.writeRule(x, false /* isElse */, nil) + _, err := w.writeRule(x, false /* isElse */, nil) + if err != nil { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, &ast.Location{}, err.Error())) + } case *ast.Head: - w.writeHead(x, + _, err := w.writeHead(x, false, // isDefault false, // isExpandedConst nil) + if err != nil { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, &ast.Location{}, err.Error())) + } case ast.Body: - w.writeBody(x, nil) + _, err := w.writeBody(x, nil) + if err != nil { + return nil, err + } case *ast.Expr: - w.writeExpr(x, nil) + _, err := w.writeExpr(x, nil) + if err != nil { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, &ast.Location{}, err.Error())) + } case *ast.With: - w.writeWith(x, nil, false) + _, err := w.writeWith(x, nil, false) + if err != nil { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, &ast.Location{}, err.Error())) + } case *ast.Term: - w.writeTerm(x, nil) + _, err := w.writeTerm(x, nil) + if err != nil { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, &ast.Location{}, err.Error())) + } case ast.Value: - w.writeTerm(&ast.Term{Value: x, Location: &ast.Location{}}, nil) + _, err := w.writeTerm(&ast.Term{Value: x, Location: &ast.Location{}}, nil) + if err != nil { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, &ast.Location{}, err.Error())) + } case *ast.Comment: - w.writeComments([]*ast.Comment{x}) + err := w.writeComments([]*ast.Comment{x}) + if err != nil { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, &ast.Location{}, err.Error())) + } default: return nil, fmt.Errorf("not an ast element: %v", x) } @@ -309,16 +372,17 @@ func defaultLocation(x ast.Node) *ast.Location { type writer struct { buf bytes.Buffer - indent string - level int - inline bool - beforeEnd *ast.Comment - delay bool - errs ast.Errors - fmtOpts fmtOpts + indent string + level int + inline bool + beforeEnd *ast.Comment + delay bool + errs ast.Errors + fmtOpts fmtOpts + writeCommentOnFinalLine bool } -func (w *writer) writeModule(module *ast.Module) { +func (w *writer) writeModule(module *ast.Module) error { var pkg *ast.Package var others []interface{} var comments []*ast.Comment @@ -340,23 +404,41 @@ func (w *writer) writeModule(module *ast.Module) { visitor.Walk(module) sort.Slice(comments, func(i, j int) bool { - return locLess(comments[i], comments[j]) + l, err := locLess(comments[i], comments[j]) + if err != nil { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, &ast.Location{}, err.Error())) + } + return l }) sort.Slice(others, func(i, j int) bool { - return locLess(others[i], others[j]) + l, err := locLess(others[i], others[j]) + if err != nil { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, &ast.Location{}, err.Error())) + } + return l }) comments = trimTrailingWhitespaceInComments(comments) - comments = w.writePackage(pkg, comments) + var err error + comments, err = w.writePackage(pkg, comments) + if err != nil { + return err + } var imports []*ast.Import var rules []*ast.Rule for len(others) > 0 { imports, others = gatherImports(others) - comments = w.writeImports(imports, comments) + comments, err = w.writeImports(imports, comments) + if err != nil { + return err + } rules, others = gatherRules(others) - comments = w.writeRules(rules, comments) + comments, err = w.writeRules(rules, comments) + if err != nil { + return err + } } for i, c := range comments { @@ -365,6 +447,8 @@ func (w *writer) writeModule(module *ast.Module) { w.write("\n") } } + + return nil } func trimTrailingWhitespaceInComments(comments []*ast.Comment) []*ast.Comment { @@ -375,45 +459,97 @@ func trimTrailingWhitespaceInComments(comments []*ast.Comment) []*ast.Comment { return comments } -func (w *writer) writePackage(pkg *ast.Package, comments []*ast.Comment) []*ast.Comment { - comments = w.insertComments(comments, pkg.Location) +func (w *writer) writePackage(pkg *ast.Package, comments []*ast.Comment) ([]*ast.Comment, error) { + var err error + comments, err = w.insertComments(comments, pkg.Location) + if err != nil { + return nil, err + } w.startLine() // Omit head as all packages have the DefaultRootDocument prepended at parse time. path := make(ast.Ref, len(pkg.Path)-1) + if len(path) == 0 { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, pkg.Location, "invalid package path: %s", pkg.Path)) + return comments, nil + } + path[0] = ast.VarTerm(string(pkg.Path[1].Value.(ast.String))) copy(path[1:], pkg.Path[2:]) w.write("package ") - w.writeRef(path) + _, err = w.writeRef(path, nil) + if err != nil { + return nil, err + } w.blankLine() - return comments + return comments, nil } -func (w *writer) writeComments(comments []*ast.Comment) { - for i := 0; i < len(comments); i++ { - if i > 0 && locCmp(comments[i], comments[i-1]) > 1 { - w.blankLine() +func (w *writer) writeComments(comments []*ast.Comment) error { + for i := range comments { + if i > 0 { + l, err := locCmp(comments[i], comments[i-1]) + if err != nil { + return err + } + if l > 1 { + w.blankLine() + } } + w.writeLine(comments[i].String()) } + + return nil } -func (w *writer) writeRules(rules []*ast.Rule, comments []*ast.Comment) []*ast.Comment { - for _, rule := range rules { - comments = w.insertComments(comments, rule.Location) - comments = w.writeRule(rule, false, comments) +func (w *writer) writeRules(rules []*ast.Rule, comments []*ast.Comment) ([]*ast.Comment, error) { + for i, rule := range rules { + var err error + comments, err = w.insertComments(comments, rule.Location) + if err != nil && !errors.As(err, &unexpectedCommentError{}) { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, &ast.Location{}, err.Error())) + } + + comments, err = w.writeRule(rule, false, comments) + if err != nil && !errors.As(err, &unexpectedCommentError{}) { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, &ast.Location{}, err.Error())) + } + + if i < len(rules)-1 && w.groupableOneLiner(rule) { + next := rules[i+1] + if w.groupableOneLiner(next) && next.Location.Row == rule.Location.Row+1 { + // Current rule and the next are both groupable one-liners, and + // adjacent in the original policy (i.e. no extra newlines between them). + continue + } + } w.blankLine() } - return comments + return comments, nil +} + +var expandedConst = ast.NewBody(ast.NewExpr(ast.InternedBooleanTerm(true))) + +func (w *writer) groupableOneLiner(rule *ast.Rule) bool { + // Location required to determine if two rules are adjacent in the policy. + // If not, we respect line breaks between rules. + if len(rule.Body) > 1 || rule.Default || rule.Location == nil { + return false + } + + partialSetException := w.fmtOpts.contains || rule.Head.Value != nil + + return (w.fmtOpts.regoV1 || w.fmtOpts.ifs) && partialSetException } -func (w *writer) writeRule(rule *ast.Rule, isElse bool, comments []*ast.Comment) []*ast.Comment { +func (w *writer) writeRule(rule *ast.Rule, isElse bool, comments []*ast.Comment) ([]*ast.Comment, error) { if rule == nil { - return comments + return comments, nil } if !isElse { @@ -428,37 +564,67 @@ func (w *writer) writeRule(rule *ast.Rule, isElse bool, comments []*ast.Comment) // `foo = {"a": "b"} { true }` in the AST. We want to preserve that notation // in the formatted code instead of expanding the bodies into rules, so we // pretend that the rule has no body in this case. - isExpandedConst := rule.Body.Equal(ast.NewBody(ast.NewExpr(ast.BooleanTerm(true)))) && rule.Else == nil - - comments = w.writeHead(rule.Head, rule.Default, isExpandedConst, comments) + isExpandedConst := rule.Body.Equal(expandedConst) && rule.Else == nil + w.writeCommentOnFinalLine = isExpandedConst - // this excludes partial sets UNLESS `contains` is used - partialSetException := w.fmtOpts.contains || rule.Head.Value != nil + var err error + var unexpectedComment bool + comments, err = w.writeHead(rule.Head, rule.Default, isExpandedConst, comments) + if err != nil { + if errors.As(err, &unexpectedCommentError{}) { + unexpectedComment = true + } else { + return nil, err + } + } if len(rule.Body) == 0 || isExpandedConst { w.endLine() - return comments + return comments, nil } + w.writeCommentOnFinalLine = true + + // this excludes partial sets UNLESS `contains` is used + partialSetException := w.fmtOpts.contains || rule.Head.Value != nil + if (w.fmtOpts.regoV1 || w.fmtOpts.ifs) && partialSetException { w.write(" if") if len(rule.Body) == 1 { if rule.Body[0].Location.Row == rule.Head.Location.Row { w.write(" ") - comments = w.writeExpr(rule.Body[0], comments) + var err error + comments, err = w.writeExpr(rule.Body[0], comments) + if err != nil { + return nil, err + } w.endLine() if rule.Else != nil { - comments = w.writeElse(rule, comments) + comments, err = w.writeElse(rule, comments) + if err != nil { + return nil, err + } } - return comments + return comments, nil } } } - w.write(" {") - w.endLine() + if unexpectedComment && len(comments) > 0 { + w.write(" { ") + } else { + w.write(" {") + w.endLine() + } + w.up() - comments = w.writeBody(rule.Body, comments) + comments, err = w.writeBody(rule.Body, comments) + if err != nil { + // the unexpected comment error is passed up to be handled by writeHead + if !errors.As(err, &unexpectedCommentError{}) { + return nil, err + } + } var closeLoc *ast.Location @@ -470,18 +636,28 @@ func (w *writer) writeRule(rule *ast.Rule, isElse bool, comments []*ast.Comment) closeLoc = closingLoc(0, 0, '{', '}', rule.Location) } - comments = w.insertComments(comments, closeLoc) + comments, err = w.insertComments(comments, closeLoc) + if err != nil { + return nil, err + } - w.down() + if err := w.down(); err != nil { + return nil, err + } w.startLine() w.write("}") if rule.Else != nil { - comments = w.writeElse(rule, comments) + comments, err = w.writeElse(rule, comments) + if err != nil { + return nil, err + } } - return comments + return comments, nil } -func (w *writer) writeElse(rule *ast.Rule, comments []*ast.Comment) []*ast.Comment { +var elseVar ast.Value = ast.Var("else") + +func (w *writer) writeElse(rule *ast.Rule, comments []*ast.Comment) ([]*ast.Comment, error) { // If there was nothing else on the line before the "else" starts // then preserve this style of else block, otherwise it will be // started as an "inline" else eg: @@ -526,9 +702,17 @@ func (w *writer) writeElse(rule *ast.Rule, comments []*ast.Comment) []*ast.Comme } rule.Else.Head.Name = "else" // NOTE(sr): whaaat - rule.Else.Head.Reference = ast.Ref{ast.VarTerm("else")} + + elseHeadReference := ast.NewTerm(elseVar) // construct a reference for the term + elseHeadReference.Location = rule.Else.Head.Location // and set the location to match the rule location + + rule.Else.Head.Reference = ast.Ref{elseHeadReference} rule.Else.Head.Args = nil - comments = w.insertComments(comments, rule.Else.Head.Location) + var err error + comments, err = w.insertComments(comments, rule.Else.Head.Location) + if err != nil { + return nil, err + } if hasCommentAbove && !wasInline { // The comments would have ended the line, be sure to start one again @@ -546,14 +730,27 @@ func (w *writer) writeElse(rule *ast.Rule, comments []*ast.Comment) []*ast.Comme return w.writeRule(rule.Else, true, comments) } -func (w *writer) writeHead(head *ast.Head, isDefault, isExpandedConst bool, comments []*ast.Comment) []*ast.Comment { +func (w *writer) writeHead(head *ast.Head, isDefault bool, isExpandedConst bool, comments []*ast.Comment) ([]*ast.Comment, error) { ref := head.Ref() if head.Key != nil && head.Value == nil && !head.HasDynamicRef() { ref = ref.GroundPrefix() } if w.fmtOpts.refHeads || len(ref) == 1 { - w.writeRef(ref) + var err error + comments, err = w.writeRef(ref, comments) + if err != nil { + return nil, err + } } else { + // if there are comments within the object in the rule head, don't format it + if len(comments) > 0 && ref[1].Location.Row == comments[0].Location.Row { + comments, err := w.writeUnformatted(head.Location, comments) + if err != nil { + return nil, err + } + return comments, nil + } + w.write(ref[0].String()) w.write("[") w.write(ref[1].String()) @@ -566,22 +763,34 @@ func (w *writer) writeHead(head *ast.Head, isDefault, isExpandedConst bool, comm for _, arg := range head.Args { args = append(args, arg) } - comments = w.writeIterable(args, head.Location, closingLoc(0, 0, '(', ')', head.Location), comments, w.listWriter()) + var err error + comments, err = w.writeIterable(args, head.Location, closingLoc(0, 0, '(', ')', head.Location), comments, w.listWriter()) w.write(")") + if err != nil { + return comments, err + } } if head.Key != nil { if w.fmtOpts.contains && head.Value == nil { w.write(" contains ") - comments = w.writeTerm(head.Key, comments) + var err error + comments, err = w.writeTerm(head.Key, comments) + if err != nil { + return comments, err + } } else if head.Value == nil { // no `if` for p[x] notation w.write("[") - comments = w.writeTerm(head.Key, comments) + var err error + comments, err = w.writeTerm(head.Key, comments) + if err != nil { + return comments, err + } w.write("]") } } if head.Value != nil && - (head.Key != nil || ast.Compare(head.Value, ast.BooleanTerm(true)) != 0 || isExpandedConst || isDefault) { + (head.Key != nil || !ast.InternedBooleanTerm(true).Equal(head.Value) || isExpandedConst || isDefault) { // in rego v1, explicitly print value for ref-head constants that aren't partial set assignments, e.g.: // * a -> parser error, won't reach here @@ -592,12 +801,12 @@ func (w *writer) writeHead(head *ast.Head, isDefault, isExpandedConst bool, comm if head.Location == head.Value.Location && head.Name != "else" && - ast.Compare(head.Value, ast.BooleanTerm(true)) == 0 && + ast.InternedBooleanTerm(true).Equal(head.Value) && !isRegoV1RefConst { // If the value location is the same as the location of the head, // we know that the value is generated, i.e. f(1) // Don't print the value (` = true`) as it is implied. - return comments + return comments, nil } if head.Assign || w.fmtOpts.regoV1 { @@ -606,24 +815,35 @@ func (w *writer) writeHead(head *ast.Head, isDefault, isExpandedConst bool, comm } else { w.write(" = ") } - comments = w.writeTerm(head.Value, comments) + var err error + comments, err = w.writeTerm(head.Value, comments) + if err != nil { + return comments, err + } } - return comments + return comments, nil } -func (w *writer) insertComments(comments []*ast.Comment, loc *ast.Location) []*ast.Comment { +func (w *writer) insertComments(comments []*ast.Comment, loc *ast.Location) ([]*ast.Comment, error) { before, at, comments := partitionComments(comments, loc) - w.writeComments(before) + + err := w.writeComments(before) + if err != nil { + return nil, err + } if len(before) > 0 && loc.Row-before[len(before)-1].Location.Row > 1 { w.blankLine() } - w.beforeLineEnd(at) - return comments + return comments, w.beforeLineEnd(at) } -func (w *writer) writeBody(body ast.Body, comments []*ast.Comment) []*ast.Comment { - comments = w.insertComments(comments, body.Loc()) +func (w *writer) writeBody(body ast.Body, comments []*ast.Comment) ([]*ast.Comment, error) { + var err error + comments, err = w.insertComments(comments, body.Loc()) + if err != nil { + return comments, err + } for i, expr := range body { // Insert a blank line in before the expression if it was not right // after the previous expression. @@ -640,14 +860,21 @@ func (w *writer) writeBody(body ast.Body, comments []*ast.Comment) []*ast.Commen } w.startLine() - comments = w.writeExpr(expr, comments) + comments, err = w.writeExpr(expr, comments) + if err != nil && !errors.As(err, &unexpectedCommentError{}) { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, &ast.Location{}, err.Error())) + } w.endLine() } - return comments + return comments, nil } -func (w *writer) writeExpr(expr *ast.Expr, comments []*ast.Comment) []*ast.Comment { - comments = w.insertComments(comments, expr.Location) +func (w *writer) writeExpr(expr *ast.Expr, comments []*ast.Comment) ([]*ast.Comment, error) { + var err error + comments, err = w.insertComments(comments, expr.Location) + if err != nil { + return comments, err + } if !w.inline { w.startLine() } @@ -658,37 +885,65 @@ func (w *writer) writeExpr(expr *ast.Expr, comments []*ast.Comment) []*ast.Comme switch t := expr.Terms.(type) { case *ast.SomeDecl: - comments = w.writeSomeDecl(t, comments) + comments, err = w.writeSomeDecl(t, comments) + if err != nil { + return nil, err + } case *ast.Every: - comments = w.writeEvery(t, comments) + comments, err = w.writeEvery(t, comments) + if err != nil { + return nil, err + } case []*ast.Term: - comments = w.writeFunctionCall(expr, comments) + comments, err = w.writeFunctionCall(expr, comments) + if err != nil { + return comments, err + } case *ast.Term: - comments = w.writeTerm(t, comments) + comments, err = w.writeTerm(t, comments) + if err != nil { + return comments, err + } } - var indented bool + var indented, down bool for i, with := range expr.With { if i == 0 || with.Location.Row == expr.With[i-1].Location.Row { // we're on the same line - comments = w.writeWith(with, comments, false) + comments, err = w.writeWith(with, comments, false) + if err != nil { + return nil, err + } } else { // we're on a new line if !indented { indented = true w.up() - defer w.down() + down = true } w.endLine() w.startLine() - comments = w.writeWith(with, comments, true) + comments, err = w.writeWith(with, comments, true) + if err != nil { + return nil, err + } } } - return comments + if down { + if err := w.down(); err != nil { + return nil, err + } + } + + return comments, nil } -func (w *writer) writeSomeDecl(decl *ast.SomeDecl, comments []*ast.Comment) []*ast.Comment { - comments = w.insertComments(comments, decl.Location) +func (w *writer) writeSomeDecl(decl *ast.SomeDecl, comments []*ast.Comment) ([]*ast.Comment, error) { + var err error + comments, err = w.insertComments(comments, decl.Location) + if err != nil { + return nil, err + } w.write("some ") row := decl.Location.Row @@ -705,41 +960,66 @@ func (w *writer) writeSomeDecl(decl *ast.SomeDecl, comments []*ast.Comment) []*a w.write(" ") } - comments = w.writeTerm(term, comments) + comments, err = w.writeTerm(term, comments) + if err != nil { + return nil, err + } if i < len(decl.Symbols)-1 { w.write(",") } case ast.Call: - comments = w.writeInOperator(false, val[1:], comments, decl.Location, ast.BuiltinMap[val[0].String()].Decl) + comments, err = w.writeInOperator(false, val[1:], comments, decl.Location, ast.BuiltinMap[val[0].String()].Decl) + if err != nil { + return nil, err + } } } - return comments + return comments, nil } -func (w *writer) writeEvery(every *ast.Every, comments []*ast.Comment) []*ast.Comment { - comments = w.insertComments(comments, every.Location) +func (w *writer) writeEvery(every *ast.Every, comments []*ast.Comment) ([]*ast.Comment, error) { + var err error + comments, err = w.insertComments(comments, every.Location) + if err != nil { + return nil, err + } w.write("every ") if every.Key != nil { - comments = w.writeTerm(every.Key, comments) + comments, err = w.writeTerm(every.Key, comments) + if err != nil { + return nil, err + } w.write(", ") } - comments = w.writeTerm(every.Value, comments) + comments, err = w.writeTerm(every.Value, comments) + if err != nil { + return nil, err + } w.write(" in ") - comments = w.writeTerm(every.Domain, comments) + comments, err = w.writeTerm(every.Domain, comments) + if err != nil { + return nil, err + } w.write(" {") - comments = w.writeComprehensionBody('{', '}', every.Body, every.Loc(), every.Loc(), comments) + comments, err = w.writeComprehensionBody('{', '}', every.Body, every.Loc(), every.Loc(), comments) + if err != nil { + // the unexpected comment error is passed up to be handled by writeHead + if !errors.As(err, &unexpectedCommentError{}) { + return nil, err + } + } if len(every.Body) == 1 && every.Body[0].Location.Row == every.Location.Row { w.write(" ") } w.write("}") - return comments + return comments, nil } -func (w *writer) writeFunctionCall(expr *ast.Expr, comments []*ast.Comment) []*ast.Comment { +func (w *writer) writeFunctionCall(expr *ast.Expr, comments []*ast.Comment) ([]*ast.Comment, error) { terms := expr.Terms.([]*ast.Term) operator := terms[0].Value.String() @@ -754,22 +1034,34 @@ func (w *writer) writeFunctionCall(expr *ast.Expr, comments []*ast.Comment) []*a return w.writeFunctionCallPlain(terms, comments) } - numDeclArgs := len(bi.Decl.Args()) + numDeclArgs := bi.Decl.Arity() numCallArgs := len(terms) - 1 + var err error switch numCallArgs { case numDeclArgs: // Print infix where result is unassigned (e.g., x != y) - comments = w.writeTerm(terms[1], comments) + comments, err = w.writeTerm(terms[1], comments) + if err != nil { + return nil, err + } w.write(" " + bi.Infix + " ") return w.writeTerm(terms[2], comments) - case numDeclArgs + 1: // Print infix where result is assigned (e.g., z = x + y) - comments = w.writeTerm(terms[3], comments) + comments, err = w.writeTerm(terms[3], comments) + if err != nil { + return nil, err + } w.write(" " + ast.Equality.Infix + " ") - comments = w.writeTerm(terms[1], comments) + comments, err = w.writeTerm(terms[1], comments) + if err != nil { + return nil, err + } w.write(" " + bi.Infix + " ") - comments = w.writeTerm(terms[2], comments) - return comments + comments, err = w.writeTerm(terms[2], comments) + if err != nil { + return nil, err + } + return comments, nil } // NOTE(Trolloldem): in this point we are operating with a built-in function with the // wrong arity even when the assignment notation is used @@ -777,7 +1069,7 @@ func (w *writer) writeFunctionCall(expr *ast.Expr, comments []*ast.Comment) []*a return w.writeFunctionCallPlain(terms, comments) } -func (w *writer) writeFunctionCallPlain(terms []*ast.Term, comments []*ast.Comment) []*ast.Comment { +func (w *writer) writeFunctionCallPlain(terms []*ast.Term, comments []*ast.Comment) ([]*ast.Comment, error) { w.write(terms[0].String() + "(") defer w.write(")") args := make([]interface{}, len(terms)-1) @@ -785,57 +1077,167 @@ func (w *writer) writeFunctionCallPlain(terms []*ast.Term, comments []*ast.Comme args[i] = t } loc := terms[0].Location - return w.writeIterable(args, loc, closingLoc(0, 0, '(', ')', loc), comments, w.listWriter()) + var err error + comments, err = w.writeIterable(args, loc, closingLoc(0, 0, '(', ')', loc), comments, w.listWriter()) + if err != nil { + return nil, err + } + return comments, nil } -func (w *writer) writeWith(with *ast.With, comments []*ast.Comment, indented bool) []*ast.Comment { - comments = w.insertComments(comments, with.Location) +func (w *writer) writeWith(with *ast.With, comments []*ast.Comment, indented bool) ([]*ast.Comment, error) { + var err error + comments, err = w.insertComments(comments, with.Location) + if err != nil { + return nil, err + } if !indented { w.write(" ") } w.write("with ") - comments = w.writeTerm(with.Target, comments) + comments, err = w.writeTerm(with.Target, comments) + if err != nil { + return nil, err + } w.write(" as ") - return w.writeTerm(with.Value, comments) + comments, err = w.writeTerm(with.Value, comments) + if err != nil { + return nil, err + } + return comments, nil +} + +func (w *writer) writeTerm(term *ast.Term, comments []*ast.Comment) ([]*ast.Comment, error) { + currentComments := make([]*ast.Comment, len(comments)) + copy(currentComments, comments) + + currentLen := w.buf.Len() + + comments, err := w.writeTermParens(false, term, comments) + if err != nil { + if errors.As(err, &unexpectedCommentError{}) { + w.buf.Truncate(currentLen) + + comments, uErr := w.writeUnformatted(term.Location, currentComments) + if uErr != nil { + return nil, uErr + } + return comments, err + } + return nil, err + } + + return comments, nil } -func (w *writer) writeTerm(term *ast.Term, comments []*ast.Comment) []*ast.Comment { - return w.writeTermParens(false, term, comments) +// writeUnformatted writes the unformatted text instead and updates the comment state +func (w *writer) writeUnformatted(location *ast.Location, currentComments []*ast.Comment) ([]*ast.Comment, error) { + if len(location.Text) == 0 { + return nil, errors.New("original unformatted text is empty") + } + + rawRule := string(location.Text) + rowNum := len(strings.Split(rawRule, "\n")) + + w.write(string(location.Text)) + + comments := make([]*ast.Comment, 0, len(currentComments)) + for _, c := range currentComments { + // if there is a body then wait to write the last comment + if w.writeCommentOnFinalLine && c.Location.Row == location.Row+rowNum-1 { + w.write(" " + string(c.Location.Text)) + continue + } + + // drop comments that occur within the rule raw text + if c.Location.Row < location.Row+rowNum-1 { + continue + } + comments = append(comments, c) + } + return comments, nil } -func (w *writer) writeTermParens(parens bool, term *ast.Term, comments []*ast.Comment) []*ast.Comment { - comments = w.insertComments(comments, term.Location) +func (w *writer) writeTermParens(parens bool, term *ast.Term, comments []*ast.Comment) ([]*ast.Comment, error) { + var err error + comments, err = w.insertComments(comments, term.Location) + if err != nil { + return nil, err + } if !w.inline { w.startLine() } switch x := term.Value.(type) { case ast.Ref: - w.writeRef(x) + comments, err = w.writeRef(x, comments) + if err != nil { + return nil, err + } case ast.Object: - comments = w.writeObject(x, term.Location, comments) + comments, err = w.writeObject(x, term.Location, comments) + if err != nil { + return nil, err + } case *ast.Array: - comments = w.writeArray(x, term.Location, comments) + comments, err = w.writeArray(x, term.Location, comments) + if err != nil { + return nil, err + } case ast.Set: - comments = w.writeSet(x, term.Location, comments) + comments, err = w.writeSet(x, term.Location, comments) + if err != nil { + return nil, err + } case *ast.ArrayComprehension: - comments = w.writeArrayComprehension(x, term.Location, comments) + comments, err = w.writeArrayComprehension(x, term.Location, comments) + if err != nil { + return nil, err + } case *ast.ObjectComprehension: - comments = w.writeObjectComprehension(x, term.Location, comments) + comments, err = w.writeObjectComprehension(x, term.Location, comments) + if err != nil { + return nil, err + } case *ast.SetComprehension: - comments = w.writeSetComprehension(x, term.Location, comments) + comments, err = w.writeSetComprehension(x, term.Location, comments) + if err != nil { + return nil, err + } case ast.String: if term.Location.Text[0] == '`' { // To preserve raw strings, we need to output the original text, - // not what x.String() would give us. w.write(string(term.Location.Text)) } else { - w.write(x.String()) + // x.String() cannot be used by default because it can change the input string "\u0000" to "\x00" + var after, quote string + var found bool + // term.Location.Text could contain the prefix `else :=`, remove it + switch term.Location.Text[len(term.Location.Text)-1] { + case '"': + quote = "\"" + _, after, found = strings.Cut(string(term.Location.Text), quote) + case '`': + quote = "`" + _, after, found = strings.Cut(string(term.Location.Text), quote) + } + + if !found { + // If no quoted string was found, that means it is a key being formatted to a string + // e.g. partial_set.y to partial_set["y"] + w.write(x.String()) + } else { + w.write(quote + after) + } + } case ast.Var: w.write(w.formatVar(x)) case ast.Call: - comments = w.writeCall(parens, x, term.Location, comments) + comments, err = w.writeCall(parens, x, term.Location, comments) + if err != nil { + return nil, err + } case fmt.Stringer: w.write(x.String()) } @@ -843,17 +1245,21 @@ func (w *writer) writeTermParens(parens bool, term *ast.Term, comments []*ast.Co if !w.inline { w.startLine() } - return comments + return comments, nil } -func (w *writer) writeRef(x ast.Ref) { +func (w *writer) writeRef(x ast.Ref, comments []*ast.Comment) ([]*ast.Comment, error) { if len(x) > 0 { parens := false _, ok := x[0].Value.(ast.Call) if ok { parens = x[0].Location.Text[0] == 40 // Starts with "(" } - w.writeTermParens(parens, x[0], nil) + var err error + comments, err = w.writeTermParens(parens, x[0], comments) + if err != nil { + return nil, err + } path := x[1:] for _, t := range path { switch p := t.Value.(type) { @@ -863,11 +1269,21 @@ func (w *writer) writeRef(x ast.Ref) { w.writeBracketed(w.formatVar(p)) default: w.write("[") - w.writeTerm(t, nil) + comments, err = w.writeTerm(t, comments) + if err != nil { + if errors.As(err, &unexpectedCommentError{}) { + // add a new line so that the closing bracket isn't part of the unexpected comment + w.write("\n") + } else { + return nil, err + } + } w.write("]") } } } + + return comments, nil } func (w *writer) writeBracketed(str string) { @@ -885,14 +1301,14 @@ func (w *writer) writeRefStringPath(s ast.String) { } } -func (w *writer) formatVar(v ast.Var) string { +func (*writer) formatVar(v ast.Var) string { if v.IsWildcard() { return ast.Wildcard.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, loc *ast.Location, comments []*ast.Comment) ([]*ast.Comment, error) { bi, ok := ast.BuiltinMap[x[0].String()] if !ok || bi.Infix == "" { return w.writeFunctionCallPlain(x, comments) @@ -912,57 +1328,80 @@ func (w *writer) writeCall(parens bool, x ast.Call, loc *ast.Location, comments // NOTE(Trolloldem): writeCall is only invoked when the function call is a term // of another function. The only valid arity is the one of the // built-in function - if len(bi.Decl.Args()) != len(x)-1 { + if bi.Decl.Arity() != len(x)-1 { w.errs = append(w.errs, ArityFormatMismatchError(x[1:], x[0].String(), loc, bi.Decl)) - return comments + return comments, nil } - comments = w.writeTermParens(true, x[1], comments) + var err error + comments, err = w.writeTermParens(true, x[1], comments) + if err != nil { + return nil, err + } w.write(" " + bi.Infix + " ") - comments = w.writeTermParens(true, x[2], comments) + comments, err = w.writeTermParens(true, x[2], comments) + if err != nil { + return nil, err + } if parens { w.write(")") } - return comments + return comments, nil } -func (w *writer) writeInOperator(parens bool, operands []*ast.Term, comments []*ast.Comment, loc *ast.Location, f *types.Function) []*ast.Comment { +func (w *writer) writeInOperator(parens bool, operands []*ast.Term, comments []*ast.Comment, loc *ast.Location, f *types.Function) ([]*ast.Comment, error) { - if len(operands) != len(f.Args()) { + if len(operands) != f.Arity() { // The number of operands does not math the arity of the `in` operator operator := ast.Member.Name - if len(f.Args()) == 3 { + if f.Arity() == 3 { operator = ast.MemberWithKey.Name } w.errs = append(w.errs, ArityFormatMismatchError(operands, operator, loc, f)) - return comments + return comments, nil } kw := "in" + var err error switch len(operands) { case 2: - comments = w.writeTermParens(true, operands[0], comments) + comments, err = w.writeTermParens(true, operands[0], comments) + if err != nil { + return nil, err + } w.write(" ") w.write(kw) w.write(" ") - comments = w.writeTermParens(true, operands[1], comments) + comments, err = w.writeTermParens(true, operands[1], comments) + if err != nil { + return nil, err + } case 3: if parens { w.write("(") defer w.write(")") } - comments = w.writeTermParens(true, operands[0], comments) + comments, err = w.writeTermParens(true, operands[0], comments) + if err != nil { + return nil, err + } w.write(", ") - comments = w.writeTermParens(true, operands[1], comments) + comments, err = w.writeTermParens(true, operands[1], comments) + if err != nil { + return nil, err + } w.write(" ") w.write(kw) w.write(" ") - comments = w.writeTermParens(true, operands[2], comments) + comments, err = w.writeTermParens(true, operands[2], comments) + if err != nil { + return nil, err + } } - return comments + return comments, nil } -func (w *writer) writeObject(obj ast.Object, loc *ast.Location, comments []*ast.Comment) []*ast.Comment { +func (w *writer) writeObject(obj ast.Object, loc *ast.Location, comments []*ast.Comment) ([]*ast.Comment, error) { w.write("{") defer w.write("}") @@ -973,7 +1412,7 @@ func (w *writer) writeObject(obj ast.Object, loc *ast.Location, comments []*ast. return w.writeIterable(s, loc, closingLoc(0, 0, '{', '}', loc), comments, w.objectWriter()) } -func (w *writer) writeArray(arr *ast.Array, loc *ast.Location, comments []*ast.Comment) []*ast.Comment { +func (w *writer) writeArray(arr *ast.Array, loc *ast.Location, comments []*ast.Comment) ([]*ast.Comment, error) { w.write("[") defer w.write("]") @@ -981,14 +1420,24 @@ func (w *writer) writeArray(arr *ast.Array, loc *ast.Location, comments []*ast.C arr.Foreach(func(t *ast.Term) { s = append(s, t) }) - return w.writeIterable(s, loc, closingLoc(0, 0, '[', ']', loc), comments, w.listWriter()) + var err error + comments, err = w.writeIterable(s, loc, closingLoc(0, 0, '[', ']', loc), comments, w.listWriter()) + if err != nil { + return nil, err + } + return comments, nil } -func (w *writer) writeSet(set ast.Set, loc *ast.Location, comments []*ast.Comment) []*ast.Comment { +func (w *writer) writeSet(set ast.Set, loc *ast.Location, comments []*ast.Comment) ([]*ast.Comment, error) { if set.Len() == 0 { w.write("set()") - return w.insertComments(comments, closingLoc(0, 0, '(', ')', loc)) + var err error + comments, err = w.insertComments(comments, closingLoc(0, 0, '(', ')', loc)) + if err != nil { + return nil, err + } + return comments, nil } w.write("{") @@ -998,24 +1447,29 @@ func (w *writer) writeSet(set ast.Set, loc *ast.Location, comments []*ast.Commen set.Foreach(func(t *ast.Term) { s = append(s, t) }) - return w.writeIterable(s, loc, closingLoc(0, 0, '{', '}', loc), comments, w.listWriter()) + var err error + comments, err = w.writeIterable(s, loc, closingLoc(0, 0, '{', '}', loc), comments, w.listWriter()) + if err != nil { + return nil, err + } + return comments, nil } -func (w *writer) writeArrayComprehension(arr *ast.ArrayComprehension, loc *ast.Location, comments []*ast.Comment) []*ast.Comment { +func (w *writer) writeArrayComprehension(arr *ast.ArrayComprehension, loc *ast.Location, comments []*ast.Comment) ([]*ast.Comment, error) { w.write("[") defer w.write("]") return w.writeComprehension('[', ']', arr.Term, arr.Body, loc, comments) } -func (w *writer) writeSetComprehension(set *ast.SetComprehension, loc *ast.Location, comments []*ast.Comment) []*ast.Comment { +func (w *writer) writeSetComprehension(set *ast.SetComprehension, loc *ast.Location, comments []*ast.Comment) ([]*ast.Comment, error) { w.write("{") defer w.write("}") return w.writeComprehension('{', '}', set.Term, set.Body, loc, comments) } -func (w *writer) writeObjectComprehension(object *ast.ObjectComprehension, loc *ast.Location, comments []*ast.Comment) []*ast.Comment { +func (w *writer) writeObjectComprehension(object *ast.ObjectComprehension, loc *ast.Location, comments []*ast.Comment) ([]*ast.Comment, error) { w.write("{") defer w.write("}") @@ -1025,12 +1479,16 @@ func (w *writer) writeObjectComprehension(object *ast.ObjectComprehension, loc * w.startLine() } - comments = w.writeTerm(object.Key, comments) + var err error + comments, err = w.writeTerm(object.Key, comments) + if err != nil { + return nil, err + } w.write(": ") return w.writeComprehension('{', '}', object.Value, object.Body, loc, comments) } -func (w *writer) writeComprehension(open, close byte, term *ast.Term, body ast.Body, loc *ast.Location, comments []*ast.Comment) []*ast.Comment { +func (w *writer) writeComprehension(openChar, closeChar byte, term *ast.Term, body ast.Body, loc *ast.Location, comments []*ast.Comment) ([]*ast.Comment, error) { if term.Location.Row-loc.Row >= 1 { w.endLine() w.startLine() @@ -1041,55 +1499,82 @@ func (w *writer) writeComprehension(open, close byte, term *ast.Term, body ast.B if ok { parens = term.Location.Text[0] == 40 // Starts with "(" } - comments = w.writeTermParens(parens, term, comments) + var err error + comments, err = w.writeTermParens(parens, term, comments) + if err != nil { + return nil, err + } w.write(" |") - return w.writeComprehensionBody(open, close, body, term.Location, loc, comments) + return w.writeComprehensionBody(openChar, closeChar, body, term.Location, loc, comments) } -func (w *writer) writeComprehensionBody(open, close byte, body ast.Body, term, compr *ast.Location, comments []*ast.Comment) []*ast.Comment { +func (w *writer) writeComprehensionBody(openChar, closeChar byte, body ast.Body, term, compr *ast.Location, comments []*ast.Comment) ([]*ast.Comment, error) { exprs := make([]interface{}, 0, len(body)) for _, expr := range body { exprs = append(exprs, expr) } - lines := groupIterable(exprs, term) + lines, err := w.groupIterable(exprs, term) + if err != nil { + return nil, err + } if body.Loc().Row-term.Row > 0 || len(lines) > 1 { w.endLine() w.up() defer w.startLine() - defer w.down() + defer func() { + if err := w.down(); err != nil { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, &ast.Location{}, err.Error())) + } + }() - comments = w.writeBody(body, comments) + var err error + comments, err = w.writeBody(body, comments) + if err != nil { + return comments, err + } } else { w.write(" ") i := 0 for ; i < len(body)-1; i++ { - comments = w.writeExpr(body[i], comments) + comments, err = w.writeExpr(body[i], comments) + if err != nil { + return comments, err + } w.write("; ") } - comments = w.writeExpr(body[i], comments) + comments, err = w.writeExpr(body[i], comments) + if err != nil { + return comments, err + } } - - return w.insertComments(comments, closingLoc(0, 0, open, close, compr)) + comments, err = w.insertComments(comments, closingLoc(0, 0, openChar, closeChar, compr)) + if err != nil { + return nil, err + } + return comments, nil } -func (w *writer) writeImports(imports []*ast.Import, comments []*ast.Comment) []*ast.Comment { +func (w *writer) writeImports(imports []*ast.Import, comments []*ast.Comment) ([]*ast.Comment, error) { m, comments := mapImportsToComments(imports, comments) groups := groupImports(imports) for _, group := range groups { - comments = w.insertComments(comments, group[0].Loc()) + var err error + comments, err = w.insertComments(comments, group[0].Loc()) + if err != nil { + return nil, err + } // Sort imports within a newline grouping. - sort.Slice(group, func(i, j int) bool { - a := group[i] - b := group[j] - return a.Compare(b) < 0 - }) + slices.SortFunc(group, (*ast.Import).Compare) for _, i := range group { w.startLine() - w.writeImport(i) + err = w.writeImport(i) + if err != nil { + return nil, err + } if c, ok := m[i]; ok { w.write(" " + c.String()) } @@ -1098,10 +1583,10 @@ func (w *writer) writeImports(imports []*ast.Import, comments []*ast.Comment) [] w.blankLine() } - return comments + return comments, nil } -func (w *writer) writeImport(imp *ast.Import) { +func (w *writer) writeImport(imp *ast.Import) error { path := imp.Path.Value.(ast.Ref) buf := []string{"import"} @@ -1111,7 +1596,10 @@ func (w *writer) writeImport(imp *ast.Import) { w2 := writer{ buf: bytes.Buffer{}, } - w2.writeRef(path) + _, err := w2.writeRef(path, nil) + if err != nil { + return err + } buf = append(buf, w2.buf.String()) } else { buf = append(buf, path.String()) @@ -1121,12 +1609,17 @@ func (w *writer) writeImport(imp *ast.Import) { buf = append(buf, "as "+imp.Alias.String()) } w.write(strings.Join(buf, " ")) + + return nil } -type entryWriter func(interface{}, []*ast.Comment) []*ast.Comment +type entryWriter func(interface{}, []*ast.Comment) ([]*ast.Comment, error) -func (w *writer) writeIterable(elements []interface{}, last *ast.Location, close *ast.Location, comments []*ast.Comment, fn entryWriter) []*ast.Comment { - lines := groupIterable(elements, last) +func (w *writer) writeIterable(elements []interface{}, last *ast.Location, close *ast.Location, comments []*ast.Comment, fn entryWriter) ([]*ast.Comment, error) { + lines, err := w.groupIterable(elements, last) + if err != nil { + return nil, err + } if len(lines) > 1 { w.delayBeforeEnd() w.startMultilineSeq() @@ -1134,34 +1627,49 @@ func (w *writer) writeIterable(elements []interface{}, last *ast.Location, close i := 0 for ; i < len(lines)-1; i++ { - comments = w.writeIterableLine(lines[i], comments, fn) + comments, err = w.writeIterableLine(lines[i], comments, fn) + if err != nil { + return nil, err + } w.write(",") w.endLine() w.startLine() } - comments = w.writeIterableLine(lines[i], comments, fn) + comments, err = w.writeIterableLine(lines[i], comments, fn) + if err != nil { + return nil, err + } if len(lines) > 1 { w.write(",") w.endLine() - comments = w.insertComments(comments, close) - w.down() + comments, err = w.insertComments(comments, close) + if err != nil { + return nil, err + } + if err := w.down(); err != nil { + return nil, err + } w.startLine() } - return comments + return comments, nil } -func (w *writer) writeIterableLine(elements []interface{}, comments []*ast.Comment, fn entryWriter) []*ast.Comment { +func (w *writer) writeIterableLine(elements []interface{}, comments []*ast.Comment, fn entryWriter) ([]*ast.Comment, error) { if len(elements) == 0 { - return comments + return comments, nil } i := 0 for ; i < len(elements)-1; i++ { - comments = fn(elements[i], comments) + var err error + comments, err = fn(elements[i], comments) + if err != nil { + return nil, err + } w.write(", ") } @@ -1169,7 +1677,7 @@ func (w *writer) writeIterableLine(elements []interface{}, comments []*ast.Comme } func (w *writer) objectWriter() entryWriter { - return func(x interface{}, comments []*ast.Comment) []*ast.Comment { + return func(x interface{}, comments []*ast.Comment) ([]*ast.Comment, error) { entry := x.([2]*ast.Term) call, isCall := entry[0].Value.(ast.Call) @@ -1180,7 +1688,11 @@ func (w *writer) objectWriter() entryWriter { w.write("(") } - comments = w.writeTerm(entry[0], comments) + var err error + comments, err = w.writeTerm(entry[0], comments) + if err != nil { + return nil, err + } if paren { w.write(")") } @@ -1198,7 +1710,7 @@ func (w *writer) objectWriter() entryWriter { } func (w *writer) listWriter() entryWriter { - return func(x interface{}, comments []*ast.Comment) []*ast.Comment { + return func(x interface{}, comments []*ast.Comment) ([]*ast.Comment, error) { t, ok := x.(*ast.Term) if ok { call, isCall := t.Value.(ast.Call) @@ -1214,7 +1726,7 @@ func (w *writer) listWriter() entryWriter { // groupIterable will group the `elements` slice into slices according to their // location: anything on the same line will be put into a slice. -func groupIterable(elements []interface{}, last *ast.Location) [][]interface{} { +func (w *writer) groupIterable(elements []interface{}, last *ast.Location) ([][]interface{}, error) { // Generated vars occur in the AST when we're rendering the result of // partial evaluation in a bundle build with optimization. // Those variables, and wildcard variables have the "default location", @@ -1241,18 +1753,26 @@ func groupIterable(elements []interface{}, last *ast.Location) [][]interface{} { return false }) if def { // return as-is - return [][]interface{}{elements} + return [][]interface{}{elements}, nil } } - sort.Slice(elements, func(i, j int) bool { - return locLess(elements[i], elements[j]) + + slices.SortFunc(elements, func(i, j any) int { + l, err := locCmp(i, j) + if err != nil { + w.errs = append(w.errs, ast.NewError(ast.FormatErr, &ast.Location{}, err.Error())) + } + return l }) var lines [][]interface{} cur := make([]interface{}, 0, len(elements)) for i, t := range elements { elem := t - loc := getLoc(elem) + loc, err := getLoc(elem) + if err != nil { + return nil, err + } lineDiff := loc.Row - last.Row if lineDiff > 0 && i > 0 { lines = append(lines, cur) @@ -1262,7 +1782,7 @@ func groupIterable(elements []interface{}, last *ast.Location) [][]interface{} { last = loc cur = append(cur, elem) } - return append(lines, cur) + return append(lines, cur), nil } func mapImportsToComments(imports []*ast.Import, comments []*ast.Comment) (map[*ast.Import]*ast.Comment, []*ast.Comment) { @@ -1318,14 +1838,37 @@ func groupImports(imports []*ast.Import) [][]*ast.Import { return groups } -func partitionComments(comments []*ast.Comment, l *ast.Location) (before []*ast.Comment, at *ast.Comment, after []*ast.Comment) { +func partitionComments(comments []*ast.Comment, l *ast.Location) ([]*ast.Comment, *ast.Comment, []*ast.Comment) { + if len(comments) == 0 { + return nil, nil, nil + } + + numBefore, numAfter := 0, 0 + for _, c := range comments { + switch cmp := c.Location.Row - l.Row; { + case cmp < 0: + numBefore++ + case cmp > 0: + numAfter++ + } + } + + if numAfter == len(comments) { + return nil, nil, comments + } + + var at *ast.Comment + + before := make([]*ast.Comment, 0, numBefore) + after := comments[0 : 0 : len(comments)-numBefore] + for _, c := range comments { switch cmp := c.Location.Row - l.Row; { case cmp < 0: before = append(before, c) case cmp > 0: after = append(after, c) - case cmp == 0: + default: at = c } } @@ -1361,43 +1904,52 @@ loop: return rules, others[i:] } -func locLess(a, b interface{}) bool { - return locCmp(a, b) < 0 +func locLess(a, b interface{}) (bool, error) { + c, err := locCmp(a, b) + return c < 0, err } -func locCmp(a, b interface{}) int { - al := getLoc(a) - bl := getLoc(b) +func locCmp(a, b interface{}) (int, error) { + al, err := getLoc(a) + if err != nil { + return 0, err + } + bl, err := getLoc(b) + if err != nil { + return 0, err + } switch { case al == nil && bl == nil: - return 0 + return 0, nil case al == nil: - return -1 + return -1, nil case bl == nil: - return 1 + return 1, nil } if cmp := al.Row - bl.Row; cmp != 0 { - return cmp + return cmp, nil } - return al.Col - bl.Col + return al.Col - bl.Col, nil } -func getLoc(x interface{}) *ast.Location { +func getLoc(x interface{}) (*ast.Location, error) { switch x := x.(type) { case ast.Node: // *ast.Head, *ast.Expr, *ast.With, *ast.Term - return x.Loc() + return x.Loc(), nil case *ast.Location: - return x + return x, nil case [2]*ast.Term: // Special case to allow for easy printing of objects. - return x[0].Location + return x[0].Location, nil default: - panic("Not reached") + return nil, fmt.Errorf("unable to get location for type %v", x) } } -func closingLoc(skipOpen, skipClose, open, close byte, loc *ast.Location) *ast.Location { +var negativeRow = &ast.Location{Row: -1} + +func closingLoc(skipOpen, skipClose, openChar, closeChar byte, loc *ast.Location) *ast.Location { i, offset := 0, 0 // Skip past parens/brackets/braces in rule heads. @@ -1406,26 +1958,26 @@ func closingLoc(skipOpen, skipClose, open, close byte, loc *ast.Location) *ast.L } for ; i < len(loc.Text); i++ { - if loc.Text[i] == open { + if loc.Text[i] == openChar { break } } if i >= len(loc.Text) { - return &ast.Location{Row: -1} + return negativeRow } state := 1 for state > 0 { i++ if i >= len(loc.Text) { - return &ast.Location{Row: -1} + return negativeRow } switch loc.Text[i] { - case open: + case openChar: state++ - case close: + case closeChar: state-- case '\n': offset++ @@ -1435,10 +1987,10 @@ func closingLoc(skipOpen, skipClose, open, close byte, loc *ast.Location) *ast.L return &ast.Location{Row: loc.Row + offset} } -func skipPast(open, close byte, loc *ast.Location) (int, int) { +func skipPast(openChar, closeChar byte, loc *ast.Location) (int, int) { i := 0 for ; i < len(loc.Text); i++ { - if loc.Text[i] == open { + if loc.Text[i] == openChar { break } } @@ -1452,9 +2004,9 @@ func skipPast(open, close byte, loc *ast.Location) (int, int) { } switch loc.Text[i] { - case open: + case openChar: state++ - case close: + case closeChar: state-- case '\n': offset++ @@ -1467,7 +2019,7 @@ func skipPast(open, close byte, loc *ast.Location) (int, int) { // startLine begins a line with the current indentation level. func (w *writer) startLine() { w.inline = true - for i := 0; i < w.level; i++ { + for range w.level { w.write(w.indent) } } @@ -1483,15 +2035,46 @@ func (w *writer) endLine() { w.write("\n") } +type unexpectedCommentError struct { + newComment string + newCommentRow int + existingComment string + existingCommentRow int +} + +func (u unexpectedCommentError) Error() string { + return fmt.Sprintf("unexpected new comment (%s) on line %d because there is already a comment (%s) registered for line %d", + u.newComment, u.newCommentRow, u.existingComment, u.existingCommentRow) +} + // beforeLineEnd registers a comment to be printed at the end of the current line. -func (w *writer) beforeLineEnd(c *ast.Comment) { +func (w *writer) beforeLineEnd(c *ast.Comment) error { if w.beforeEnd != nil { if c == nil { - return + return nil + } + + existingComment := truncatedString(w.beforeEnd.String(), 100) + existingCommentRow := w.beforeEnd.Location.Row + newComment := truncatedString(c.String(), 100) + w.beforeEnd = nil + + return unexpectedCommentError{ + newComment: newComment, + newCommentRow: c.Location.Row, + existingComment: existingComment, + existingCommentRow: existingCommentRow, } - panic("overwriting non-nil beforeEnd") } w.beforeEnd = c + return nil +} + +func truncatedString(s string, max int) string { + if len(s) > max { + return s[:max-2] + "..." + } + return s } func (w *writer) delayBeforeEnd() { @@ -1533,11 +2116,12 @@ func (w *writer) up() { } // down decreases the indentation level -func (w *writer) down() { +func (w *writer) down() error { if w.level == 0 { - panic("negative indentation level") + return errors.New("negative indentation level") } w.level-- + return nil } func ensureFutureKeywordImport(imps []*ast.Import, kw string) []*ast.Import { @@ -1589,22 +2173,22 @@ func ensureImport(imps []*ast.Import, path ast.Ref) []*ast.Import { return append(imps, imp) } -// ArgErrDetail but for `fmt` checks since compiler has not run yet. +// ArityFormatErrDetail but for `fmt` checks since compiler has not run yet. type ArityFormatErrDetail struct { Have []string `json:"have"` Want []string `json:"want"` } -// arityMismatchError but for `fmt` checks since the compiler has not run yet. +// ArityFormatMismatchError but for `fmt` checks since the compiler has not run yet. func ArityFormatMismatchError(operands []*ast.Term, operator string, loc *ast.Location, f *types.Function) *ast.Error { - want := make([]string, len(f.Args())) - for i := range f.Args() { - want[i] = types.Sprint(f.Args()[i]) + want := make([]string, f.Arity()) + for i, arg := range f.FuncArgs().Args { + want[i] = types.Sprint(arg) } have := make([]string, len(operands)) - for i := 0; i < len(operands); i++ { - have[i] = ast.TypeName(operands[i].Value) + for i := range operands { + have[i] = ast.ValueName(operands[i].Value) } err := ast.NewError(ast.TypeErr, loc, "%s: %s", operator, "arity mismatch") err.Details = &ArityFormatErrDetail{ @@ -1617,8 +2201,8 @@ func ArityFormatMismatchError(operands []*ast.Term, operator string, loc *ast.Lo // Lines returns the string representation of the detail. func (d *ArityFormatErrDetail) Lines() []string { return []string{ - "have: " + "(" + strings.Join(d.Have, ",") + ")", - "want: " + "(" + strings.Join(d.Want, ",") + ")", + "have: (" + strings.Join(d.Have, ",") + ")", + "want: (" + strings.Join(d.Want, ",") + ")", } } @@ -1631,10 +2215,12 @@ func moduleIsRegoV1Compatible(m *ast.Module) bool { return false } +var v1StringTerm = ast.StringTerm("v1") + // isRegoV1Compatible returns true if the passed *ast.Import is `rego.v1` func isRegoV1Compatible(imp *ast.Import) bool { path := imp.Path.Value.(ast.Ref) return len(path) == 2 && ast.RegoRootDocument.Equal(path[0]) && - path[1].Equal(ast.StringTerm("v1")) + path[1].Equal(v1StringTerm) } diff --git a/vendor/github.com/open-policy-agent/opa/hooks/hooks.go b/vendor/github.com/open-policy-agent/opa/v1/hooks/hooks.go similarity index 98% rename from vendor/github.com/open-policy-agent/opa/hooks/hooks.go rename to vendor/github.com/open-policy-agent/opa/v1/hooks/hooks.go index 9659d7b499..caf69b1242 100644 --- a/vendor/github.com/open-policy-agent/opa/hooks/hooks.go +++ b/vendor/github.com/open-policy-agent/opa/v1/hooks/hooks.go @@ -8,7 +8,7 @@ import ( "context" "fmt" - "github.com/open-policy-agent/opa/config" + "github.com/open-policy-agent/opa/v1/config" ) // Hook is a hook to be called in some select places in OPA's operation. diff --git a/vendor/github.com/open-policy-agent/opa/ir/ir.go b/vendor/github.com/open-policy-agent/opa/v1/ir/ir.go similarity index 99% rename from vendor/github.com/open-policy-agent/opa/ir/ir.go rename to vendor/github.com/open-policy-agent/opa/v1/ir/ir.go index c07670704e..3657a9b673 100644 --- a/vendor/github.com/open-policy-agent/opa/ir/ir.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ir/ir.go @@ -11,7 +11,7 @@ package ir import ( "fmt" - "github.com/open-policy-agent/opa/types" + "github.com/open-policy-agent/opa/v1/types" ) type ( @@ -106,7 +106,7 @@ const ( Unused ) -func (a *Policy) String() string { +func (*Policy) String() string { return "Policy" } diff --git a/vendor/github.com/open-policy-agent/opa/ir/marshal.go b/vendor/github.com/open-policy-agent/opa/v1/ir/marshal.go similarity index 93% rename from vendor/github.com/open-policy-agent/opa/ir/marshal.go rename to vendor/github.com/open-policy-agent/opa/v1/ir/marshal.go index 69f4b5caf6..f792e2c1b6 100644 --- a/vendor/github.com/open-policy-agent/opa/ir/marshal.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ir/marshal.go @@ -6,6 +6,7 @@ package ir import ( "encoding/json" + "fmt" "reflect" ) @@ -50,7 +51,11 @@ func (a *Operand) UnmarshalJSON(bs []byte) error { if err := json.Unmarshal(bs, &typed); err != nil { return err } - x := valFactories[typed.Type]() + f, ok := valFactories[typed.Type] + if !ok { + return fmt.Errorf("unrecognized value type %q", typed.Type) + } + x := f() if err := json.Unmarshal(typed.Value, &x); err != nil { return err } @@ -77,7 +82,11 @@ type rawTypedStmt struct { } func (raw rawTypedStmt) Unmarshal() (Stmt, error) { - x := stmtFactories[raw.Type]() + f, ok := stmtFactories[raw.Type] + if !ok { + return nil, fmt.Errorf("unrecognized statement type %q", raw.Type) + } + x := f() if err := json.Unmarshal(raw.Stmt, &x); err != nil { return nil, err } @@ -119,6 +128,7 @@ var stmtFactories = map[string]func() Stmt{ "IsArrayStmt": func() Stmt { return &IsArrayStmt{} }, "IsObjectStmt": func() Stmt { return &IsObjectStmt{} }, "IsDefinedStmt": func() Stmt { return &IsDefinedStmt{} }, + "IsSetStmt": func() Stmt { return &IsSetStmt{} }, "IsUndefinedStmt": func() Stmt { return &IsUndefinedStmt{} }, "ArrayAppendStmt": func() Stmt { return &ArrayAppendStmt{} }, "ObjectInsertStmt": func() Stmt { return &ObjectInsertStmt{} }, diff --git a/vendor/github.com/open-policy-agent/opa/ir/pretty.go b/vendor/github.com/open-policy-agent/opa/v1/ir/pretty.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/ir/pretty.go rename to vendor/github.com/open-policy-agent/opa/v1/ir/pretty.go diff --git a/vendor/github.com/open-policy-agent/opa/ir/walk.go b/vendor/github.com/open-policy-agent/opa/v1/ir/walk.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/ir/walk.go rename to vendor/github.com/open-policy-agent/opa/v1/ir/walk.go diff --git a/vendor/github.com/open-policy-agent/opa/keys/keys.go b/vendor/github.com/open-policy-agent/opa/v1/keys/keys.go similarity index 98% rename from vendor/github.com/open-policy-agent/opa/keys/keys.go rename to vendor/github.com/open-policy-agent/opa/v1/keys/keys.go index de03496943..fba7a9c939 100644 --- a/vendor/github.com/open-policy-agent/opa/keys/keys.go +++ b/vendor/github.com/open-policy-agent/opa/v1/keys/keys.go @@ -5,7 +5,7 @@ import ( "fmt" "os" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/util" ) const defaultSigningAlgorithm = "RS256" diff --git a/vendor/github.com/open-policy-agent/opa/loader/errors.go b/vendor/github.com/open-policy-agent/opa/v1/loader/errors.go similarity index 96% rename from vendor/github.com/open-policy-agent/opa/loader/errors.go rename to vendor/github.com/open-policy-agent/opa/v1/loader/errors.go index b8aafb1421..55b8e7dc44 100644 --- a/vendor/github.com/open-policy-agent/opa/loader/errors.go +++ b/vendor/github.com/open-policy-agent/opa/v1/loader/errors.go @@ -8,7 +8,7 @@ import ( "fmt" "strings" - "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/v1/ast" ) // Errors is a wrapper for multiple loader errors. diff --git a/vendor/github.com/open-policy-agent/opa/loader/extension/extension.go b/vendor/github.com/open-policy-agent/opa/v1/loader/extension/extension.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/loader/extension/extension.go rename to vendor/github.com/open-policy-agent/opa/v1/loader/extension/extension.go diff --git a/vendor/github.com/open-policy-agent/opa/loader/filter/filter.go b/vendor/github.com/open-policy-agent/opa/v1/loader/filter/filter.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/loader/filter/filter.go rename to vendor/github.com/open-policy-agent/opa/v1/loader/filter/filter.go diff --git a/vendor/github.com/open-policy-agent/opa/loader/loader.go b/vendor/github.com/open-policy-agent/opa/v1/loader/loader.go similarity index 96% rename from vendor/github.com/open-policy-agent/opa/loader/loader.go rename to vendor/github.com/open-policy-agent/opa/v1/loader/loader.go index 461639ed19..5e2217473a 100644 --- a/vendor/github.com/open-policy-agent/opa/loader/loader.go +++ b/vendor/github.com/open-policy-agent/opa/v1/loader/loader.go @@ -12,21 +12,20 @@ import ( "io/fs" "os" "path/filepath" - "sort" "strings" "sigs.k8s.io/yaml" - "github.com/open-policy-agent/opa/ast" - astJSON "github.com/open-policy-agent/opa/ast/json" - "github.com/open-policy-agent/opa/bundle" fileurl "github.com/open-policy-agent/opa/internal/file/url" "github.com/open-policy-agent/opa/internal/merge" - "github.com/open-policy-agent/opa/loader/filter" - "github.com/open-policy-agent/opa/metrics" - "github.com/open-policy-agent/opa/storage" - "github.com/open-policy-agent/opa/storage/inmem" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/ast" + astJSON "github.com/open-policy-agent/opa/v1/ast/json" + "github.com/open-policy-agent/opa/v1/bundle" + "github.com/open-policy-agent/opa/v1/loader/filter" + "github.com/open-policy-agent/opa/v1/metrics" + "github.com/open-policy-agent/opa/v1/storage" + "github.com/open-policy-agent/opa/v1/storage/inmem" + "github.com/open-policy-agent/opa/v1/util" ) // Result represents the result of successfully loading zero or more files. @@ -101,6 +100,8 @@ type FileLoader interface { WithSkipBundleVerification(bool) FileLoader WithProcessAnnotation(bool) FileLoader WithCapabilities(*ast.Capabilities) FileLoader + // Deprecated: Use SetOptions in the json package instead, where a longer description + // of why this is deprecated also can be found. WithJSONOptions(*astJSON.Options) FileLoader WithRegoVersion(ast.RegoVersion) FileLoader WithFollowSymlinks(bool) FileLoader @@ -178,9 +179,11 @@ func (fl *fileLoader) WithCapabilities(caps *ast.Capabilities) FileLoader { return fl } -// WithJSONOptions sets the JSONOptions for use when parsing files -func (fl *fileLoader) WithJSONOptions(opts *astJSON.Options) FileLoader { - fl.opts.JSONOptions = opts +// WithJSONOptions sets the JSON options on the parser (now a no-op). +// +// Deprecated: Use SetOptions in the json package instead, where a longer description +// of why this is deprecated also can be found. +func (fl *fileLoader) WithJSONOptions(*astJSON.Options) FileLoader { return fl } @@ -270,7 +273,6 @@ func (fl fileLoader) AsBundle(path string) (*bundle.Bundle, error) { WithSkipBundleVerification(fl.skipVerify). WithProcessAnnotations(fl.opts.ProcessAnnotation). WithCapabilities(fl.opts.Capabilities). - WithJSONOptions(fl.opts.JSONOptions). WithFollowSymlinks(fl.followSymlinks). WithRegoVersion(fl.opts.RegoVersion) @@ -564,12 +566,7 @@ func Dirs(paths []string) []string { unique[dir] = struct{}{} } - u := make([]string, 0, len(unique)) - for k := range unique { - u = append(u, k) - } - sort.Strings(u) - return u + return util.KeysSorted(unique) } // SplitPrefix returns a tuple specifying the document prefix and the file @@ -762,7 +759,7 @@ func loadBundleFile(path string, bs []byte, m metrics.Metrics, opts ast.ParserOp tl := bundle.NewTarballLoaderWithBaseURL(bytes.NewBuffer(bs), path) br := bundle.NewCustomReader(tl). WithRegoVersion(opts.RegoVersion). - WithJSONOptions(opts.JSONOptions). + WithCapabilities(opts.Capabilities). WithProcessAnnotations(opts.ProcessAnnotation). WithMetrics(m). WithSkipBundleVerification(true). diff --git a/vendor/github.com/open-policy-agent/opa/logging/logging.go b/vendor/github.com/open-policy-agent/opa/v1/logging/logging.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/logging/logging.go rename to vendor/github.com/open-policy-agent/opa/v1/logging/logging.go diff --git a/vendor/github.com/open-policy-agent/opa/metrics/metrics.go b/vendor/github.com/open-policy-agent/opa/v1/metrics/metrics.go similarity index 97% rename from vendor/github.com/open-policy-agent/opa/metrics/metrics.go rename to vendor/github.com/open-policy-agent/opa/v1/metrics/metrics.go index 53cd606a36..f1038e8bcb 100644 --- a/vendor/github.com/open-policy-agent/opa/metrics/metrics.go +++ b/vendor/github.com/open-policy-agent/opa/v1/metrics/metrics.go @@ -8,7 +8,7 @@ package metrics import ( "encoding/json" "fmt" - "sort" + "slices" "strings" "sync" "sync/atomic" @@ -94,8 +94,8 @@ func (m *metrics) String() string { }) } - sort.Slice(sorted, func(i, j int) bool { - return sorted[i].Key < sorted[j].Key + slices.SortFunc(sorted, func(a, b metric) int { + return strings.Compare(a.Key, b.Key) }) buf := make([]string, len(sorted)) @@ -178,7 +178,7 @@ func (m *metrics) Clear() { m.counters = map[string]Counter{} } -func (m *metrics) formatKey(name string, metrics interface{}) string { +func (*metrics) formatKey(name string, metrics interface{}) string { switch metrics.(type) { case Timer: return "timer_" + name + "_ns" diff --git a/vendor/github.com/open-policy-agent/opa/plugins/plugins.go b/vendor/github.com/open-policy-agent/opa/v1/plugins/plugins.go similarity index 94% rename from vendor/github.com/open-policy-agent/opa/plugins/plugins.go rename to vendor/github.com/open-policy-agent/opa/v1/plugins/plugins.go index 567acfb817..7e8b900bfc 100644 --- a/vendor/github.com/open-policy-agent/opa/plugins/plugins.go +++ b/vendor/github.com/open-policy-agent/opa/v1/plugins/plugins.go @@ -19,22 +19,22 @@ import ( "github.com/gorilla/mux" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/bundle" - "github.com/open-policy-agent/opa/config" - "github.com/open-policy-agent/opa/hooks" bundleUtils "github.com/open-policy-agent/opa/internal/bundle" cfg "github.com/open-policy-agent/opa/internal/config" initload "github.com/open-policy-agent/opa/internal/runtime/init" - "github.com/open-policy-agent/opa/keys" - "github.com/open-policy-agent/opa/loader" - "github.com/open-policy-agent/opa/logging" - "github.com/open-policy-agent/opa/plugins/rest" - "github.com/open-policy-agent/opa/resolver/wasm" - "github.com/open-policy-agent/opa/storage" - "github.com/open-policy-agent/opa/topdown/cache" - "github.com/open-policy-agent/opa/topdown/print" - "github.com/open-policy-agent/opa/tracing" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/bundle" + "github.com/open-policy-agent/opa/v1/config" + "github.com/open-policy-agent/opa/v1/hooks" + "github.com/open-policy-agent/opa/v1/keys" + "github.com/open-policy-agent/opa/v1/loader" + "github.com/open-policy-agent/opa/v1/logging" + "github.com/open-policy-agent/opa/v1/plugins/rest" + "github.com/open-policy-agent/opa/v1/resolver/wasm" + "github.com/open-policy-agent/opa/v1/storage" + "github.com/open-policy-agent/opa/v1/topdown/cache" + "github.com/open-policy-agent/opa/v1/topdown/print" + "github.com/open-policy-agent/opa/v1/tracing" ) // Factory defines the interface OPA uses to instantiate your plugin. @@ -163,6 +163,14 @@ func (s *Status) String() string { return fmt.Sprintf("{%v %q}", s.State, s.Message) } +func (s *Status) Equal(other *Status) bool { + if s == nil || other == nil { + return s == nil && other == nil + } + + return s.State == other.State && s.Message == other.Message +} + // StatusListener defines a handler to register for status updates. type StatusListener func(status map[string]*Status) @@ -440,6 +448,11 @@ func New(raw []byte, id string, store storage.Store, opts ...func(*Manager)) (*M f(m) } + if m.parserOptions.RegoVersion == ast.RegoUndefined { + // Default to v1 if rego-version is not set through options + m.parserOptions.RegoVersion = ast.DefaultRegoVersion + } + if m.logger == nil { m.logger = logging.Get() } @@ -472,13 +485,7 @@ func New(raw []byte, id string, store storage.Store, opts ...func(*Manager)) (*M return nil, err } - serviceOpts := cfg.ServiceOptions{ - Raw: parsedConfig.Services, - AuthPlugin: m.AuthPlugin, - Keys: m.keys, - Logger: m.logger, - DistributedTacingOpts: m.distributedTacingOpts, - } + serviceOpts := m.DefaultServiceOpts(parsedConfig) m.services, err = cfg.ParseServicesConfig(serviceOpts) if err != nil { @@ -494,8 +501,8 @@ func New(raw []byte, id string, store storage.Store, opts ...func(*Manager)) (*M m.reporter.RegisterGatherer("min_compatible_version", func(_ context.Context) (any, error) { var minimumCompatibleVersion string - if m.compiler != nil && m.compiler.Required != nil { - minimumCompatibleVersion, _ = m.compiler.Required.MinimumCompatibleVersion() + if c := m.GetCompiler(); c != nil && c.Required != nil { + minimumCompatibleVersion, _ = c.Required.MinimumCompatibleVersion() } return minimumCompatibleVersion, nil }) @@ -537,6 +544,7 @@ func (m *Manager) Init(ctx context.Context) error { Bundles: m.initBundles, MaxErrors: m.maxErrors, EnablePrintStatements: m.enablePrintStatements, + ParserOptions: m.parserOptions, }) if err != nil { @@ -746,14 +754,19 @@ func (m *Manager) Stop(ctx context.Context) { } } -// Reconfigure updates the configuration on the manager. -func (m *Manager) Reconfigure(config *config.Config) error { - opts := cfg.ServiceOptions{ +func (m *Manager) DefaultServiceOpts(config *config.Config) cfg.ServiceOptions { + return cfg.ServiceOptions{ Raw: config.Services, AuthPlugin: m.AuthPlugin, Logger: m.logger, + Keys: m.keys, DistributedTacingOpts: m.distributedTacingOpts, } +} + +// Reconfigure updates the configuration on the manager. +func (m *Manager) Reconfigure(config *config.Config) error { + opts := m.DefaultServiceOpts(config) keys, err := keys.ParseKeysConfig(config.Keys) if err != nil { @@ -790,7 +803,7 @@ func (m *Manager) Reconfigure(config *config.Config) error { m.Config = config m.interQueryBuiltinCacheConfig = interQueryBuiltinCacheConfig - for name, client := range services { + for name, client := range services { //nolint:gocritic m.services[name] = client } @@ -939,7 +952,13 @@ func loadCompilerFromStore(ctx context.Context, store storage.Store, txn storage modules[policy] = module } - compiler := ast.NewCompiler().WithEnablePrintStatements(enablePrintStatements) + compiler := ast.NewCompiler(). + WithEnablePrintStatements(enablePrintStatements) + + if popts.RegoVersion != ast.RegoUndefined { + compiler = compiler.WithDefaultRegoVersion(popts.RegoVersion) + } + compiler.Compile(modules) return compiler, nil } diff --git a/vendor/github.com/open-policy-agent/opa/plugins/rest/auth.go b/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/auth.go similarity index 96% rename from vendor/github.com/open-policy-agent/opa/plugins/rest/auth.go rename to vendor/github.com/open-policy-agent/opa/v1/plugins/rest/auth.go index 11e72001a2..7ef9bf7dfd 100644 --- a/vendor/github.com/open-policy-agent/opa/plugins/rest/auth.go +++ b/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/auth.go @@ -33,8 +33,8 @@ import ( "github.com/open-policy-agent/opa/internal/jwx/jws/sign" "github.com/open-policy-agent/opa/internal/providers/aws" "github.com/open-policy-agent/opa/internal/uuid" - "github.com/open-policy-agent/opa/keys" - "github.com/open-policy-agent/opa/logging" + "github.com/open-policy-agent/opa/v1/keys" + "github.com/open-policy-agent/opa/v1/logging" ) const ( @@ -126,10 +126,14 @@ type bearerAuthPlugin struct { // encode is set to true for the OCIDownloader because // it expects tokens in plain text but needs them in base64. encode bool + logger logging.Logger } func (ap *bearerAuthPlugin) NewClient(c Config) (*http.Client, error) { t, err := DefaultTLSConfig(c) + + ap.logger = c.logger + if err != nil { return nil, err } @@ -153,6 +157,9 @@ func (ap *bearerAuthPlugin) NewClient(c Config) (*http.Client, error) { func (ap *bearerAuthPlugin) Prepare(req *http.Request) error { token := ap.Token + if ap.logger == nil { + ap.logger = logging.Get() + } if ap.TokenPath != "" { bytes, err := os.ReadFile(ap.TokenPath) @@ -166,7 +173,12 @@ func (ap *bearerAuthPlugin) Prepare(req *http.Request) error { token = base64.StdEncoding.EncodeToString([]byte(token)) } - req.Header.Add("Authorization", fmt.Sprintf("%v %v", ap.Scheme, token)) + if req.Response != nil && (req.Response.StatusCode == http.StatusPermanentRedirect || req.Response.StatusCode == http.StatusTemporaryRedirect) { + ap.logger.Debug("not attaching authorization header as the response contains a redirect") + } else { + ap.logger.Debug("attaching authorization header") + req.Header.Add("Authorization", fmt.Sprintf("%v %v", ap.Scheme, token)) + } return nil } @@ -194,7 +206,7 @@ func convertSignatureToBase64(alg string, der []byte) (string, error) { return signatureData, nil } -func pointsFromDER(der []byte) (R, S *big.Int, err error) { +func pointsFromDER(der []byte) (R, S *big.Int, err error) { //nolint:gocritic R, S = &big.Int{}, &big.Int{} data := asn1.RawValue{} if _, err := asn1.Unmarshal(der, &data); err != nil { @@ -364,7 +376,7 @@ func (ap *oauth2ClientCredentialsAuthPlugin) createAuthJWT(ctx context.Context, return &jwt, nil } -func (ap *oauth2ClientCredentialsAuthPlugin) mapKMSAlgToSign(alg string) (string, error) { +func (*oauth2ClientCredentialsAuthPlugin) mapKMSAlgToSign(alg string) (string, error) { switch alg { case "ECDSA_SHA_256": return "ES256", nil @@ -382,12 +394,7 @@ func (ap *oauth2ClientCredentialsAuthPlugin) SignWithKMS(ctx context.Context, pa encodedHdr := base64.RawURLEncoding.EncodeToString(hdrBuf) encodedPayload := base64.RawURLEncoding.EncodeToString(payload) - input := strings.Join( - []string{ - encodedHdr, - encodedPayload, - }, ".", - ) + input := encodedHdr + "." + encodedPayload digest, err := messageDigest([]byte(input), ap.AWSKmsKey.Algorithm) if err != nil { return nil, err @@ -616,7 +623,7 @@ func (ap *oauth2ClientCredentialsAuthPlugin) requestToken(ctx context.Context) ( return nil, err } - if strings.ToLower(tokenResponse.TokenType) != "bearer" { + if !strings.EqualFold(tokenResponse.TokenType, "bearer") { return nil, errors.New("unknown token type returned from token endpoint") } @@ -751,7 +758,7 @@ func (ap *clientTLSAuthPlugin) NewClient(c Config) (*http.Client, error) { return client, nil } -func (ap *clientTLSAuthPlugin) Prepare(_ *http.Request) error { +func (*clientTLSAuthPlugin) Prepare(_ *http.Request) error { return nil } diff --git a/vendor/github.com/open-policy-agent/opa/plugins/rest/aws.go b/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/aws.go similarity index 99% rename from vendor/github.com/open-policy-agent/opa/plugins/rest/aws.go rename to vendor/github.com/open-policy-agent/opa/v1/plugins/rest/aws.go index cc45dfa9c7..a610a8014b 100644 --- a/vendor/github.com/open-policy-agent/opa/plugins/rest/aws.go +++ b/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/aws.go @@ -19,7 +19,7 @@ import ( "github.com/go-ini/ini" "github.com/open-policy-agent/opa/internal/providers/aws" - "github.com/open-policy-agent/opa/logging" + "github.com/open-policy-agent/opa/v1/logging" ) const ( @@ -69,7 +69,7 @@ type awsEnvironmentCredentialService struct { logger logging.Logger } -func (cs *awsEnvironmentCredentialService) credentials(context.Context) (aws.Credentials, error) { +func (*awsEnvironmentCredentialService) credentials(context.Context) (aws.Credentials, error) { var creds aws.Credentials creds.AccessKey = os.Getenv(accessKeyEnvVar) if creds.AccessKey == "" { @@ -678,7 +678,7 @@ func (ap *ecrAuthPlugin) Prepare(r *http.Request) error { ap.logger.Debug("Signing request with ECR authorization token") - r.Header.Set("Authorization", fmt.Sprintf("Basic %s", ap.token.AuthorizationToken)) + r.Header.Set("Authorization", "Basic "+ap.token.AuthorizationToken) return nil } diff --git a/vendor/github.com/open-policy-agent/opa/plugins/rest/azure.go b/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/azure.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/plugins/rest/azure.go rename to vendor/github.com/open-policy-agent/opa/v1/plugins/rest/azure.go diff --git a/vendor/github.com/open-policy-agent/opa/plugins/rest/gcp.go b/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/gcp.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/plugins/rest/gcp.go rename to vendor/github.com/open-policy-agent/opa/v1/plugins/rest/gcp.go diff --git a/vendor/github.com/open-policy-agent/opa/plugins/rest/rest.go b/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/rest.go similarity index 94% rename from vendor/github.com/open-policy-agent/opa/plugins/rest/rest.go rename to vendor/github.com/open-policy-agent/opa/v1/plugins/rest/rest.go index fd59058ca1..e5d8e0f0d6 100644 --- a/vendor/github.com/open-policy-agent/opa/plugins/rest/rest.go +++ b/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/rest.go @@ -12,16 +12,17 @@ import ( "errors" "fmt" "io" + "maps" "net/http" "net/http/httputil" "reflect" "strings" "github.com/open-policy-agent/opa/internal/version" - "github.com/open-policy-agent/opa/keys" - "github.com/open-policy-agent/opa/logging" - "github.com/open-policy-agent/opa/tracing" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/keys" + "github.com/open-policy-agent/opa/v1/logging" + "github.com/open-policy-agent/opa/v1/tracing" + "github.com/open-policy-agent/opa/v1/util" ) const ( @@ -94,7 +95,7 @@ func (c *Config) AuthPlugin(lookup AuthPluginLookupFunc) (HTTPAuthPlugin, error) } // reflection avoids need for this code to change as auth plugins are added s := reflect.ValueOf(c.Credentials) - for i := 0; i < s.NumField(); i++ { + for i := range s.NumField() { if s.Field(i).IsNil() { continue } @@ -293,7 +294,7 @@ func (c Client) Do(ctx context.Context, method, path string) (*http.Response, er } url := c.config.URL + "/" + path - req, err := http.NewRequest(method, url, body) + req, err := http.NewRequestWithContext(ctx, method, url, body) if err != nil { return nil, err } @@ -303,23 +304,16 @@ func (c Client) Do(ctx context.Context, method, path string) (*http.Response, er } // Copy custom headers from config. - for key, value := range c.config.Headers { - headers[key] = value - } + maps.Copy(headers, c.config.Headers) // Overwrite with headers set directly on client. - for key, value := range c.headers { - headers[key] = value - } + maps.Copy(headers, c.headers) for key, value := range headers { req.Header.Add(key, value) } - req = req.WithContext(ctx) - - err = c.config.authPrepare(req, c.authPluginLookup) - if err != nil { + if err = c.config.authPrepare(req, c.authPluginLookup); err != nil { return nil, err } @@ -347,7 +341,7 @@ func (c Client) Do(ctx context.Context, method, path string) (*http.Response, er return nil, err } - if len(string(dump)) < defaultResponseSizeLimitBytes { + if len(dump) < defaultResponseSizeLimitBytes { c.loggerFields["response"] = string(dump) } else { c.loggerFields["response"] = fmt.Sprintf("%v...", string(dump[:defaultResponseSizeLimitBytes])) diff --git a/vendor/github.com/open-policy-agent/opa/rego/errors.go b/vendor/github.com/open-policy-agent/opa/v1/rego/errors.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/rego/errors.go rename to vendor/github.com/open-policy-agent/opa/v1/rego/errors.go diff --git a/vendor/github.com/open-policy-agent/opa/rego/plugins.go b/vendor/github.com/open-policy-agent/opa/v1/rego/plugins.go similarity index 85% rename from vendor/github.com/open-policy-agent/opa/rego/plugins.go rename to vendor/github.com/open-policy-agent/opa/v1/rego/plugins.go index abaa910341..55b5ed7803 100644 --- a/vendor/github.com/open-policy-agent/opa/rego/plugins.go +++ b/vendor/github.com/open-policy-agent/opa/v1/rego/plugins.go @@ -8,8 +8,8 @@ import ( "context" "sync" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/ir" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/ir" ) var targetPlugins = map[string]TargetPlugin{} @@ -24,7 +24,7 @@ type TargetPluginEval interface { Eval(context.Context, *EvalContext, ast.Value) (ast.Value, error) } -func (r *Rego) targetPlugin(tgt string) TargetPlugin { +func (*Rego) targetPlugin(tgt string) TargetPlugin { for _, p := range targetPlugins { if p.IsTarget(tgt) { return p diff --git a/vendor/github.com/open-policy-agent/opa/rego/rego.go b/vendor/github.com/open-policy-agent/opa/v1/rego/rego.go similarity index 92% rename from vendor/github.com/open-policy-agent/opa/rego/rego.go rename to vendor/github.com/open-policy-agent/opa/v1/rego/rego.go index 64b4b9b93e..fae39273af 100644 --- a/vendor/github.com/open-policy-agent/opa/rego/rego.go +++ b/vendor/github.com/open-policy-agent/opa/v1/rego/rego.go @@ -11,31 +11,32 @@ import ( "errors" "fmt" "io" + "maps" "strings" "time" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/bundle" bundleUtils "github.com/open-policy-agent/opa/internal/bundle" "github.com/open-policy-agent/opa/internal/compiler/wasm" "github.com/open-policy-agent/opa/internal/future" "github.com/open-policy-agent/opa/internal/planner" "github.com/open-policy-agent/opa/internal/rego/opa" "github.com/open-policy-agent/opa/internal/wasm/encoding" - "github.com/open-policy-agent/opa/ir" - "github.com/open-policy-agent/opa/loader" - "github.com/open-policy-agent/opa/metrics" - "github.com/open-policy-agent/opa/plugins" - "github.com/open-policy-agent/opa/resolver" - "github.com/open-policy-agent/opa/storage" - "github.com/open-policy-agent/opa/storage/inmem" - "github.com/open-policy-agent/opa/topdown" - "github.com/open-policy-agent/opa/topdown/builtins" - "github.com/open-policy-agent/opa/topdown/cache" - "github.com/open-policy-agent/opa/topdown/print" - "github.com/open-policy-agent/opa/tracing" - "github.com/open-policy-agent/opa/types" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/bundle" + "github.com/open-policy-agent/opa/v1/ir" + "github.com/open-policy-agent/opa/v1/loader" + "github.com/open-policy-agent/opa/v1/metrics" + "github.com/open-policy-agent/opa/v1/plugins" + "github.com/open-policy-agent/opa/v1/resolver" + "github.com/open-policy-agent/opa/v1/storage" + "github.com/open-policy-agent/opa/v1/storage/inmem" + "github.com/open-policy-agent/opa/v1/topdown" + "github.com/open-policy-agent/opa/v1/topdown/builtins" + "github.com/open-policy-agent/opa/v1/topdown/cache" + "github.com/open-policy-agent/opa/v1/topdown/print" + "github.com/open-policy-agent/opa/v1/tracing" + "github.com/open-policy-agent/opa/v1/types" + "github.com/open-policy-agent/opa/v1/util" ) const ( @@ -78,12 +79,8 @@ func (pr PartialResult) Rego(options ...func(*Rego)) *Rego { r := New(options...) // Propagate any custom builtins. - for k, v := range pr.builtinDecls { - r.builtinDecls[k] = v - } - for k, v := range pr.builtinFuncs { - r.builtinFuncs[k] = v - } + maps.Copy(r.builtinDecls, pr.builtinDecls) + maps.Copy(r.builtinFuncs, pr.builtinFuncs) return r } @@ -113,6 +110,7 @@ type EvalContext struct { compiledQuery compiledQuery unknowns []string disableInlining []ast.Ref + nondeterministicBuiltins bool parsedUnknowns []*ast.Term indexing bool earlyExit bool @@ -120,12 +118,14 @@ type EvalContext struct { interQueryBuiltinValueCache cache.InterQueryValueCache ndBuiltinCache builtins.NDBCache resolvers []refResolver + httpRoundTripper topdown.CustomizeRoundTripper sortSets bool copyMaps bool printHook print.Hook capabilities *ast.Capabilities strictBuiltinErrors bool virtualCache topdown.VirtualCache + baseCache topdown.BaseCache } func (e *EvalContext) RawInput() *interface{} { @@ -335,6 +335,13 @@ func EvalResolver(ref ast.Ref, r resolver.Resolver) EvalOption { } } +// EvalHTTPRoundTripper allows customizing the http.RoundTripper for this evaluation. +func EvalHTTPRoundTripper(t topdown.CustomizeRoundTripper) EvalOption { + return func(e *EvalContext) { + e.httpRoundTripper = t + } +} + // EvalSortSets causes the evaluator to sort sets before returning them as JSON arrays. func EvalSortSets(yes bool) EvalOption { return func(e *EvalContext) { @@ -356,14 +363,31 @@ func EvalPrintHook(ph print.Hook) EvalOption { } } -// EvalVirtualCache sets the topdown.VirtualCache to use for evaluation. This is -// optional, and if not set, the default cache is used. +// EvalVirtualCache sets the topdown.VirtualCache to use for evaluation. +// This is optional, and if not set, the default cache is used. func EvalVirtualCache(vc topdown.VirtualCache) EvalOption { return func(e *EvalContext) { e.virtualCache = vc } } +// EvalBaseCache sets the topdown.BaseCache to use for evaluation. +// This is optional, and if not set, the default cache is used. +func EvalBaseCache(bc topdown.BaseCache) EvalOption { + return func(e *EvalContext) { + e.baseCache = bc + } +} + +// EvalNondeterministicBuiltins causes non-deterministic builtins to be evalued +// during partial evaluation. This is needed to pull in external data, or validate +// a JWT, during PE, so that the result informs what queries are returned. +func EvalNondeterministicBuiltins(yes bool) EvalOption { + return func(e *EvalContext) { + e.nondeterministicBuiltins = yes + } +} + func (pq preparedQuery) Modules() map[string]*ast.Module { mods := make(map[string]*ast.Module) @@ -386,24 +410,25 @@ func (pq preparedQuery) Modules() map[string]*ast.Module { // been opened. func (pq preparedQuery) newEvalContext(ctx context.Context, options []EvalOption) (*EvalContext, func(context.Context), error) { ectx := &EvalContext{ - hasInput: false, - rawInput: nil, - parsedInput: nil, - metrics: nil, - txn: nil, - instrument: false, - instrumentation: nil, - partialNamespace: pq.r.partialNamespace, - queryTracers: nil, - unknowns: pq.r.unknowns, - parsedUnknowns: pq.r.parsedUnknowns, - compiledQuery: compiledQuery{}, - indexing: true, - earlyExit: true, - resolvers: pq.r.resolvers, - printHook: pq.r.printHook, - capabilities: pq.r.capabilities, - strictBuiltinErrors: pq.r.strictBuiltinErrors, + hasInput: false, + rawInput: nil, + parsedInput: nil, + metrics: nil, + txn: nil, + instrument: false, + instrumentation: nil, + partialNamespace: pq.r.partialNamespace, + queryTracers: nil, + unknowns: pq.r.unknowns, + parsedUnknowns: pq.r.parsedUnknowns, + nondeterministicBuiltins: pq.r.nondeterministicBuiltins, + compiledQuery: compiledQuery{}, + indexing: true, + earlyExit: true, + resolvers: pq.r.resolvers, + printHook: pq.r.printHook, + capabilities: pq.r.capabilities, + strictBuiltinErrors: pq.r.strictBuiltinErrors, } for _, o := range options { @@ -572,6 +597,7 @@ type Rego struct { parsedUnknowns []*ast.Term disableInlining []string shallowInlining bool + nondeterministicBuiltins bool skipPartialNamespace bool partialNamespace string modules []rawModule @@ -621,6 +647,10 @@ type Rego struct { regoVersion ast.RegoVersion } +func (r *Rego) RegoVersion() ast.RegoVersion { + return r.regoVersion +} + // Function represents a built-in function that is callable in Rego. type Function struct { Name string @@ -801,7 +831,7 @@ func memoize(decl *Function, bctx BuiltinContext, terms []*ast.Term, ifEmpty fun // The term slice _may_ include an output term depending on how the caller // referred to the built-in function. Only use the arguments as the cache // key. Unification ensures we don't get false positive matches. - for i := 0; i < len(decl.Decl.Args()); i++ { + for i := range decl.Decl.Arity() { if _, err := b.WriteString(terms[i].String()); err != nil { return nil, err } @@ -910,6 +940,15 @@ func DisableInlining(paths []string) func(r *Rego) { } } +// NondeterministicBuiltins causes non-deterministic builtins to be evalued during +// partial evaluation. This is needed to pull in external data, or validate a JWT, +// during PE, so that the result informs what queries are returned. +func NondeterministicBuiltins(yes bool) func(r *Rego) { + return func(r *Rego) { + r.nondeterministicBuiltins = yes + } +} + // ShallowInlining prevents rules that depend on unknown values from being inlined. // Rules that only depend on known values are inlined. func ShallowInlining(yes bool) func(r *Rego) { @@ -1273,6 +1312,10 @@ func New(options ...func(r *Rego)) *Rego { if r.target == targetWasm { r.compiler = r.compiler.WithEvalMode(ast.EvalModeIR) } + + if r.regoVersion != ast.RegoUndefined { + r.compiler = r.compiler.WithDefaultRegoVersion(r.regoVersion) + } } if r.store == nil { @@ -1533,7 +1576,7 @@ func (r *Rego) Compile(ctx context.Context, opts ...CompileOption) (*CompileResu } if tgt := r.targetPlugin(r.target); tgt != nil { - return nil, fmt.Errorf("unsupported for rego target plugins") + return nil, errors.New("unsupported for rego target plugins") } return r.compileWasm(modules, queries, compileQueryType) // TODO(sr) control flow is funky here @@ -1593,10 +1636,9 @@ func WithNoInline(paths []string) PrepareOption { func WithBuiltinFuncs(bis map[string]*topdown.Builtin) PrepareOption { return func(p *PrepareConfig) { if p.builtinFuncs == nil { - p.builtinFuncs = make(map[string]*topdown.Builtin, len(bis)) - } - for k, v := range bis { - p.builtinFuncs[k] = v + p.builtinFuncs = maps.Clone(bis) + } else { + maps.Copy(p.builtinFuncs, bis) } } } @@ -1611,7 +1653,7 @@ func (p *PrepareConfig) BuiltinFuncs() map[string]*topdown.Builtin { // of evaluating them. func (r *Rego) PrepareForEval(ctx context.Context, opts ...PrepareOption) (PreparedEvalQuery, error) { if !r.hasQuery() { - return PreparedEvalQuery{}, fmt.Errorf("cannot evaluate empty query") + return PreparedEvalQuery{}, errors.New("cannot evaluate empty query") } pCfg := &PrepareConfig{} @@ -1665,7 +1707,7 @@ func (r *Rego) PrepareForEval(ctx context.Context, opts ...PrepareOption) (Prepa if r.hasWasmModule() { _ = txnClose(ctx, err) // Ignore error - return PreparedEvalQuery{}, fmt.Errorf("wasm target not supported") + return PreparedEvalQuery{}, errors.New("wasm target not supported") } var modules []*ast.Module @@ -1719,9 +1761,6 @@ func (r *Rego) PrepareForEval(ctx context.Context, opts ...PrepareOption) (Prepa } txnErr := txnClose(ctx, err) // Always call closer - if err != nil { - return PreparedEvalQuery{}, err - } if txnErr != nil { return PreparedEvalQuery{}, txnErr } @@ -1733,7 +1772,7 @@ func (r *Rego) PrepareForEval(ctx context.Context, opts ...PrepareOption) (Prepa // of partially evaluating them. func (r *Rego) PrepareForPartial(ctx context.Context, opts ...PrepareOption) (PreparedPartialQuery, error) { if !r.hasQuery() { - return PreparedPartialQuery{}, fmt.Errorf("cannot evaluate empty query") + return PreparedPartialQuery{}, errors.New("cannot evaluate empty query") } pCfg := &PrepareConfig{} @@ -1897,6 +1936,7 @@ func (r *Rego) loadFiles(ctx context.Context, txn storage.Transaction, m metrics WithMetrics(m). WithProcessAnnotation(true). WithRegoVersion(r.regoVersion). + WithCapabilities(r.capabilities). Filtered(r.loadPaths.paths, r.loadPaths.filter) if err != nil { return err @@ -1928,6 +1968,7 @@ func (r *Rego) loadBundles(_ context.Context, _ storage.Transaction, m metrics.M WithProcessAnnotation(true). WithSkipBundleVerification(r.skipBundleVerification). WithRegoVersion(r.regoVersion). + WithCapabilities(r.capabilities). AsBundle(path) if err != nil { return fmt.Errorf("loading error: %s", err) @@ -1944,7 +1985,7 @@ func (r *Rego) parseInput() (ast.Value, error) { return r.parseRawInput(r.rawInput, r.metrics) } -func (r *Rego) parseRawInput(rawInput *interface{}, m metrics.Metrics) (ast.Value, error) { +func (*Rego) parseRawInput(rawInput *interface{}, m metrics.Metrics) (ast.Value, error) { var input ast.Value if rawInput == nil { @@ -2147,7 +2188,8 @@ func (r *Rego) eval(ctx context.Context, ectx *EvalContext) (ResultSet, error) { WithSeed(ectx.seed). WithPrintHook(ectx.printHook). WithDistributedTracingOpts(r.distributedTacingOpts). - WithVirtualCache(ectx.virtualCache) + WithVirtualCache(ectx.virtualCache). + WithBaseCache(ectx.baseCache) if !ectx.time.IsZero() { q = q.WithTime(ectx.time) @@ -2165,6 +2207,10 @@ func (r *Rego) eval(ctx context.Context, ectx *EvalContext) (ResultSet, error) { q = q.WithInput(ast.NewTerm(ectx.parsedInput)) } + if ectx.httpRoundTripper != nil { + q = q.WithHTTPRoundTripper(ectx.httpRoundTripper) + } + for i := range ectx.resolvers { q = q.WithResolver(ectx.resolvers[i].ref, ectx.resolvers[i].r) } @@ -2230,7 +2276,7 @@ func (r *Rego) evalWasm(ctx context.Context, ectx *EvalContext) (ResultSet, erro func (r *Rego) valueToQueryResult(res ast.Value, ectx *EvalContext) (ResultSet, error) { resultSet, ok := res.(ast.Set) if !ok { - return nil, fmt.Errorf("illegal result type") + return nil, errors.New("illegal result type") } if resultSet.Len() == 0 { @@ -2241,7 +2287,7 @@ func (r *Rego) valueToQueryResult(res ast.Value, ectx *EvalContext) (ResultSet, err := resultSet.Iter(func(term *ast.Term) error { obj, ok := term.Value.(ast.Object) if !ok { - return fmt.Errorf("illegal result type") + return errors.New("illegal result type") } qr := topdown.QueryResult{} obj.Foreach(func(k, v *ast.Term) { @@ -2315,17 +2361,18 @@ func (r *Rego) partialResult(ctx context.Context, pCfg *PrepareConfig) (PartialR } ectx := &EvalContext{ - parsedInput: r.parsedInput, - metrics: r.metrics, - txn: r.txn, - partialNamespace: r.partialNamespace, - queryTracers: r.queryTracers, - compiledQuery: r.compiledQueries[partialResultQueryType], - instrumentation: r.instrumentation, - indexing: true, - resolvers: r.resolvers, - capabilities: r.capabilities, - strictBuiltinErrors: r.strictBuiltinErrors, + parsedInput: r.parsedInput, + metrics: r.metrics, + txn: r.txn, + partialNamespace: r.partialNamespace, + queryTracers: r.queryTracers, + compiledQuery: r.compiledQueries[partialResultQueryType], + instrumentation: r.instrumentation, + indexing: true, + resolvers: r.resolvers, + capabilities: r.capabilities, + strictBuiltinErrors: r.strictBuiltinErrors, + nondeterministicBuiltins: r.nondeterministicBuiltins, } disableInlining := r.disableInlining @@ -2347,9 +2394,10 @@ func (r *Rego) partialResult(ctx context.Context, pCfg *PrepareConfig) (PartialR // Construct module for queries. id := fmt.Sprintf("__partialresult__%s__", ectx.partialNamespace) - module, err := ast.ParseModule(id, "package "+ectx.partialNamespace) + module, err := ast.ParseModuleWithOpts(id, "package "+ectx.partialNamespace, + ast.ParserOptions{RegoVersion: r.regoVersion}) if err != nil { - return PartialResult{}, fmt.Errorf("bad partial namespace") + return PartialResult{}, errors.New("bad partial namespace") } module.Rules = make([]*ast.Rule, len(pq.Queries)) @@ -2421,6 +2469,7 @@ func (r *Rego) partial(ctx context.Context, ectx *EvalContext) (*PartialQueries, WithInstrumentation(ectx.instrumentation). WithUnknowns(unknowns). WithDisableInlining(ectx.disableInlining). + WithNondeterministicBuiltins(ectx.nondeterministicBuiltins). WithRuntime(r.runtime). WithIndexing(ectx.indexing). WithEarlyExit(ectx.earlyExit). @@ -2468,7 +2517,10 @@ func (r *Rego) partial(ctx context.Context, ectx *EvalContext) (*PartialQueries, } // If the target rego-version is v0, and the rego.v1 import is available, then we attempt to apply it to support modules. - if r.regoVersion == ast.RegoV0 && (r.capabilities == nil || r.capabilities.ContainsFeature(ast.FeatureRegoV1Import)) { + if r.regoVersion == ast.RegoV0 && + (r.capabilities == nil || + r.capabilities.ContainsFeature(ast.FeatureRegoV1Import) || + r.capabilities.ContainsFeature(ast.FeatureRegoV1)) { for i, mod := range support { // We can't apply the RegoV0CompatV1 version to the support module if it contains rules or vars that @@ -2480,7 +2532,7 @@ func (r *Rego) partial(ctx context.Context, ectx *EvalContext) (*PartialQueries, if name == "" && len(r.Head.Reference) > 0 { name = r.Head.Reference[0].Value.(ast.Var) } - if ast.IsFutureKeyword(name.String()) { + if ast.IsFutureKeywordForRegoVersion(name.String(), ast.RegoV0) { applyRegoVersion = false return true } @@ -2489,7 +2541,7 @@ func (r *Rego) partial(ctx context.Context, ectx *EvalContext) (*PartialQueries, if applyRegoVersion { ast.WalkVars(mod, func(v ast.Var) bool { - if ast.IsFutureKeyword(v.String()) { + if ast.IsFutureKeywordForRegoVersion(v.String(), ast.RegoV0) { applyRegoVersion = false return true } @@ -2563,23 +2615,23 @@ func (r *Rego) rewriteQueryToCaptureValue(_ ast.QueryCompiler, query ast.Body) ( return query, nil } -func (r *Rego) rewriteQueryForPartialEval(_ ast.QueryCompiler, query ast.Body) (ast.Body, error) { +func (*Rego) rewriteQueryForPartialEval(_ ast.QueryCompiler, query ast.Body) (ast.Body, error) { if len(query) != 1 { - return nil, fmt.Errorf("partial evaluation requires single ref (not multiple expressions)") + return nil, errors.New("partial evaluation requires single ref (not multiple expressions)") } term, ok := query[0].Terms.(*ast.Term) if !ok { - return nil, fmt.Errorf("partial evaluation requires ref (not expression)") + return nil, errors.New("partial evaluation requires ref (not expression)") } ref, ok := term.Value.(ast.Ref) if !ok { - return nil, fmt.Errorf("partial evaluation requires ref (not %v)", ast.TypeName(term.Value)) + return nil, fmt.Errorf("partial evaluation requires ref (not %v)", ast.ValueName(term.Value)) } if !ref.IsGround() { - return nil, fmt.Errorf("partial evaluation requires ground ref") + return nil, errors.New("partial evaluation requires ground ref") } return ast.NewBody(ast.Equality.Expr(ast.Wildcard, term)), nil @@ -2589,7 +2641,7 @@ func (r *Rego) rewriteQueryForPartialEval(_ ast.QueryCompiler, query ast.Body) ( // this wouldn't be done, except for handling queries with the `Partial` API // where rewriting them can substantially simplify the result, and it is unlikely // that the caller would need expression values. -func (r *Rego) rewriteEqualsForPartialQueryCompile(_ ast.QueryCompiler, query ast.Body) (ast.Body, error) { +func (*Rego) rewriteEqualsForPartialQueryCompile(_ ast.QueryCompiler, query ast.Body) (ast.Body, error) { doubleEq := ast.Equal.Ref() unifyOp := ast.Equality.Ref() ast.WalkExprs(query, func(x *ast.Expr) bool { @@ -2798,17 +2850,26 @@ func parseStringsToRefs(s []string) ([]ast.Ref, error) { func finishFunction(name string, bctx topdown.BuiltinContext, result *ast.Term, err error, iter func(*ast.Term) error) error { if err != nil { var e *HaltError + sb := strings.Builder{} if errors.As(err, &e) { + sb.Grow(len(name) + len(e.Error()) + 2) + sb.WriteString(name) + sb.WriteString(": ") + sb.WriteString(e.Error()) tdErr := &topdown.Error{ Code: topdown.BuiltinErr, - Message: fmt.Sprintf("%v: %v", name, e.Error()), + Message: sb.String(), Location: bctx.Location, } return topdown.Halt{Err: tdErr.Wrap(e)} } + sb.Grow(len(name) + len(err.Error()) + 2) + sb.WriteString(name) + sb.WriteString(": ") + sb.WriteString(err.Error()) tdErr := &topdown.Error{ Code: topdown.BuiltinErr, - Message: fmt.Sprintf("%v: %v", name, err.Error()), + Message: sb.String(), Location: bctx.Location, } return tdErr.Wrap(err) @@ -2849,14 +2910,8 @@ func (r *Rego) planQuery(queries []ast.Body, evalQueryType queryType) (*ir.Polic } decls := make(map[string]*ast.Builtin, len(r.builtinDecls)+len(ast.BuiltinMap)) - - for k, v := range ast.BuiltinMap { - decls[k] = v - } - - for k, v := range r.builtinDecls { - decls[k] = v - } + maps.Copy(decls, ast.BuiltinMap) + maps.Copy(decls, r.builtinDecls) const queryName = "eval" // NOTE(tsandall): the query name is arbitrary diff --git a/vendor/github.com/open-policy-agent/opa/rego/resultset.go b/vendor/github.com/open-policy-agent/opa/v1/rego/resultset.go similarity index 98% rename from vendor/github.com/open-policy-agent/opa/rego/resultset.go rename to vendor/github.com/open-policy-agent/opa/v1/rego/resultset.go index e60fa6fbe4..cc0710426e 100644 --- a/vendor/github.com/open-policy-agent/opa/rego/resultset.go +++ b/vendor/github.com/open-policy-agent/opa/v1/rego/resultset.go @@ -3,7 +3,7 @@ package rego import ( "fmt" - "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/v1/ast" ) // ResultSet represents a collection of output from Rego evaluation. An empty diff --git a/vendor/github.com/open-policy-agent/opa/resolver/interface.go b/vendor/github.com/open-policy-agent/opa/v1/resolver/interface.go similarity index 86% rename from vendor/github.com/open-policy-agent/opa/resolver/interface.go rename to vendor/github.com/open-policy-agent/opa/v1/resolver/interface.go index fc02329f57..1f04d21c01 100644 --- a/vendor/github.com/open-policy-agent/opa/resolver/interface.go +++ b/vendor/github.com/open-policy-agent/opa/v1/resolver/interface.go @@ -7,8 +7,8 @@ package resolver import ( "context" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/metrics" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/metrics" ) // Resolver defines an external value resolver for OPA evaluations. diff --git a/vendor/github.com/open-policy-agent/opa/resolver/wasm/wasm.go b/vendor/github.com/open-policy-agent/opa/v1/resolver/wasm/wasm.go similarity index 94% rename from vendor/github.com/open-policy-agent/opa/resolver/wasm/wasm.go rename to vendor/github.com/open-policy-agent/opa/v1/resolver/wasm/wasm.go index 9c13879dc3..c70daa8db6 100644 --- a/vendor/github.com/open-policy-agent/opa/resolver/wasm/wasm.go +++ b/vendor/github.com/open-policy-agent/opa/v1/resolver/wasm/wasm.go @@ -6,12 +6,13 @@ package wasm import ( "context" + "errors" "fmt" "strconv" - "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/internal/rego/opa" - "github.com/open-policy-agent/opa/resolver" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/resolver" ) // New creates a new Resolver instance which is using the Wasm module @@ -144,7 +145,7 @@ func getResult(evalResult *opa.Result) (ast.Value, error) { resultSet, ok := parsed.Value.(ast.Set) if !ok { - return nil, fmt.Errorf("illegal result type") + return nil, errors.New("illegal result type") } if resultSet.Len() == 0 { @@ -152,14 +153,14 @@ func getResult(evalResult *opa.Result) (ast.Value, error) { } if resultSet.Len() > 1 { - return nil, fmt.Errorf("illegal result type") + return nil, errors.New("illegal result type") } var obj ast.Object err = resultSet.Iter(func(term *ast.Term) error { obj, ok = term.Value.(ast.Object) if !ok || obj.Len() != 1 { - return fmt.Errorf("illegal result type") + return errors.New("illegal result type") } return nil }) diff --git a/vendor/github.com/open-policy-agent/opa/schemas/authorizationPolicy.json b/vendor/github.com/open-policy-agent/opa/v1/schemas/authorizationPolicy.json similarity index 100% rename from vendor/github.com/open-policy-agent/opa/schemas/authorizationPolicy.json rename to vendor/github.com/open-policy-agent/opa/v1/schemas/authorizationPolicy.json diff --git a/vendor/github.com/open-policy-agent/opa/schemas/schemas.go b/vendor/github.com/open-policy-agent/opa/v1/schemas/schemas.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/schemas/schemas.go rename to vendor/github.com/open-policy-agent/opa/v1/schemas/schemas.go diff --git a/vendor/github.com/open-policy-agent/opa/storage/doc.go b/vendor/github.com/open-policy-agent/opa/v1/storage/doc.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/storage/doc.go rename to vendor/github.com/open-policy-agent/opa/v1/storage/doc.go diff --git a/vendor/github.com/open-policy-agent/opa/storage/errors.go b/vendor/github.com/open-policy-agent/opa/v1/storage/errors.go similarity index 98% rename from vendor/github.com/open-policy-agent/opa/storage/errors.go rename to vendor/github.com/open-policy-agent/opa/v1/storage/errors.go index 8c789052ed..a3d1c00737 100644 --- a/vendor/github.com/open-policy-agent/opa/storage/errors.go +++ b/vendor/github.com/open-policy-agent/opa/v1/storage/errors.go @@ -56,8 +56,7 @@ func (err *Error) Error() string { // IsNotFound returns true if this error is a NotFoundErr. func IsNotFound(err error) bool { - switch err := err.(type) { - case *Error: + if err, ok := err.(*Error); ok { return err.Code == NotFoundErr } return false diff --git a/vendor/github.com/open-policy-agent/opa/storage/inmem/ast.go b/vendor/github.com/open-policy-agent/opa/v1/storage/inmem/ast.go similarity index 94% rename from vendor/github.com/open-policy-agent/opa/storage/inmem/ast.go rename to vendor/github.com/open-policy-agent/opa/v1/storage/inmem/ast.go index 5a8a6743fa..9f14df0e5b 100644 --- a/vendor/github.com/open-policy-agent/opa/storage/inmem/ast.go +++ b/vendor/github.com/open-policy-agent/opa/v1/storage/inmem/ast.go @@ -8,10 +8,10 @@ import ( "fmt" "strconv" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/storage" - "github.com/open-policy-agent/opa/storage/internal/errors" - "github.com/open-policy-agent/opa/storage/internal/ptr" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/storage" + "github.com/open-policy-agent/opa/v1/storage/internal/errors" + "github.com/open-policy-agent/opa/v1/storage/internal/ptr" ) type updateAST struct { @@ -101,8 +101,7 @@ func newUpdateArrayAST(data *ast.Array, op storage.PatchOp, path storage.Path, i return nil, invalidPatchError("%v: invalid patch path", path) } - cpy := data.Copy() - cpy = cpy.Append(ast.NewTerm(value)) + cpy := data.Append(ast.NewTerm(value)) return &updateAST{path[:len(path)-1], false, cpy}, nil } @@ -114,7 +113,7 @@ func newUpdateArrayAST(data *ast.Array, op storage.PatchOp, path storage.Path, i switch op { case storage.AddOp: var results []*ast.Term - for i := 0; i < data.Len(); i++ { + for i := range data.Len() { if i == pos { results = append(results, ast.NewTerm(value)) } @@ -125,7 +124,7 @@ func newUpdateArrayAST(data *ast.Array, op storage.PatchOp, path storage.Path, i case storage.RemoveOp: var results []*ast.Term - for i := 0; i < data.Len(); i++ { + for i := range data.Len() { if i != pos { results = append(results, data.Elem(i)) } @@ -134,7 +133,7 @@ func newUpdateArrayAST(data *ast.Array, op storage.PatchOp, path storage.Path, i default: var results []*ast.Term - for i := 0; i < data.Len(); i++ { + for i := range data.Len() { if i == pos { results = append(results, ast.NewTerm(value)) } else { @@ -296,7 +295,7 @@ func removeInAstArray(arr *ast.Array, path storage.Path) (ast.Value, error) { if len(path) == 1 { var elems []*ast.Term // Note: possibly expensive operation for large data. - for i := 0; i < arr.Len(); i++ { + for i := range arr.Len() { if i == idx { continue } diff --git a/vendor/github.com/open-policy-agent/opa/storage/inmem/inmem.go b/vendor/github.com/open-policy-agent/opa/v1/storage/inmem/inmem.go similarity index 97% rename from vendor/github.com/open-policy-agent/opa/storage/inmem/inmem.go rename to vendor/github.com/open-policy-agent/opa/v1/storage/inmem/inmem.go index 9f5b8ba258..c70d234d74 100644 --- a/vendor/github.com/open-policy-agent/opa/storage/inmem/inmem.go +++ b/vendor/github.com/open-policy-agent/opa/v1/storage/inmem/inmem.go @@ -24,10 +24,10 @@ import ( "sync" "sync/atomic" - "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/internal/merge" - "github.com/open-policy-agent/opa/storage" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/storage" + "github.com/open-policy-agent/opa/v1/util" ) // New returns an empty in-memory store. @@ -185,7 +185,9 @@ func (db *store) Truncate(ctx context.Context, txn storage.Transaction, params s } } - if err != nil && err != io.EOF { + // err is known not to be nil at this point, as it getting assigned + // a non-nil value is the only way the loop above can exit. + if err != io.EOF { return err } @@ -442,7 +444,7 @@ func lookup(path storage.Path, data map[string]interface{}) (interface{}, bool) if len(path) == 0 { return data, true } - for i := 0; i < len(path)-1; i++ { + for i := range len(path) - 1 { value, ok := data[path[i]] if !ok { return nil, false diff --git a/vendor/github.com/open-policy-agent/opa/storage/inmem/opts.go b/vendor/github.com/open-policy-agent/opa/v1/storage/inmem/opts.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/storage/inmem/opts.go rename to vendor/github.com/open-policy-agent/opa/v1/storage/inmem/opts.go diff --git a/vendor/github.com/open-policy-agent/opa/storage/inmem/txn.go b/vendor/github.com/open-policy-agent/opa/v1/storage/inmem/txn.go similarity index 98% rename from vendor/github.com/open-policy-agent/opa/storage/inmem/txn.go rename to vendor/github.com/open-policy-agent/opa/v1/storage/inmem/txn.go index d3252e8822..f8a7303912 100644 --- a/vendor/github.com/open-policy-agent/opa/storage/inmem/txn.go +++ b/vendor/github.com/open-policy-agent/opa/v1/storage/inmem/txn.go @@ -9,11 +9,11 @@ import ( "encoding/json" "strconv" - "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/internal/deepcopy" - "github.com/open-policy-agent/opa/storage" - "github.com/open-policy-agent/opa/storage/internal/errors" - "github.com/open-policy-agent/opa/storage/internal/ptr" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/storage" + "github.com/open-policy-agent/opa/v1/storage/internal/errors" + "github.com/open-policy-agent/opa/v1/storage/internal/ptr" ) // transaction implements the low-level read/write operations on the in-memory diff --git a/vendor/github.com/open-policy-agent/opa/storage/interface.go b/vendor/github.com/open-policy-agent/opa/v1/storage/interface.go similarity index 99% rename from vendor/github.com/open-policy-agent/opa/storage/interface.go rename to vendor/github.com/open-policy-agent/opa/v1/storage/interface.go index 6baca9a59f..94e02a47bc 100644 --- a/vendor/github.com/open-policy-agent/opa/storage/interface.go +++ b/vendor/github.com/open-policy-agent/opa/v1/storage/interface.go @@ -7,7 +7,7 @@ package storage import ( "context" - "github.com/open-policy-agent/opa/metrics" + "github.com/open-policy-agent/opa/v1/metrics" ) // Transaction defines the interface that identifies a consistent snapshot over diff --git a/vendor/github.com/open-policy-agent/opa/storage/internal/errors/errors.go b/vendor/github.com/open-policy-agent/opa/v1/storage/internal/errors/errors.go similarity index 85% rename from vendor/github.com/open-policy-agent/opa/storage/internal/errors/errors.go rename to vendor/github.com/open-policy-agent/opa/v1/storage/internal/errors/errors.go index 0bba74b907..778f30d1f4 100644 --- a/vendor/github.com/open-policy-agent/opa/storage/internal/errors/errors.go +++ b/vendor/github.com/open-policy-agent/opa/v1/storage/internal/errors/errors.go @@ -8,7 +8,7 @@ package errors import ( "fmt" - "github.com/open-policy-agent/opa/storage" + "github.com/open-policy-agent/opa/v1/storage" ) const ArrayIndexTypeMsg = "array index must be integer" @@ -20,7 +20,11 @@ func NewNotFoundError(path storage.Path) *storage.Error { } func NewNotFoundErrorWithHint(path storage.Path, hint string) *storage.Error { - return NewNotFoundErrorf("%v: %v", path.String(), hint) + message := path.String() + ": " + hint + return &storage.Error{ + Code: storage.NotFoundErr, + Message: message, + } } func NewNotFoundErrorf(f string, a ...interface{}) *storage.Error { diff --git a/vendor/github.com/open-policy-agent/opa/storage/internal/ptr/ptr.go b/vendor/github.com/open-policy-agent/opa/v1/storage/internal/ptr/ptr.go similarity index 83% rename from vendor/github.com/open-policy-agent/opa/storage/internal/ptr/ptr.go rename to vendor/github.com/open-policy-agent/opa/v1/storage/internal/ptr/ptr.go index 14adbd682e..902e73546e 100644 --- a/vendor/github.com/open-policy-agent/opa/storage/internal/ptr/ptr.go +++ b/vendor/github.com/open-policy-agent/opa/v1/storage/internal/ptr/ptr.go @@ -8,9 +8,9 @@ package ptr import ( "strconv" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/storage" - "github.com/open-policy-agent/opa/storage/internal/errors" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/storage" + "github.com/open-policy-agent/opa/v1/storage/internal/errors" ) func Ptr(data interface{}, path storage.Path) (interface{}, error) { @@ -43,8 +43,15 @@ func ValuePtr(data ast.Value, path storage.Path) (ast.Value, error) { key := path[i] switch curr := node.(type) { case ast.Object: - keyTerm := ast.StringTerm(key) + // This term is only created for the lookup, which is not.. ideal. + // By using the pool, we can at least avoid allocating the term itself, + // while still having to pay 1 allocation for the value. A better solution + // would be dynamically interned string terms. + keyTerm := ast.TermPtrPool.Get() + keyTerm.Value = ast.String(key) + val := curr.Get(keyTerm) + ast.TermPtrPool.Put(keyTerm) if val == nil { return nil, errors.NewNotFoundError(path) } diff --git a/vendor/github.com/open-policy-agent/opa/storage/path.go b/vendor/github.com/open-policy-agent/opa/v1/storage/path.go similarity index 88% rename from vendor/github.com/open-policy-agent/opa/storage/path.go rename to vendor/github.com/open-policy-agent/opa/v1/storage/path.go index 02ef4cab40..f774d2eeda 100644 --- a/vendor/github.com/open-policy-agent/opa/storage/path.go +++ b/vendor/github.com/open-policy-agent/opa/v1/storage/path.go @@ -5,12 +5,13 @@ package storage import ( + "errors" "fmt" "net/url" "strconv" "strings" - "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/v1/ast" ) // Path refers to a document in storage. @@ -50,7 +51,7 @@ func ParsePathEscaped(str string) (path Path, ok bool) { func NewPathForRef(ref ast.Ref) (path Path, err error) { if len(ref) == 0 { - return nil, fmt.Errorf("empty reference (indicates error in caller)") + return nil, errors.New("empty reference (indicates error in caller)") } if len(ref) == 1 { @@ -84,11 +85,7 @@ func NewPathForRef(ref ast.Ref) (path Path, err error) { // is less than other, 0 if p is equal to other, or 1 if p is greater than // other. func (p Path) Compare(other Path) (cmp int) { - min := len(p) - if len(other) < min { - min = len(other) - } - for i := 0; i < min; i++ { + for i := range min(len(p), len(other)) { if cmp := strings.Compare(p[i], other[i]); cmp != 0 { return cmp } @@ -136,11 +133,22 @@ func (p Path) Ref(head *ast.Term) (ref ast.Ref) { } func (p Path) String() string { - buf := make([]string, len(p)) - for i := range buf { - buf[i] = url.PathEscape(p[i]) + if len(p) == 0 { + return "/" + } + + l := 0 + for i := range p { + l += len(p[i]) + 1 + } + + sb := strings.Builder{} + sb.Grow(l) + for i := range p { + sb.WriteByte('/') + sb.WriteString(url.PathEscape(p[i])) } - return "/" + strings.Join(buf, "/") + return sb.String() } // MustParsePath returns a new Path for s. If s cannot be parsed, this function diff --git a/vendor/github.com/open-policy-agent/opa/storage/storage.go b/vendor/github.com/open-policy-agent/opa/v1/storage/storage.go similarity index 98% rename from vendor/github.com/open-policy-agent/opa/storage/storage.go rename to vendor/github.com/open-policy-agent/opa/v1/storage/storage.go index 2f8a39c597..34305f2912 100644 --- a/vendor/github.com/open-policy-agent/opa/storage/storage.go +++ b/vendor/github.com/open-policy-agent/opa/v1/storage/storage.go @@ -7,7 +7,7 @@ package storage import ( "context" - "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/v1/ast" ) // NewTransactionOrDie is a helper function to create a new transaction. If the diff --git a/vendor/github.com/open-policy-agent/opa/topdown/aggregates.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/aggregates.go similarity index 80% rename from vendor/github.com/open-policy-agent/opa/topdown/aggregates.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/aggregates.go index a0f67a7c95..fb59fd07f0 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/aggregates.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/aggregates.go @@ -7,20 +7,20 @@ package topdown import ( "math/big" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) func builtinCount(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { switch a := operands[0].Value.(type) { case *ast.Array: - return iter(ast.IntNumberTerm(a.Len())) + return iter(ast.InternedIntNumberTerm(a.Len())) case ast.Object: - return iter(ast.IntNumberTerm(a.Len())) + return iter(ast.InternedIntNumberTerm(a.Len())) case ast.Set: - return iter(ast.IntNumberTerm(a.Len())) + return iter(ast.InternedIntNumberTerm(a.Len())) case ast.String: - return iter(ast.IntNumberTerm(len([]rune(a)))) + return iter(ast.InternedIntNumberTerm(len([]rune(a)))) } return builtins.NewOperandTypeErr(1, operands[0].Value, "array", "object", "set", "string") } @@ -99,7 +99,7 @@ func builtinMax(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err if a.Len() == 0 { return nil } - var max = ast.Value(ast.Null{}) + max := ast.InternedNullTerm.Value a.Foreach(func(x *ast.Term) { if ast.Compare(max, x.Value) <= 0 { max = x.Value @@ -110,7 +110,7 @@ func builtinMax(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err if a.Len() == 0 { return nil } - max, err := a.Reduce(ast.NullTerm(), func(max *ast.Term, elem *ast.Term) (*ast.Term, error) { + max, err := a.Reduce(ast.InternedNullTerm, func(max *ast.Term, elem *ast.Term) (*ast.Term, error) { if ast.Compare(max, elem) <= 0 { return elem, nil } @@ -142,11 +142,11 @@ func builtinMin(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err if a.Len() == 0 { return nil } - min, err := a.Reduce(ast.NullTerm(), func(min *ast.Term, elem *ast.Term) (*ast.Term, error) { + min, err := a.Reduce(ast.InternedNullTerm, func(min *ast.Term, elem *ast.Term) (*ast.Term, error) { // The null term is considered to be less than any other term, // so in order for min of a set to make sense, we need to check // for it. - if min.Value.Compare(ast.Null{}) == 0 { + if min.Value.Compare(ast.InternedNullTerm.Value) == 0 { return elem, nil } @@ -178,7 +178,7 @@ func builtinAll(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err switch val := operands[0].Value.(type) { case ast.Set: res := true - match := ast.BooleanTerm(true) + match := ast.InternedBooleanTerm(true) val.Until(func(term *ast.Term) bool { if !match.Equal(term) { res = false @@ -186,10 +186,10 @@ func builtinAll(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err } return false }) - return iter(ast.BooleanTerm(res)) + return iter(ast.InternedBooleanTerm(res)) case *ast.Array: res := true - match := ast.BooleanTerm(true) + match := ast.InternedBooleanTerm(true) val.Until(func(term *ast.Term) bool { if !match.Equal(term) { res = false @@ -197,7 +197,7 @@ func builtinAll(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err } return false }) - return iter(ast.BooleanTerm(res)) + return iter(ast.InternedBooleanTerm(res)) default: return builtins.NewOperandTypeErr(1, operands[0].Value, "array", "set") } @@ -206,11 +206,11 @@ func builtinAll(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err func builtinAny(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { switch val := operands[0].Value.(type) { case ast.Set: - res := val.Len() > 0 && val.Contains(ast.BooleanTerm(true)) - return iter(ast.BooleanTerm(res)) + res := val.Len() > 0 && val.Contains(ast.InternedBooleanTerm(true)) + return iter(ast.InternedBooleanTerm(res)) case *ast.Array: res := false - match := ast.BooleanTerm(true) + match := ast.InternedBooleanTerm(true) val.Until(func(term *ast.Term) bool { if match.Equal(term) { res = true @@ -218,7 +218,7 @@ func builtinAny(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err } return false }) - return iter(ast.BooleanTerm(res)) + return iter(ast.InternedBooleanTerm(res)) default: return builtins.NewOperandTypeErr(1, operands[0].Value, "array", "set") } @@ -228,27 +228,20 @@ func builtinMember(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) containee := operands[0] switch c := operands[1].Value.(type) { case ast.Set: - return iter(ast.BooleanTerm(c.Contains(containee))) + return iter(ast.InternedBooleanTerm(c.Contains(containee))) case *ast.Array: - ret := false - c.Until(func(v *ast.Term) bool { - if v.Value.Compare(containee.Value) == 0 { - ret = true + for i := range c.Len() { + if c.Elem(i).Value.Compare(containee.Value) == 0 { + return iter(ast.InternedBooleanTerm(true)) } - return ret - }) - return iter(ast.BooleanTerm(ret)) + } + return iter(ast.InternedBooleanTerm(false)) case ast.Object: - ret := false - c.Until(func(_, v *ast.Term) bool { - if v.Value.Compare(containee.Value) == 0 { - ret = true - } - return ret - }) - return iter(ast.BooleanTerm(ret)) + return iter(ast.InternedBooleanTerm(c.Until(func(_, v *ast.Term) bool { + return v.Value.Compare(containee.Value) == 0 + }))) } - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } func builtinMemberWithKey(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -259,9 +252,9 @@ func builtinMemberWithKey(_ BuiltinContext, operands []*ast.Term, iter func(*ast if act := c.Get(key); act != nil { ret = act.Value.Compare(val.Value) == 0 } - return iter(ast.BooleanTerm(ret)) + return iter(ast.InternedBooleanTerm(ret)) } - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } func init() { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/arithmetic.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/arithmetic.go similarity index 92% rename from vendor/github.com/open-policy-agent/opa/topdown/arithmetic.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/arithmetic.go index 3ac703efa3..acfbba3c74 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/arithmetic.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/arithmetic.go @@ -5,11 +5,11 @@ package topdown import ( - "fmt" + "errors" "math/big" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) type arithArity1 func(a *big.Float) (*big.Float, error) @@ -67,7 +67,7 @@ func builtinPlus(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) er y, ok2 := n2.Int() if ok1 && ok2 && inSmallIntRange(x) && inSmallIntRange(y) { - return iter(ast.IntNumberTerm(x + y)) + return iter(ast.InternedIntNumberTerm(x + y)) } f, err := arithPlus(builtins.NumberToFloat(n1), builtins.NumberToFloat(n2)) @@ -91,7 +91,7 @@ func builtinMultiply(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term y, ok2 := n2.Int() if ok1 && ok2 && inSmallIntRange(x) && inSmallIntRange(y) { - return iter(ast.IntNumberTerm(x * y)) + return iter(ast.InternedIntNumberTerm(x * y)) } f, err := arithMultiply(builtins.NumberToFloat(n1), builtins.NumberToFloat(n2)) @@ -116,14 +116,14 @@ func arithMultiply(a, b *big.Float) (*big.Float, error) { func arithDivide(a, b *big.Float) (*big.Float, error) { i, acc := b.Int64() if acc == big.Exact && i == 0 { - return nil, fmt.Errorf("divide by zero") + return nil, errors.New("divide by zero") } return new(big.Float).Quo(a, b), nil } func arithRem(a, b *big.Int) (*big.Int, error) { if b.Int64() == 0 { - return nil, fmt.Errorf("modulo by zero") + return nil, errors.New("modulo by zero") } return new(big.Int).Rem(a, b), nil } @@ -171,7 +171,7 @@ func builtinMinus(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) e y, oky := n2.Int() if okx && oky && inSmallIntRange(x) && inSmallIntRange(y) { - return iter(ast.IntNumberTerm(x - y)) + return iter(ast.InternedIntNumberTerm(x - y)) } f, err := arithMinus(builtins.NumberToFloat(n1), builtins.NumberToFloat(n2)) @@ -210,17 +210,17 @@ func builtinRem(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err if okx && oky && inSmallIntRange(x) && inSmallIntRange(y) { if y == 0 { - return fmt.Errorf("modulo by zero") + return errors.New("modulo by zero") } - return iter(ast.IntNumberTerm(x % y)) + return iter(ast.InternedIntNumberTerm(x % y)) } op1, err1 := builtins.NumberToInt(n1) op2, err2 := builtins.NumberToInt(n2) if err1 != nil || err2 != nil { - return fmt.Errorf("modulo on floating-point number") + return errors.New("modulo on floating-point number") } i, err := arithRem(op1, op2) diff --git a/vendor/github.com/open-policy-agent/opa/topdown/array.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/array.go similarity index 86% rename from vendor/github.com/open-policy-agent/opa/topdown/array.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/array.go index e7fe5be643..526e3ed26d 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/array.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/array.go @@ -5,8 +5,8 @@ package topdown import ( - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) func builtinArrayConcat(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -20,6 +20,13 @@ func builtinArrayConcat(_ BuiltinContext, operands []*ast.Term, iter func(*ast.T return err } + if arrA.Len() == 0 { + return iter(operands[1]) + } + if arrB.Len() == 0 { + return iter(operands[0]) + } + arrC := make([]*ast.Term, arrA.Len()+arrB.Len()) i := 0 @@ -33,7 +40,7 @@ func builtinArrayConcat(_ BuiltinContext, operands []*ast.Term, iter func(*ast.T i++ }) - return iter(ast.NewTerm(ast.NewArray(arrC...))) + return iter(ast.ArrayTerm(arrC...)) } func builtinArraySlice(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -68,6 +75,10 @@ func builtinArraySlice(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Te startIndex = stopIndex } + if startIndex == 0 && stopIndex >= arr.Len() { + return iter(operands[0]) + } + return iter(ast.NewTerm(arr.Slice(startIndex, stopIndex))) } @@ -80,7 +91,7 @@ func builtinArrayReverse(_ BuiltinContext, operands []*ast.Term, iter func(*ast. length := arr.Len() reversedArr := make([]*ast.Term, length) - for index := 0; index < length; index++ { + for index := range length { reversedArr[index] = arr.Elem(length - index - 1) } diff --git a/vendor/github.com/open-policy-agent/opa/topdown/binary.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/binary.go similarity index 90% rename from vendor/github.com/open-policy-agent/opa/topdown/binary.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/binary.go index b4f9dbd392..6f7ebaf40c 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/binary.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/binary.go @@ -5,8 +5,8 @@ package topdown import ( - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) func builtinBinaryAnd(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/bindings.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/bindings.go similarity index 95% rename from vendor/github.com/open-policy-agent/opa/topdown/bindings.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/bindings.go index 30a8ac5ec4..8c7bfbd178 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/bindings.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/bindings.go @@ -6,9 +6,10 @@ package topdown import ( "fmt" + "strconv" "strings" - "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/v1/ast" ) type undo struct { @@ -68,7 +69,7 @@ func (u *bindings) Plug(a *ast.Term) *ast.Term { } func (u *bindings) PlugNamespaced(a *ast.Term, caller *bindings) *ast.Term { - if u != nil { + if u != nil && u.instr != nil { u.instr.startTimer(evalOpPlug) t := u.plugNamespaced(a, caller) u.instr.stopTimer(evalOpPlug) @@ -184,7 +185,7 @@ func (u *bindings) namespaceVar(v *ast.Term, caller *bindings) *ast.Term { // Root documents (i.e., data, input) should never be namespaced because they // are globally unique. if !ast.RootDocumentNames.Contains(v) { - return ast.NewTerm(ast.Var(string(name) + fmt.Sprint(u.id))) + return ast.NewTerm(ast.Var(string(name) + strconv.FormatUint(u.id, 10))) } } return v @@ -313,12 +314,12 @@ func (b *bindingsArrayHashmap) Put(key *ast.Term, value value) { if b.a == nil { b.a = new([maxLinearScan]bindingArrayKeyValue) } else if i := b.find(key); i >= 0 { - (*b.a)[i].value = value + b.a[i].value = value return } if b.n < maxLinearScan { - (*b.a)[b.n] = bindingArrayKeyValue{key, value} + b.a[b.n] = bindingArrayKeyValue{key, value} b.n++ return } @@ -341,7 +342,7 @@ func (b *bindingsArrayHashmap) Put(key *ast.Term, value value) { func (b *bindingsArrayHashmap) Get(key *ast.Term) (value, bool) { if b.m == nil { if i := b.find(key); i >= 0 { - return (*b.a)[i].value, true + return b.a[i].value, true } return value{}, false @@ -360,7 +361,7 @@ func (b *bindingsArrayHashmap) Delete(key *ast.Term) { if i := b.find(key); i >= 0 { n := b.n - 1 if i < n { - (*b.a)[i] = (*b.a)[n] + b.a[i] = b.a[n] } b.n = n @@ -373,8 +374,8 @@ func (b *bindingsArrayHashmap) Delete(key *ast.Term) { func (b *bindingsArrayHashmap) Iter(f func(k *ast.Term, v value) bool) { if b.m == nil { - for i := 0; i < b.n; i++ { - if f((*b.a)[i].key, (*b.a)[i].value) { + for i := range b.n { + if f(b.a[i].key, b.a[i].value) { return } } @@ -390,8 +391,8 @@ func (b *bindingsArrayHashmap) Iter(f func(k *ast.Term, v value) bool) { func (b *bindingsArrayHashmap) find(key *ast.Term) int { v := key.Value.(ast.Var) - for i := 0; i < b.n; i++ { - if (*b.a)[i].key.Value.(ast.Var) == v { + for i := range b.n { + if b.a[i].key.Value.(ast.Var) == v { return i } } diff --git a/vendor/github.com/open-policy-agent/opa/topdown/bits.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/bits.go similarity index 96% rename from vendor/github.com/open-policy-agent/opa/topdown/bits.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/bits.go index 7a63c0df1e..e420ffe611 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/bits.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/bits.go @@ -7,8 +7,8 @@ package topdown import ( "math/big" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) type bitsArity1 func(a *big.Int) (*big.Int, error) diff --git a/vendor/github.com/open-policy-agent/opa/topdown/builtins.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/builtins.go similarity index 95% rename from vendor/github.com/open-policy-agent/opa/topdown/builtins.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/builtins.go index cf694d4331..e0b893d477 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/builtins.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/builtins.go @@ -11,12 +11,12 @@ import ( "io" "math/rand" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/metrics" - "github.com/open-policy-agent/opa/topdown/builtins" - "github.com/open-policy-agent/opa/topdown/cache" - "github.com/open-policy-agent/opa/topdown/print" - "github.com/open-policy-agent/opa/tracing" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/metrics" + "github.com/open-policy-agent/opa/v1/topdown/builtins" + "github.com/open-policy-agent/opa/v1/topdown/cache" + "github.com/open-policy-agent/opa/v1/topdown/print" + "github.com/open-policy-agent/opa/v1/tracing" ) type ( @@ -52,6 +52,7 @@ type ( QueryID uint64 // identifies query being evaluated ParentID uint64 // identifies parent of query being evaluated PrintHook print.Hook // provides callback function to use for printing + RoundTripper CustomizeRoundTripper // customize transport to use for HTTP requests DistributedTracingOpts tracing.Options // options to be used by distributed tracing. rand *rand.Rand // randomization source for non-security-sensitive operations Capabilities *ast.Capabilities diff --git a/vendor/github.com/open-policy-agent/opa/topdown/builtins/builtins.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/builtins/builtins.go similarity index 94% rename from vendor/github.com/open-policy-agent/opa/topdown/builtins/builtins.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/builtins/builtins.go index 353f956840..9fcaea4a23 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/builtins/builtins.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/builtins/builtins.go @@ -7,12 +7,13 @@ package builtins import ( "encoding/json" + "errors" "fmt" "math/big" "strings" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/util" ) // Cache defines the built-in cache used by the top-down evaluation. The keys @@ -97,7 +98,7 @@ func (c *NDBCache) UnmarshalJSON(data []byte) error { out[string(k.Value.(ast.String))] = obj return nil } - return fmt.Errorf("expected Object, got other Value type in conversion") + return errors.New("expected Object, got other Value type in conversion") }) if err != nil { return err @@ -128,23 +129,23 @@ func NewOperandErr(pos int, f string, a ...interface{}) error { func NewOperandTypeErr(pos int, got ast.Value, expected ...string) error { if len(expected) == 1 { - return NewOperandErr(pos, "must be %v but got %v", expected[0], ast.TypeName(got)) + return NewOperandErr(pos, "must be %v but got %v", expected[0], ast.ValueName(got)) } - return NewOperandErr(pos, "must be one of {%v} but got %v", strings.Join(expected, ", "), ast.TypeName(got)) + return NewOperandErr(pos, "must be one of {%v} but got %v", strings.Join(expected, ", "), ast.ValueName(got)) } // NewOperandElementErr returns an operand error indicating an element in the // composite operand was wrong. func NewOperandElementErr(pos int, composite ast.Value, got ast.Value, expected ...string) error { - tpe := ast.TypeName(composite) + tpe := ast.ValueName(composite) if len(expected) == 1 { - return NewOperandErr(pos, "must be %v of %vs but got %v containing %v", tpe, expected[0], tpe, ast.TypeName(got)) + return NewOperandErr(pos, "must be %v of %vs but got %v containing %v", tpe, expected[0], tpe, ast.ValueName(got)) } - return NewOperandErr(pos, "must be %v of (any of) {%v} but got %v containing %v", tpe, strings.Join(expected, ", "), tpe, ast.TypeName(got)) + return NewOperandErr(pos, "must be %v of (any of) {%v} but got %v containing %v", tpe, strings.Join(expected, ", "), tpe, ast.ValueName(got)) } // NewOperandEnumErr returns an operand error indicating a value was wrong. @@ -233,7 +234,7 @@ func ObjectOperand(x ast.Value, pos int) (ast.Object, error) { func ArrayOperand(x ast.Value, pos int) (*ast.Array, error) { a, ok := x.(*ast.Array) if !ok { - return ast.NewArray(), NewOperandTypeErr(pos, x, "array") + return nil, NewOperandTypeErr(pos, x, "array") } return a, nil } @@ -262,7 +263,7 @@ func NumberToInt(n ast.Number) (*big.Int, error) { f := NumberToFloat(n) r, accuracy := f.Int(nil) if accuracy != big.Exact { - return nil, fmt.Errorf("illegal value") + return nil, errors.New("illegal value") } return r, nil } @@ -309,7 +310,7 @@ func RuneSliceOperand(x ast.Value, pos int) ([]rune, error) { } var f = make([]rune, a.Len()) - for k := 0; k < a.Len(); k++ { + for k := range a.Len() { b := a.Elem(k) c, ok := b.Value.(ast.String) if !ok { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/cache.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/cache.go similarity index 84% rename from vendor/github.com/open-policy-agent/opa/topdown/cache.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/cache.go index 265457e02f..42fb6ad3f5 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/cache.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/cache.go @@ -5,8 +5,8 @@ package topdown import ( - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/util" ) // VirtualCache defines the interface for a cache that stores the results of @@ -32,13 +32,19 @@ type VirtualCache interface { Keys() []ast.Ref } +// BaseCache defines the interface for a cache that stores cached base documents, i.e. data. +type BaseCache interface { + Get(ast.Ref) ast.Value + Put(ast.Ref, ast.Value) +} + type virtualCache struct { stack []*virtualCacheElem } type virtualCacheElem struct { value *ast.Term - children *util.HashMap + children *util.HasherMap[*ast.Term, *virtualCacheElem] undefined bool } @@ -65,12 +71,12 @@ func (c *virtualCache) Pop() { // ast.Term, true is impossible func (c *virtualCache) Get(ref ast.Ref) (*ast.Term, bool) { node := c.stack[len(c.stack)-1] - for i := 0; i < len(ref); i++ { + for i := range ref { x, ok := node.children.Get(ref[i]) if !ok { return nil, false } - node = x.(*virtualCacheElem) + node = x } if node.undefined { return nil, true @@ -83,10 +89,10 @@ func (c *virtualCache) Get(ref ast.Ref) (*ast.Term, bool) { // indicate that the Ref has resolved to undefined. func (c *virtualCache) Put(ref ast.Ref, value *ast.Term) { node := c.stack[len(c.stack)-1] - for i := 0; i < len(ref); i++ { + for i := range ref { x, ok := node.children.Get(ref[i]) if ok { - node = x.(*virtualCacheElem) + node = x } else { next := newVirtualCacheElem() node.children.Put(ref[i], next) @@ -107,13 +113,13 @@ func (c *virtualCache) Keys() []ast.Ref { func keysRecursive(root ast.Ref, node *virtualCacheElem) []ast.Ref { var keys []ast.Ref - node.children.Iter(func(k, v util.T) bool { - ref := root.Append(k.(*ast.Term)) - if v.(*virtualCacheElem).value != nil { + node.children.Iter(func(k *ast.Term, v *virtualCacheElem) bool { + ref := root.Append(k) + if v.value != nil { keys = append(keys, ref) } - if v.(*virtualCacheElem).children.Len() > 0 { - keys = append(keys, keysRecursive(ref, v.(*virtualCacheElem))...) + if v.children.Len() > 0 { + keys = append(keys, keysRecursive(ref, v)...) } return false }) @@ -124,12 +130,8 @@ func newVirtualCacheElem() *virtualCacheElem { return &virtualCacheElem{children: newVirtualCacheHashMap()} } -func newVirtualCacheHashMap() *util.HashMap { - return util.NewHashMap(func(a, b util.T) bool { - return a.(*ast.Term).Equal(b.(*ast.Term)) - }, func(x util.T) int { - return x.(*ast.Term).Hash() - }) +func newVirtualCacheHashMap() *util.HasherMap[*ast.Term, *virtualCacheElem] { + return util.NewHasherMap[*ast.Term, *virtualCacheElem](ast.TermValueEqual) } // baseCache implements a trie structure to cache base documents read out of @@ -148,11 +150,17 @@ func newBaseCache() *baseCache { func (c *baseCache) Get(ref ast.Ref) ast.Value { node := c.root - for i := 0; i < len(ref); i++ { + for i := range ref { node = node.children[ref[i].Value] if node == nil { return nil } else if node.value != nil { + if len(ref) == 1 && ast.IsScalar(node.value) { + // If the node is a scalar, return the value directly + // and avoid an allocation when calling Find. + return node.value + } + result, err := node.value.Find(ref[i+1:]) if err != nil { return nil @@ -165,7 +173,7 @@ func (c *baseCache) Get(ref ast.Ref) ast.Value { func (c *baseCache) Put(ref ast.Ref, value ast.Value) { node := c.root - for i := 0; i < len(ref); i++ { + for i := range ref { if child, ok := node.children[ref[i].Value]; ok { node = child } else { @@ -232,7 +240,7 @@ type comprehensionCache struct { type comprehensionCacheElem struct { value *ast.Term - children *util.HashMap + children *util.HasherMap[*ast.Term, *comprehensionCacheElem] } func newComprehensionCache() *comprehensionCache { @@ -264,22 +272,22 @@ func newComprehensionCacheElem() *comprehensionCacheElem { func (c *comprehensionCacheElem) Get(key []*ast.Term) *ast.Term { node := c - for i := 0; i < len(key); i++ { + for i := range key { x, ok := node.children.Get(key[i]) if !ok { return nil } - node = x.(*comprehensionCacheElem) + node = x } return node.value } func (c *comprehensionCacheElem) Put(key []*ast.Term, value *ast.Term) { node := c - for i := 0; i < len(key); i++ { + for i := range key { x, ok := node.children.Get(key[i]) if ok { - node = x.(*comprehensionCacheElem) + node = x } else { next := newComprehensionCacheElem() node.children.Put(key[i], next) @@ -289,12 +297,8 @@ func (c *comprehensionCacheElem) Put(key []*ast.Term, value *ast.Term) { node.value = value } -func newComprehensionCacheHashMap() *util.HashMap { - return util.NewHashMap(func(a, b util.T) bool { - return a.(*ast.Term).Equal(b.(*ast.Term)) - }, func(x util.T) int { - return x.(*ast.Term).Hash() - }) +func newComprehensionCacheHashMap() *util.HasherMap[*ast.Term, *comprehensionCacheElem] { + return util.NewHasherMap[*ast.Term, *comprehensionCacheElem](ast.TermValueEqual) } type functionMocksStack struct { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/cache/cache.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/cache/cache.go similarity index 63% rename from vendor/github.com/open-policy-agent/opa/topdown/cache/cache.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/cache/cache.go index 55ed340619..60f38aaba2 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/cache/cache.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/cache/cache.go @@ -13,8 +13,8 @@ import ( "sync" "time" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/util" ) const ( @@ -24,16 +24,36 @@ const ( defaultStaleEntryEvictionPeriodSeconds = int64(0) // never ) +var interQueryBuiltinValueCacheDefaultConfigs = map[string]*NamedValueCacheConfig{} + +func getDefaultInterQueryBuiltinValueCacheConfig(name string) *NamedValueCacheConfig { + return interQueryBuiltinValueCacheDefaultConfigs[name] +} + +// RegisterDefaultInterQueryBuiltinValueCacheConfig registers a default configuration for the inter-query value cache; +// used when none has been explicitly configured. +// To disable a named cache when not configured, pass a nil config. +func RegisterDefaultInterQueryBuiltinValueCacheConfig(name string, config *NamedValueCacheConfig) { + interQueryBuiltinValueCacheDefaultConfigs[name] = config +} + // Config represents the configuration for the inter-query builtin cache. type Config struct { InterQueryBuiltinCache InterQueryBuiltinCacheConfig `json:"inter_query_builtin_cache"` InterQueryBuiltinValueCache InterQueryBuiltinValueCacheConfig `json:"inter_query_builtin_value_cache"` } +// NamedValueCacheConfig represents the configuration of a named cache that built-in functions can utilize. +// A default configuration to be used if not explicitly configured can be registered using RegisterDefaultInterQueryBuiltinValueCacheConfig. +type NamedValueCacheConfig struct { + MaxNumEntries *int `json:"max_num_entries,omitempty"` +} + // InterQueryBuiltinValueCacheConfig represents the configuration of the inter-query value cache that built-in functions can utilize. // MaxNumEntries - max number of cache entries type InterQueryBuiltinValueCacheConfig struct { - MaxNumEntries *int `json:"max_num_entries,omitempty"` + MaxNumEntries *int `json:"max_num_entries,omitempty"` + NamedCacheConfigs map[string]*NamedValueCacheConfig `json:"named,omitempty"` } // InterQueryBuiltinCacheConfig represents the configuration of the inter-query cache that built-in functions can utilize. @@ -59,8 +79,16 @@ func ParseCachingConfig(raw []byte) (*Config, error) { maxInterQueryBuiltinValueCacheSize := new(int) *maxInterQueryBuiltinValueCacheSize = defaultInterQueryBuiltinValueCacheSize - return &Config{InterQueryBuiltinCache: InterQueryBuiltinCacheConfig{MaxSizeBytes: maxSize, ForcedEvictionThresholdPercentage: threshold, StaleEntryEvictionPeriodSeconds: period}, - InterQueryBuiltinValueCache: InterQueryBuiltinValueCacheConfig{MaxNumEntries: maxInterQueryBuiltinValueCacheSize}}, nil + return &Config{ + InterQueryBuiltinCache: InterQueryBuiltinCacheConfig{ + MaxSizeBytes: maxSize, + ForcedEvictionThresholdPercentage: threshold, + StaleEntryEvictionPeriodSeconds: period, + }, + InterQueryBuiltinValueCache: InterQueryBuiltinValueCacheConfig{ + MaxNumEntries: maxInterQueryBuiltinValueCacheSize, + }, + }, nil } var config Config @@ -114,6 +142,13 @@ func (c *Config) validateAndInjectDefaults() error { } } + for name, namedConfig := range c.InterQueryBuiltinValueCache.NamedCacheConfigs { + numEntries := *namedConfig.MaxNumEntries + if numEntries < 0 { + return fmt.Errorf("invalid max_num_entries %v for named cache %v", numEntries, name) + } + } + return nil } @@ -154,11 +189,14 @@ func NewInterQueryCache(config *Config) InterQueryCache { func NewInterQueryCacheWithContext(ctx context.Context, config *Config) InterQueryCache { iqCache := newCache(config) if iqCache.staleEntryEvictionTimePeriodSeconds() > 0 { - cleanupTicker := time.NewTicker(time.Duration(iqCache.staleEntryEvictionTimePeriodSeconds()) * time.Second) go func() { + cleanupTicker := time.NewTicker(time.Duration(iqCache.staleEntryEvictionTimePeriodSeconds()) * time.Second) for { select { case <-cleanupTicker.C: + // NOTE: We stop the ticker and create a new one here to ensure that applications + // get _at least_ staleEntryEvictionTimePeriodSeconds with the cache unlocked; + // see https://github.com/open-policy-agent/opa/pull/7188/files#r1855342998 cleanupTicker.Stop() iqCache.cleanStaleValues() cleanupTicker = time.NewTicker(time.Duration(iqCache.staleEntryEvictionTimePeriodSeconds()) * time.Second) @@ -287,7 +325,7 @@ func (c *cache) unsafeDelete(k ast.Value) { c.l.Remove(cacheItem.keyElement) } -func (c *cache) unsafeClone(value InterQueryCacheValue) (InterQueryCacheValue, error) { +func (*cache) unsafeClone(value InterQueryCacheValue) (InterQueryCacheValue, error) { return value.Clone() } @@ -327,62 +365,59 @@ func (c *cache) cleanStaleValues() (dropped int) { return dropped } -type InterQueryValueCache interface { +type InterQueryValueCacheBucket interface { Get(key ast.Value) (value any, found bool) Insert(key ast.Value, value any) int Delete(key ast.Value) - UpdateConfig(config *Config) } -type interQueryValueCache struct { - items map[string]any - config *Config +type interQueryValueCacheBucket struct { + items util.HasherMap[ast.Value, any] + config *NamedValueCacheConfig mtx sync.RWMutex } -// Get returns the value in the cache for k. -func (c *interQueryValueCache) Get(k ast.Value) (any, bool) { +func newItemsMap() *util.HasherMap[ast.Value, any] { + return util.NewHasherMap[ast.Value, any](ast.ValueEqual) +} + +func (c *interQueryValueCacheBucket) Get(k ast.Value) (any, bool) { c.mtx.RLock() defer c.mtx.RUnlock() - value, ok := c.items[k.String()] - return value, ok + return c.items.Get(k) } -// Insert inserts a key k into the cache with value v. -func (c *interQueryValueCache) Insert(k ast.Value, v any) (dropped int) { +func (c *interQueryValueCacheBucket) Insert(k ast.Value, v any) (dropped int) { c.mtx.Lock() defer c.mtx.Unlock() maxEntries := c.maxNumEntries() if maxEntries > 0 { - if len(c.items) >= maxEntries { - itemsToRemove := len(c.items) - maxEntries + 1 + l := c.items.Len() + if l >= maxEntries { + itemsToRemove := l - maxEntries + 1 // Delete a (semi-)random key to make room for the new one. - for k := range c.items { - delete(c.items, k) + c.items.Iter(func(k ast.Value, _ any) bool { + c.items.Delete(k) dropped++ - if itemsToRemove == dropped { - break - } - } + return itemsToRemove == dropped + }) } } - c.items[k.String()] = v + c.items.Put(k, v) return dropped } -// Delete deletes the value in the cache for k. -func (c *interQueryValueCache) Delete(k ast.Value) { +func (c *interQueryValueCacheBucket) Delete(k ast.Value) { c.mtx.Lock() defer c.mtx.Unlock() - delete(c.items, k.String()) + c.items.Delete(k) } -// UpdateConfig updates the cache config. -func (c *interQueryValueCache) UpdateConfig(config *Config) { +func (c *interQueryValueCacheBucket) updateConfig(config *NamedValueCacheConfig) { if config == nil { return } @@ -391,16 +426,149 @@ func (c *interQueryValueCache) UpdateConfig(config *Config) { c.config = config } -func (c *interQueryValueCache) maxNumEntries() int { +func (c *interQueryValueCacheBucket) maxNumEntries() int { if c.config == nil { return defaultInterQueryBuiltinValueCacheSize } - return *c.config.InterQueryBuiltinValueCache.MaxNumEntries + return *c.config.MaxNumEntries +} + +type InterQueryValueCache interface { + InterQueryValueCacheBucket + GetCache(name string) InterQueryValueCacheBucket + UpdateConfig(config *Config) } func NewInterQueryValueCache(_ context.Context, config *Config) InterQueryValueCache { - return &interQueryValueCache{ - items: map[string]any{}, - config: config, + var c *InterQueryBuiltinValueCacheConfig + var nc *NamedValueCacheConfig + if config != nil { + c = &config.InterQueryBuiltinValueCache + // NOTE: This is a side-effect of reusing the interQueryValueCacheBucket as the global cache. + // It's a hidden implementation detail that we can clean up in the future when revisiting the named caches + // to automatically apply them to any built-in instead of the global cache. + nc = &NamedValueCacheConfig{ + MaxNumEntries: c.MaxNumEntries, + } + } + + return &interQueryBuiltinValueCache{ + globalCache: interQueryValueCacheBucket{ + items: *newItemsMap(), + config: nc, + }, + namedCaches: map[string]*interQueryValueCacheBucket{}, + config: c, + } +} + +type interQueryBuiltinValueCache struct { + globalCache interQueryValueCacheBucket + namedCachesLock sync.RWMutex + namedCaches map[string]*interQueryValueCacheBucket + config *InterQueryBuiltinValueCacheConfig +} + +func (c *interQueryBuiltinValueCache) Get(k ast.Value) (any, bool) { + if c == nil { + return nil, false + } + + return c.globalCache.Get(k) +} + +func (c *interQueryBuiltinValueCache) Insert(k ast.Value, v any) int { + if c == nil { + return 0 + } + + return c.globalCache.Insert(k, v) +} + +func (c *interQueryBuiltinValueCache) Delete(k ast.Value) { + if c == nil { + return + } + + c.globalCache.Delete(k) +} + +func (c *interQueryBuiltinValueCache) GetCache(name string) InterQueryValueCacheBucket { + if c == nil { + return nil + } + + if c.namedCaches == nil { + return nil + } + + c.namedCachesLock.RLock() + nc, ok := c.namedCaches[name] + c.namedCachesLock.RUnlock() + + if !ok { + c.namedCachesLock.Lock() + defer c.namedCachesLock.Unlock() + + if nc, ok := c.namedCaches[name]; ok { + // Some other goroutine has created the cache while we were waiting for the lock. + return nc + } + + var config *NamedValueCacheConfig + if c.config != nil { + config = c.config.NamedCacheConfigs[name] + if config == nil { + config = getDefaultInterQueryBuiltinValueCacheConfig(name) + } + } + + if config == nil { + // No config, cache disabled. + return nil + } + + nc = &interQueryValueCacheBucket{ + items: *newItemsMap(), + config: config, + } + + c.namedCaches[name] = nc + } + + return nc +} + +func (c *interQueryBuiltinValueCache) UpdateConfig(config *Config) { + if c == nil { + return + } + + if config == nil { + c.globalCache.updateConfig(nil) + } else { + + c.globalCache.updateConfig(&NamedValueCacheConfig{ + MaxNumEntries: config.InterQueryBuiltinValueCache.MaxNumEntries, + }) + } + + c.namedCachesLock.Lock() + defer c.namedCachesLock.Unlock() + + c.config = &config.InterQueryBuiltinValueCache + + for name, nc := range c.namedCaches { + // For each named cache: if it has a config, update it; if no config, remove it. + namedConfig := c.config.NamedCacheConfigs[name] + if namedConfig == nil { + namedConfig = getDefaultInterQueryBuiltinValueCacheConfig(name) + } + + if namedConfig == nil { + delete(c.namedCaches, name) + } else { + nc.updateConfig(namedConfig) + } } } diff --git a/vendor/github.com/open-policy-agent/opa/topdown/cancel.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/cancel.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/topdown/cancel.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/cancel.go diff --git a/vendor/github.com/open-policy-agent/opa/topdown/casts.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/casts.go similarity index 76% rename from vendor/github.com/open-policy-agent/opa/topdown/casts.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/casts.go index 2eb8f97fc9..f395324841 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/casts.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/casts.go @@ -6,24 +6,38 @@ package topdown import ( "strconv" + "strings" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) func builtinToNumber(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { switch a := operands[0].Value.(type) { case ast.Null: - return iter(ast.NumberTerm("0")) + return iter(ast.InternedIntNumberTerm(0)) case ast.Boolean: if a { - return iter(ast.NumberTerm("1")) + return iter(ast.InternedIntNumberTerm(1)) } - return iter(ast.NumberTerm("0")) + return iter(ast.InternedIntNumberTerm(0)) case ast.Number: - return iter(ast.NewTerm(a)) + return iter(operands[0]) case ast.String: - _, err := strconv.ParseFloat(string(a), 64) + strValue := string(a) + + if it := ast.InternedIntNumberTermFromString(strValue); it != nil { + return iter(it) + } + + trimmedVal := strings.TrimLeft(strValue, "+-") + lowerCaseVal := strings.ToLower(trimmedVal) + + if lowerCaseVal == "inf" || lowerCaseVal == "infinity" || lowerCaseVal == "nan" { + return builtins.NewOperandTypeErr(1, operands[0].Value, "valid number string") + } + + _, err := strconv.ParseFloat(strValue, 64) if err != nil { return err } @@ -32,7 +46,7 @@ func builtinToNumber(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term return builtins.NewOperandTypeErr(1, operands[0].Value, "null", "boolean", "number", "string") } -// Deprecated in v0.13.0. +// Deprecated: deprecated in v0.13.0. func builtinToArray(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { switch val := operands[0].Value.(type) { case *ast.Array: @@ -50,7 +64,7 @@ func builtinToArray(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) } } -// Deprecated in v0.13.0. +// Deprecated: deprecated in v0.13.0. func builtinToSet(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { switch val := operands[0].Value.(type) { case *ast.Array: @@ -66,7 +80,7 @@ func builtinToSet(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) e } } -// Deprecated in v0.13.0. +// Deprecated: deprecated in v0.13.0. func builtinToString(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { switch val := operands[0].Value.(type) { case ast.String: @@ -76,7 +90,7 @@ func builtinToString(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term } } -// Deprecated in v0.13.0. +// Deprecated: deprecated in v0.13.0. func builtinToBoolean(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { switch val := operands[0].Value.(type) { case ast.Boolean: @@ -86,7 +100,7 @@ func builtinToBoolean(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter } } -// Deprecated in v0.13.0. +// Deprecated: deprecated in v0.13.0. func builtinToNull(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { switch val := operands[0].Value.(type) { case ast.Null: @@ -96,7 +110,7 @@ func builtinToNull(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) } } -// Deprecated in v0.13.0. +// Deprecated: deprecated in v0.13.0. func builtinToObject(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { switch val := operands[0].Value.(type) { case ast.Object: diff --git a/vendor/github.com/open-policy-agent/opa/topdown/cidr.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/cidr.go similarity index 94% rename from vendor/github.com/open-policy-agent/opa/topdown/cidr.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/cidr.go index 5b011bd161..00c034656b 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/cidr.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/cidr.go @@ -8,9 +8,9 @@ import ( "net" "sort" - "github.com/open-policy-agent/opa/ast" cidrMerge "github.com/open-policy-agent/opa/internal/cidr/merge" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) func getNetFromOperand(v ast.Value) (*net.IPNet, error) { @@ -31,7 +31,7 @@ func getLastIP(cidr *net.IPNet) (net.IP, error) { prefixLen, bits := cidr.Mask.Size() if prefixLen == 0 && bits == 0 { // non-standard mask, see https://golang.org/pkg/net/#IPMask.Size - return nil, fmt.Errorf("CIDR mask is in non-standard format") + return nil, errors.New("CIDR mask is in non-standard format") } var lastIP []byte if prefixLen == bits { @@ -75,7 +75,7 @@ func builtinNetCIDRIntersects(_ BuiltinContext, operands []*ast.Term, iter func( // If either net contains the others starting IP they are overlapping cidrsOverlap := cidrnetA.Contains(cidrnetB.IP) || cidrnetB.Contains(cidrnetA.IP) - return iter(ast.BooleanTerm(cidrsOverlap)) + return iter(ast.InternedBooleanTerm(cidrsOverlap)) } func builtinNetCIDRContains(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -92,7 +92,7 @@ func builtinNetCIDRContains(_ BuiltinContext, operands []*ast.Term, iter func(*a ip := net.ParseIP(string(bStr)) if ip != nil { - return iter(ast.BooleanTerm(cidrnetA.Contains(ip))) + return iter(ast.InternedBooleanTerm(cidrnetA.Contains(ip))) } // It wasn't an IP, try and parse it as a CIDR @@ -113,7 +113,7 @@ func builtinNetCIDRContains(_ BuiltinContext, operands []*ast.Term, iter func(*a cidrContained = cidrnetA.Contains(lastIP) } - return iter(ast.BooleanTerm(cidrContained)) + return iter(ast.InternedBooleanTerm(cidrContained)) } var errNetCIDRContainsMatchElementType = errors.New("element must be string or non-empty array") @@ -137,12 +137,12 @@ func evalNetCIDRContainsMatchesOperand(operand int, a *ast.Term, iter func(cidr, case ast.String: return iter(a, a) case *ast.Array: - for i := 0; i < v.Len(); i++ { + for i := range v.Len() { cidr, err := getCIDRMatchTerm(v.Elem(i)) if err != nil { return fmt.Errorf("operand %v: %v", operand, err) } - if err := iter(cidr, ast.IntNumberTerm(i)); err != nil { + if err := iter(cidr, ast.InternedIntNumberTerm(i)); err != nil { return err } } @@ -219,13 +219,13 @@ func builtinNetCIDRExpand(bctx BuiltinContext, operands []*ast.Term, iter func(* func builtinNetCIDRIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { cidr, err := builtins.StringOperand(operands[0].Value, 1) if err != nil { - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } if _, _, err := net.ParseCIDR(string(cidr)); err != nil { - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } - return iter(ast.BooleanTerm(true)) + return iter(ast.InternedBooleanTerm(true)) } type cidrBlockRange struct { @@ -255,7 +255,7 @@ func (c cidrBlockRanges) Less(i, j int) bool { } // Then compare first IP. - cmp = bytes.Compare(*c[i].First, *c[i].First) + cmp = bytes.Compare(*c[i].First, *c[j].First) if cmp < 0 { return true } else if cmp > 0 { @@ -274,7 +274,7 @@ func builtinNetCIDRMerge(_ BuiltinContext, operands []*ast.Term, iter func(*ast. switch v := operands[0].Value.(type) { case *ast.Array: - for i := 0; i < v.Len(); i++ { + for i := range v.Len() { network, err := generateIPNet(v.Elem(i)) if err != nil { return err diff --git a/vendor/github.com/open-policy-agent/opa/topdown/comparison.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/comparison.go similarity index 90% rename from vendor/github.com/open-policy-agent/opa/topdown/comparison.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/comparison.go index 0d033d2c32..9e1585a28a 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/comparison.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/comparison.go @@ -4,7 +4,7 @@ package topdown -import "github.com/open-policy-agent/opa/ast" +import "github.com/open-policy-agent/opa/v1/ast" type compareFunc func(a, b ast.Value) bool @@ -34,7 +34,7 @@ func compareEq(a, b ast.Value) bool { func builtinCompare(cmp compareFunc) BuiltinFunc { return func(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - return iter(ast.BooleanTerm(cmp(operands[0].Value, operands[1].Value))) + return iter(ast.InternedBooleanTerm(cmp(operands[0].Value, operands[1].Value))) } } diff --git a/vendor/github.com/open-policy-agent/opa/topdown/copypropagation/copypropagation.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/copypropagation/copypropagation.go similarity index 97% rename from vendor/github.com/open-policy-agent/opa/topdown/copypropagation/copypropagation.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/copypropagation/copypropagation.go index 8824d19bd2..9f4beca54a 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/copypropagation/copypropagation.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/copypropagation/copypropagation.go @@ -8,7 +8,7 @@ import ( "fmt" "sort" - "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/v1/ast" ) // CopyPropagator implements a simple copy propagation optimization to remove @@ -209,7 +209,7 @@ func (p *CopyPropagator) Apply(query ast.Body) ast.Body { // plugBindings applies the binding list and union-find to x. This process // removes as many variables as possible. -func (p *CopyPropagator) plugBindings(pctx *plugContext, expr *ast.Expr) *ast.Expr { +func (*CopyPropagator) plugBindings(pctx *plugContext, expr *ast.Expr) *ast.Expr { xform := bindingPlugTransform{ pctx: pctx, @@ -244,7 +244,7 @@ func (t bindingPlugTransform) Transform(x interface{}) (interface{}, error) { } } -func (t bindingPlugTransform) plugBindingsVar(pctx *plugContext, v ast.Var) ast.Value { +func (bindingPlugTransform) plugBindingsVar(pctx *plugContext, v ast.Var) ast.Value { var result ast.Value = v @@ -274,7 +274,7 @@ func (t bindingPlugTransform) plugBindingsVar(pctx *plugContext, v ast.Var) ast. return b } -func (t bindingPlugTransform) plugBindingsRef(pctx *plugContext, v ast.Ref) ast.Ref { +func (bindingPlugTransform) plugBindingsRef(pctx *plugContext, v ast.Ref) ast.Ref { // Apply union-find to remove redundant variables from input. if root, ok := pctx.uf.Find(v[0].Value); ok { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/copypropagation/unionfind.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/copypropagation/unionfind.go similarity index 83% rename from vendor/github.com/open-policy-agent/opa/topdown/copypropagation/unionfind.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/copypropagation/unionfind.go index 38ec56f315..528c83a0f4 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/copypropagation/unionfind.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/copypropagation/unionfind.go @@ -7,25 +7,21 @@ package copypropagation import ( "fmt" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/util" ) type rankFunc func(*unionFindRoot, *unionFindRoot) (*unionFindRoot, *unionFindRoot) type unionFind struct { - roots *util.HashMap + roots *util.HasherMap[ast.Value, *unionFindRoot] parents *ast.ValueMap rank rankFunc } func newUnionFind(rank rankFunc) *unionFind { return &unionFind{ - roots: util.NewHashMap(func(a util.T, b util.T) bool { - return a.(ast.Value).Compare(b.(ast.Value)) == 0 - }, func(v util.T) int { - return v.(ast.Value).Hash() - }), + roots: util.NewHasherMap[ast.Value, *unionFindRoot](ast.ValueEqual), parents: ast.NewValueMap(), rank: rank, } @@ -53,7 +49,7 @@ func (uf *unionFind) Find(v ast.Value) (*unionFindRoot, bool) { if parent.Compare(v) == 0 { r, ok := uf.roots.Get(v) - return r.(*unionFindRoot), ok + return r, ok } return uf.Find(parent) @@ -93,13 +89,13 @@ func (uf *unionFind) String() string { map[string]ast.Value{}, } - uf.roots.Iter(func(k util.T, v util.T) bool { - o.Roots[k.(ast.Value).String()] = struct { + uf.roots.Iter(func(k ast.Value, v *unionFindRoot) bool { + o.Roots[k.String()] = struct { Constant *ast.Term Key ast.Value }{ - v.(*unionFindRoot).constant, - v.(*unionFindRoot).key, + v.constant, + v.key, } return true }) diff --git a/vendor/github.com/open-policy-agent/opa/topdown/crypto.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/crypto.go similarity index 89% rename from vendor/github.com/open-policy-agent/opa/topdown/crypto.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/crypto.go index f24432a264..dafbac7850 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/crypto.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/crypto.go @@ -15,8 +15,10 @@ import ( "crypto/tls" "crypto/x509" "encoding/base64" + "encoding/hex" "encoding/json" "encoding/pem" + "errors" "fmt" "hash" "os" @@ -25,9 +27,9 @@ import ( "github.com/open-policy-agent/opa/internal/jwx/jwk" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" + "github.com/open-policy-agent/opa/v1/util" ) const ( @@ -96,7 +98,7 @@ func builtinCryptoX509ParseAndVerifyCertificates(_ BuiltinContext, operands []*a } invalid := ast.ArrayTerm( - ast.BooleanTerm(false), + ast.InternedBooleanTerm(false), ast.NewTerm(ast.NewArray()), ) @@ -116,7 +118,7 @@ func builtinCryptoX509ParseAndVerifyCertificates(_ BuiltinContext, operands []*a } valid := ast.ArrayTerm( - ast.BooleanTerm(true), + ast.InternedBooleanTerm(true), ast.NewTerm(value), ) @@ -152,14 +154,12 @@ func builtinCryptoX509ParseAndVerifyCertificatesWithOptions(_ BuiltinContext, op return err } - invalid := ast.ArrayTerm( - ast.BooleanTerm(false), - ast.NewTerm(ast.NewArray()), - ) - certs, err := getX509CertsFromString(string(input)) if err != nil { - return iter(invalid) + return iter(ast.ArrayTerm( + ast.InternedBooleanTerm(false), + ast.NewTerm(ast.NewArray()), + )) } // Collect the cert verification options @@ -170,7 +170,10 @@ func builtinCryptoX509ParseAndVerifyCertificatesWithOptions(_ BuiltinContext, op verified, err := verifyX509CertificateChain(certs, verifyOpt) if err != nil { - return iter(invalid) + return iter(ast.ArrayTerm( + ast.InternedBooleanTerm(false), + ast.NewTerm(ast.NewArray()), + )) } value, err := ast.InterfaceToValue(verified) @@ -178,12 +181,10 @@ func builtinCryptoX509ParseAndVerifyCertificatesWithOptions(_ BuiltinContext, op return err } - valid := ast.ArrayTerm( - ast.BooleanTerm(true), + return iter(ast.ArrayTerm( + ast.InternedBooleanTerm(true), ast.NewTerm(value), - ) - - return iter(valid) + )) } func extractVerifyOpts(options ast.Object) (verifyOpt x509.VerifyOptions, err error) { @@ -204,7 +205,7 @@ func extractVerifyOpts(options ast.Object) (verifyOpt x509.VerifyOptions, err er if ok { verifyOpt.DNSName = strings.Trim(string(dns), "\"") } else { - return verifyOpt, fmt.Errorf("'DNSName' should be a string") + return verifyOpt, errors.New("'DNSName' should be a string") } case "CurrentTime": c, ok := options.Get(key).Value.(ast.Number) @@ -213,10 +214,10 @@ func extractVerifyOpts(options ast.Object) (verifyOpt x509.VerifyOptions, err er if ok { verifyOpt.CurrentTime = time.Unix(0, nanosecs) } else { - return verifyOpt, fmt.Errorf("'CurrentTime' should be a valid int64 number") + return verifyOpt, errors.New("'CurrentTime' should be a valid int64 number") } } else { - return verifyOpt, fmt.Errorf("'CurrentTime' should be a number") + return verifyOpt, errors.New("'CurrentTime' should be a number") } case "MaxConstraintComparisons": c, ok := options.Get(key).Value.(ast.Number) @@ -225,23 +226,23 @@ func extractVerifyOpts(options ast.Object) (verifyOpt x509.VerifyOptions, err er if ok { verifyOpt.MaxConstraintComparisions = maxComparisons } else { - return verifyOpt, fmt.Errorf("'MaxConstraintComparisons' should be a valid number") + return verifyOpt, errors.New("'MaxConstraintComparisons' should be a valid number") } } else { - return verifyOpt, fmt.Errorf("'MaxConstraintComparisons' should be a number") + return verifyOpt, errors.New("'MaxConstraintComparisons' should be a number") } case "KeyUsages": type forEach interface { Foreach(func(*ast.Term)) } var ks forEach - switch options.Get(key).Value.(type) { + switch v := options.Get(key).Value.(type) { case *ast.Array: - ks = options.Get(key).Value.(*ast.Array) + ks = v case ast.Set: - ks = options.Get(key).Value.(ast.Set) + ks = v default: - return verifyOpt, fmt.Errorf("'KeyUsages' should be an Array or Set") + return verifyOpt, errors.New("'KeyUsages' should be an Array or Set") } // Collect the x509.ExtKeyUsage values by looking up the @@ -262,7 +263,7 @@ func extractVerifyOpts(options ast.Object) (verifyOpt x509.VerifyOptions, err er return x509.VerifyOptions{}, fmt.Errorf("invalid entries for 'KeyUsages' found: %s", invalidKUsgs) } default: - return verifyOpt, fmt.Errorf("invalid key option") + return verifyOpt, errors.New("invalid key option") } } @@ -312,7 +313,7 @@ func builtinCryptoX509ParseCertificateRequest(_ BuiltinContext, operands []*ast. p, _ := pem.Decode(bytes) if p != nil && p.Type != blockTypeCertificateRequest { - return fmt.Errorf("invalid PEM-encoded certificate signing request") + return errors.New("invalid PEM-encoded certificate signing request") } if p != nil { bytes = p.Bytes @@ -354,7 +355,7 @@ func builtinCryptoJWKFromPrivateKey(_ BuiltinContext, operands []*ast.Term, iter pemDataString := string(input) if pemDataString == "" { - return fmt.Errorf("input PEM data was empty") + return errors.New("input PEM data was empty") } // This built in must be supplied a valid PEM or base64 encoded string. @@ -374,7 +375,7 @@ func builtinCryptoJWKFromPrivateKey(_ BuiltinContext, operands []*ast.Term, iter } if len(rawKeys) == 0 { - return iter(ast.NullTerm()) + return iter(ast.InternedNullTerm) } key, err := jwk.New(rawKeys[0]) @@ -408,7 +409,7 @@ func builtinCryptoParsePrivateKeys(_ BuiltinContext, operands []*ast.Term, iter } if string(input) == "" { - return iter(ast.NullTerm()) + return iter(ast.InternedNullTerm) } // get the raw private key @@ -418,7 +419,7 @@ func builtinCryptoParsePrivateKeys(_ BuiltinContext, operands []*ast.Term, iter } if len(rawKeys) == 0 { - return iter(ast.NewTerm(ast.NewArray())) + return iter(emptyArr) } bs, err := json.Marshal(rawKeys) @@ -439,36 +440,43 @@ func builtinCryptoParsePrivateKeys(_ BuiltinContext, operands []*ast.Term, iter return iter(ast.NewTerm(value)) } -func hashHelper(a ast.Value, h func(ast.String) string) (ast.Value, error) { - s, err := builtins.StringOperand(a, 1) - if err != nil { - return nil, err - } - return ast.String(h(s)), nil +func toHexEncodedString(src []byte) string { + dst := make([]byte, hex.EncodedLen(len(src))) + hex.Encode(dst, src) + return util.ByteSliceToString(dst) } func builtinCryptoMd5(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - res, err := hashHelper(operands[0].Value, func(s ast.String) string { return fmt.Sprintf("%x", md5.Sum([]byte(s))) }) + s, err := builtins.StringOperand(operands[0].Value, 1) if err != nil { return err } - return iter(ast.NewTerm(res)) + + md5sum := md5.Sum([]byte(s)) + + return iter(ast.StringTerm(toHexEncodedString(md5sum[:]))) } func builtinCryptoSha1(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - res, err := hashHelper(operands[0].Value, func(s ast.String) string { return fmt.Sprintf("%x", sha1.Sum([]byte(s))) }) + s, err := builtins.StringOperand(operands[0].Value, 1) if err != nil { return err } - return iter(ast.NewTerm(res)) + + sha1sum := sha1.Sum([]byte(s)) + + return iter(ast.StringTerm(toHexEncodedString(sha1sum[:]))) } func builtinCryptoSha256(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - res, err := hashHelper(operands[0].Value, func(s ast.String) string { return fmt.Sprintf("%x", sha256.Sum256([]byte(s))) }) + s, err := builtins.StringOperand(operands[0].Value, 1) if err != nil { return err } - return iter(ast.NewTerm(res)) + + sha256sum := sha256.Sum256([]byte(s)) + + return iter(ast.StringTerm(toHexEncodedString(sha256sum[:]))) } func hmacHelper(operands []*ast.Term, iter func(*ast.Term) error, h func() hash.Hash) error { @@ -488,7 +496,7 @@ func hmacHelper(operands []*ast.Term, iter func(*ast.Term) error, h func() hash. mac.Write([]byte(message)) messageDigest := mac.Sum(nil) - return iter(ast.StringTerm(fmt.Sprintf("%x", messageDigest))) + return iter(ast.StringTerm(hex.EncodeToString(messageDigest))) } func builtinCryptoHmacMd5(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -522,7 +530,7 @@ func builtinCryptoHmacEqual(_ BuiltinContext, operands []*ast.Term, iter func(*a res := hmac.Equal([]byte(mac1), []byte(mac2)) - return iter(ast.BooleanTerm(res)) + return iter(ast.InternedBooleanTerm(res)) } func init() { @@ -697,7 +705,7 @@ func addCACertsFromBytes(pool *x509.CertPool, pemBytes []byte) (*x509.CertPool, } if ok := pool.AppendCertsFromPEM(pemBytes); !ok { - return nil, fmt.Errorf("could not append certificates") + return nil, errors.New("could not append certificates") } return pool, nil @@ -725,9 +733,11 @@ func readCertFromFile(localCertFile string) ([]byte, error) { return certPEM, nil } +var beginPrefix = []byte("-----BEGIN ") + func getTLSx509KeyPairFromString(certPemBlock []byte, keyPemBlock []byte) (*tls.Certificate, error) { - if !strings.HasPrefix(string(certPemBlock), "-----BEGIN") { + if !bytes.HasPrefix(certPemBlock, beginPrefix) { s, err := base64.StdEncoding.DecodeString(string(certPemBlock)) if err != nil { return nil, err @@ -735,7 +745,7 @@ func getTLSx509KeyPairFromString(certPemBlock []byte, keyPemBlock []byte) (*tls. certPemBlock = s } - if !strings.HasPrefix(string(keyPemBlock), "-----BEGIN") { + if !bytes.HasPrefix(keyPemBlock, beginPrefix) { s, err := base64.StdEncoding.DecodeString(string(keyPemBlock)) if err != nil { return nil, err @@ -744,7 +754,7 @@ func getTLSx509KeyPairFromString(certPemBlock []byte, keyPemBlock []byte) (*tls. } // we assume it a DER certificate and try to convert it to a PEM. - if !bytes.HasPrefix(certPemBlock, []byte("-----BEGIN")) { + if !bytes.HasPrefix(certPemBlock, beginPrefix) { pemBlock := &pem.Block{ Type: "CERTIFICATE", diff --git a/vendor/github.com/open-policy-agent/opa/topdown/doc.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/doc.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/topdown/doc.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/doc.go diff --git a/vendor/github.com/open-policy-agent/opa/topdown/encoding.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/encoding.go similarity index 95% rename from vendor/github.com/open-policy-agent/opa/topdown/encoding.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/encoding.go index f3475a60d0..a27a9c2450 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/encoding.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/encoding.go @@ -15,9 +15,9 @@ import ( "sigs.k8s.io/yaml" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" + "github.com/open-policy-agent/opa/v1/util" ) func builtinJSONMarshal(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -144,10 +144,10 @@ func builtinJSONIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast.T str, err := builtins.StringOperand(operands[0].Value, 1) if err != nil { - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } - return iter(ast.BooleanTerm(json.Valid([]byte(str)))) + return iter(ast.InternedBooleanTerm(json.Valid([]byte(str)))) } func builtinBase64Encode(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -175,11 +175,11 @@ func builtinBase64Decode(_ BuiltinContext, operands []*ast.Term, iter func(*ast. func builtinBase64IsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { str, err := builtins.StringOperand(operands[0].Value, 1) if err != nil { - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } _, err = base64.StdEncoding.DecodeString(string(str)) - return iter(ast.BooleanTerm(err == nil)) + return iter(ast.InternedBooleanTerm(err == nil)) } func builtinBase64UrlEncode(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -355,12 +355,12 @@ func builtinYAMLUnmarshal(_ BuiltinContext, operands []*ast.Term, iter func(*ast func builtinYAMLIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { str, err := builtins.StringOperand(operands[0].Value, 1) if err != nil { - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } var x interface{} err = yaml.Unmarshal([]byte(str), &x) - return iter(ast.BooleanTerm(err == nil)) + return iter(ast.InternedBooleanTerm(err == nil)) } func builtinHexEncode(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/errors.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/errors.go similarity index 98% rename from vendor/github.com/open-policy-agent/opa/topdown/errors.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/errors.go index 918df6c853..cadd163198 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/errors.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/errors.go @@ -8,7 +8,7 @@ import ( "errors" "fmt" - "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/v1/ast" ) // Halt is a special error type that built-in function implementations return to indicate diff --git a/vendor/github.com/open-policy-agent/opa/topdown/eval.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/eval.go similarity index 85% rename from vendor/github.com/open-policy-agent/opa/topdown/eval.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/eval.go index 7884ac01e0..221b29d005 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/eval.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/eval.go @@ -5,19 +5,21 @@ import ( "errors" "fmt" "io" - "sort" + "slices" "strconv" "strings" - - "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/topdown/builtins" - "github.com/open-policy-agent/opa/topdown/cache" - "github.com/open-policy-agent/opa/topdown/copypropagation" - "github.com/open-policy-agent/opa/topdown/print" - "github.com/open-policy-agent/opa/tracing" - "github.com/open-policy-agent/opa/types" + "sync" + + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/metrics" + "github.com/open-policy-agent/opa/v1/storage" + "github.com/open-policy-agent/opa/v1/topdown/builtins" + "github.com/open-policy-agent/opa/v1/topdown/cache" + "github.com/open-policy-agent/opa/v1/topdown/copypropagation" + "github.com/open-policy-agent/opa/v1/topdown/print" + "github.com/open-policy-agent/opa/v1/tracing" + "github.com/open-policy-agent/opa/v1/types" + "github.com/open-policy-agent/opa/v1/util" ) type evalIterator func(*eval) error @@ -57,60 +59,91 @@ func (ee deferredEarlyExitError) Error() string { return fmt.Sprintf("%v: deferred early exit", ee.e.query) } +// Note(æ): this struct is formatted for optimal alignment as it is big, internal and instantiated +// *very* frequently during evaluation. If you need to add fields here, please consider the alignment +// of the struct, and use something like betteralign (https://github.com/dkorunic/betteralign) if you +// need help with that. type eval struct { ctx context.Context metrics metrics.Metrics seed io.Reader + cancel Cancel + queryCompiler ast.QueryCompiler + store storage.Store + txn storage.Transaction + virtualCache VirtualCache + baseCache BaseCache + interQueryBuiltinCache cache.InterQueryCache + interQueryBuiltinValueCache cache.InterQueryValueCache + printHook print.Hook time *ast.Term - queryID uint64 queryIDFact *queryIDFactory parent *eval caller *eval - cancel Cancel - query ast.Body - queryCompiler ast.QueryCompiler - index int - indexing bool - earlyExit bool bindings *bindings - store storage.Store - baseCache *baseCache - txn storage.Transaction compiler *ast.Compiler input *ast.Term data *ast.Term external *resolverTrie targetStack *refStack - tracers []QueryTracer - traceEnabled bool traceLastLocation *ast.Location // Last location of a trace event. - plugTraceVars bool instr *Instrumentation builtins map[string]*Builtin builtinCache builtins.Cache ndBuiltinCache builtins.NDBCache functionMocks *functionMocksStack - virtualCache VirtualCache comprehensionCache *comprehensionCache - interQueryBuiltinCache cache.InterQueryCache - interQueryBuiltinValueCache cache.InterQueryValueCache saveSet *saveSet saveStack *saveStack saveSupport *saveSupport saveNamespace *ast.Term - skipSaveNamespace bool inliningControl *inliningControl - genvarprefix string - genvarid int runtime *ast.Term builtinErrors *builtinErrors - printHook print.Hook + roundTripper CustomizeRoundTripper + genvarprefix string + query ast.Body + tracers []QueryTracer tracingOpts tracing.Options + queryID uint64 + index int + genvarid int + indexing bool + earlyExit bool + traceEnabled bool + plugTraceVars bool + skipSaveNamespace bool findOne bool strictObjects bool + defined bool +} + +type evp struct { + pool sync.Pool +} + +func (ep *evp) Put(e *eval) { + ep.pool.Put(e) +} + +func (ep *evp) Get() *eval { + return ep.pool.Get().(*eval) +} + +var evalPool = evp{ + pool: sync.Pool{ + New: func() any { + return &eval{} + }, + }, } func (e *eval) Run(iter evalIterator) error { + if !e.traceEnabled { + // avoid function literal escaping to heap if we don't need the trace + return e.eval(iter) + } + e.traceEnter(e.query) return e.eval(func(e *eval) error { e.traceExit(e.query) @@ -129,10 +162,10 @@ func (e *eval) String() string { func (e *eval) string(s *strings.Builder) { fmt.Fprintf(s, "') + s.WriteByte('>') } func (e *eval) builtinFunc(name string) (*ast.Builtin, BuiltinFunc, bool) { @@ -151,25 +184,23 @@ func (e *eval) builtinFunc(name string) (*ast.Builtin, BuiltinFunc, bool) { return nil, nil, false } -func (e *eval) closure(query ast.Body) *eval { - cpy := *e +func (e *eval) closure(query ast.Body, cpy *eval) { + *cpy = *e cpy.index = 0 cpy.query = query cpy.queryID = cpy.queryIDFact.Next() cpy.parent = e cpy.findOne = false - return &cpy } -func (e *eval) child(query ast.Body) *eval { - cpy := *e +func (e *eval) child(query ast.Body, cpy *eval) { + *cpy = *e cpy.index = 0 cpy.query = query cpy.queryID = cpy.queryIDFact.Next() cpy.bindings = newBindings(cpy.queryID, e.instr) cpy.parent = e cpy.findOne = false - return &cpy } func (e *eval) next(iter evalIterator) error { @@ -335,6 +366,13 @@ func (e *eval) evalExpr(iter evalIterator) error { } if e.cancel != nil && e.cancel.Cancelled() { + if e.ctx != nil && e.ctx.Err() != nil { + return &Error{ + Code: CancelErr, + Message: e.ctx.Err().Error(), + err: e.ctx.Err(), + } + } return &Error{ Code: CancelErr, Message: "caller cancelled query execution", @@ -342,13 +380,9 @@ func (e *eval) evalExpr(iter evalIterator) error { } if e.index >= len(e.query) { - err := iter(e) - - if err != nil { + if err := iter(e); err != nil { switch err := err.(type) { - case *deferredEarlyExitError: - return wrapErr(err) - case *earlyExitError: + case *deferredEarlyExitError, *earlyExitError: return wrapErr(err) default: return err @@ -374,46 +408,110 @@ func (e *eval) evalExpr(iter evalIterator) error { } func (e *eval) evalStep(iter evalIterator) error { - expr := e.query[e.index] if expr.Negated { return e.evalNot(iter) } - var defined bool var err error + + // NOTE(æ): the reason why there's one branch for the tracing case and one almost + // identical branch below for when tracing is disabled is that the tracing case + // allocates wildly. These allocations are cause by the "defined" boolean variable + // escaping to the heap as its value is set from inside of closures. There may very + // well be more elegant solutions to this problem, but this is one that works, and + // saves several *million* allocations for some workloads. So feel free to refactor + // this, but do make sure that the common non-tracing case doesn't pay in allocations + // for something that is only needed when tracing is enabled. + if e.traceEnabled { + var defined bool + switch terms := expr.Terms.(type) { + case []*ast.Term: + switch { + case expr.IsEquality(): + err = e.unify(terms[1], terms[2], func() error { + defined = true + err := iter(e) + e.traceRedo(expr) + return err + }) + default: + err = e.evalCall(terms, func() error { + defined = true + err := iter(e) + e.traceRedo(expr) + return err + }) + } + case *ast.Term: + // generateVar inlined here to avoid extra allocations in hot path + rterm := ast.VarTerm(e.fmtVarTerm()) + err = e.unify(terms, rterm, func() error { + if e.saveSet.Contains(rterm, e.bindings) { + return e.saveExpr(ast.NewExpr(rterm), e.bindings, func() error { + return iter(e) + }) + } + if !e.bindings.Plug(rterm).Equal(ast.InternedBooleanTerm(false)) { + defined = true + err := iter(e) + e.traceRedo(expr) + return err + } + return nil + }) + case *ast.Every: + eval := evalEvery{ + Every: terms, + e: e, + expr: expr, + } + err = eval.eval(func() error { + defined = true + err := iter(e) + e.traceRedo(expr) + return err + }) + + default: // guard-rail for adding extra (Expr).Terms types + return fmt.Errorf("got %T terms: %[1]v", terms) + } + + if err != nil { + return err + } + + if !defined { + e.traceFail(expr) + } + + return nil + } + switch terms := expr.Terms.(type) { case []*ast.Term: switch { case expr.IsEquality(): err = e.unify(terms[1], terms[2], func() error { - defined = true - err := iter(e) - e.traceRedo(expr) - return err + return iter(e) }) default: err = e.evalCall(terms, func() error { - defined = true - err := iter(e) - e.traceRedo(expr) - return err + return iter(e) }) } case *ast.Term: - rterm := e.generateVar(fmt.Sprintf("term_%d_%d", e.queryID, e.index)) + // generateVar inlined here to avoid extra allocations in hot path + rterm := ast.VarTerm(e.fmtVarTerm()) err = e.unify(terms, rterm, func() error { if e.saveSet.Contains(rterm, e.bindings) { return e.saveExpr(ast.NewExpr(rterm), e.bindings, func() error { return iter(e) }) } - if !e.bindings.Plug(rterm).Equal(ast.BooleanTerm(false)) { - defined = true - err := iter(e) - e.traceRedo(expr) - return err + if !e.bindings.Plug(rterm).Equal(ast.InternedBooleanTerm(false)) { + return iter(e) } return nil }) @@ -424,25 +522,28 @@ func (e *eval) evalStep(iter evalIterator) error { expr: expr, } err = eval.eval(func() error { - defined = true - err := iter(e) - e.traceRedo(expr) - return err + return iter(e) }) default: // guard-rail for adding extra (Expr).Terms types return fmt.Errorf("got %T terms: %[1]v", terms) } - if err != nil { - return err - } + return err +} - if !defined { - e.traceFail(expr) - } +// Single-purpose fmt.Sprintf replacement for generating variable names with only +// one allocation performed instead of 4, and in 1/3 the time. +func (e *eval) fmtVarTerm() string { + buf := make([]byte, 0, len(e.genvarprefix)+util.NumDigitsUint(e.queryID)+util.NumDigitsInt(e.index)+7) - return nil + buf = append(buf, e.genvarprefix...) + buf = append(buf, "_term_"...) + buf = strconv.AppendUint(buf, e.queryID, 10) + buf = append(buf, '_') + buf = strconv.AppendInt(buf, int64(e.index), 10) + + return util.ByteSliceToString(buf) } func (e *eval) evalNot(iter evalIterator) error { @@ -453,27 +554,34 @@ func (e *eval) evalNot(iter evalIterator) error { return e.evalNotPartial(iter) } - negation := ast.NewBody(expr.Complement().NoWith()) - child := e.closure(negation) + negation := ast.NewBody(expr.ComplementNoWith()) + child := evalPool.Get() + defer evalPool.Put(child) - var defined bool - child.traceEnter(negation) + e.closure(negation, child) - err := child.eval(func(*eval) error { - child.traceExit(negation) - defined = true - child.traceRedo(negation) - return nil - }) + if e.traceEnabled { + child.traceEnter(negation) + } - if err != nil { + if err := child.eval(func(*eval) error { + if e.traceEnabled { + child.traceExit(negation) + child.traceRedo(negation) + } + child.defined = true + + return nil + }); err != nil { return err } - if !defined { + if !child.defined { return iter(e) } + child.defined = false + e.traceFail(expr) return nil } @@ -482,16 +590,18 @@ func (e *eval) evalWith(iter evalIterator) error { expr := e.query[e.index] - // Disable inlining on all references in the expression so the result of - // partial evaluation has the same semantics w/ the with statements - // preserved. var disable []ast.Ref - disableRef := func(x ast.Ref) bool { - disable = append(disable, x.GroundPrefix()) - return false - } if e.partial() { + // Avoid the `disable` var to escape to heap unless partial evaluation is enabled. + var disablePartial []ast.Ref + // Disable inlining on all references in the expression so the result of + // partial evaluation has the same semantics w/ the with statements + // preserved. + disableRef := func(x ast.Ref) bool { + disablePartial = append(disablePartial, x.GroundPrefix()) + return false + } // If the value is unknown the with statement cannot be evaluated and so // the entire expression should be saved to be safe. In the future this @@ -516,12 +626,15 @@ func (e *eval) evalWith(iter evalIterator) error { } ast.WalkRefs(expr.NoWith(), disableRef) + + disable = disablePartial } pairsInput := [][2]*ast.Term{} pairsData := [][2]*ast.Term{} - functionMocks := [][2]*ast.Term{} - targets := []ast.Ref{} + targets := make([]ast.Ref, 0, len(expr.With)) + + var functionMocks [][2]*ast.Term for i := range expr.With { target := expr.With[i].Target @@ -613,11 +726,14 @@ func (e *eval) evalWithPop(input, data *ast.Term) { } func (e *eval) evalNotPartial(iter evalIterator) error { - // Prepare query normally. expr := e.query[e.index] - negation := expr.Complement().NoWith() - child := e.closure(ast.NewBody(negation)) + negation := expr.ComplementNoWith() + + child := evalPool.Get() + defer evalPool.Put(child) + + e.closure(ast.NewBody(negation), child) // Unknowns is the set of variables that are marked as unknown. The variables // are namespaced with the query ID that they originate in. This ensures that @@ -710,9 +826,7 @@ func (e *eval) evalNotPartialSupport(negationID uint64, expr *ast.Expr, unknowns args = append(args, ast.NewTerm(v)) } - sort.Slice(args, func(i, j int) bool { - return args[i].Value.Compare(args[j].Value) < 0 - }) + slices.SortFunc(args, ast.TermValueCompare) if len(args) > 0 { head.Args = args @@ -747,7 +861,6 @@ func (e *eval) evalCall(terms []*ast.Term, iter unifyIterator) error { ref := terms[0].Value.(ast.Ref) - var mocked bool mock, mocked := e.functionMocks.Get(ref) if mocked { if m, ok := mock.Value.(ast.Ref); ok && isFunction(e.compiler.TypeEnv, m) { // builtin or data function @@ -770,7 +883,7 @@ func (e *eval) evalCall(terms []*ast.Term, iter unifyIterator) error { if ref[0].Equal(ast.DefaultRootDocument) { if mocked { f := e.compiler.TypeEnv.Get(ref).(*types.Function) - return e.evalCallValue(len(f.FuncArgs().Args), terms, mock, iter) + return e.evalCallValue(f.Arity(), terms, mock, iter) } var ir *ast.IndexResult @@ -800,11 +913,11 @@ func (e *eval) evalCall(terms []*ast.Term, iter unifyIterator) error { } if mocked { // value replacement of built-in call - return e.evalCallValue(len(bi.Decl.Args()), terms, mock, iter) + return e.evalCallValue(bi.Decl.Arity(), terms, mock, iter) } if e.unknown(e.query[e.index], e.bindings) { - return e.saveCall(len(bi.Decl.Args()), terms, iter) + return e.saveCall(bi.Decl.Arity(), terms, iter) } var parentID uint64 @@ -836,6 +949,7 @@ func (e *eval) evalCall(terms []*ast.Term, iter unifyIterator) error { PrintHook: e.printHook, DistributedTracingOpts: e.tracingOpts, Capabilities: capabilities, + RoundTripper: e.roundTripper, } eval := evalBuiltin{ @@ -855,7 +969,7 @@ func (e *eval) evalCallValue(arity int, terms []*ast.Term, mock *ast.Term, iter return e.unify(terms[len(terms)-1], mock, iter) case len(terms) == arity+1: - if mock.Value.Compare(ast.Boolean(false)) != 0 { + if !ast.Boolean(false).Equal(mock.Value) { return iter() } return nil @@ -932,6 +1046,22 @@ func (e *eval) biunifyArraysRec(a, b *ast.Array, b1, b2 *bindings, iter unifyIte }) } +func (e *eval) biunifyTerms(a, b []*ast.Term, b1, b2 *bindings, iter unifyIterator) error { + if len(a) != len(b) { + return nil + } + return e.biunifyTermsRec(a, b, b1, b2, iter, 0) +} + +func (e *eval) biunifyTermsRec(a, b []*ast.Term, b1, b2 *bindings, iter unifyIterator, idx int) error { + if idx == len(a) { + return iter() + } + return e.biunify(a[idx], b[idx], b1, b2, func() error { + return e.biunifyTermsRec(a, b, b1, b2, iter, idx+1) + }) +} + func (e *eval) biunifyObjects(a, b ast.Object, b1, b2 *bindings, iter unifyIterator) error { if a.Len() != b.Len() { return nil @@ -1057,7 +1187,7 @@ func (e *eval) biunifyRef(a, b *ast.Term, b1, b2 *bindings, iter unifyIterator) e: e, ref: ref, pos: 1, - plugged: ref.Copy(), + plugged: ref.CopyNonGround(), bindings: b1, rterm: b, rbindings: b2, @@ -1165,7 +1295,10 @@ func (e *eval) buildComprehensionCache(a *ast.Term) (*ast.Term, error) { } func (e *eval) buildComprehensionCacheArray(x *ast.ArrayComprehension, keys []*ast.Term) (*comprehensionCacheElem, error) { - child := e.child(x.Body) + child := evalPool.Get() + defer evalPool.Put(child) + + e.child(x.Body, child) node := newComprehensionCacheElem() return node, child.Run(func(child *eval) error { values := make([]*ast.Term, len(keys)) @@ -1184,7 +1317,10 @@ func (e *eval) buildComprehensionCacheArray(x *ast.ArrayComprehension, keys []*a } func (e *eval) buildComprehensionCacheSet(x *ast.SetComprehension, keys []*ast.Term) (*comprehensionCacheElem, error) { - child := e.child(x.Body) + child := evalPool.Get() + defer evalPool.Put(child) + + e.child(x.Body, child) node := newComprehensionCacheElem() return node, child.Run(func(child *eval) error { values := make([]*ast.Term, len(keys)) @@ -1204,7 +1340,10 @@ func (e *eval) buildComprehensionCacheSet(x *ast.SetComprehension, keys []*ast.T } func (e *eval) buildComprehensionCacheObject(x *ast.ObjectComprehension, keys []*ast.Term) (*comprehensionCacheElem, error) { - child := e.child(x.Body) + child := evalPool.Get() + defer evalPool.Put(child) + + e.child(x.Body, child) node := newComprehensionCacheElem() return node, child.Run(func(child *eval) error { values := make([]*ast.Term, len(keys)) @@ -1285,7 +1424,11 @@ func (e *eval) amendComprehension(a *ast.Term, b1 *bindings) (*ast.Term, error) func (e *eval) biunifyComprehensionArray(x *ast.ArrayComprehension, b *ast.Term, b1, b2 *bindings, iter unifyIterator) error { result := ast.NewArray() - child := e.closure(x.Body) + child := evalPool.Get() + + e.closure(x.Body, child) + defer evalPool.Put(child) + err := child.Run(func(child *eval) error { result = result.Append(child.bindings.Plug(x.Term)) return nil @@ -1298,7 +1441,11 @@ func (e *eval) biunifyComprehensionArray(x *ast.ArrayComprehension, b *ast.Term, func (e *eval) biunifyComprehensionSet(x *ast.SetComprehension, b *ast.Term, b1, b2 *bindings, iter unifyIterator) error { result := ast.NewSet() - child := e.closure(x.Body) + child := evalPool.Get() + + e.closure(x.Body, child) + defer evalPool.Put(child) + err := child.Run(func(child *eval) error { result.Add(child.bindings.Plug(x.Term)) return nil @@ -1310,8 +1457,13 @@ func (e *eval) biunifyComprehensionSet(x *ast.SetComprehension, b *ast.Term, b1, } func (e *eval) biunifyComprehensionObject(x *ast.ObjectComprehension, b *ast.Term, b1, b2 *bindings, iter unifyIterator) error { + child := evalPool.Get() + defer evalPool.Put(child) + + e.closure(x.Body, child) + result := ast.NewObject() - child := e.closure(x.Body) + err := child.Run(func(child *eval) error { key := child.bindings.Plug(x.Key) value := child.bindings.Plug(x.Value) @@ -1354,7 +1506,7 @@ func (e *eval) saveExprMarkUnknowns(expr *ast.Expr, b *bindings, iter unifyItera e.traceSave(expr) err = iter() e.saveStack.Pop() - for i := 0; i < pops; i++ { + for range pops { e.saveSet.Pop() } return err @@ -1384,7 +1536,7 @@ func (e *eval) saveUnify(a, b *ast.Term, b1, b2 *bindings, iter unifyIterator) e err := iter() e.saveStack.Pop() - for i := 0; i < pops; i++ { + for range pops { e.saveSet.Pop() } @@ -1411,7 +1563,7 @@ func (e *eval) saveCall(declArgsLen int, terms []*ast.Term, iter unifyIterator) err := iter() e.saveStack.Pop() - for i := 0; i < pops; i++ { + for range pops { e.saveSet.Pop() } return err @@ -1433,7 +1585,7 @@ func (e *eval) saveInlinedNegatedExprs(exprs []*ast.Expr, iter unifyIterator) er e.traceSave(expr) } err := iter() - for i := 0; i < len(exprs); i++ { + for range exprs { e.saveStack.Pop() } return err @@ -1448,12 +1600,22 @@ func (e *eval) getRules(ref ast.Ref, args []*ast.Term) (*ast.IndexResult, error) return nil, nil } + resolver := resolverPool.Get().(*evalResolver) + defer func() { + resolver.e = nil + resolver.args = nil + resolverPool.Put(resolver) + }() + var result *ast.IndexResult var err error if e.indexing { - result, err = index.Lookup(&evalResolver{e: e, args: args}) + resolver.e = e + resolver.args = args + result, err = index.Lookup(resolver) } else { - result, err = index.AllRules(&evalResolver{e: e}) + resolver.e = e + result, err = index.AllRules(resolver) } if err != nil { return nil, err @@ -1461,20 +1623,27 @@ func (e *eval) getRules(ref ast.Ref, args []*ast.Term) (*ast.IndexResult, error) result.EarlyExit = result.EarlyExit && e.earlyExit - var msg strings.Builder - if len(result.Rules) == 1 { - msg.WriteString("(matched 1 rule") - } else { - msg.Grow(len("(matched NNNN rules)")) - msg.WriteString("(matched ") - msg.WriteString(strconv.Itoa(len(result.Rules))) - msg.WriteString(" rules") - } - if result.EarlyExit { - msg.WriteString(", early exit") + if e.traceEnabled { + var msg strings.Builder + if len(result.Rules) == 1 { + msg.WriteString("(matched 1 rule") + } else { + msg.Grow(len("(matched NNNN rules)")) + msg.WriteString("(matched ") + msg.WriteString(strconv.Itoa(len(result.Rules))) + msg.WriteString(" rules") + } + if result.EarlyExit { + msg.WriteString(", early exit") + } + msg.WriteRune(')') + + // Copy ref here as ref otherwise always escapes to the heap, + // whether tracing is enabled or not. + r := ref.Copy() + e.traceIndex(e.query[e.index], msg.String(), &r) } - msg.WriteRune(')') - e.traceIndex(e.query[e.index], msg.String(), &ref) + return result, err } @@ -1487,10 +1656,20 @@ type evalResolver struct { args []*ast.Term } +var ( + resolverPool = sync.Pool{ + New: func() any { + return &evalResolver{} + }, + } +) + func (e *evalResolver) Resolve(ref ast.Ref) (ast.Value, error) { e.e.instr.startTimer(evalOpResolve) - if e.e.inliningControl.Disabled(ref, true) || e.e.saveSet.Contains(ast.NewTerm(ref), nil) { + // NOTE(ae): nil check on saveSet to avoid ast.NewTerm allocation when not needed + if e.e.inliningControl.Disabled(ref, true) || (e.e.saveSet != nil && + e.e.saveSet.Contains(ast.NewTerm(ref), nil)) { e.e.instr.stopTimer(evalOpResolve) return nil, ast.UnknownValueErr{} } @@ -1568,7 +1747,7 @@ func (e *evalResolver) Resolve(ref ast.Ref) (ast.Value, error) { return merged, err } e.e.instr.stopTimer(evalOpResolve) - return nil, fmt.Errorf("illegal ref") + return nil, errors.New("illegal ref") } func (e *eval) resolveReadFromStorage(ref ast.Ref, a ast.Value) (ast.Value, error) { @@ -1611,16 +1790,7 @@ func (e *eval) resolveReadFromStorage(ref ast.Ref, a ast.Value) (ast.Value, erro } case ast.Object: if obj.Len() > 0 { - cpy := ast.NewObject() - if err := obj.Iter(func(k *ast.Term, v *ast.Term) error { - if !ast.SystemDocumentKey.Equal(k.Value) { - cpy.Insert(k, v) - } - return nil - }); err != nil { - return nil, err - } - blob = cpy + blob, _ = obj.Map(systemDocumentKeyRemoveMapper) } } } @@ -1653,8 +1823,21 @@ func (e *eval) resolveReadFromStorage(ref ast.Ref, a ast.Value) (ast.Value, erro return merged, nil } +func systemDocumentKeyRemoveMapper(k, v *ast.Term) (*ast.Term, *ast.Term, error) { + if ast.SystemDocumentKey.Equal(k.Value) { + return nil, nil, nil + } + return k, v, nil +} + func (e *eval) generateVar(suffix string) *ast.Term { - return ast.VarTerm(fmt.Sprintf("%v_%v", e.genvarprefix, suffix)) + buf := make([]byte, 0, len(e.genvarprefix)+len(suffix)+1) + + buf = append(buf, e.genvarprefix...) + buf = append(buf, '_') + buf = append(buf, suffix...) + + return ast.VarTerm(util.ByteSliceToString(buf)) } func (e *eval) rewrittenVar(v ast.Var) (ast.Var, bool) { @@ -1681,7 +1864,7 @@ func (e *eval) getDeclArgsLen(x *ast.Expr) (int, error) { bi, _, ok := e.builtinFunc(operator.String()) if ok { - return len(bi.Decl.Args()), nil + return bi.Decl.Arity(), nil } ir, err := e.getRules(operator, nil) @@ -1716,7 +1899,7 @@ func (e *evalBuiltin) canUseNDBCache(bi *ast.Builtin) bool { return bi.Nondeterministic && e.bctx.NDBuiltinCache != nil } -func (e evalBuiltin) eval(iter unifyIterator) error { +func (e *evalBuiltin) eval(iter unifyIterator) error { operands := make([]*ast.Term, len(e.terms)) @@ -1724,10 +1907,9 @@ func (e evalBuiltin) eval(iter unifyIterator) error { operands[i] = e.e.bindings.Plug(e.terms[i]) } - numDeclArgs := len(e.bi.Decl.FuncArgs().Args) + numDeclArgs := e.bi.Decl.Arity() e.e.instr.startTimer(evalOpBuiltinCall) - var err error // NOTE(philipc): We sometimes have to drop the very last term off // the args list for cases where a builtin's result is used/assigned, @@ -1749,7 +1931,7 @@ func (e evalBuiltin) eval(iter unifyIterator) error { case e.bi.Decl.Result() == nil: return iter() case len(operands) == numDeclArgs: - if v.Compare(ast.Boolean(false)) == 0 { + if ast.Boolean(false).Equal(v) { return nil // nothing to do } return iter() @@ -1763,7 +1945,7 @@ func (e evalBuiltin) eval(iter unifyIterator) error { } // Normal unification flow for builtins: - err = e.f(e.bctx, operands, func(output *ast.Term) error { + err := e.f(e.bctx, operands, func(output *ast.Term) error { e.e.instr.stopTimer(evalOpBuiltinCall) @@ -1773,7 +1955,7 @@ func (e evalBuiltin) eval(iter unifyIterator) error { case e.bi.Decl.Result() == nil: err = iter() case len(operands) == numDeclArgs: - if output.Value.Compare(ast.Boolean(false)) != 0 { + if !ast.Boolean(false).Equal(output.Value) { err = iter() } // else: nothing to do, don't iter() default: @@ -1813,9 +1995,9 @@ func (e evalBuiltin) eval(iter unifyIterator) error { type evalFunc struct { e *eval + ir *ast.IndexResult ref ast.Ref terms []*ast.Term - ir *ast.IndexResult } func (e evalFunc) eval(iter unifyIterator) error { @@ -1837,15 +2019,36 @@ func (e evalFunc) eval(iter unifyIterator) error { return e.e.saveCall(argCount, e.terms, iter) } - if e.e.partial() && (e.e.inliningControl.shallow || e.e.inliningControl.Disabled(e.ref, false)) { - // check if the function definitions, or any of the arguments - // contain something unknown - unknown := e.e.unknown(e.ref, e.e.bindings) - for i := 1; !unknown && i <= argCount; i++ { - unknown = e.e.unknown(e.terms[i], e.e.bindings) + if e.e.partial() { + var mustGenerateSupport bool + + if defRule := e.ir.Default; defRule != nil { + // The presence of a default func might force us to generate support + if len(defRule.Head.Args) == len(e.terms)-1 { + // The function is called without collecting the result in an output term, + // therefore any successful evaluation of the function is of interest, including the default value ... + if ret := defRule.Head.Value; ret == nil || !ret.Equal(ast.InternedBooleanTerm(false)) { + // ... unless the default value is false, + mustGenerateSupport = true + } + } else { + // The function is called with an output term, therefore any successful evaluation of the function is of interest. + // NOTE: Because of how the compiler rewrites function calls, we can't know if the result value is compared + // to a constant value, so we can't be as clever as we are for rules. + mustGenerateSupport = true + } } - if unknown { - return e.partialEvalSupport(argCount, iter) + + if mustGenerateSupport || e.e.inliningControl.shallow || e.e.inliningControl.Disabled(e.ref, false) { + // check if the function definitions, or any of the arguments + // contain something unknown + unknown := e.e.unknown(e.ref, e.e.bindings) + for i := 1; !unknown && i <= argCount; i++ { + unknown = e.e.unknown(e.terms[i], e.e.bindings) + } + if unknown { + return e.partialEvalSupport(argCount, iter) + } } } @@ -1854,9 +2057,9 @@ func (e evalFunc) eval(iter unifyIterator) error { func (e evalFunc) evalValue(iter unifyIterator, argCount int, findOne bool) error { var cacheKey ast.Ref - var hit bool - var err error if !e.e.partial() { + var hit bool + var err error cacheKey, hit, err = e.evalCache(argCount, iter) if err != nil { return err @@ -1865,12 +2068,23 @@ func (e evalFunc) evalValue(iter unifyIterator, argCount int, findOne bool) erro } } + // NOTE(anders): While it makes the code a bit more complex, reusing the + // args slice across each function increment saves a lot of resources + // compared to creating a new one inside each call to evalOneRule... so + // think twice before simplifying this :) + args := make([]*ast.Term, len(e.terms)-1) + var prev *ast.Term return withSuppressEarlyExit(func() error { var outerEe *deferredEarlyExitError for _, rule := range e.ir.Rules { - next, err := e.evalOneRule(iter, rule, cacheKey, prev, findOne) + copy(args, rule.Head.Args) + if len(args) == len(rule.Head.Args)+1 { + args[len(args)-1] = rule.Head.Value + } + + next, err := e.evalOneRule(iter, rule, args, cacheKey, prev, findOne) if err != nil { if oee, ok := err.(*deferredEarlyExitError); ok { if outerEe == nil { @@ -1882,7 +2096,12 @@ func (e evalFunc) evalValue(iter unifyIterator, argCount int, findOne bool) erro } if next == nil { for _, erule := range e.ir.Else[rule] { - next, err = e.evalOneRule(iter, erule, cacheKey, prev, findOne) + copy(args, erule.Head.Args) + if len(args) == len(erule.Head.Args)+1 { + args[len(args)-1] = erule.Head.Value + } + + next, err = e.evalOneRule(iter, erule, args, cacheKey, prev, findOne) if err != nil { if oee, ok := err.(*deferredEarlyExitError); ok { if outerEe == nil { @@ -1903,7 +2122,13 @@ func (e evalFunc) evalValue(iter unifyIterator, argCount int, findOne bool) erro } if e.ir.Default != nil && prev == nil { - _, err := e.evalOneRule(iter, e.ir.Default, cacheKey, prev, findOne) + copy(args, e.ir.Default.Head.Args) + if len(args) == len(e.ir.Default.Head.Args)+1 { + args[len(args)-1] = e.ir.Default.Head.Value + } + + _, err := e.evalOneRule(iter, e.ir.Default, args, cacheKey, prev, findOne) + return err } @@ -1922,9 +2147,15 @@ func (e evalFunc) evalCache(argCount int, iter unifyIterator) (ast.Ref, bool, er } else { plen = len(e.terms) } + cacheKey := make([]*ast.Term, plen) - for i := 0; i < plen; i++ { - cacheKey[i] = e.e.bindings.Plug(e.terms[i]) + for i := range plen { + if e.terms[i].IsGround() { + // Avoid expensive copying of ref if it is ground. + cacheKey[i] = e.terms[i] + } else { + cacheKey[i] = e.e.bindings.Plug(e.terms[i]) + } } cached, _ := e.e.virtualCache.Get(cacheKey) @@ -1943,23 +2174,18 @@ func (e evalFunc) evalCache(argCount int, iter unifyIterator) (ast.Ref, bool, er return cacheKey, false, nil } -func (e evalFunc) evalOneRule(iter unifyIterator, rule *ast.Rule, cacheKey ast.Ref, prev *ast.Term, findOne bool) (*ast.Term, error) { +func (e evalFunc) evalOneRule(iter unifyIterator, rule *ast.Rule, args []*ast.Term, cacheKey ast.Ref, prev *ast.Term, findOne bool) (*ast.Term, error) { + child := evalPool.Get() + defer evalPool.Put(child) - child := e.e.child(rule.Body) + e.e.child(rule.Body, child) child.findOne = findOne - args := make([]*ast.Term, len(e.terms)-1) - copy(args, rule.Head.Args) - - if len(args) == len(rule.Head.Args)+1 { - args[len(args)-1] = rule.Head.Value - } - var result *ast.Term child.traceEnter(rule) - err := child.biunifyArrays(ast.NewArray(e.terms[1:]...), ast.NewArray(args...), e.e.bindings, child.bindings, func() error { + err := child.biunifyTerms(e.terms[1:], args, e.e.bindings, child.bindings, func() error { return child.eval(func(child *eval) error { child.traceExit(rule) @@ -1976,28 +2202,24 @@ func (e evalFunc) evalOneRule(iter unifyIterator, rule *ast.Rule, cacheKey ast.R e.e.virtualCache.Put(cacheKey, result) // the redos confirm this, or the evaluation is aborted } - if len(rule.Head.Args) == len(e.terms)-1 { - if result.Value.Compare(ast.Boolean(false)) == 0 { - if prev != nil && ast.Compare(prev, result) != 0 { - return functionConflictErr(rule.Location) - } - prev = result - return nil + if len(rule.Head.Args) == len(e.terms)-1 && ast.Boolean(false).Equal(result.Value) { + if prev != nil && !prev.Equal(result) { + return functionConflictErr(rule.Location) } + prev = result + return nil } // Partial evaluation should explore all rules and may not produce // a ground result so we do not perform conflict detection or // deduplication. See "ignore conflicts: functions" test case for // an example. - if !e.e.partial() { - if prev != nil { - if ast.Compare(prev, result) != 0 { - return functionConflictErr(rule.Location) - } - child.traceRedo(rule) - return nil + if !e.e.partial() && prev != nil { + if !prev.Equal(result) { + return functionConflictErr(rule.Location) } + child.traceRedo(rule) + return nil } prev = result @@ -2017,7 +2239,6 @@ func (e evalFunc) evalOneRule(iter unifyIterator, rule *ast.Rule, cacheKey ast.R func (e evalFunc) partialEvalSupport(declArgsLen int, iter unifyIterator) error { path := e.e.namespaceRef(e.ref) - term := ast.NewTerm(path) if !e.e.saveSupport.Exists(path) { for _, rule := range e.ir.Rules { @@ -2026,18 +2247,29 @@ func (e evalFunc) partialEvalSupport(declArgsLen int, iter unifyIterator) error return err } } + + if e.ir.Default != nil { + err := e.partialEvalSupportRule(e.ir.Default, path) + if err != nil { + return err + } + } } if !e.e.saveSupport.Exists(path) { // we haven't saved anything, nothing to call return nil } + term := ast.NewTerm(path) + return e.e.saveCall(declArgsLen, append([]*ast.Term{term}, e.terms[1:]...), iter) } func (e evalFunc) partialEvalSupportRule(rule *ast.Rule, path ast.Ref) error { + child := evalPool.Get() + defer evalPool.Put(child) - child := e.e.child(rule.Body) + e.e.child(rule.Body, child) child.traceEnter(rule) e.e.saveStack.PushQuery(nil) @@ -2070,8 +2302,9 @@ func (e evalFunc) partialEvalSupportRule(rule *ast.Rule, path ast.Ref) error { } e.e.saveSupport.Insert(path, &ast.Rule{ - Head: head, - Body: plugged, + Head: head, + Body: plugged, + Default: rule.Default, }) } child.traceRedo(rule) @@ -2084,15 +2317,48 @@ func (e evalFunc) partialEvalSupportRule(rule *ast.Rule, path ast.Ref) error { return err } +type deferredEarlyExitContainer struct { + deferred *deferredEarlyExitError +} + +func (dc *deferredEarlyExitContainer) handleErr(err error) error { + if err == nil { + return nil + } + + if dc.deferred == nil && errors.As(err, &dc.deferred) && dc.deferred != nil { + return nil + } + + return err +} + +// copyError returns a copy of the deferred early exit error if one is present. +// This exists only to allow the container to be reused. +func (dc *deferredEarlyExitContainer) copyError() *deferredEarlyExitError { + if dc.deferred == nil { + return nil + } + + cpy := *dc.deferred + return &cpy +} + +var deecPool = sync.Pool{ + New: func() any { + return &deferredEarlyExitContainer{} + }, +} + type evalTree struct { e *eval - ref ast.Ref - plugged ast.Ref - pos int bindings *bindings rterm *ast.Term rbindings *bindings node *ast.TreeNode + ref ast.Ref + plugged ast.Ref + pos int } func (e evalTree) eval(iter unifyIterator) error { @@ -2115,9 +2381,7 @@ func (e evalTree) finish(iter unifyIterator) error { // In some cases, it may not be possible to PE the ref. If the path refers // to virtual docs that PE does not support or base documents where inlining // has been disabled, then we have to save. - save := e.e.unknown(e.plugged, e.e.bindings) - - if save { + if e.e.partial() && e.e.unknown(e.plugged, e.e.bindings) { return e.e.saveUnify(ast.NewTerm(e.plugged), e.rterm, e.bindings, e.rbindings, iter) } @@ -2171,28 +2435,20 @@ func (e evalTree) enumerate(iter unifyIterator) error { return err } - var deferredEe *deferredEarlyExitError - handleErr := func(err error) error { - var dee *deferredEarlyExitError - if errors.As(err, &dee) { - if deferredEe == nil { - deferredEe = dee - } - return nil - } - return err - } + dc := deecPool.Get().(*deferredEarlyExitContainer) + dc.deferred = nil + defer deecPool.Put(dc) if doc != nil { switch doc := doc.(type) { case *ast.Array: - for i := 0; i < doc.Len(); i++ { - k := ast.IntNumberTerm(i) + for i := range doc.Len() { + k := ast.InternedIntNumberTerm(i) err := e.e.biunify(k, e.ref[e.pos], e.bindings, e.bindings, func() error { return e.next(iter, k) }) - if err := handleErr(err); err != nil { + if err := dc.handleErr(err); err != nil { return err } } @@ -2202,7 +2458,7 @@ func (e evalTree) enumerate(iter unifyIterator) error { err := e.e.biunify(k, e.ref[e.pos], e.bindings, e.bindings, func() error { return e.next(iter, k) }) - if err := handleErr(err); err != nil { + if err := dc.handleErr(err); err != nil { return err } } @@ -2211,15 +2467,15 @@ func (e evalTree) enumerate(iter unifyIterator) error { err := e.e.biunify(elem, e.ref[e.pos], e.bindings, e.bindings, func() error { return e.next(iter, elem) }) - return handleErr(err) + return dc.handleErr(err) }); err != nil { return err } } } - if deferredEe != nil { - return deferredEe + if dc.deferred != nil { + return dc.copyError() } if e.node == nil { @@ -2317,12 +2573,12 @@ func (e evalTree) leaves(plugged ast.Ref, node *ast.TreeNode) (ast.Object, error type evalVirtual struct { e *eval - ref ast.Ref - plugged ast.Ref - pos int bindings *bindings rterm *ast.Term rbindings *bindings + ref ast.Ref + plugged ast.Ref + pos int } func (e evalVirtual) eval(iter unifyIterator) error { @@ -2393,14 +2649,14 @@ func (e evalVirtual) eval(iter unifyIterator) error { type evalVirtualPartial struct { e *eval - ref ast.Ref - plugged ast.Ref - pos int ir *ast.IndexResult bindings *bindings rterm *ast.Term rbindings *bindings empty *ast.Term + ref ast.Ref + plugged ast.Ref + pos int } type evalVirtualPartialCacheHint struct { @@ -2442,7 +2698,7 @@ func maxRefLength(rules []*ast.Rule, ceil int) int { for _, r := range rules { rl := len(r.Ref()) if r.Head.RuleKind() == ast.MultiValue { - rl = rl + 1 + rl++ } if rl >= ceil { return ceil @@ -2459,14 +2715,16 @@ func (e evalVirtualPartial) evalEachRule(iter unifyIterator, unknown bool) error return nil } - m := maxRefLength(e.ir.Rules, len(e.ref)) - if e.e.unknown(e.ref[e.pos+1:m], e.bindings) { - for _, rule := range e.ir.Rules { - if err := e.evalOneRulePostUnify(iter, rule); err != nil { - return err + if e.e.partial() { + m := maxRefLength(e.ir.Rules, len(e.ref)) + if e.e.unknown(e.ref[e.pos+1:m], e.bindings) { + for _, rule := range e.ir.Rules { + if err := e.evalOneRulePostUnify(iter, rule); err != nil { + return err + } } + return nil } - return nil } hint, err := e.evalCache(iter) @@ -2536,8 +2794,11 @@ func (e evalVirtualPartial) evalAllRulesNoCache(rules []*ast.Rule) (*ast.Term, e var visitedRefs []ast.Ref + child := evalPool.Get() + defer evalPool.Put(child) + for _, rule := range rules { - child := e.e.child(rule.Body) + e.e.child(rule.Body, child) child.traceEnter(rule) err := child.eval(func(*eval) error { child.traceExit(rule) @@ -2570,8 +2831,10 @@ func wrapInObjects(leaf *ast.Term, ref ast.Ref) *ast.Term { } func (e evalVirtualPartial) evalOneRulePreUnify(iter unifyIterator, rule *ast.Rule, result *ast.Term, unknown bool, visitedRefs *[]ast.Ref) (*ast.Term, error) { + child := evalPool.Get() + defer evalPool.Put(child) - child := e.e.child(rule.Body) + e.e.child(rule.Body, child) child.traceEnter(rule) var defined bool @@ -2663,7 +2926,10 @@ func (e *eval) biunifyDynamicRef(pos int, a, b ast.Ref, b1, b2 *bindings, iter u } func (e evalVirtualPartial) evalOneRulePostUnify(iter unifyIterator, rule *ast.Rule) error { - child := e.e.child(rule.Body) + child := evalPool.Get() + defer evalPool.Put(child) + + e.e.child(rule.Body, child) child.traceEnter(rule) var defined bool @@ -2747,8 +3013,10 @@ func (e evalVirtualPartial) partialEvalSupport(iter unifyIterator) error { } func (e evalVirtualPartial) partialEvalSupportRule(rule *ast.Rule, _ ast.Ref) (bool, error) { + child := evalPool.Get() + defer evalPool.Put(child) - child := e.e.child(rule.Body) + e.e.child(rule.Body, child) child.traceEnter(rule) e.e.saveStack.PushQuery(nil) @@ -2977,7 +3245,7 @@ func (q vcKeyScope) Hash() int { return hash } -func (q vcKeyScope) IsGround() bool { +func (vcKeyScope) IsGround() bool { return false } @@ -3111,13 +3379,13 @@ func (e evalVirtualPartial) reduce(rule *ast.Rule, b *bindings, result *ast.Term type evalVirtualComplete struct { e *eval - ref ast.Ref - plugged ast.Ref - pos int ir *ast.IndexResult bindings *bindings rterm *ast.Term rbindings *bindings + ref ast.Ref + plugged ast.Ref + pos int } func (e evalVirtualComplete) eval(iter unifyIterator) error { @@ -3226,8 +3494,10 @@ func (e evalVirtualComplete) evalValue(iter unifyIterator, findOne bool) error { } func (e evalVirtualComplete) evalValueRule(iter unifyIterator, rule *ast.Rule, prev *ast.Term, findOne bool) (*ast.Term, error) { + child := evalPool.Get() + defer evalPool.Put(child) - child := e.e.child(rule.Body) + e.e.child(rule.Body, child) child.findOne = findOne child.traceEnter(rule) var result *ast.Term @@ -3262,9 +3532,11 @@ func (e evalVirtualComplete) evalValueRule(iter unifyIterator, rule *ast.Rule, p } func (e evalVirtualComplete) partialEval(iter unifyIterator) error { + child := evalPool.Get() + defer evalPool.Put(child) for _, rule := range e.ir.Rules { - child := e.e.child(rule.Body) + e.e.child(rule.Body, child) child.traceEnter(rule) err := child.eval(func(child *eval) error { @@ -3327,8 +3599,10 @@ func (e evalVirtualComplete) partialEvalSupport(iter unifyIterator) error { } func (e evalVirtualComplete) partialEvalSupportRule(rule *ast.Rule, path ast.Ref) (bool, error) { + child := evalPool.Get() + defer evalPool.Put(child) - child := e.e.child(rule.Body) + e.e.child(rule.Body, child) child.traceEnter(rule) e.e.saveStack.PushQuery(nil) @@ -3383,13 +3657,13 @@ func (e evalVirtualComplete) evalTerm(iter unifyIterator, term *ast.Term, termbi type evalTerm struct { e *eval - ref ast.Ref - pos int bindings *bindings term *ast.Term termbindings *bindings rterm *ast.Term rbindings *bindings + ref ast.Ref + pos int } func (e evalTerm) eval(iter unifyIterator) error { @@ -3440,33 +3714,56 @@ func (e evalTerm) enumerate(iter unifyIterator) error { switch v := e.term.Value.(type) { case *ast.Array: - for i := 0; i < v.Len(); i++ { - k := ast.IntNumberTerm(i) - err := e.e.biunify(k, e.ref[e.pos], e.bindings, e.bindings, func() error { - return e.next(iter, k) - }) + // Note(anders): + // For this case (e.g. input.foo[_]), we can avoid the (quite expensive) overhead of a callback + // function literal escaping to the heap in each iteration by inlining the biunification logic, + // meaning a 10x reduction in both the number of allocations made as well as the memory consumed. + // It is possible that such inlining could be done for the set/object cases as well, and that's + // worth looking into later, as I imagine set iteration in particular would be an even greater + // win across most policies. Those cases are however much more complex, as we need to deal with + // any type on either side, not just int/var as is the case here. + for i := range v.Len() { + a := ast.InternedIntNumberTerm(i) + b := e.ref[e.pos] + + if _, ok := b.Value.(ast.Var); ok { + if e.e.traceEnabled { + e.e.traceUnify(a, b) + } + var undo undo + b, e.bindings = e.bindings.apply(b) + e.bindings.bind(b, a, e.bindings, &undo) - if err := handleErr(err); err != nil { - return err + err := e.next(iter, a) + undo.Undo() + if err != nil { + if err := handleErr(err); err != nil { + return err + } + } } } case ast.Object: - if err := v.Iter(func(k, _ *ast.Term) error { + for _, k := range v.Keys() { err := e.e.biunify(k, e.ref[e.pos], e.termbindings, e.bindings, func() error { return e.next(iter, e.termbindings.Plug(k)) }) - return handleErr(err) - }); err != nil { - return err + if err != nil { + if err := handleErr(err); err != nil { + return err + } + } } case ast.Set: - if err := v.Iter(func(elem *ast.Term) error { + for _, elem := range v.Slice() { err := e.e.biunify(elem, e.ref[e.pos], e.termbindings, e.bindings, func() error { return e.next(iter, e.termbindings.Plug(elem)) }) - return handleErr(err) - }); err != nil { - return err + if err != nil { + if err := handleErr(err); err != nil { + return err + } + } } } @@ -3569,7 +3866,11 @@ func (e evalEvery) eval(iter unifyIterator) error { ).SetLocation(e.Domain.Location), ) - domain := e.e.closure(generator) + domain := evalPool.Get() + defer evalPool.Put(domain) + + e.e.closure(generator, domain) + all := true // all generator evaluations yield one successful body evaluation domain.traceEnter(e.expr) @@ -3580,7 +3881,11 @@ func (e evalEvery) eval(iter unifyIterator) error { // This would do extra work, like iterating needlessly if domain was a large array. return nil } - body := child.closure(e.Body) + + body := evalPool.Get() + defer evalPool.Put(body) + + child.closure(e.Body, body) body.findOne = true body.traceEnter(e.Body) done := false @@ -3707,10 +4012,12 @@ func applyCopyPropagation(p *copypropagation.CopyPropagator, instr *Instrumentat return result } +func nonGroundKey(k, _ *ast.Term) bool { + return !k.IsGround() +} + func nonGroundKeys(a ast.Object) bool { - return a.Until(func(k, _ *ast.Term) bool { - return !k.IsGround() - }) + return a.Until(nonGroundKey) } func plugKeys(a ast.Object, b *bindings) ast.Object { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/glob.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/glob.go similarity index 85% rename from vendor/github.com/open-policy-agent/opa/topdown/glob.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/glob.go index baf092ab6d..efaf1d1248 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/glob.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/glob.go @@ -6,15 +6,17 @@ import ( "github.com/gobwas/glob" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) const globCacheMaxSize = 100 const globInterQueryValueCacheHits = "rego_builtin_glob_interquery_value_cache_hits" -var globCacheLock = sync.Mutex{} -var globCache map[string]glob.Glob +var noDelimiters = []rune{} +var dotDelimiters = []rune{'.'} +var globCacheLock = sync.RWMutex{} +var globCache = map[string]glob.Glob{} func builtinGlobMatch(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { pattern, err := builtins.StringOperand(operands[0].Value, 1) @@ -25,14 +27,14 @@ func builtinGlobMatch(bctx BuiltinContext, operands []*ast.Term, iter func(*ast. var delimiters []rune switch operands[1].Value.(type) { case ast.Null: - delimiters = []rune{} + delimiters = noDelimiters case *ast.Array: delimiters, err = builtins.RuneSliceOperand(operands[1].Value, 2) if err != nil { return err } if len(delimiters) == 0 { - delimiters = []rune{'.'} + delimiters = dotDelimiters } default: return builtins.NewOperandTypeErr(2, operands[1].Value, "array", "null") @@ -55,12 +57,13 @@ func builtinGlobMatch(bctx BuiltinContext, operands []*ast.Term, iter func(*ast. if err != nil { return err } - return iter(ast.BooleanTerm(m)) + return iter(ast.InternedBooleanTerm(m)) } func globCompileAndMatch(bctx BuiltinContext, id, pattern, match string, delimiters []rune) (bool, error) { if bctx.InterQueryBuiltinValueCache != nil { + // TODO: Use named cache val, ok := bctx.InterQueryBuiltinValueCache.Get(ast.String(id)) if ok { pat, valid := val.(glob.Glob) @@ -86,14 +89,15 @@ func globCompileAndMatch(bctx BuiltinContext, id, pattern, match string, delimit return res.Match(match), nil } - globCacheLock.Lock() - defer globCacheLock.Unlock() + globCacheLock.RLock() p, ok := globCache[id] + globCacheLock.RUnlock() if !ok { var err error if p, err = glob.Compile(pattern, delimiters...); err != nil { return false, err } + globCacheLock.Lock() if len(globCache) >= globCacheMaxSize { // Delete a (semi-)random key to make room for the new one. for k := range globCache { @@ -102,9 +106,10 @@ func globCompileAndMatch(bctx BuiltinContext, id, pattern, match string, delimit } } globCache[id] = p + globCacheLock.Unlock() } - out := p.Match(match) - return out, nil + + return p.Match(match), nil } func builtinGlobQuoteMeta(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -117,7 +122,6 @@ func builtinGlobQuoteMeta(_ BuiltinContext, operands []*ast.Term, iter func(*ast } func init() { - globCache = map[string]glob.Glob{} RegisterBuiltinFunc(ast.GlobMatch.Name, builtinGlobMatch) RegisterBuiltinFunc(ast.GlobQuoteMeta.Name, builtinGlobQuoteMeta) } diff --git a/vendor/github.com/open-policy-agent/opa/topdown/graphql.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/graphql.go similarity index 54% rename from vendor/github.com/open-policy-agent/opa/topdown/graphql.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/graphql.go index 8fb1b58a76..c887041cd7 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/graphql.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/graphql.go @@ -16,8 +16,9 @@ import ( // Side-effecting import. Triggers GraphQL library's validation rule init() functions. _ "github.com/open-policy-agent/opa/internal/gqlparser/validator/rules" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" + "github.com/open-policy-agent/opa/v1/topdown/cache" ) // Parses a GraphQL schema, and returns the GraphQL AST for the schema. @@ -160,7 +161,7 @@ func pruneIrrelevantGraphQLASTNodes(value ast.Value) ast.Value { // Iterate over the array's elements, and do the following: // - Drop any Nulls // - Drop any any empty object/array value (after running the pruner) - for i := 0; i < x.Len(); i++ { + for i := range x.Len() { vTerm := x.Elem(i) switch v := vTerm.Value.(type) { case ast.Null: @@ -174,7 +175,7 @@ func pruneIrrelevantGraphQLASTNodes(value ast.Value) ast.Value { case ast.Object: // Safe, because we knew the type before going to prune it. vo := pruneIrrelevantGraphQLASTNodes(v).(ast.Object) - if len(vo.Keys()) > 0 { + if vo.Len() > 0 { result = result.Append(ast.NewTerm(vo)) } default: @@ -209,7 +210,7 @@ func pruneIrrelevantGraphQLASTNodes(value ast.Value) ast.Value { case ast.Object: // Safe, because we knew the type before going to prune it. vo := pruneIrrelevantGraphQLASTNodes(v).(ast.Object) - if len(vo.Keys()) > 0 { + if vo.Len() > 0 { result.Insert(k, ast.NewTerm(vo)) } default: @@ -223,9 +224,11 @@ func pruneIrrelevantGraphQLASTNodes(value ast.Value) ast.Value { } // Reports errors from parsing/validation. -func builtinGraphQLParse(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { +func builtinGraphQLParse(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { var queryDoc *gqlast.QueryDocument var schemaDoc *gqlast.SchemaDocument + var schemaASTValue ast.Value + var querySchema ast.Value var err error // Parse/translate query if it's a string/object. @@ -242,42 +245,56 @@ func builtinGraphQLParse(_ BuiltinContext, operands []*ast.Term, iter func(*ast. return err } - // Parse/translate schema if it's a string/object. - switch x := operands[1].Value.(type) { - case ast.String: - schemaDoc, err = parseSchema(string(x)) - case ast.Object: - schemaDoc, err = objectToSchemaDocument(x) - default: - // Error if wrong type. - return builtins.NewOperandTypeErr(1, x, "string", "object") - } - if err != nil { - return err - } + schemaCacheKey, schema := cacheGetSchema(bctx, operands[1]) + schemaASTCacheKey, querySchema := cacheGetSchemaAST(bctx, operands[1]) + if schema == nil || querySchema == nil { + // Parse/translate schema if it's a string/object. + switch x := operands[1].Value.(type) { + case ast.String: + schemaDoc, err = parseSchema(string(x)) + case ast.Object: + schemaDoc, err = objectToSchemaDocument(x) + default: + // Error if wrong type. + return builtins.NewOperandTypeErr(1, x, "string", "object") + } + if err != nil { + return err + } + + // Convert SchemaDoc to Object before validating and converting it to a Schema + // This precludes inclusion of extra definitions from the default GraphQL schema + if querySchema == nil { + schemaASTValue, err = ast.InterfaceToValue(schemaDoc) + if err != nil { + return err + } + querySchema = pruneIrrelevantGraphQLASTNodes(schemaASTValue.(ast.Object)) + cacheInsertSchemaAST(bctx, schemaASTCacheKey, querySchema) + } + + // Validate the query against the schema, erroring if there's an issue. + if schema == nil { + schema, err = convertSchema(schemaDoc) + if err != nil { + return err + } + cacheInsertSchema(bctx, schemaCacheKey, schema) + } + } // Transform the ASTs into Objects. queryASTValue, err := ast.InterfaceToValue(queryDoc) if err != nil { return err } - schemaASTValue, err := ast.InterfaceToValue(schemaDoc) - if err != nil { - return err - } - // Validate the query against the schema, erroring if there's an issue. - schema, err := convertSchema(schemaDoc) - if err != nil { - return err - } if err := validateQuery(schema, queryDoc); err != nil { return err } // Recursively remove irrelevant AST structures. queryResult := pruneIrrelevantGraphQLASTNodes(queryASTValue.(ast.Object)) - querySchema := pruneIrrelevantGraphQLASTNodes(schemaASTValue.(ast.Object)) // Construct return value. verified := ast.ArrayTerm( @@ -289,13 +306,15 @@ func builtinGraphQLParse(_ BuiltinContext, operands []*ast.Term, iter func(*ast. } // Returns default value when errors occur. -func builtinGraphQLParseAndVerify(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { +func builtinGraphQLParseAndVerify(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { var queryDoc *gqlast.QueryDocument var schemaDoc *gqlast.SchemaDocument + var schemaASTValue ast.Value + var querySchema ast.Value var err error unverified := ast.ArrayTerm( - ast.BooleanTerm(false), + ast.InternedBooleanTerm(false), ast.NewTerm(ast.NewObject()), ast.NewTerm(ast.NewObject()), ) @@ -314,46 +333,61 @@ func builtinGraphQLParseAndVerify(_ BuiltinContext, operands []*ast.Term, iter f return iter(unverified) } - // Parse/translate schema if it's a string/object. - switch x := operands[1].Value.(type) { - case ast.String: - schemaDoc, err = parseSchema(string(x)) - case ast.Object: - schemaDoc, err = objectToSchemaDocument(x) - default: - // Error if wrong type. - return iter(unverified) - } - if err != nil { - return iter(unverified) - } - // Transform the ASTs into Objects. queryASTValue, err := ast.InterfaceToValue(queryDoc) if err != nil { return iter(unverified) } - schemaASTValue, err := ast.InterfaceToValue(schemaDoc) - if err != nil { - return iter(unverified) + + schemaCacheKey, schema := cacheGetSchema(bctx, operands[1]) + schemaASTCacheKey, querySchema := cacheGetSchemaAST(bctx, operands[1]) + if schema == nil || querySchema == nil { + // Parse/translate schema if it's a string/object. + switch x := operands[1].Value.(type) { + case ast.String: + schemaDoc, err = parseSchema(string(x)) + case ast.Object: + schemaDoc, err = objectToSchemaDocument(x) + default: + // Error if wrong type. + return iter(unverified) + } + if err != nil { + return iter(unverified) + } + + // Convert SchemaDoc to Object before validating and converting it to a Schema + // This precludes inclusion of extra definitions from the default GraphQL schema + if querySchema == nil { + schemaASTValue, err = ast.InterfaceToValue(schemaDoc) + if err != nil { + return iter(unverified) + } + querySchema = pruneIrrelevantGraphQLASTNodes(schemaASTValue.(ast.Object)) + cacheInsertSchemaAST(bctx, schemaASTCacheKey, querySchema) + } + + if schema == nil { + schema, err = convertSchema(schemaDoc) + if err != nil { + return iter(unverified) + } + cacheInsertSchema(bctx, schemaCacheKey, schema) + } + } // Validate the query against the schema, erroring if there's an issue. - schema, err := convertSchema(schemaDoc) - if err != nil { - return iter(unverified) - } if err := validateQuery(schema, queryDoc); err != nil { return iter(unverified) } // Recursively remove irrelevant AST structures. queryResult := pruneIrrelevantGraphQLASTNodes(queryASTValue.(ast.Object)) - querySchema := pruneIrrelevantGraphQLASTNodes(schemaASTValue.(ast.Object)) // Construct return value. verified := ast.ArrayTerm( - ast.BooleanTerm(true), + ast.InternedBooleanTerm(true), ast.NewTerm(queryResult), ast.NewTerm(querySchema), ) @@ -385,33 +419,43 @@ func builtinGraphQLParseQuery(_ BuiltinContext, operands []*ast.Term, iter func( return iter(ast.NewTerm(result)) } -func builtinGraphQLParseSchema(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - raw, err := builtins.StringOperand(operands[0].Value, 1) - if err != nil { - return err - } +func builtinGraphQLParseSchema(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + schemaDocCacheKey, schemaDoc := cacheGetSchemaDoc(bctx, operands[0]) + if schemaDoc == nil { + raw, err := builtins.StringOperand(operands[0].Value, 1) + if err != nil { + return err + } - // Get the highly-nested AST struct, along with any errors generated. - schema, err := parseSchema(string(raw)) - if err != nil { - return err + // Get the highly-nested AST struct, along with any errors generated. + schemaDoc, err = parseSchema(string(raw)) + if err != nil { + return err + } + // Note SchemaDoc is not validated + cacheInsertSchemaDoc(bctx, schemaDocCacheKey, schemaDoc) } - // Transform the AST into an Object. - value, err := ast.InterfaceToValue(schema) - if err != nil { - return err - } + schemaASTCacheKey, schemaAST := cacheGetSchemaAST(bctx, operands[0]) + if schemaAST == nil { - // Recursively remove irrelevant AST structures. - result := pruneIrrelevantGraphQLASTNodes(value.(ast.Object)) + // Transform the AST into an Object. + value, err := ast.InterfaceToValue(schemaDoc) + if err != nil { + return err + } - return iter(ast.NewTerm(result)) + // Recursively remove irrelevant AST structures. + schemaAST = pruneIrrelevantGraphQLASTNodes(value.(ast.Object)) + cacheInsertSchemaAST(bctx, schemaASTCacheKey, schemaAST) + } + return iter(ast.NewTerm(schemaAST)) } -func builtinGraphQLIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { +func builtinGraphQLIsValid(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { var queryDoc *gqlast.QueryDocument var schemaDoc *gqlast.SchemaDocument + var schema *gqlast.Schema var err error switch x := operands[0].Value.(type) { @@ -421,61 +465,205 @@ func builtinGraphQLIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*as queryDoc, err = objectToQueryDocument(x) default: // Error if wrong type. - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } if err != nil { - return iter(ast.BooleanTerm(false)) - } + return iter(ast.InternedBooleanTerm(false)) + } + + schemaCacheKey, schema := cacheGetSchema(bctx, operands[1]) + if schema == nil { + switch x := operands[1].Value.(type) { + case ast.String: + schemaDoc, err = parseSchema(string(x)) + case ast.Object: + schemaDoc, err = objectToSchemaDocument(x) + default: + // Error if wrong type. + return iter(ast.InternedBooleanTerm(false)) + } + if err != nil { + return iter(ast.InternedBooleanTerm(false)) + } - switch x := operands[1].Value.(type) { - case ast.String: - schemaDoc, err = parseSchema(string(x)) - case ast.Object: - schemaDoc, err = objectToSchemaDocument(x) - default: - // Error if wrong type. - return iter(ast.BooleanTerm(false)) - } - if err != nil { - return iter(ast.BooleanTerm(false)) + // Validate the query against the schema, erroring if there's an issue. + schema, err = convertSchema(schemaDoc) + if err != nil { + return iter(ast.InternedBooleanTerm(false)) + } + cacheInsertSchema(bctx, schemaCacheKey, schema) } - // Validate the query against the schema, erroring if there's an issue. - schema, err := convertSchema(schemaDoc) - if err != nil { - return iter(ast.BooleanTerm(false)) - } if err := validateQuery(schema, queryDoc); err != nil { - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } // If we got this far, the GraphQL query passed validation. - return iter(ast.BooleanTerm(true)) + return iter(ast.InternedBooleanTerm(true)) } -func builtinGraphQLSchemaIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - var schemaDoc *gqlast.SchemaDocument +func builtinGraphQLSchemaIsValid(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { var err error - switch x := operands[0].Value.(type) { - case ast.String: - schemaDoc, err = parseSchema(string(x)) - case ast.Object: - schemaDoc, err = objectToSchemaDocument(x) - default: - // Error if wrong type. - return iter(ast.BooleanTerm(false)) + // Schemas are only cached if they are valid + schemaCacheKey, schema := cacheGetSchema(bctx, operands[0]) + if schema == nil { + var schemaDoc *gqlast.SchemaDocument + var validatedSchema *gqlast.Schema + + switch x := operands[0].Value.(type) { + case ast.String: + schemaDoc, err = parseSchema(string(x)) + case ast.Object: + schemaDoc, err = objectToSchemaDocument(x) + default: + // Error if wrong type. + return iter(ast.InternedBooleanTerm(false)) + } + if err != nil { + return iter(ast.InternedBooleanTerm(false)) + } + // Validate the schema, this determines the result + // and whether there is a schema to cache + validatedSchema, err = convertSchema(schemaDoc) + if err == nil { + cacheInsertSchema(bctx, schemaCacheKey, validatedSchema) + } } - if err != nil { - return iter(ast.BooleanTerm(false)) + + return iter(ast.InternedBooleanTerm(err == nil)) +} + +// Insert Schema into cache +func cacheInsertSchema(bctx BuiltinContext, key string, schema *gqlast.Schema) { + if bctx.InterQueryBuiltinValueCache == nil || key == "" { + return + } + cacheKey := ast.String(key) + c := bctx.InterQueryBuiltinValueCache.GetCache(gqlCacheName) + if c == nil { + return + } + c.Insert(cacheKey, schema) +} + +// Insert SchemaAST into cache +func cacheInsertSchemaAST(bctx BuiltinContext, key string, schemaAST ast.Value) { + if bctx.InterQueryBuiltinValueCache == nil || key == "" { + return + } + cacheKeyAST := ast.String(key) + c := bctx.InterQueryBuiltinValueCache.GetCache(gqlCacheName) + if c == nil { + return + } + c.Insert(cacheKeyAST, schemaAST) +} + +// Insert SchemaDocument into cache +func cacheInsertSchemaDoc(bctx BuiltinContext, key string, schemaDoc *gqlast.SchemaDocument) { + if bctx.InterQueryBuiltinValueCache == nil || key == "" { + return + } + cacheKey := ast.String(key) + c := bctx.InterQueryBuiltinValueCache.GetCache(gqlCacheName) + if c == nil { + return + } + c.Insert(cacheKey, schemaDoc) +} + +// Returns the cache key and a Schema if this key already exists in the cache +func cacheGetSchema(bctx BuiltinContext, t *ast.Term) (string, *gqlast.Schema) { + if bctx.InterQueryBuiltinValueCache != nil { + if c := bctx.InterQueryBuiltinValueCache.GetCache(gqlCacheName); c != nil { + if key, keyOk := cacheKeyWithPrefix(bctx, t, "gql_schema-"); keyOk { + if val, ok := c.Get(ast.String(key)); ok { + if schema, isSchema := val.(*gqlast.Schema); isSchema { + return key, schema + } + } + return key, nil + } + } + } + return "", nil +} + +// Returns the cache key and a SchemaDocument if this key already exists in the cache +// Note: the SchemaDocument is not a validated Schema +func cacheGetSchemaDoc(bctx BuiltinContext, t *ast.Term) (string, *gqlast.SchemaDocument) { + if bctx.InterQueryBuiltinValueCache != nil { + if c := bctx.InterQueryBuiltinValueCache.GetCache(gqlCacheName); c != nil { + if key, keyOk := cacheKeyWithPrefix(bctx, t, "gql_schema_doc-"); keyOk { + if val, ok := c.Get(ast.String(key)); ok { + if schemaDoc, isSchemaDoc := val.(*gqlast.SchemaDocument); isSchemaDoc { + return key, schemaDoc + } + } + return key, nil + } + } + } + return "", nil +} + +// Returns the cache key and a SchemaDocument if this key already exists in the cache +// Note: the AST should be pruned +func cacheGetSchemaAST(bctx BuiltinContext, t *ast.Term) (string, ast.Value) { + if bctx.InterQueryBuiltinValueCache != nil { + if c := bctx.InterQueryBuiltinValueCache.GetCache(gqlCacheName); c != nil { + if key, keyOk := cacheKeyWithPrefix(bctx, t, "gql_schema_ast-"); keyOk { + if val, ok := c.Get(ast.String(key)); ok { + if schemaAST, isSchemaAST := val.(ast.Value); isSchemaAST { + return key, schemaAST + } + } + return key, nil + } + } + } + return "", nil +} + +// Compute a constant size key for use with the cache +func cacheKeyWithPrefix(bctx BuiltinContext, t *ast.Term, prefix string) (string, bool) { + var cacheKey ast.String + var ok = false + + if bctx.InterQueryBuiltinValueCache != nil { + switch t.Value.(type) { + case ast.String: + err := builtinCryptoSha256(bctx, []*ast.Term{t}, func(term *ast.Term) error { + cacheKey = term.Value.(ast.String) + return nil + }) + ok = (len(cacheKey) > 0) && (err == nil) + case ast.Object: + objTerm := ast.StringTerm(t.String()) + err := builtinCryptoSha256(bctx, []*ast.Term{objTerm}, func(term *ast.Term) error { + cacheKey = term.Value.(ast.String) + return nil + }) + ok = (len(cacheKey) > 0) && (err == nil) + default: + ok = false + } } - // Validate the schema, this determines the result - _, err = convertSchema(schemaDoc) - return iter(ast.BooleanTerm(err == nil)) + return prefix + string(cacheKey), ok } +const gqlCacheName = "graphql" + func init() { + + var defaultCacheEntries int = 10 + var graphqlCacheConfig = cache.NamedValueCacheConfig{ + MaxNumEntries: &defaultCacheEntries, + } + cache.RegisterDefaultInterQueryBuiltinValueCacheConfig(gqlCacheName, &graphqlCacheConfig) + RegisterBuiltinFunc(ast.GraphQLParse.Name, builtinGraphQLParse) RegisterBuiltinFunc(ast.GraphQLParseAndVerify.Name, builtinGraphQLParseAndVerify) RegisterBuiltinFunc(ast.GraphQLParseQuery.Name, builtinGraphQLParseQuery) diff --git a/vendor/github.com/open-policy-agent/opa/topdown/http.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/http.go similarity index 90% rename from vendor/github.com/open-policy-agent/opa/topdown/http.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/http.go index 18bfd3c722..463f01de22 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/http.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/http.go @@ -10,6 +10,7 @@ import ( "crypto/tls" "crypto/x509" "encoding/json" + "errors" "fmt" "io" "math" @@ -22,12 +23,12 @@ import ( "strings" "time" - "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/internal/version" - "github.com/open-policy-agent/opa/topdown/builtins" - "github.com/open-policy-agent/opa/topdown/cache" - "github.com/open-policy-agent/opa/tracing" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" + "github.com/open-policy-agent/opa/v1/topdown/cache" + "github.com/open-policy-agent/opa/v1/tracing" + "github.com/open-policy-agent/opa/v1/util" ) type cachingMode string @@ -86,16 +87,33 @@ var cacheableHTTPStatusCodes = [...]int{ http.StatusNotImplemented, } +var ( + codeTerm = ast.StringTerm("code") + messageTerm = ast.StringTerm("message") + statusCodeTerm = ast.StringTerm("status_code") + errorTerm = ast.StringTerm("error") + methodTerm = ast.StringTerm("method") + urlTerm = ast.StringTerm("url") + + httpSendNetworkErrTerm = ast.StringTerm(HTTPSendNetworkErr) + httpSendInternalErrTerm = ast.StringTerm(HTTPSendInternalErr) +) + var ( allowedKeys = ast.NewSet() + keyCache = make(map[string]*ast.Term, len(allowedKeyNames)) cacheableCodes = ast.NewSet() - requiredKeys = ast.NewSet(ast.StringTerm("method"), ast.StringTerm("url")) - httpSendLatencyMetricKey = "rego_builtin_" + strings.ReplaceAll(ast.HTTPSend.Name, ".", "_") + requiredKeys = ast.NewSet(methodTerm, urlTerm) + httpSendLatencyMetricKey = "rego_builtin_http_send" httpSendInterQueryCacheHits = httpSendLatencyMetricKey + "_interquery_cache_hits" ) type httpSendKey string +// CustomizeRoundTripper allows customizing an existing http.Transport, +// to the returned value, which could be the same Transport or a new one. +type CustomizeRoundTripper func(*http.Transport) http.RoundTripper + const ( // httpSendBuiltinCacheKey is the key in the builtin context cache that // points to the http.send() specific cache resides at. @@ -147,22 +165,24 @@ func builtinHTTPSend(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.T } func generateRaiseErrorResult(err error) *ast.Term { - obj := ast.NewObject() - obj.Insert(ast.StringTerm("status_code"), ast.IntNumberTerm(0)) - - errObj := ast.NewObject() - + var errObj ast.Object switch err.(type) { case *url.Error: - errObj.Insert(ast.StringTerm("code"), ast.StringTerm(HTTPSendNetworkErr)) + errObj = ast.NewObject( + ast.Item(codeTerm, httpSendNetworkErrTerm), + ast.Item(messageTerm, ast.StringTerm(err.Error())), + ) default: - errObj.Insert(ast.StringTerm("code"), ast.StringTerm(HTTPSendInternalErr)) + errObj = ast.NewObject( + ast.Item(codeTerm, httpSendInternalErrTerm), + ast.Item(messageTerm, ast.StringTerm(err.Error())), + ) } - errObj.Insert(ast.StringTerm("message"), ast.StringTerm(err.Error())) - obj.Insert(ast.StringTerm("error"), ast.NewTerm(errObj)) - - return ast.NewTerm(obj) + return ast.NewTerm(ast.NewObject( + ast.Item(statusCodeTerm, ast.InternedIntNumberTerm(0)), + ast.Item(errorTerm, ast.NewTerm(errObj)), + )) } func getHTTPResponse(bctx BuiltinContext, req ast.Object) (*ast.Term, error) { @@ -208,21 +228,21 @@ func getHTTPResponse(bctx BuiltinContext, req ast.Object) (*ast.Term, error) { func getKeyFromRequest(req ast.Object) (ast.Object, error) { // deep copy so changes to key do not reflect in the request object key := req.Copy() - cacheIgnoredHeadersTerm := req.Get(ast.StringTerm("cache_ignored_headers")) + cacheIgnoredHeadersTerm := req.Get(keyCache["cache_ignored_headers"]) allHeadersTerm := req.Get(ast.StringTerm("headers")) // skip because no headers to delete if cacheIgnoredHeadersTerm == nil || allHeadersTerm == nil { // need to explicitly set cache_ignored_headers to null // equivalent requests might have different sets of exclusion lists - key.Insert(ast.StringTerm("cache_ignored_headers"), ast.NullTerm()) + key.Insert(ast.StringTerm("cache_ignored_headers"), ast.InternedNullTerm) return key, nil } var cacheIgnoredHeaders []string - var allHeaders map[string]interface{} err := ast.As(cacheIgnoredHeadersTerm.Value, &cacheIgnoredHeaders) if err != nil { return nil, err } + var allHeaders map[string]interface{} err = ast.As(allHeadersTerm.Value, &allHeaders) if err != nil { return nil, err @@ -234,14 +254,14 @@ func getKeyFromRequest(req ast.Object) (ast.Object, error) { if err != nil { return nil, err } - key.Insert(ast.StringTerm("headers"), ast.NewTerm(val)) + key.Insert(keyCache["headers"], ast.NewTerm(val)) // remove cache_ignored_headers key - key.Insert(ast.StringTerm("cache_ignored_headers"), ast.NullTerm()) + key.Insert(keyCache["cache_ignored_headers"], ast.InternedNullTerm) return key, nil } func init() { - createAllowedKeys() + createKeys() createCacheableHTTPStatusCodes() initDefaults() RegisterBuiltinFunc(ast.HTTPSend.Name, builtinHTTPSend) @@ -385,33 +405,24 @@ func verifyURLHost(bctx BuiltinContext, unverifiedURL string) error { } func createHTTPRequest(bctx BuiltinContext, obj ast.Object) (*http.Request, *http.Client, error) { - var url string - var method string - - // Additional CA certificates loading options. - var tlsCaCert []byte - var tlsCaCertEnvVar string - var tlsCaCertFile string - - // Client TLS certificate and key options. Each input source - // comes in a matched pair. - var tlsClientCert []byte - var tlsClientKey []byte - - var tlsClientCertEnvVar string - var tlsClientKeyEnvVar string - - var tlsClientCertFile string - var tlsClientKeyFile string - - var tlsServerName string - var body *bytes.Buffer - var rawBody *bytes.Buffer - var enableRedirect bool - var tlsUseSystemCerts *bool - var tlsConfig tls.Config - var customHeaders map[string]interface{} - var tlsInsecureSkipVerify bool + var ( + url, method string + // Additional CA certificates loading options. + tlsCaCert []byte + tlsCaCertEnvVar, tlsCaCertFile string + // Client TLS certificate and key options. Each input source + // comes in a matched pair. + tlsClientCert, tlsClientKey []byte + tlsClientCertEnvVar, tlsClientKeyEnvVar string + tlsClientCertFile, tlsClientKeyFile, tlsServerName string + + body, rawBody *bytes.Buffer + enableRedirect, tlsInsecureSkipVerify bool + tlsUseSystemCerts *bool + tlsConfig tls.Config + customHeaders map[string]interface{} + ) + timeout := defaultHTTPRequestTimeout for _, val := range obj.Keys() { @@ -509,7 +520,7 @@ func createHTTPRequest(bctx BuiltinContext, obj ast.Object) (*http.Request, *htt var ok bool customHeaders, ok = headersValInterface.(map[string]interface{}) if !ok { - return nil, nil, fmt.Errorf("invalid type for headers key") + return nil, nil, errors.New("invalid type for headers key") } case "tls_insecure_skip_verify": tlsInsecureSkipVerify, err = strconv.ParseBool(obj.Get(val).String()) @@ -596,7 +607,7 @@ func createHTTPRequest(bctx BuiltinContext, obj ast.Object) (*http.Request, *htt } if len(tlsCaCert) != 0 { - tlsCaCert = bytes.Replace(tlsCaCert, []byte("\\n"), []byte("\n"), -1) + tlsCaCert = bytes.ReplaceAll(tlsCaCert, []byte("\\n"), []byte("\n")) pool, err := addCACertsFromBytes(tlsConfig.RootCAs, tlsCaCert) if err != nil { return nil, nil, err @@ -626,23 +637,29 @@ func createHTTPRequest(bctx BuiltinContext, obj ast.Object) (*http.Request, *htt tlsConfig.RootCAs = pool } + var transport *http.Transport if isTLS { if ok, parsedURL, tr := useSocket(url, &tlsConfig); ok { - client.Transport = tr + transport = tr url = parsedURL } else { - tr := http.DefaultTransport.(*http.Transport).Clone() - tr.TLSClientConfig = &tlsConfig - tr.DisableKeepAlives = true - client.Transport = tr + transport = http.DefaultTransport.(*http.Transport).Clone() + transport.TLSClientConfig = &tlsConfig + transport.DisableKeepAlives = true } } else { if ok, parsedURL, tr := useSocket(url, nil); ok { - client.Transport = tr + transport = tr url = parsedURL } } + if bctx.RoundTripper != nil { + client.Transport = bctx.RoundTripper(transport) + } else if transport != nil { + client.Transport = transport + } + // check if redirects are enabled if enableRedirect { client.CheckRedirect = func(req *http.Request, _ []*http.Request) error { @@ -714,7 +731,7 @@ func executeHTTPRequest(req *http.Request, client *http.Client, inputReqObj ast. var err error var retry int - retry, err = getNumberValFromReqObj(inputReqObj, ast.StringTerm("max_retry_attempts")) + retry, err = getNumberValFromReqObj(inputReqObj, keyCache["max_retry_attempts"]) if err != nil { return nil, err } @@ -764,28 +781,17 @@ type httpSendCacheEntry struct { // The httpSendCache is used for intra-query caching of http.send results. type httpSendCache struct { - entries *util.HashMap + entries *util.HasherMap[ast.Value, httpSendCacheEntry] } func newHTTPSendCache() *httpSendCache { return &httpSendCache{ - entries: util.NewHashMap(valueEq, valueHash), + entries: util.NewHasherMap[ast.Value, httpSendCacheEntry](ast.ValueEqual), } } -func valueHash(v util.T) int { - return ast.StringTerm(v.(ast.Value).String()).Hash() -} - -func valueEq(a, b util.T) bool { - av := a.(ast.Value) - bv := b.(ast.Value) - return av.String() == bv.String() -} - func (cache *httpSendCache) get(k ast.Value) *httpSendCacheEntry { if v, ok := cache.entries.Get(k); ok { - v := v.(httpSendCacheEntry) return &v } return nil @@ -966,7 +972,7 @@ func (c *interQueryCache) checkHTTPSendInterQueryCache() (ast.Value, error) { // insertIntoHTTPSendInterQueryCache inserts given key and value in the inter-query cache func insertIntoHTTPSendInterQueryCache(bctx BuiltinContext, key ast.Value, resp *http.Response, respBody []byte, cacheParams *forceCacheParams) error { - if resp == nil || (!forceCaching(cacheParams) && !canStore(resp.Header)) || !cacheableCodes.Contains(ast.IntNumberTerm(resp.StatusCode)) { + if resp == nil || (!forceCaching(cacheParams) && !canStore(resp.Header)) || !cacheableCodes.Contains(ast.InternedIntNumberTerm(resp.StatusCode)) { return nil } @@ -974,7 +980,7 @@ func insertIntoHTTPSendInterQueryCache(bctx BuiltinContext, key ast.Value, resp obj, ok := key.(ast.Object) if !ok { - return fmt.Errorf("interface conversion error") + return errors.New("interface conversion error") } cachingMode, err := getCachingMode(obj) @@ -999,15 +1005,18 @@ func insertIntoHTTPSendInterQueryCache(bctx BuiltinContext, key ast.Value, resp return nil } -func createAllowedKeys() { +func createKeys() { for _, element := range allowedKeyNames { - allowedKeys.Add(ast.StringTerm(element)) + term := ast.StringTerm(element) + + allowedKeys.Add(term) + keyCache[element] = term } } func createCacheableHTTPStatusCodes() { for _, element := range cacheableHTTPStatusCodes { - cacheableCodes.Add(ast.IntNumberTerm(element)) + cacheableCodes.Add(ast.InternedIntNumberTerm(element)) } } @@ -1035,7 +1044,7 @@ func parseTimeout(timeoutVal ast.Value) (time.Duration, error) { } return timeout, nil default: - return timeout, builtins.NewOperandErr(1, "'timeout' must be one of {string, number} but got %s", ast.TypeName(t)) + return timeout, builtins.NewOperandErr(1, "'timeout' must be one of {string, number} but got %s", ast.ValueName(t)) } } @@ -1068,7 +1077,7 @@ func getNumberValFromReqObj(req ast.Object, key *ast.Term) (int, error) { } func getCachingMode(req ast.Object) (cachingMode, error) { - key := ast.StringTerm("caching_mode") + key := keyCache["caching_mode"] var s ast.String var ok bool if v := req.Get(key); v != nil { @@ -1188,7 +1197,7 @@ func (c *interQueryCacheData) toCacheValue() (*interQueryCacheValue, error) { return &interQueryCacheValue{Data: b}, nil } -func (c *interQueryCacheData) SizeInBytes() int64 { +func (*interQueryCacheData) SizeInBytes() int64 { return 0 } @@ -1317,7 +1326,7 @@ func parseCacheControlHeader(headers http.Header) map[string]string { func getResponseHeaderDate(headers http.Header) (date time.Time, err error) { dateHeader := headers.Get("date") if dateHeader == "" { - err = fmt.Errorf("no date header") + err = errors.New("no date header") return } return http.ParseTime(dateHeader) @@ -1467,11 +1476,11 @@ func (c *interQueryCache) CheckCache() (ast.Value, error) { return resp, nil } - c.forceJSONDecode, err = getBoolValFromReqObj(c.key, ast.StringTerm("force_json_decode")) + c.forceJSONDecode, err = getBoolValFromReqObj(c.key, keyCache["force_json_decode"]) if err != nil { return nil, handleHTTPSendErr(c.bctx, err) } - c.forceYAMLDecode, err = getBoolValFromReqObj(c.key, ast.StringTerm("force_yaml_decode")) + c.forceYAMLDecode, err = getBoolValFromReqObj(c.key, keyCache["force_yaml_decode"]) if err != nil { return nil, handleHTTPSendErr(c.bctx, err) } @@ -1535,11 +1544,11 @@ func (c *intraQueryCache) CheckCache() (ast.Value, error) { // InsertIntoCache inserts the key set on this object into the cache with the given value func (c *intraQueryCache) InsertIntoCache(value *http.Response) (ast.Value, error) { - forceJSONDecode, err := getBoolValFromReqObj(c.key, ast.StringTerm("force_json_decode")) + forceJSONDecode, err := getBoolValFromReqObj(c.key, keyCache["force_json_decode"]) if err != nil { return nil, handleHTTPSendErr(c.bctx, err) } - forceYAMLDecode, err := getBoolValFromReqObj(c.key, ast.StringTerm("force_yaml_decode")) + forceYAMLDecode, err := getBoolValFromReqObj(c.key, keyCache["force_yaml_decode"]) if err != nil { return nil, handleHTTPSendErr(c.bctx, err) } @@ -1549,7 +1558,7 @@ func (c *intraQueryCache) InsertIntoCache(value *http.Response) (ast.Value, erro return nil, handleHTTPSendErr(c.bctx, err) } - if cacheableCodes.Contains(ast.IntNumberTerm(value.StatusCode)) { + if cacheableCodes.Contains(ast.InternedIntNumberTerm(value.StatusCode)) { insertIntoHTTPSendCache(c.bctx, c.key, result) } @@ -1570,12 +1579,12 @@ func (c *intraQueryCache) ExecuteHTTPRequest() (*http.Response, error) { } func useInterQueryCache(req ast.Object) (bool, *forceCacheParams, error) { - value, err := getBoolValFromReqObj(req, ast.StringTerm("cache")) + value, err := getBoolValFromReqObj(req, keyCache["cache"]) if err != nil { return false, nil, err } - valueForceCache, err := getBoolValFromReqObj(req, ast.StringTerm("force_cache")) + valueForceCache, err := getBoolValFromReqObj(req, keyCache["force_cache"]) if err != nil { return false, nil, err } @@ -1593,9 +1602,9 @@ type forceCacheParams struct { } func newForceCacheParams(req ast.Object) (*forceCacheParams, error) { - term := req.Get(ast.StringTerm("force_cache_duration_seconds")) + term := req.Get(keyCache["force_cache_duration_seconds"]) if term == nil { - return nil, fmt.Errorf("'force_cache' set but 'force_cache_duration_seconds' parameter is missing") + return nil, errors.New("'force_cache' set but 'force_cache_duration_seconds' parameter is missing") } forceCacheDurationSeconds := term.String() @@ -1611,9 +1620,9 @@ func newForceCacheParams(req ast.Object) (*forceCacheParams, error) { func getRaiseErrorValue(req ast.Object) (bool, error) { result := ast.Boolean(true) var ok bool - if v := req.Get(ast.StringTerm("raise_error")); v != nil { + if v := req.Get(keyCache["raise_error"]); v != nil { if result, ok = v.Value.(ast.Boolean); !ok { - return false, fmt.Errorf("invalid value for raise_error field") + return false, errors.New("invalid value for raise_error field") } } return bool(result), nil diff --git a/vendor/github.com/open-policy-agent/opa/topdown/http_fixup.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/http_fixup.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/topdown/http_fixup.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/http_fixup.go diff --git a/vendor/github.com/open-policy-agent/opa/topdown/http_fixup_darwin.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/http_fixup_darwin.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/topdown/http_fixup_darwin.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/http_fixup_darwin.go diff --git a/vendor/github.com/open-policy-agent/opa/topdown/input.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/input.go similarity index 95% rename from vendor/github.com/open-policy-agent/opa/topdown/input.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/input.go index cb70aeb71e..ec37b36451 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/input.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/input.go @@ -5,12 +5,12 @@ package topdown import ( - "fmt" + "errors" - "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/v1/ast" ) -var errBadPath = fmt.Errorf("bad document path") +var errBadPath = errors.New("bad document path") func mergeTermWithValues(exist *ast.Term, pairs [][2]*ast.Term) (*ast.Term, error) { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/instrumentation.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/instrumentation.go similarity index 97% rename from vendor/github.com/open-policy-agent/opa/topdown/instrumentation.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/instrumentation.go index 6eacc338ef..93da1d0022 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/instrumentation.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/instrumentation.go @@ -4,7 +4,7 @@ package topdown -import "github.com/open-policy-agent/opa/metrics" +import "github.com/open-policy-agent/opa/v1/metrics" const ( evalOpPlug = "eval_op_plug" diff --git a/vendor/github.com/open-policy-agent/opa/topdown/json.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/json.go similarity index 95% rename from vendor/github.com/open-policy-agent/opa/topdown/json.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/json.go index 8a5d232836..aa1023d377 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/json.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/json.go @@ -5,12 +5,13 @@ package topdown import ( + "errors" "fmt" "strconv" "strings" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" "github.com/open-policy-agent/opa/internal/edittree" ) @@ -98,7 +99,7 @@ func jsonRemove(a *ast.Term, b *ast.Term) (*ast.Term, error) { // When indexes are removed we shift left to close empty spots in the array // as per the JSON patch spec. newArray := ast.NewArray() - for i := 0; i < aValue.Len(); i++ { + for i := range aValue.Len() { v := aValue.Elem(i) // recurse and add the diff of sub objects as needed // Note: Keys in b will be strings for the index, eg path /a/1/b => {"a": {"1": {"b": null}}} @@ -144,7 +145,7 @@ func getJSONPaths(operand ast.Value) ([]ast.Ref, error) { switch v := operand.(type) { case *ast.Array: - for i := 0; i < v.Len(); i++ { + for i := range v.Len() { filter, err := parsePath(v.Elem(i)) if err != nil { return nil, err @@ -189,7 +190,7 @@ func parsePath(path *ast.Term) (ast.Ref, error) { pathSegments = append(pathSegments, term) }) default: - return nil, builtins.NewOperandErr(2, "must be one of {set, array} containing string paths or array of path segments but got %v", ast.TypeName(p)) + return nil, builtins.NewOperandErr(2, "must be one of {set, array} containing string paths or array of path segments but got %v", ast.ValueName(p)) } return pathSegments, nil @@ -231,7 +232,7 @@ func pathsToObject(paths []ast.Ref) ast.Object { } if !done { - node.Insert(path[len(path)-1], ast.NullTerm()) + node.Insert(path[len(path)-1], ast.InternedNullTerm) } } @@ -263,7 +264,7 @@ func getPatch(o ast.Object) (jsonPatch, error) { } op, ok := opTerm.Value.(ast.String) if !ok { - return out, fmt.Errorf("attribute 'op' must be a string") + return out, errors.New("attribute 'op' must be a string") } out.op = string(op) if _, found := validOps[out.op]; !found { @@ -302,10 +303,10 @@ func getPatch(o ast.Object) (jsonPatch, error) { func applyPatches(source *ast.Term, operations *ast.Array) (*ast.Term, error) { et := edittree.NewEditTree(source) - for i := 0; i < operations.Len(); i++ { + for i := range operations.Len() { object, ok := operations.Elem(i).Value.(ast.Object) if !ok { - return nil, fmt.Errorf("must be an array of JSON-Patch objects, but at least one element is not an object") + return nil, errors.New("must be an array of JSON-Patch objects, but at least one element is not an object") } patch, err := getPatch(object) if err != nil { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/jsonschema.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/jsonschema.go similarity index 96% rename from vendor/github.com/open-policy-agent/opa/topdown/jsonschema.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/jsonschema.go index d319bc0b0d..b1609fb044 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/jsonschema.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/jsonschema.go @@ -8,8 +8,8 @@ import ( "encoding/json" "errors" - "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/internal/gojsonschema" + "github.com/open-policy-agent/opa/v1/ast" ) // astValueToJSONSchemaLoader converts a value to JSON Loader. @@ -44,7 +44,7 @@ func astValueToJSONSchemaLoader(value ast.Value) (gojsonschema.JSONLoader, error } func newResultTerm(valid bool, data *ast.Term) *ast.Term { - return ast.ArrayTerm(ast.BooleanTerm(valid), data) + return ast.ArrayTerm(ast.InternedBooleanTerm(valid), data) } // builtinJSONSchemaVerify accepts 1 argument which can be string or object and checks if it is valid JSON schema. @@ -61,7 +61,7 @@ func builtinJSONSchemaVerify(_ BuiltinContext, operands []*ast.Term, iter func(* return iter(newResultTerm(false, ast.StringTerm("jsonschema: "+err.Error()))) } - return iter(newResultTerm(true, ast.NullTerm())) + return iter(newResultTerm(true, ast.InternedNullTerm)) } // builtinJSONMatchSchema accepts 2 arguments both can be string or object and verifies if the document matches the JSON schema. diff --git a/vendor/github.com/open-policy-agent/opa/topdown/net.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/net.go similarity index 93% rename from vendor/github.com/open-policy-agent/opa/topdown/net.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/net.go index 534520529a..17ed779844 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/net.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/net.go @@ -8,8 +8,8 @@ import ( "net" "strings" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) type lookupIPAddrCacheKey string diff --git a/vendor/github.com/open-policy-agent/opa/topdown/numbers.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/numbers.go similarity index 63% rename from vendor/github.com/open-policy-agent/opa/topdown/numbers.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/numbers.go index 27f3156b8a..398040d7ae 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/numbers.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/numbers.go @@ -5,18 +5,23 @@ package topdown import ( + "errors" "fmt" "math/big" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) type randIntCachingKey string +var zero = big.NewInt(0) var one = big.NewInt(1) func builtinNumbersRange(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + if canGenerateCheapRange(operands) { + return generateCheapRange(operands, iter) + } x, err := builtins.BigIntOperand(operands[0].Value, 1) if err != nil { @@ -53,8 +58,8 @@ func builtinNumbersRangeStep(bctx BuiltinContext, operands []*ast.Term, iter fun return err } - if step.Cmp(big.NewInt(0)) <= 0 { - return fmt.Errorf("numbers.range_step: step must be a positive number above zero") + if step.Cmp(zero) <= 0 { + return errors.New("numbers.range_step: step must be a positive number above zero") } ast, err := generateRange(bctx, x, y, step, "numbers.range_step") @@ -65,6 +70,59 @@ func builtinNumbersRangeStep(bctx BuiltinContext, operands []*ast.Term, iter fun return iter(ast) } +func canGenerateCheapRange(operands []*ast.Term) bool { + x, err := builtins.IntOperand(operands[0].Value, 1) + if err != nil || !ast.HasInternedIntNumberTerm(x) { + return false + } + + y, err := builtins.IntOperand(operands[1].Value, 2) + if err != nil || !ast.HasInternedIntNumberTerm(y) { + return false + } + + return true +} + +func generateCheapRange(operands []*ast.Term, iter func(*ast.Term) error) error { + x, err := builtins.IntOperand(operands[0].Value, 1) + if err != nil { + return err + } + + y, err := builtins.IntOperand(operands[1].Value, 2) + if err != nil { + return err + } + + step := 1 + + if len(operands) > 2 { + stepOp, err := builtins.IntOperand(operands[2].Value, 3) + if err == nil { + step = stepOp + } + } + + if step <= 0 { + return errors.New("numbers.range_step: step must be a positive number above zero") + } + + terms := make([]*ast.Term, 0, y+1) + + if x <= y { + for i := x; i <= y; i += step { + terms = append(terms, ast.InternedIntNumberTerm(i)) + } + } else { + for i := x; i >= y; i -= step { + terms = append(terms, ast.InternedIntNumberTerm(i)) + } + } + + return iter(ast.ArrayTerm(terms...)) +} + func generateRange(bctx BuiltinContext, x *big.Int, y *big.Int, step *big.Int, funcName string) (*ast.Term, error) { cmp := x.Cmp(y) @@ -81,7 +139,7 @@ func generateRange(bctx BuiltinContext, x *big.Int, y *big.Int, step *big.Int, f haltErr := Halt{ Err: &Error{ Code: CancelErr, - Message: fmt.Sprintf("%s: timed out before generating all numbers in range", funcName), + Message: funcName + ": timed out before generating all numbers in range", }, } @@ -109,7 +167,7 @@ func builtinRandIntn(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.T } if n == 0 { - return iter(ast.IntNumberTerm(0)) + return iter(ast.InternedIntNumberTerm(0)) } if n < 0 { @@ -126,7 +184,7 @@ func builtinRandIntn(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.T if err != nil { return err } - result := ast.IntNumberTerm(r.Intn(n)) + result := ast.InternedIntNumberTerm(r.Intn(n)) bctx.Cache.Put(key, result) return iter(result) diff --git a/vendor/github.com/open-policy-agent/opa/topdown/object.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/object.go similarity index 91% rename from vendor/github.com/open-policy-agent/opa/topdown/object.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/object.go index ba5d77ff37..56313b5b56 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/object.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/object.go @@ -5,9 +5,9 @@ package topdown import ( - "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/internal/ref" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) func builtinObjectUnion(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -21,6 +21,16 @@ func builtinObjectUnion(_ BuiltinContext, operands []*ast.Term, iter func(*ast.T return err } + if objA.Len() == 0 { + return iter(operands[1]) + } + if objB.Len() == 0 { + return iter(operands[0]) + } + if objA.Compare(objB) == 0 { + return iter(operands[0]) + } + r := mergeWithOverwrite(objA, objB) return iter(ast.NewTerm(r)) @@ -50,9 +60,6 @@ func builtinObjectUnionN(_ BuiltinContext, operands []*ast.Term, iter func(*ast. return builtins.NewOperandElementErr(1, arr, arr.Elem(i).Value, "object") } mergewithOverwriteInPlace(result, o, frozenKeys) - if err != nil { - return err - } } return iter(ast.NewTerm(result)) @@ -95,7 +102,7 @@ func builtinObjectFilter(_ BuiltinContext, operands []*ast.Term, iter func(*ast. filterObj := ast.NewObject() keys.Foreach(func(key *ast.Term) { - filterObj.Insert(key, ast.NullTerm()) + filterObj.Insert(key, ast.InternedNullTerm) }) // Actually do the filtering @@ -144,37 +151,24 @@ func builtinObjectKeys(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Te return err } - keys := ast.SetTerm(object.Keys()...) - - return iter(keys) + return iter(ast.SetTerm(object.Keys()...)) } // getObjectKeysParam returns a set of key values // from a supplied ast array, object, set value func getObjectKeysParam(arrayOrSet ast.Value) (ast.Set, error) { - keys := ast.NewSet() - switch v := arrayOrSet.(type) { case *ast.Array: - _ = v.Iter(func(f *ast.Term) error { - keys.Add(f) - return nil - }) + keys := ast.NewSet() + v.Foreach(keys.Add) + return keys, nil case ast.Set: - _ = v.Iter(func(f *ast.Term) error { - keys.Add(f) - return nil - }) + return ast.NewSet(v.Slice()...), nil case ast.Object: - _ = v.Iter(func(k *ast.Term, _ *ast.Term) error { - keys.Add(k) - return nil - }) - default: - return nil, builtins.NewOperandTypeErr(2, arrayOrSet, "object", "set", "array") + return ast.NewSet(v.Keys()...), nil } - return keys, nil + return nil, builtins.NewOperandTypeErr(2, arrayOrSet, "object", "set", "array") } func mergeWithOverwrite(objA, objB ast.Object) ast.Object { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/parse.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/parse.go similarity index 91% rename from vendor/github.com/open-policy-agent/opa/topdown/parse.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/parse.go index c46222b413..464e0141a2 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/parse.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/parse.go @@ -9,8 +9,8 @@ import ( "encoding/json" "fmt" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) func builtinRegoParseModule(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -25,6 +25,7 @@ func builtinRegoParseModule(_ BuiltinContext, operands []*ast.Term, iter func(*a return err } + // FIXME: Use configured rego-version? module, err := ast.ParseModule(string(filename), string(input)) if err != nil { return err diff --git a/vendor/github.com/open-policy-agent/opa/topdown/parse_bytes.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/parse_bytes.go similarity index 74% rename from vendor/github.com/open-policy-agent/opa/topdown/parse_bytes.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/parse_bytes.go index 0cd4bc193a..cd36b87b17 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/parse_bytes.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/parse_bytes.go @@ -10,8 +10,8 @@ import ( "strings" "unicode" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) const ( @@ -109,7 +109,7 @@ func builtinNumBytes(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term func formatString(s ast.String) string { str := string(s) lower := strings.ToLower(str) - return strings.Replace(lower, "\"", "", -1) + return strings.ReplaceAll(lower, "\"", "") } // Splits the string into a number string à la "10" or "10.2" and a unit @@ -121,21 +121,35 @@ func extractNumAndUnit(s string) (string, string) { } firstNonNumIdx := -1 - for idx, r := range s { - if !isNum(r) { + for idx := 0; idx < len(s); idx++ { + r := rune(s[idx]) + // Identify the first non-numeric character, marking the boundary between the number and the unit. + if !isNum(r) && r != 'e' && r != 'E' && r != '+' && r != '-' { firstNonNumIdx = idx break } + if r == 'e' || r == 'E' { + // Check if the next character is a valid digit or +/- for scientific notation + if idx == len(s)-1 || (!unicode.IsDigit(rune(s[idx+1])) && rune(s[idx+1]) != '+' && rune(s[idx+1]) != '-') { + firstNonNumIdx = idx + break + } + // Skip the next character if it is '+' or '-' + if idx+1 < len(s) && (s[idx+1] == '+' || s[idx+1] == '-') { + idx++ + } + } } - if firstNonNumIdx == -1 { // only digits and '.' + if firstNonNumIdx == -1 { // only digits, '.', or valid scientific notation return s, "" } if firstNonNumIdx == 0 { // only units (starts with non-digit) return "", s } - return s[0:firstNonNumIdx], s[firstNonNumIdx:] + // Return the number and the rest as the unit + return s[:firstNonNumIdx], s[firstNonNumIdx:] } func init() { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/parse_units.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/parse_units.go similarity index 95% rename from vendor/github.com/open-policy-agent/opa/topdown/parse_units.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/parse_units.go index daf240214c..44aec86299 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/parse_units.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/parse_units.go @@ -10,8 +10,8 @@ import ( "math/big" "strings" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) // Binary Si unit constants are borrowed from topdown/parse_bytes @@ -50,7 +50,7 @@ func builtinUnits(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) e // We remove escaped quotes from strings here to retain parity with units.parse_bytes. s := string(raw) - s = strings.Replace(s, "\"", "", -1) + s = strings.ReplaceAll(s, "\"", "") if strings.Contains(s, " ") { return errIncludesSpaces diff --git a/vendor/github.com/open-policy-agent/opa/topdown/print.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/print.go similarity index 88% rename from vendor/github.com/open-policy-agent/opa/topdown/print.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/print.go index 765b344b3a..f852f3e320 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/print.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/print.go @@ -9,9 +9,9 @@ import ( "io" "strings" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" - "github.com/open-policy-agent/opa/topdown/print" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" + "github.com/open-policy-agent/opa/v1/topdown/print" ) func NewPrintHook(w io.Writer) print.Hook { @@ -62,7 +62,7 @@ func builtinPrintCrossProductOperands(bctx BuiltinContext, buf []string, operand xs, ok := operands.Elem(i).Value.(ast.Set) if !ok { - return Halt{Err: internalErr(bctx.Location, fmt.Sprintf("illegal argument type: %v", ast.TypeName(operands.Elem(i).Value)))} + return Halt{Err: internalErr(bctx.Location, fmt.Sprintf("illegal argument type: %v", ast.ValueName(operands.Elem(i).Value)))} } if xs.Len() == 0 { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/print/print.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/print/print.go similarity index 92% rename from vendor/github.com/open-policy-agent/opa/topdown/print/print.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/print/print.go index 0fb6abdca8..ce684ae945 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/print/print.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/print/print.go @@ -3,7 +3,7 @@ package print import ( "context" - "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/v1/ast" ) // Context provides the Hook implementation context about the print() call. diff --git a/vendor/github.com/open-policy-agent/opa/topdown/providers.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/providers.go similarity index 97% rename from vendor/github.com/open-policy-agent/opa/topdown/providers.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/providers.go index 77db917982..dd84026e4b 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/providers.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/providers.go @@ -9,9 +9,9 @@ import ( "net/url" "time" - "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/internal/providers/aws" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) var awsRequiredConfigKeyNames = ast.NewSet( @@ -119,9 +119,6 @@ func builtinAWSSigV4SignReq(_ BuiltinContext, operands []*ast.Term, iter func(*a } signingTimestamp = time.Unix(0, ts) - if err != nil { - return err - } // Make sure our required keys exist! // This check is stricter than required, but better to break here than downstream. diff --git a/vendor/github.com/open-policy-agent/opa/topdown/query.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/query.go similarity index 90% rename from vendor/github.com/open-policy-agent/opa/topdown/query.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/query.go index 8406cfdd87..bb55b4a6cc 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/query.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/query.go @@ -7,15 +7,15 @@ import ( "sort" "time" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/metrics" - "github.com/open-policy-agent/opa/resolver" - "github.com/open-policy-agent/opa/storage" - "github.com/open-policy-agent/opa/topdown/builtins" - "github.com/open-policy-agent/opa/topdown/cache" - "github.com/open-policy-agent/opa/topdown/copypropagation" - "github.com/open-policy-agent/opa/topdown/print" - "github.com/open-policy-agent/opa/tracing" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/metrics" + "github.com/open-policy-agent/opa/v1/resolver" + "github.com/open-policy-agent/opa/v1/storage" + "github.com/open-policy-agent/opa/v1/topdown/builtins" + "github.com/open-policy-agent/opa/v1/topdown/cache" + "github.com/open-policy-agent/opa/v1/topdown/copypropagation" + "github.com/open-policy-agent/opa/v1/topdown/print" + "github.com/open-policy-agent/opa/v1/tracing" ) // QueryResultSet represents a collection of results returned by a query. @@ -46,6 +46,7 @@ type Query struct { instr *Instrumentation disableInlining []ast.Ref shallowInlining bool + nondeterministicBuiltins bool genvarprefix string runtime *ast.Term builtins map[string]*Builtin @@ -57,9 +58,11 @@ type Query struct { strictBuiltinErrors bool builtinErrorList *[]Error strictObjects bool + roundTripper CustomizeRoundTripper printHook print.Hook tracingOpts tracing.Options virtualCache VirtualCache + baseCache BaseCache } // Builtin represents a built-in function that queries can call. @@ -279,6 +282,12 @@ func (q *Query) WithResolver(ref ast.Ref, r resolver.Resolver) *Query { return q } +// WithHTTPRoundTripper configures a custom HTTP transport for built-in functions that make HTTP requests. +func (q *Query) WithHTTPRoundTripper(t CustomizeRoundTripper) *Query { + q.roundTripper = t + return q +} + func (q *Query) WithPrintHook(h print.Hook) *Query { q.printHook = h return q @@ -306,6 +315,21 @@ func (q *Query) WithVirtualCache(vc VirtualCache) *Query { return q } +// WithBaseCache sets the BaseCache to use during evaluation. This is +// optional, and if not set, the default cache is used. +func (q *Query) WithBaseCache(bc BaseCache) *Query { + q.baseCache = bc + return q +} + +// WithNondeterministicBuiltins causes non-deterministic builtins to be evalued +// during partial evaluation. This is needed to pull in external data, or validate +// a JWT, during PE, so that the result informs what queries are returned. +func (q *Query) WithNondeterministicBuiltins(yes bool) *Query { + q.nondeterministicBuiltins = yes + return q +} + // PartialRun executes partial evaluation on the query with respect to unknown // values. Partial evaluation attempts to evaluate as much of the query as // possible without requiring values for the unknowns set on the query. The @@ -320,7 +344,7 @@ func (q *Query) PartialRun(ctx context.Context) (partials []ast.Body, support [] if q.seed == nil { q.seed = rand.Reader } - if !q.time.IsZero() { + if q.time.IsZero() { q.time = time.Now() } if q.metrics == nil { @@ -337,6 +361,13 @@ func (q *Query) PartialRun(ctx context.Context) (partials []ast.Body, support [] vc = NewVirtualCache() } + var bc BaseCache + if q.baseCache != nil { + bc = q.baseCache + } else { + bc = newBaseCache() + } + e := &eval{ ctx: ctx, metrics: q.metrics, @@ -350,7 +381,7 @@ func (q *Query) PartialRun(ctx context.Context) (partials []ast.Body, support [] bindings: b, compiler: q.compiler, store: q.store, - baseCache: newBaseCache(), + baseCache: bc, targetStack: newRefStack(), txn: q.txn, input: q.input, @@ -373,7 +404,8 @@ func (q *Query) PartialRun(ctx context.Context) (partials []ast.Body, support [] saveNamespace: ast.StringTerm(q.partialNamespace), skipSaveNamespace: q.skipSaveNamespace, inliningControl: &inliningControl{ - shallow: q.shallowInlining, + shallow: q.shallowInlining, + nondeterministicBuiltins: q.nondeterministicBuiltins, }, genvarprefix: q.genvarprefix, runtime: q.runtime, @@ -474,7 +506,11 @@ func (q *Query) PartialRun(ctx context.Context) (partials []ast.Body, support [] } } - for i := range support { + for i, m := range support { + if regoVersion := q.compiler.DefaultRegoVersion(); regoVersion != ast.RegoUndefined { + ast.SetModuleRegoVersion(m, q.compiler.DefaultRegoVersion()) + } + sort.Slice(support[i].Rules, func(j, k int) bool { return support[i].Rules[j].Compare(support[i].Rules[k]) < 0 }) @@ -523,6 +559,13 @@ func (q *Query) Iter(ctx context.Context, iter func(QueryResult) error) error { vc = NewVirtualCache() } + var bc BaseCache + if q.baseCache != nil { + bc = q.baseCache + } else { + bc = newBaseCache() + } + e := &eval{ ctx: ctx, metrics: q.metrics, @@ -536,7 +579,7 @@ func (q *Query) Iter(ctx context.Context, iter func(QueryResult) error) error { bindings: newBindings(0, q.instr), compiler: q.compiler, store: q.store, - baseCache: newBaseCache(), + baseCache: bc, targetStack: newRefStack(), txn: q.txn, input: q.input, @@ -561,6 +604,7 @@ func (q *Query) Iter(ctx context.Context, iter func(QueryResult) error) error { printHook: q.printHook, tracingOpts: q.tracingOpts, strictObjects: q.strictObjects, + roundTripper: q.roundTripper, } e.caller = e q.metrics.Timer(metrics.RegoQueryEval).Start() diff --git a/vendor/github.com/open-policy-agent/opa/topdown/reachable.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/reachable.go similarity index 97% rename from vendor/github.com/open-policy-agent/opa/topdown/reachable.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/reachable.go index 8d61018e76..1c31019db9 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/reachable.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/reachable.go @@ -5,8 +5,8 @@ package topdown import ( - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) // Helper: sets of vertices can be represented as Arrays or Sets. diff --git a/vendor/github.com/open-policy-agent/opa/topdown/regex.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/regex.go similarity index 93% rename from vendor/github.com/open-policy-agent/opa/topdown/regex.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/regex.go index 452e7d58bf..2c434dda87 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/regex.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/regex.go @@ -11,8 +11,8 @@ import ( gintersect "github.com/yashtewari/glob-intersection" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) const regexCacheMaxSize = 100 @@ -25,15 +25,15 @@ func builtinRegexIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast. s, err := builtins.StringOperand(operands[0].Value, 1) if err != nil { - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } _, err = regexp.Compile(string(s)) if err != nil { - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } - return iter(ast.BooleanTerm(true)) + return iter(ast.InternedBooleanTerm(true)) } func builtinRegexMatch(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -49,7 +49,7 @@ func builtinRegexMatch(bctx BuiltinContext, operands []*ast.Term, iter func(*ast if err != nil { return err } - return iter(ast.BooleanTerm(re.MatchString(string(s2)))) + return iter(ast.InternedBooleanTerm(re.MatchString(string(s2)))) } func builtinRegexMatchTemplate(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -79,7 +79,7 @@ func builtinRegexMatchTemplate(_ BuiltinContext, operands []*ast.Term, iter func if err != nil { return err } - return iter(ast.BooleanTerm(re.MatchString(string(match)))) + return iter(ast.InternedBooleanTerm(re.MatchString(string(match)))) } func builtinRegexSplit(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -106,6 +106,7 @@ func builtinRegexSplit(bctx BuiltinContext, operands []*ast.Term, iter func(*ast func getRegexp(bctx BuiltinContext, pat string) (*regexp.Regexp, error) { if bctx.InterQueryBuiltinValueCache != nil { + // TODO: Use named cache val, ok := bctx.InterQueryBuiltinValueCache.Get(ast.String(pat)) if ok { res, valid := val.(*regexp.Regexp) @@ -176,7 +177,7 @@ func builtinGlobsMatch(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Te if err != nil { return err } - return iter(ast.BooleanTerm(ne)) + return iter(ast.InternedBooleanTerm(ne)) } func builtinRegexFind(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -259,6 +260,9 @@ func builtinRegexReplace(bctx BuiltinContext, operands []*ast.Term, iter func(*a } res := re.ReplaceAllString(string(base), string(value)) + if res == string(base) { + return iter(operands[0]) + } return iter(ast.StringTerm(res)) } diff --git a/vendor/github.com/open-policy-agent/opa/topdown/regex_template.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/regex_template.go similarity index 99% rename from vendor/github.com/open-policy-agent/opa/topdown/regex_template.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/regex_template.go index 4bcddc060b..a1d946fd59 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/regex_template.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/regex_template.go @@ -45,7 +45,7 @@ import ( func delimiterIndices(s string, delimiterStart, delimiterEnd byte) ([]int, error) { var level, idx int idxs := make([]int, 0) - for i := 0; i < len(s); i++ { + for i := range len(s) { switch s[i] { case delimiterStart: if level++; level == 1 { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/resolver.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/resolver.go similarity index 86% rename from vendor/github.com/open-policy-agent/opa/topdown/resolver.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/resolver.go index 5ed6c1e443..3620168874 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/resolver.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/resolver.go @@ -5,9 +5,9 @@ package topdown import ( - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/metrics" - "github.com/open-policy-agent/opa/resolver" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/metrics" + "github.com/open-policy-agent/opa/v1/resolver" ) type resolverTrie struct { @@ -48,7 +48,11 @@ func (t *resolverTrie) Resolve(e *eval, ref ast.Ref) (ast.Value, error) { Input: e.input, Metrics: e.metrics, } - e.traceWasm(e.query[e.index], &in.Ref) + if e.traceEnabled { + // avoid leaking pointer if trace is disabled + cpy := in.Ref + e.traceWasm(e.query[e.index], &cpy) + } if e.data != nil { return nil, errInScopeWithStmt } @@ -75,7 +79,10 @@ func (t *resolverTrie) Resolve(e *eval, ref ast.Ref) (ast.Value, error) { func (t *resolverTrie) mktree(e *eval, in resolver.Input) (ast.Value, error) { if t.r != nil { - e.traceWasm(e.query[e.index], &in.Ref) + if e.traceEnabled { + cpy := in.Ref + e.traceWasm(e.query[e.index], &cpy) + } if e.data != nil { return nil, errInScopeWithStmt } diff --git a/vendor/github.com/open-policy-agent/opa/topdown/runtime.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/runtime.go similarity index 86% rename from vendor/github.com/open-policy-agent/opa/topdown/runtime.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/runtime.go index 7d512f7c00..dc72fc5818 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/runtime.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/runtime.go @@ -5,19 +5,24 @@ package topdown import ( + "errors" "fmt" - "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/v1/ast" ) +var configStringTerm = ast.StringTerm("config") + +var nothingResolver ast.Resolver = illegalResolver{} + func builtinOPARuntime(bctx BuiltinContext, _ []*ast.Term, iter func(*ast.Term) error) error { if bctx.Runtime == nil { - return iter(ast.ObjectTerm()) + return iter(ast.InternedEmptyObject) } - if bctx.Runtime.Get(ast.StringTerm("config")) != nil { - iface, err := ast.ValueToInterface(bctx.Runtime.Value, illegalResolver{}) + if bctx.Runtime.Get(configStringTerm) != nil { + iface, err := ast.ValueToInterface(bctx.Runtime.Value, nothingResolver) if err != nil { return err } @@ -110,7 +115,7 @@ func removeCryptoKeys(x interface{}) error { func removeKey(x interface{}, keys ...string) error { val, ok := x.(map[string]interface{}) if !ok { - return fmt.Errorf("type assertion error") + return errors.New("type assertion error") } for _, key := range keys { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/save.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/save.go similarity index 96% rename from vendor/github.com/open-policy-agent/opa/topdown/save.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/save.go index 0468692cc6..439f554a34 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/save.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/save.go @@ -5,7 +5,7 @@ import ( "fmt" "strings" - "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/v1/ast" ) // saveSet contains a stack of terms that are considered 'unknown' during @@ -365,7 +365,13 @@ func saveRequired(c *ast.Compiler, ic *inliningControl, icIgnoreInternal bool, s } switch node := node.(type) { case *ast.Expr: - found = len(node.With) > 0 || ignoreExprDuringPartial(node) + found = len(node.With) > 0 + if found { + return found + } + if !ic.nondeterministicBuiltins { // skip evaluating non-det builtins for PE + found = ignoreExprDuringPartial(node) + } case *ast.Term: switch v := node.Value.(type) { case ast.Var: @@ -422,8 +428,9 @@ func ignoreDuringPartial(bi *ast.Builtin) bool { } type inliningControl struct { - shallow bool - disable []disableInliningFrame + shallow bool + disable []disableInliningFrame + nondeterministicBuiltins bool // evaluate non-det builtins during PE (if args are known) } type disableInliningFrame struct { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/semver.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/semver.go similarity index 85% rename from vendor/github.com/open-policy-agent/opa/topdown/semver.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/semver.go index 7bb7b9c183..0e7daaeae6 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/semver.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/semver.go @@ -7,9 +7,9 @@ package topdown import ( "fmt" - "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/internal/semver" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) func builtinSemVerCompare(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -34,13 +34,13 @@ func builtinSemVerCompare(_ BuiltinContext, operands []*ast.Term, iter func(*ast result := versionA.Compare(*versionB) - return iter(ast.IntNumberTerm(result)) + return iter(ast.InternedIntNumberTerm(result)) } func builtinSemVerIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { versionString, err := builtins.StringOperand(operands[0].Value, 1) if err != nil { - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } result := true @@ -50,7 +50,7 @@ func builtinSemVerIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast result = false } - return iter(ast.BooleanTerm(result)) + return iter(ast.InternedBooleanTerm(result)) } func init() { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/sets.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/sets.go similarity index 92% rename from vendor/github.com/open-policy-agent/opa/topdown/sets.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/sets.go index a973404f3f..9df2d328a0 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/sets.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/sets.go @@ -5,11 +5,11 @@ package topdown import ( - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) -// Deprecated in v0.4.2 in favour of minus/infix "-" operation. +// Deprecated: deprecated in v0.4.2 in favour of minus/infix "-" operation. func builtinSetDiff(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { s1, err := builtins.SetOperand(operands[0].Value, 1) diff --git a/vendor/github.com/open-policy-agent/opa/topdown/strings.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/strings.go similarity index 71% rename from vendor/github.com/open-policy-agent/opa/topdown/strings.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/strings.go index d9e4a55e58..3b1a412c39 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/strings.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/strings.go @@ -5,15 +5,20 @@ package topdown import ( + "errors" "fmt" "math/big" "sort" + "strconv" "strings" + "unicode" + "unicode/utf8" "github.com/tchap/go-patricia/v2/patricia" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" + "github.com/open-policy-agent/opa/v1/util" ) func builtinAnyPrefixMatch(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -47,7 +52,7 @@ func builtinAnyPrefixMatch(_ BuiltinContext, operands []*ast.Term, iter func(*as return builtins.NewOperandTypeErr(2, b, "string", "set", "array") } - return iter(ast.BooleanTerm(anyStartsWithAny(strs, prefixes))) + return iter(ast.InternedBooleanTerm(anyStartsWithAny(strs, prefixes))) } func builtinAnySuffixMatch(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -87,7 +92,7 @@ func builtinAnySuffixMatch(_ BuiltinContext, operands []*ast.Term, iter func(*as return builtins.NewOperandTypeErr(2, b, "string", "set", "array") } - return iter(ast.BooleanTerm(anyStartsWithAny(strsReversed, suffixesReversed))) + return iter(ast.InternedBooleanTerm(anyStartsWithAny(strsReversed, suffixesReversed))) } func anyStartsWithAny(strs []string, prefixes []string) bool { @@ -99,11 +104,11 @@ func anyStartsWithAny(strs []string, prefixes []string) bool { } trie := patricia.NewTrie() - for i := 0; i < len(strs); i++ { + for i := range strs { trie.Insert([]byte(strs[i]), true) } - for i := 0; i < len(prefixes); i++ { + for i := range prefixes { if trie.MatchSubtree([]byte(prefixes[i])) { return true } @@ -151,33 +156,48 @@ func builtinConcat(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) return err } - strs := []string{} + var strs []string switch b := operands[1].Value.(type) { case *ast.Array: - err := b.Iter(func(x *ast.Term) error { - s, ok := x.Value.(ast.String) + var l int + for i := range b.Len() { + s, ok := b.Elem(i).Value.(ast.String) if !ok { - return builtins.NewOperandElementErr(2, operands[1].Value, x.Value, "string") + return builtins.NewOperandElementErr(2, operands[1].Value, b.Elem(i).Value, "string") } - strs = append(strs, string(s)) - return nil - }) - if err != nil { - return err + l += len(string(s)) + } + + if b.Len() == 1 { + return iter(b.Elem(0)) } + + strs = make([]string, 0, l) + for i := range b.Len() { + strs = append(strs, string(b.Elem(i).Value.(ast.String))) + } + case ast.Set: - err := b.Iter(func(x *ast.Term) error { - s, ok := x.Value.(ast.String) + var l int + terms := b.Slice() + for i := range terms { + s, ok := terms[i].Value.(ast.String) if !ok { - return builtins.NewOperandElementErr(2, operands[1].Value, x.Value, "string") + return builtins.NewOperandElementErr(2, operands[1].Value, terms[i].Value, "string") } - strs = append(strs, string(s)) - return nil - }) - if err != nil { - return err + l += len(string(s)) } + + if b.Len() == 1 { + return iter(b.Slice()[0]) + } + + strs = make([]string, 0, l) + for i := range b.Len() { + strs = append(strs, string(terms[i].Value.(ast.String))) + } + default: return builtins.NewOperandTypeErr(2, operands[1].Value, "set", "array") } @@ -208,7 +228,14 @@ func builtinIndexOf(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) return err } if len(string(search)) == 0 { - return fmt.Errorf("empty search character") + return errors.New("empty search character") + } + + if isASCII(string(base)) && isASCII(string(search)) { + // this is a false positive in the indexAlloc rule that thinks + // we're converting byte arrays to strings + //nolint:gocritic + return iter(ast.InternedIntNumberTerm(strings.Index(string(base), string(search)))) } baseRunes := []rune(string(base)) @@ -218,14 +245,14 @@ func builtinIndexOf(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) for i, r := range baseRunes { if len(baseRunes) >= i+searchLen { if r == searchRunes[0] && runesEqual(baseRunes[i:i+searchLen], searchRunes) { - return iter(ast.IntNumberTerm(i)) + return iter(ast.InternedIntNumberTerm(i)) } } else { break } } - return iter(ast.IntNumberTerm(-1)) + return iter(ast.InternedIntNumberTerm(-1)) } func builtinIndexOfN(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -239,7 +266,7 @@ func builtinIndexOfN(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term return err } if len(string(search)) == 0 { - return fmt.Errorf("empty search character") + return errors.New("empty search character") } baseRunes := []rune(string(base)) @@ -250,7 +277,7 @@ func builtinIndexOfN(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term for i, r := range baseRunes { if len(baseRunes) >= i+searchLen { if r == searchRunes[0] && runesEqual(baseRunes[i:i+searchLen], searchRunes) { - arr = append(arr, ast.IntNumberTerm(i)) + arr = append(arr, ast.InternedIntNumberTerm(i)) } } else { break @@ -266,15 +293,10 @@ func builtinSubstring(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter if err != nil { return err } - runes := []rune(base) startIndex, err := builtins.IntOperand(operands[1].Value, 2) if err != nil { return err - } else if startIndex >= len(runes) { - return iter(ast.StringTerm("")) - } else if startIndex < 0 { - return fmt.Errorf("negative offset") } length, err := builtins.IntOperand(operands[2].Value, 3) @@ -282,18 +304,68 @@ func builtinSubstring(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter return err } - var s ast.String + if startIndex < 0 { + return errors.New("negative offset") + } + + sbase := string(base) + if sbase == "" { + return iter(ast.InternedEmptyString) + } + + // Optimized path for the likely common case of ASCII strings. + // This allocates less memory and runs in about 1/3 the time. + if isASCII(sbase) { + if startIndex >= len(sbase) { + return iter(ast.InternedEmptyString) + } + + if length < 0 { + return iter(ast.StringTerm(sbase[startIndex:])) + } + + if startIndex == 0 && length >= len(sbase) { + return iter(operands[0]) + } + + upto := startIndex + length + if len(sbase) < upto { + upto = len(sbase) + } + return iter(ast.StringTerm(sbase[startIndex:upto])) + } + + if startIndex == 0 && length >= utf8.RuneCountInString(sbase) { + return iter(operands[0]) + } + + runes := []rune(base) + + if startIndex >= len(runes) { + return iter(ast.InternedEmptyString) + } + + var s string if length < 0 { - s = ast.String(runes[startIndex:]) + s = string(runes[startIndex:]) } else { upto := startIndex + length if len(runes) < upto { upto = len(runes) } - s = ast.String(runes[startIndex:upto]) + s = string(runes[startIndex:upto]) } - return iter(ast.NewTerm(s)) + return iter(ast.StringTerm(s)) +} + +func isASCII(s string) bool { + for i := range len(s) { + if s[i] > unicode.MaxASCII { + return false + } + } + return true } func builtinContains(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -307,7 +379,7 @@ func builtinContains(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term return err } - return iter(ast.BooleanTerm(strings.Contains(string(s), string(substr)))) + return iter(ast.InternedBooleanTerm(strings.Contains(string(s), string(substr)))) } func builtinStringCount(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -323,10 +395,9 @@ func builtinStringCount(_ BuiltinContext, operands []*ast.Term, iter func(*ast.T baseTerm := string(s) searchTerm := string(substr) - count := strings.Count(baseTerm, searchTerm) - return iter(ast.IntNumberTerm(count)) + return iter(ast.InternedIntNumberTerm(count)) } func builtinStartsWith(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -340,7 +411,7 @@ func builtinStartsWith(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Te return err } - return iter(ast.BooleanTerm(strings.HasPrefix(string(s), string(prefix)))) + return iter(ast.InternedBooleanTerm(strings.HasPrefix(string(s), string(prefix)))) } func builtinEndsWith(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -354,7 +425,7 @@ func builtinEndsWith(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term return err } - return iter(ast.BooleanTerm(strings.HasSuffix(string(s), string(suffix)))) + return iter(ast.InternedBooleanTerm(strings.HasSuffix(string(s), string(suffix)))) } func builtinLower(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -372,7 +443,14 @@ func builtinUpper(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) e return err } - return iter(ast.StringTerm(strings.ToUpper(string(s)))) + arg := string(s) + upp := strings.ToUpper(arg) + + if arg == upp { + return iter(operands[0]) + } + + return iter(ast.StringTerm(upp)) } func builtinSplit(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -380,15 +458,22 @@ func builtinSplit(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) e if err != nil { return err } + d, err := builtins.StringOperand(operands[1].Value, 2) if err != nil { return err } + + if !strings.Contains(string(s), string(d)) { + return iter(ast.ArrayTerm(operands[0])) + } + elems := strings.Split(string(s), string(d)) - arr := make([]*ast.Term, len(elems)) + arr := util.NewPtrSlice[ast.Term](len(elems)) for i := range elems { - arr[i] = ast.StringTerm(elems[i]) + arr[i].Value = ast.String(elems[i]) } + return iter(ast.ArrayTerm(arr...)) } @@ -408,7 +493,12 @@ func builtinReplace(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) return err } - return iter(ast.StringTerm(strings.Replace(string(s), string(old), string(n), -1))) + replaced := strings.ReplaceAll(string(s), string(old), string(n)) + if replaced == string(s) { + return iter(operands[0]) + } + + return iter(ast.StringTerm(replaced)) } func builtinReplaceN(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -437,14 +527,8 @@ func builtinReplaceN(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term } oldnewArr = append(oldnewArr, string(keyVal), string(strVal)) } - if err != nil { - return err - } - - r := strings.NewReplacer(oldnewArr...) - replaced := r.Replace(string(s)) - return iter(ast.StringTerm(replaced)) + return iter(ast.StringTerm(strings.NewReplacer(oldnewArr...).Replace(string(s)))) } func builtinTrim(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -458,6 +542,11 @@ func builtinTrim(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) er return err } + trimmed := strings.Trim(string(s), string(c)) + if trimmed == string(s) { + return iter(operands[0]) + } + return iter(ast.StringTerm(strings.Trim(string(s), string(c)))) } @@ -472,7 +561,12 @@ func builtinTrimLeft(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term return err } - return iter(ast.StringTerm(strings.TrimLeft(string(s), string(c)))) + trimmed := strings.TrimLeft(string(s), string(c)) + if trimmed == string(s) { + return iter(operands[0]) + } + + return iter(ast.StringTerm(trimmed)) } func builtinTrimPrefix(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -486,7 +580,12 @@ func builtinTrimPrefix(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Te return err } - return iter(ast.StringTerm(strings.TrimPrefix(string(s), string(pre)))) + trimmed := strings.TrimPrefix(string(s), string(pre)) + if trimmed == string(s) { + return iter(operands[0]) + } + + return iter(ast.StringTerm(trimmed)) } func builtinTrimRight(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -500,7 +599,12 @@ func builtinTrimRight(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter return err } - return iter(ast.StringTerm(strings.TrimRight(string(s), string(c)))) + trimmed := strings.TrimRight(string(s), string(c)) + if trimmed == string(s) { + return iter(operands[0]) + } + + return iter(ast.StringTerm(trimmed)) } func builtinTrimSuffix(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -514,7 +618,12 @@ func builtinTrimSuffix(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Te return err } - return iter(ast.StringTerm(strings.TrimSuffix(string(s), string(suf)))) + trimmed := strings.TrimSuffix(string(s), string(suf)) + if trimmed == string(s) { + return iter(operands[0]) + } + + return iter(ast.StringTerm(trimmed)) } func builtinTrimSpace(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -523,7 +632,12 @@ func builtinTrimSpace(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter return err } - return iter(ast.StringTerm(strings.TrimSpace(string(s)))) + trimmed := strings.TrimSpace(string(s)) + if trimmed == string(s) { + return iter(operands[0]) + } + + return iter(ast.StringTerm(trimmed)) } func builtinSprintf(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -537,7 +651,17 @@ func builtinSprintf(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) return builtins.NewOperandTypeErr(2, operands[1].Value, "array") } - args := make([]interface{}, astArr.Len()) + // Optimized path for where sprintf is used as a "to_string" function for + // a single integer, i.e. sprintf("%d", [x]) where x is an integer. + if s == "%d" && astArr.Len() == 1 { + if n, ok := astArr.Elem(0).Value.(ast.Number); ok { + if i, ok := n.Int(); ok { + return iter(ast.InternedStringTerm(strconv.Itoa(i))) + } + } + } + + args := make([]any, astArr.Len()) for i := range args { switch v := astArr.Elem(i).Value.(type) { @@ -571,15 +695,23 @@ func builtinReverse(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) } func reverseString(str string) string { - sRunes := []rune(str) - length := len(sRunes) - reversedRunes := make([]rune, length) + var buf []byte + var arr [255]byte + size := len(str) + + if size < 255 { + buf = arr[:size:size] + } else { + buf = make([]byte, size) + } - for index, r := range sRunes { - reversedRunes[length-index-1] = r + for start := 0; start < size; { + r, n := utf8.DecodeRuneInString(str[start:]) + start += n + utf8.EncodeRune(buf[size-start:], r) } - return string(reversedRunes) + return string(buf) } func init() { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/subset.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/subset.go similarity index 82% rename from vendor/github.com/open-policy-agent/opa/topdown/subset.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/subset.go index 7b152a5ef9..29354d9730 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/subset.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/subset.go @@ -5,8 +5,8 @@ package topdown import ( - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) func bothObjects(t1, t2 *ast.Term) (bool, ast.Object, ast.Object) { @@ -88,9 +88,8 @@ func arraySet(t1, t2 *ast.Term) (bool, *ast.Array, ast.Set) { // associated with a key. func objectSubset(super ast.Object, sub ast.Object) bool { var superTerm *ast.Term - isSubset := true - sub.Until(func(key, subTerm *ast.Term) bool { + notSubset := sub.Until(func(key, subTerm *ast.Term) bool { // This really wants to be a for loop, hence the somewhat // weird internal structure. However, using Until() in this // was is a performance optimization, as it avoids performing @@ -98,10 +97,9 @@ func objectSubset(super ast.Object, sub ast.Object) bool { superTerm = super.Get(key) - // subTerm is can't be nil because we got it from Until(), so + // subTerm can't be nil because we got it from Until(), so // we only need to verify that super is non-nil. if superTerm == nil { - isSubset = false return true // break, not a subset } @@ -114,58 +112,39 @@ func objectSubset(super ast.Object, sub ast.Object) bool { // them normally. If only one term is an object, then we // do a normal comparison which will come up false. if ok, superObj, subObj := bothObjects(superTerm, subTerm); ok { - if !objectSubset(superObj, subObj) { - isSubset = false - return true // break, not a subset - } - - return false // continue + return !objectSubset(superObj, subObj) } if ok, superSet, subSet := bothSets(superTerm, subTerm); ok { - if !setSubset(superSet, subSet) { - isSubset = false - return true // break, not a subset - } - - return false // continue + return !setSubset(superSet, subSet) } if ok, superArray, subArray := bothArrays(superTerm, subTerm); ok { - if !arraySubset(superArray, subArray) { - isSubset = false - return true // break, not a subset - } - - return false // continue + return !arraySubset(superArray, subArray) } // We have already checked for exact equality, as well as for // all of the types of nested subsets we care about, so if we // get here it means this isn't a subset. - isSubset = false return true // break, not a subset }) - return isSubset + return !notSubset } // setSubset implements the subset operation on sets. // // Unlike in the object case, this is not recursive, we just compare values -// using ast.Set.Contains() because we have no well defined way to "match up" +// using ast.Set.Contains() because we have no well-defined way to "match up" // objects that are in different sets. func setSubset(super ast.Set, sub ast.Set) bool { - isSubset := true - sub.Until(func(t *ast.Term) bool { - if !super.Contains(t) { - isSubset = false - return true + for _, elem := range sub.Slice() { + if !super.Contains(elem) { + return false } - return false - }) + } - return isSubset + return true } // arraySubset implements the subset operation on arrays. @@ -197,12 +176,12 @@ func arraySubset(super, sub *ast.Array) bool { return false } - subElem := sub.Elem(subCursor) superElem := super.Elem(superCursor + subCursor) if superElem == nil { return false } + subElem := sub.Elem(subCursor) if superElem.Value.Compare(subElem.Value) == 0 { subCursor++ } else { @@ -237,22 +216,22 @@ func builtinObjectSubset(_ BuiltinContext, operands []*ast.Term, iter func(*ast. if ok, superObj, subObj := bothObjects(superTerm, subTerm); ok { // Both operands are objects. - return iter(ast.BooleanTerm(objectSubset(superObj, subObj))) + return iter(ast.InternedBooleanTerm(objectSubset(superObj, subObj))) } if ok, superSet, subSet := bothSets(superTerm, subTerm); ok { // Both operands are sets. - return iter(ast.BooleanTerm(setSubset(superSet, subSet))) + return iter(ast.InternedBooleanTerm(setSubset(superSet, subSet))) } if ok, superArray, subArray := bothArrays(superTerm, subTerm); ok { // Both operands are sets. - return iter(ast.BooleanTerm(arraySubset(superArray, subArray))) + return iter(ast.InternedBooleanTerm(arraySubset(superArray, subArray))) } if ok, superArray, subSet := arraySet(superTerm, subTerm); ok { // Super operand is array and sub operand is set - return iter(ast.BooleanTerm(arraySetSubset(superArray, subSet))) + return iter(ast.InternedBooleanTerm(arraySetSubset(superArray, subSet))) } return builtins.ErrOperand("both arguments object.subset must be of the same type or array and set") diff --git a/vendor/github.com/open-policy-agent/opa/topdown/template.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/template.go similarity index 90% rename from vendor/github.com/open-policy-agent/opa/topdown/template.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/template.go index cf42477ee8..cf4635559d 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/template.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/template.go @@ -4,8 +4,8 @@ import ( "bytes" "text/template" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) func renderTemplate(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/test.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/test.go new file mode 100644 index 0000000000..02958d2264 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/test.go @@ -0,0 +1,30 @@ +// Copyright 2025 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 topdown + +import "github.com/open-policy-agent/opa/v1/ast" + +const TestCaseOp Op = "TestCase" + +func builtinTestCase(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + e := &Event{ + Op: TestCaseOp, + QueryID: bctx.QueryID, + Node: ast.NewExpr([]*ast.Term{ + ast.NewTerm(ast.InternalTestCase.Ref()), + ast.NewTerm(operands[0].Value), + }), + } + + for _, tracer := range bctx.QueryTracers { + tracer.TraceEvent(*e) + } + + return iter(ast.BooleanTerm(true)) +} + +func init() { + RegisterBuiltinFunc(ast.InternalTestCase.Name, builtinTestCase) +} diff --git a/vendor/github.com/open-policy-agent/opa/topdown/time.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/time.go similarity index 92% rename from vendor/github.com/open-policy-agent/opa/topdown/time.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/time.go index ba3efc75dc..8d2d9b27a2 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/time.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/time.go @@ -6,7 +6,7 @@ package topdown import ( "encoding/json" - "fmt" + "errors" "math" "math/big" "strconv" @@ -14,8 +14,8 @@ import ( "time" _ "time/tzdata" // this is needed to have LoadLocation when no filesystem tzdata is available - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) var tzCache map[string]*time.Location @@ -29,7 +29,7 @@ var maxDateAllowedForNsConversion = time.Unix(0, math.MaxInt64) func toSafeUnixNano(t time.Time, iter func(*ast.Term) error) error { if t.Before(minDateAllowedForNsConversion) || t.After(maxDateAllowedForNsConversion) { - return fmt.Errorf("time outside of valid range") + return errors.New("time outside of valid range") } return iter(ast.NewTerm(ast.Number(int64ToJSONNumber(t.UnixNano())))) @@ -127,7 +127,7 @@ func builtinDate(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) er return err } year, month, day := t.Date() - result := ast.NewArray(ast.IntNumberTerm(year), ast.IntNumberTerm(int(month)), ast.IntNumberTerm(day)) + result := ast.NewArray(ast.InternedIntNumberTerm(year), ast.InternedIntNumberTerm(int(month)), ast.InternedIntNumberTerm(day)) return iter(ast.NewTerm(result)) } @@ -137,7 +137,7 @@ func builtinClock(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) e return err } hour, minute, second := t.Clock() - result := ast.NewArray(ast.IntNumberTerm(hour), ast.IntNumberTerm(minute), ast.IntNumberTerm(second)) + result := ast.NewArray(ast.InternedIntNumberTerm(hour), ast.InternedIntNumberTerm(minute), ast.InternedIntNumberTerm(second)) return iter(ast.NewTerm(result)) } @@ -238,8 +238,8 @@ func builtinDiff(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) er } // END REDISTRIBUTION FROM APACHE 2.0 LICENSED PROJECT - return iter(ast.ArrayTerm(ast.IntNumberTerm(year), ast.IntNumberTerm(month), ast.IntNumberTerm(day), - ast.IntNumberTerm(hour), ast.IntNumberTerm(min), ast.IntNumberTerm(sec))) + return iter(ast.ArrayTerm(ast.InternedIntNumberTerm(year), ast.InternedIntNumberTerm(month), ast.InternedIntNumberTerm(day), + ast.InternedIntNumberTerm(hour), ast.InternedIntNumberTerm(min), ast.InternedIntNumberTerm(sec))) } func tzTime(a ast.Value) (t time.Time, lay string, err error) { @@ -313,7 +313,7 @@ func tzTime(a ast.Value) (t time.Time, lay string, err error) { f := builtins.NumberToFloat(value) i64, acc := f.Int64() if acc != big.Exact { - return time.Time{}, layout, fmt.Errorf("timestamp too big") + return time.Time{}, layout, errors.New("timestamp too big") } t = time.Unix(0, i64).In(loc) diff --git a/vendor/github.com/open-policy-agent/opa/topdown/tokens.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/tokens.go similarity index 74% rename from vendor/github.com/open-policy-agent/opa/topdown/tokens.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/tokens.go index 7457f1f15d..2050e82d63 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/tokens.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/tokens.go @@ -21,11 +21,12 @@ import ( "math/big" "strings" - "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/internal/jwx/jwa" "github.com/open-policy-agent/opa/internal/jwx/jwk" "github.com/open-policy-agent/opa/internal/jwx/jws" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" + "github.com/open-policy-agent/opa/v1/topdown/cache" ) var ( @@ -129,8 +130,8 @@ func builtinJWTDecode(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter } // Implements RS256 JWT signature verification -func builtinJWTVerifyRS256(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - result, err := builtinJWTVerifyRSA(operands[0].Value, operands[1].Value, sha256.New, func(publicKey *rsa.PublicKey, digest []byte, signature []byte) error { +func builtinJWTVerifyRS256(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + result, err := builtinJWTVerifyRSA(bctx, operands[0].Value, operands[1].Value, sha256.New, func(publicKey *rsa.PublicKey, digest []byte, signature []byte) error { return rsa.VerifyPKCS1v15( publicKey, crypto.SHA256, @@ -144,8 +145,8 @@ func builtinJWTVerifyRS256(_ BuiltinContext, operands []*ast.Term, iter func(*as } // Implements RS384 JWT signature verification -func builtinJWTVerifyRS384(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - result, err := builtinJWTVerifyRSA(operands[0].Value, operands[1].Value, sha512.New384, func(publicKey *rsa.PublicKey, digest []byte, signature []byte) error { +func builtinJWTVerifyRS384(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + result, err := builtinJWTVerifyRSA(bctx, operands[0].Value, operands[1].Value, sha512.New384, func(publicKey *rsa.PublicKey, digest []byte, signature []byte) error { return rsa.VerifyPKCS1v15( publicKey, crypto.SHA384, @@ -159,8 +160,8 @@ func builtinJWTVerifyRS384(_ BuiltinContext, operands []*ast.Term, iter func(*as } // Implements RS512 JWT signature verification -func builtinJWTVerifyRS512(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - result, err := builtinJWTVerifyRSA(operands[0].Value, operands[1].Value, sha512.New, func(publicKey *rsa.PublicKey, digest []byte, signature []byte) error { +func builtinJWTVerifyRS512(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + result, err := builtinJWTVerifyRSA(bctx, operands[0].Value, operands[1].Value, sha512.New, func(publicKey *rsa.PublicKey, digest []byte, signature []byte) error { return rsa.VerifyPKCS1v15( publicKey, crypto.SHA512, @@ -174,8 +175,8 @@ func builtinJWTVerifyRS512(_ BuiltinContext, operands []*ast.Term, iter func(*as } // Implements PS256 JWT signature verification -func builtinJWTVerifyPS256(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - result, err := builtinJWTVerifyRSA(operands[0].Value, operands[1].Value, sha256.New, func(publicKey *rsa.PublicKey, digest []byte, signature []byte) error { +func builtinJWTVerifyPS256(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + result, err := builtinJWTVerifyRSA(bctx, operands[0].Value, operands[1].Value, sha256.New, func(publicKey *rsa.PublicKey, digest []byte, signature []byte) error { return rsa.VerifyPSS( publicKey, crypto.SHA256, @@ -190,8 +191,8 @@ func builtinJWTVerifyPS256(_ BuiltinContext, operands []*ast.Term, iter func(*as } // Implements PS384 JWT signature verification -func builtinJWTVerifyPS384(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - result, err := builtinJWTVerifyRSA(operands[0].Value, operands[1].Value, sha512.New384, func(publicKey *rsa.PublicKey, digest []byte, signature []byte) error { +func builtinJWTVerifyPS384(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + result, err := builtinJWTVerifyRSA(bctx, operands[0].Value, operands[1].Value, sha512.New384, func(publicKey *rsa.PublicKey, digest []byte, signature []byte) error { return rsa.VerifyPSS( publicKey, crypto.SHA384, @@ -206,8 +207,8 @@ func builtinJWTVerifyPS384(_ BuiltinContext, operands []*ast.Term, iter func(*as } // Implements PS512 JWT signature verification -func builtinJWTVerifyPS512(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - result, err := builtinJWTVerifyRSA(operands[0].Value, operands[1].Value, sha512.New, func(publicKey *rsa.PublicKey, digest []byte, signature []byte) error { +func builtinJWTVerifyPS512(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + result, err := builtinJWTVerifyRSA(bctx, operands[0].Value, operands[1].Value, sha512.New, func(publicKey *rsa.PublicKey, digest []byte, signature []byte) error { return rsa.VerifyPSS( publicKey, crypto.SHA512, @@ -222,19 +223,19 @@ func builtinJWTVerifyPS512(_ BuiltinContext, operands []*ast.Term, iter func(*as } // Implements RSA JWT signature verification. -func builtinJWTVerifyRSA(a ast.Value, b ast.Value, hasher func() hash.Hash, verify func(publicKey *rsa.PublicKey, digest []byte, signature []byte) error) (ast.Value, error) { - return builtinJWTVerify(a, b, hasher, func(publicKey interface{}, digest []byte, signature []byte) error { +func builtinJWTVerifyRSA(bctx BuiltinContext, jwt ast.Value, keyStr ast.Value, hasher func() hash.Hash, verify func(publicKey *rsa.PublicKey, digest []byte, signature []byte) error) (ast.Value, error) { + return builtinJWTVerify(bctx, jwt, keyStr, hasher, func(publicKey interface{}, digest []byte, signature []byte) error { publicKeyRsa, ok := publicKey.(*rsa.PublicKey) if !ok { - return fmt.Errorf("incorrect public key type") + return errors.New("incorrect public key type") } return verify(publicKeyRsa, digest, signature) }) } // Implements ES256 JWT signature verification. -func builtinJWTVerifyES256(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - result, err := builtinJWTVerify(operands[0].Value, operands[1].Value, sha256.New, verifyES) +func builtinJWTVerifyES256(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + result, err := builtinJWTVerify(bctx, operands[0].Value, operands[1].Value, sha256.New, verifyES) if err == nil { return iter(ast.NewTerm(result)) } @@ -242,8 +243,8 @@ func builtinJWTVerifyES256(_ BuiltinContext, operands []*ast.Term, iter func(*as } // Implements ES384 JWT signature verification -func builtinJWTVerifyES384(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - result, err := builtinJWTVerify(operands[0].Value, operands[1].Value, sha512.New384, verifyES) +func builtinJWTVerifyES384(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + result, err := builtinJWTVerify(bctx, operands[0].Value, operands[1].Value, sha512.New384, verifyES) if err == nil { return iter(ast.NewTerm(result)) } @@ -251,8 +252,8 @@ func builtinJWTVerifyES384(_ BuiltinContext, operands []*ast.Term, iter func(*as } // Implements ES512 JWT signature verification -func builtinJWTVerifyES512(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - result, err := builtinJWTVerify(operands[0].Value, operands[1].Value, sha512.New, verifyES) +func builtinJWTVerifyES512(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + result, err := builtinJWTVerify(bctx, operands[0].Value, operands[1].Value, sha512.New, verifyES) if err == nil { return iter(ast.NewTerm(result)) } @@ -267,7 +268,7 @@ func verifyES(publicKey interface{}, digest []byte, signature []byte) (err error }() publicKeyEcdsa, ok := publicKey.(*ecdsa.PublicKey) if !ok { - return fmt.Errorf("incorrect public key type") + return errors.New("incorrect public key type") } r, s := &big.Int{}, &big.Int{} n := len(signature) / 2 @@ -276,7 +277,7 @@ func verifyES(publicKey interface{}, digest []byte, signature []byte) (err error if ecdsa.Verify(publicKeyEcdsa, digest, r, s) { return nil } - return fmt.Errorf("ECDSA signature verification error") + return errors.New("ECDSA signature verification error") } type verificationKey struct { @@ -291,7 +292,7 @@ type verificationKey struct { func getKeysFromCertOrJWK(certificate string) ([]verificationKey, error) { if block, rest := pem.Decode([]byte(certificate)); block != nil { if len(rest) > 0 { - return nil, fmt.Errorf("extra data after a PEM certificate block") + return nil, errors.New("extra data after a PEM certificate block") } if block.Type == blockTypeCertificate { @@ -311,7 +312,7 @@ func getKeysFromCertOrJWK(certificate string) ([]verificationKey, error) { return []verificationKey{{key: key}}, nil } - return nil, fmt.Errorf("failed to extract a Key from the PEM certificate") + return nil, errors.New("failed to extract a Key from the PEM certificate") } jwks, err := jwk.ParseString(certificate) @@ -345,13 +346,17 @@ func getKeyByKid(kid string, keys []verificationKey) *verificationKey { } // Implements JWT signature verification. -func builtinJWTVerify(a ast.Value, b ast.Value, hasher func() hash.Hash, verify func(publicKey interface{}, digest []byte, signature []byte) error) (ast.Value, error) { - token, err := decodeJWT(a) +func builtinJWTVerify(bctx BuiltinContext, jwt ast.Value, keyStr ast.Value, hasher func() hash.Hash, verify func(publicKey interface{}, digest []byte, signature []byte) error) (ast.Value, error) { + if found, _, _, valid := getTokenFromCache(bctx, jwt, keyStr); found { + return ast.Boolean(valid), nil + } + + token, err := decodeJWT(jwt) if err != nil { return nil, err } - s, err := builtins.StringOperand(b, 2) + s, err := builtins.StringOperand(keyStr, 2) if err != nil { return nil, err } @@ -375,6 +380,11 @@ func builtinJWTVerify(a ast.Value, b ast.Value, hasher func() hash.Hash, verify return nil, err } + done := func(valid bool) (ast.Boolean, error) { + putTokenInCache(bctx, jwt, keyStr, nil, nil, valid) + return ast.Boolean(valid), nil + } + // Validate the JWT signature // First, check if there's a matching key ID (`kid`) in both token header and key(s). @@ -383,7 +393,7 @@ func builtinJWTVerify(a ast.Value, b ast.Value, hasher func() hash.Hash, verify if key := getKeyByKid(header.kid, keys); key != nil { err = verify(key.key, getInputSHA([]byte(token.header+"."+token.payload), hasher), []byte(signature)) - return ast.Boolean(err == nil), nil + return done(err == nil) } } @@ -395,7 +405,7 @@ func builtinJWTVerify(a ast.Value, b ast.Value, hasher func() hash.Hash, verify // we'll need to verify to find out err = verify(key.key, getInputSHA([]byte(token.header+"."+token.payload), hasher), []byte(signature)) if err == nil { - return ast.Boolean(true), nil + return done(true) } } else { if header.alg != key.alg { @@ -403,48 +413,32 @@ func builtinJWTVerify(a ast.Value, b ast.Value, hasher func() hash.Hash, verify } err = verify(key.key, getInputSHA([]byte(token.header+"."+token.payload), hasher), []byte(signature)) if err == nil { - return ast.Boolean(true), nil + return done(true) } } } // None of the keys worked, return false - return ast.Boolean(false), nil + return done(false) } // Implements HS256 (secret) JWT signature verification -func builtinJWTVerifyHS256(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - // Decode the JSON Web Token - token, err := decodeJWT(operands[0].Value) - if err != nil { - return err - } - - // Process Secret input - astSecret, err := builtins.StringOperand(operands[1].Value, 2) - if err != nil { - return err - } - secret := string(astSecret) - - mac := hmac.New(sha256.New, []byte(secret)) - _, err = mac.Write([]byte(token.header + "." + token.payload)) - if err != nil { - return err - } +func builtinJWTVerifyHS256(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + return builtinJWTVerifyHS(bctx, operands, sha256.New, iter) +} - signature, err := token.decodeSignature() - if err != nil { - return err - } +// Implements HS384 JWT signature verification +func builtinJWTVerifyHS384(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + return builtinJWTVerifyHS(bctx, operands, sha512.New384, iter) +} - return iter(ast.NewTerm(ast.Boolean(hmac.Equal([]byte(signature), mac.Sum(nil))))) +// Implements HS512 JWT signature verification +func builtinJWTVerifyHS512(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + return builtinJWTVerifyHS(bctx, operands, sha512.New, iter) } -// Implements HS384 JWT signature verification -func builtinJWTVerifyHS384(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - // Decode the JSON Web Token - token, err := decodeJWT(operands[0].Value) +func builtinJWTVerifyHS(bctx BuiltinContext, operands []*ast.Term, hashF func() hash.Hash, iter func(*ast.Term) error) error { + jwt, err := builtins.StringOperand(operands[0].Value, 1) if err != nil { return err } @@ -454,38 +448,20 @@ func builtinJWTVerifyHS384(_ BuiltinContext, operands []*ast.Term, iter func(*as if err != nil { return err } - secret := string(astSecret) - - mac := hmac.New(sha512.New384, []byte(secret)) - _, err = mac.Write([]byte(token.header + "." + token.payload)) - if err != nil { - return err - } - signature, err := token.decodeSignature() - if err != nil { - return err + if found, _, _, valid := getTokenFromCache(bctx, jwt, astSecret); found { + return iter(ast.NewTerm(ast.Boolean(valid))) } - return iter(ast.NewTerm(ast.Boolean(hmac.Equal([]byte(signature), mac.Sum(nil))))) -} - -// Implements HS512 JWT signature verification -func builtinJWTVerifyHS512(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { // Decode the JSON Web Token - token, err := decodeJWT(operands[0].Value) + token, err := decodeJWT(jwt) if err != nil { return err } - // Process Secret input - astSecret, err := builtins.StringOperand(operands[1].Value, 2) - if err != nil { - return err - } secret := string(astSecret) - mac := hmac.New(sha512.New, []byte(secret)) + mac := hmac.New(hashF, []byte(secret)) _, err = mac.Write([]byte(token.header + "." + token.payload)) if err != nil { return err @@ -496,7 +472,11 @@ func builtinJWTVerifyHS512(_ BuiltinContext, operands []*ast.Term, iter func(*as return err } - return iter(ast.NewTerm(ast.Boolean(hmac.Equal([]byte(signature), mac.Sum(nil))))) + valid := hmac.Equal([]byte(signature), mac.Sum(nil)) + + putTokenInCache(bctx, jwt, astSecret, nil, nil, valid) + + return iter(ast.NewTerm(ast.Boolean(valid))) } // -- Full JWT verification and decoding -- @@ -553,7 +533,7 @@ var tokenConstraintTypes = map[string]tokenConstraintHandler{ func tokenConstraintCert(value ast.Value, constraints *tokenConstraints) error { s, ok := value.(ast.String) if !ok { - return fmt.Errorf("cert constraint: must be a string") + return errors.New("cert constraint: must be a string") } keys, err := getKeysFromCertOrJWK(string(s)) @@ -578,14 +558,14 @@ func tokenConstraintTime(value ast.Value, constraints *tokenConstraints) error { func timeFromValue(value ast.Value) (float64, error) { time, ok := value.(ast.Number) if !ok { - return 0, fmt.Errorf("token time constraint: must be a number") + return 0, errors.New("token time constraint: must be a number") } timeFloat, ok := time.Float64() if !ok { - return 0, fmt.Errorf("token time constraint: unvalid float64") + return 0, errors.New("token time constraint: unvalid float64") } if timeFloat < 0 { - return 0, fmt.Errorf("token time constraint: must not be negative") + return 0, errors.New("token time constraint: must not be negative") } return timeFloat, nil } @@ -636,10 +616,10 @@ func (constraints *tokenConstraints) validate() error { keys++ } if keys > 1 { - return fmt.Errorf("duplicate key constraints") + return errors.New("duplicate key constraints") } if keys < 1 { - return fmt.Errorf("no key constraint") + return errors.New("no key constraint") } return nil } @@ -753,7 +733,7 @@ var errSignatureNotVerified = errors.New("signature not verified") func verifyHMAC(key interface{}, hash crypto.Hash, payload []byte, signature []byte) error { macKey, ok := key.([]byte) if !ok { - return fmt.Errorf("incorrect symmetric key type") + return errors.New("incorrect symmetric key type") } mac := hmac.New(hash.New, macKey) if _, err := mac.Write(payload); err != nil { @@ -776,7 +756,7 @@ func verifyAsymmetric(verify tokenVerifyAsymmetricFunction) tokenVerifyFunction func verifyRSAPKCS(key interface{}, hash crypto.Hash, digest []byte, signature []byte) error { publicKeyRsa, ok := key.(*rsa.PublicKey) if !ok { - return fmt.Errorf("incorrect public key type") + return errors.New("incorrect public key type") } if err := rsa.VerifyPKCS1v15(publicKeyRsa, hash, digest, signature); err != nil { return errSignatureNotVerified @@ -787,7 +767,7 @@ func verifyRSAPKCS(key interface{}, hash crypto.Hash, digest []byte, signature [ func verifyRSAPSS(key interface{}, hash crypto.Hash, digest []byte, signature []byte) error { publicKeyRsa, ok := key.(*rsa.PublicKey) if !ok { - return fmt.Errorf("incorrect public key type") + return errors.New("incorrect public key type") } if err := rsa.VerifyPSS(publicKeyRsa, hash, digest, signature, nil); err != nil { return errSignatureNotVerified @@ -803,7 +783,7 @@ func verifyECDSA(key interface{}, _ crypto.Hash, digest []byte, signature []byte }() publicKeyEcdsa, ok := key.(*ecdsa.PublicKey) if !ok { - return fmt.Errorf("incorrect public key type") + return errors.New("incorrect public key type") } r, s := &big.Int{}, &big.Int{} n := len(signature) / 2 @@ -852,19 +832,19 @@ var tokenHeaderTypes = map[string]tokenHeaderHandler{ func tokenHeaderCrit(header *tokenHeader, value ast.Value) error { v, ok := value.(*ast.Array) if !ok { - return fmt.Errorf("crit: must be a list") + return errors.New("crit: must be a list") } header.crit = map[string]bool{} _ = v.Iter(func(elem *ast.Term) error { tv, ok := elem.Value.(ast.String) if !ok { - return fmt.Errorf("crit: must be a list of strings") + return errors.New("crit: must be a list of strings") } header.crit[string(tv)] = true return nil }) if len(header.crit) == 0 { - return fmt.Errorf("crit: must be a nonempty list") // 'MUST NOT' use the empty list + return errors.New("crit: must be a nonempty list") // 'MUST NOT' use the empty list } return nil } @@ -923,7 +903,7 @@ func commonBuiltinJWTEncodeSign(bctx BuiltinContext, inputHeaders, jwsPayload, j return err } if jwk.GetKeyTypeFromKey(key) != keys.Keys[0].GetKeyType() { - return fmt.Errorf("JWK derived key type and keyType parameter do not match") + return errors.New("JWK derived key type and keyType parameter do not match") } standardHeaders := &jws.StandardHeaders{} @@ -934,11 +914,11 @@ func commonBuiltinJWTEncodeSign(bctx BuiltinContext, inputHeaders, jwsPayload, j } alg := standardHeaders.GetAlgorithm() if alg == jwa.Unsupported { - return fmt.Errorf("unknown signature algorithm") + return errors.New("unknown signature algorithm") } if (standardHeaders.Type == "" || standardHeaders.Type == headerJwt) && !json.Valid([]byte(jwsPayload)) { - return fmt.Errorf("type is JWT but payload is not JSON") + return errors.New("type is JWT but payload is not JSON") } // process payload and sign @@ -1024,7 +1004,7 @@ func builtinJWTDecodeVerify(bctx BuiltinContext, operands []*ast.Term, iter func } unverified := ast.ArrayTerm( - ast.BooleanTerm(false), + ast.InternedBooleanTerm(false), ast.NewTerm(ast.NewObject()), ast.NewTerm(ast.NewObject()), ) @@ -1036,57 +1016,115 @@ func builtinJWTDecodeVerify(bctx BuiltinContext, operands []*ast.Term, iter func return err } var token *JSONWebToken - var p *ast.Term - for { - // RFC7519 7.2 #1-2 split into parts - if token, err = decodeJWT(a); err != nil { - return err - } - // RFC7519 7.2 #3, #4, #6 - if err := token.decodeHeader(); err != nil { - return err - } - // RFC7159 7.2 #5 (and RFC7159 5.2 #5) validate header fields - header, err := parseTokenHeader(token) - if err != nil { - return err - } - if !header.valid() { + var payload ast.Object + var header ast.Object + + // FIXME: optimize + k, _ := b.Filter(ast.NewObject( + ast.Item(ast.StringTerm("secret"), ast.ObjectTerm()), + ast.Item(ast.StringTerm("cert"), ast.ObjectTerm()), + )) + + if found, th, tp, validSignature := getTokenFromCache(bctx, a, k); found { + if !validSignature { + // For the given token and key(s), the signature is invalid return iter(unverified) } - // Check constraints that impact signature verification. - if constraints.alg != "" && constraints.alg != header.alg { - return iter(unverified) - } - // RFC7159 7.2 #7 verify the signature - signature, err := token.decodeSignature() - if err != nil { - return err + + if th != nil && tp != nil { + header = th + payload = tp + } else { + // Cache entry was created by one of the other built-ins that doesn't decode header/payload + + if token, err = decodeJWT(a); err != nil { + return err + } + + header = token.decodedHeader + + p, err := getResult(builtinBase64UrlDecode, ast.StringTerm(token.payload)) + if err != nil { + return fmt.Errorf("JWT payload had invalid encoding: %v", err) + } + + payload, err = extractJSONObject(string(p.Value.(ast.String))) + if err != nil { + return err + } + + putTokenInCache(bctx, a, k, header, payload, true) } - if err := constraints.verify(header.kid, header.alg, token.header, token.payload, signature); err != nil { - if err == errSignatureNotVerified { + } else { + var p *ast.Term + + for { + // RFC7519 7.2 #1-2 split into parts + if token, err = decodeJWT(a); err != nil { + return err + } + + // RFC7519 7.2 #3, #4, #6 + if err := token.decodeHeader(); err != nil { + return err + } + + // RFC7159 7.2 #5 (and RFC7159 5.2 #5) validate header fields + header, err := parseTokenHeader(token) + if err != nil { + return err + } + + if !header.valid() { return iter(unverified) } - return err + + // Check constraints that impact signature verification. + if constraints.alg != "" && constraints.alg != header.alg { + return iter(unverified) + } + + // RFC7159 7.2 #7 verify the signature + signature, err := token.decodeSignature() + if err != nil { + return err + } + + if err := constraints.verify(header.kid, header.alg, token.header, token.payload, signature); err != nil { + if err == errSignatureNotVerified { + putTokenInCache(bctx, a, k, nil, nil, false) + return iter(unverified) + } + return err + } + + // RFC7159 7.2 #9-10 decode the payload + p, err = getResult(builtinBase64UrlDecode, ast.StringTerm(token.payload)) + if err != nil { + return fmt.Errorf("JWT payload had invalid encoding: %v", err) + } + + // RFC7159 7.2 #8 and 5.2 cty + if strings.EqualFold(header.cty, headerJwt) { + // Nested JWT, go round again with payload as first argument + a = p.Value + continue + } + + // Non-nested JWT (or we've reached the bottom of the nesting). + break } - // RFC7159 7.2 #9-10 decode the payload - p, err = getResult(builtinBase64UrlDecode, ast.StringTerm(token.payload)) + + payload, err = extractJSONObject(string(p.Value.(ast.String))) if err != nil { - return fmt.Errorf("JWT payload had invalid encoding: %v", err) - } - // RFC7159 7.2 #8 and 5.2 cty - if strings.ToUpper(header.cty) == headerJwt { - // Nested JWT, go round again with payload as first argument - a = p.Value - continue + return err } - // Non-nested JWT (or we've reached the bottom of the nesting). - break - } - payload, err := extractJSONObject(string(p.Value.(ast.String))) - if err != nil { - return err + + header = token.decodedHeader + + putTokenInCache(bctx, a, k, header, payload, true) } + // Check registered claim names against constraints or environment // RFC7159 4.1.1 iss if constraints.iss != "" { @@ -1111,34 +1149,34 @@ func builtinJWTDecodeVerify(bctx BuiltinContext, operands []*ast.Term, iter func } // RFC7159 4.1.4 exp if exp := payload.Get(jwtExpKey); exp != nil { - switch exp.Value.(type) { + switch v := exp.Value.(type) { case ast.Number: // constraints.time is in nanoseconds but exp Value is in seconds compareTime := ast.FloatNumberTerm(constraints.time / 1000000000) - if ast.Compare(compareTime, exp.Value.(ast.Number)) != -1 { + if ast.Compare(compareTime, v) != -1 { return iter(unverified) } default: - return fmt.Errorf("exp value must be a number") + return errors.New("exp value must be a number") } } // RFC7159 4.1.5 nbf if nbf := payload.Get(jwtNbfKey); nbf != nil { - switch nbf.Value.(type) { + switch v := nbf.Value.(type) { case ast.Number: // constraints.time is in nanoseconds but nbf Value is in seconds compareTime := ast.FloatNumberTerm(constraints.time / 1000000000) - if ast.Compare(compareTime, nbf.Value.(ast.Number)) == -1 { + if ast.Compare(compareTime, v) == -1 { return iter(unverified) } default: - return fmt.Errorf("nbf value must be a number") + return errors.New("nbf value must be a number") } } verified := ast.ArrayTerm( - ast.BooleanTerm(true), - ast.NewTerm(token.decodedHeader), + ast.InternedBooleanTerm(true), + ast.NewTerm(header), ast.NewTerm(payload), ) return iter(verified) @@ -1226,7 +1264,63 @@ func getInputSHA(input []byte, h func() hash.Hash) []byte { return hasher.Sum(nil) } +type jwtCacheEntry struct { + payload ast.Object + header ast.Object + validSignature bool +} + +const tokenCacheName = "io_jwt" + +func getTokenFromCache(bctx BuiltinContext, serializedJwt ast.Value, publicKey ast.Value) (bool, ast.Object, ast.Object, bool) { + if bctx.InterQueryBuiltinValueCache == nil { + return false, nil, nil, false + } + + c := bctx.InterQueryBuiltinValueCache.GetCache(tokenCacheName) + if c == nil { + return false, nil, nil, false + } + + key := createTokenCacheKey(serializedJwt, publicKey) + + entry, ok := c.Get(key) + if !ok { + return false, nil, nil, false + } + + if jwtEntry, ok := entry.(jwtCacheEntry); ok { + return true, jwtEntry.header, jwtEntry.payload, jwtEntry.validSignature + } + + return false, nil, nil, false +} + +func putTokenInCache(bctx BuiltinContext, serializedJwt ast.Value, publicKey ast.Value, header ast.Object, payload ast.Object, validSignature bool) { + if bctx.InterQueryBuiltinValueCache == nil { + return + } + + c := bctx.InterQueryBuiltinValueCache.GetCache(tokenCacheName) + if c == nil { + return + } + + key := createTokenCacheKey(serializedJwt, publicKey) + + c.Insert(key, jwtCacheEntry{header: header, payload: payload, validSignature: validSignature}) +} + +func createTokenCacheKey(serializedJwt ast.Value, publicKey ast.Value) ast.Value { + // We need to create a key that is unique to the serialized JWT (for lookup) and the public key used to verify it, + // so that we don't get a misleading cached validation result for a different, invalid key. + return ast.NewArray(ast.NewTerm(serializedJwt), ast.NewTerm(publicKey)) +} + func init() { + // By default, the JWT cache is disabled. + cache.RegisterDefaultInterQueryBuiltinValueCacheConfig(tokenCacheName, nil) + RegisterBuiltinFunc(ast.JWTDecode.Name, builtinJWTDecode) RegisterBuiltinFunc(ast.JWTVerifyRS256.Name, builtinJWTVerifyRS256) RegisterBuiltinFunc(ast.JWTVerifyRS384.Name, builtinJWTVerifyRS384) diff --git a/vendor/github.com/open-policy-agent/opa/topdown/trace.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/trace.go similarity index 98% rename from vendor/github.com/open-policy-agent/opa/topdown/trace.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/trace.go index 277c94b626..070e254d28 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/trace.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/trace.go @@ -13,8 +13,8 @@ import ( iStrs "github.com/open-policy-agent/opa/internal/strings" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) const ( @@ -199,7 +199,7 @@ func (l *legacyTracer) Enabled() bool { return l.t.Enabled() } -func (l *legacyTracer) Config() TraceConfig { +func (*legacyTracer) Config() TraceConfig { return TraceConfig{ PlugLocalVars: true, // For backwards compatibility old tracers will plug local variables } @@ -241,7 +241,7 @@ func (b *BufferTracer) TraceEvent(evt Event) { } // Config returns the Tracers standard configuration -func (b *BufferTracer) Config() TraceConfig { +func (*BufferTracer) Config() TraceConfig { return TraceConfig{PlugLocalVars: true} } @@ -373,10 +373,6 @@ func exprLocalVars(e *Event) *ast.ValueMap { vars := ast.NewValueMap() findVars := func(term *ast.Term) bool { - //if r, ok := term.Value.(ast.Ref); ok { - // fmt.Printf("ref: %v\n", r) - // //return true - //} if name, ok := term.Value.(ast.Var); ok { if meta, ok := e.LocalMetadata[name]; ok { if val := e.Locals.Get(name); val != nil { @@ -537,7 +533,7 @@ func builtinTrace(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term } if !bctx.TraceEnabled { - return iter(ast.BooleanTerm(true)) + return iter(ast.InternedBooleanTerm(true)) } evt := Event{ @@ -552,7 +548,7 @@ func builtinTrace(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term bctx.QueryTracers[i].TraceEvent(evt) } - return iter(ast.BooleanTerm(true)) + return iter(ast.InternedBooleanTerm(true)) } func rewrite(event *Event) *Event { @@ -867,7 +863,7 @@ func printArrows(w *bytes.Buffer, l []varInfo, printValueAt int) { spaces = (col - prevCol) - 1 } - for j := 0; j < spaces; j++ { + for j := range spaces { tab := false for _, t := range info.exprLoc.Tabs { if t == j+prevCol+1 { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/type.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/type.go similarity index 71% rename from vendor/github.com/open-policy-agent/opa/topdown/type.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/type.go index dab5c853cd..6103fbe484 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/type.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/type.go @@ -5,69 +5,69 @@ package topdown import ( - "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/v1/ast" ) func builtinIsNumber(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { switch operands[0].Value.(type) { case ast.Number: - return iter(ast.BooleanTerm(true)) + return iter(ast.InternedBooleanTerm(true)) default: - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } } func builtinIsString(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { switch operands[0].Value.(type) { case ast.String: - return iter(ast.BooleanTerm(true)) + return iter(ast.InternedBooleanTerm(true)) default: - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } } func builtinIsBoolean(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { switch operands[0].Value.(type) { case ast.Boolean: - return iter(ast.BooleanTerm(true)) + return iter(ast.InternedBooleanTerm(true)) default: - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } } func builtinIsArray(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { switch operands[0].Value.(type) { case *ast.Array: - return iter(ast.BooleanTerm(true)) + return iter(ast.InternedBooleanTerm(true)) default: - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } } func builtinIsSet(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { switch operands[0].Value.(type) { case ast.Set: - return iter(ast.BooleanTerm(true)) + return iter(ast.InternedBooleanTerm(true)) default: - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } } func builtinIsObject(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { switch operands[0].Value.(type) { case ast.Object: - return iter(ast.BooleanTerm(true)) + return iter(ast.InternedBooleanTerm(true)) default: - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } } func builtinIsNull(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { switch operands[0].Value.(type) { case ast.Null: - return iter(ast.BooleanTerm(true)) + return iter(ast.InternedBooleanTerm(true)) default: - return iter(ast.BooleanTerm(false)) + return iter(ast.InternedBooleanTerm(false)) } } diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/type_name.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/type_name.go new file mode 100644 index 0000000000..a611e8f30e --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/type_name.go @@ -0,0 +1,46 @@ +// Copyright 2018 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 topdown + +import ( + "errors" + + "github.com/open-policy-agent/opa/v1/ast" +) + +var ( + nullStringTerm = ast.StringTerm("null") + booleanStringTerm = ast.StringTerm("boolean") + numberStringTerm = ast.StringTerm("number") + stringStringTerm = ast.StringTerm("string") + arrayStringTerm = ast.StringTerm("array") + objectStringTerm = ast.StringTerm("object") + setStringTerm = ast.StringTerm("set") +) + +func builtinTypeName(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + switch operands[0].Value.(type) { + case ast.Null: + return iter(nullStringTerm) + case ast.Boolean: + return iter(booleanStringTerm) + case ast.Number: + return iter(numberStringTerm) + case ast.String: + return iter(stringStringTerm) + case *ast.Array: + return iter(arrayStringTerm) + case ast.Object: + return iter(objectStringTerm) + case ast.Set: + return iter(setStringTerm) + } + + return errors.New("illegal value") +} + +func init() { + RegisterBuiltinFunc(ast.TypeNameBuiltin.Name, builtinTypeName) +} diff --git a/vendor/github.com/open-policy-agent/opa/topdown/uuid.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/uuid.go similarity index 92% rename from vendor/github.com/open-policy-agent/opa/topdown/uuid.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/uuid.go index d3a7a5f900..d013df9fea 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/uuid.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/uuid.go @@ -5,9 +5,9 @@ package topdown import ( - "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/internal/uuid" - "github.com/open-policy-agent/opa/topdown/builtins" + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" ) type uuidCachingKey string diff --git a/vendor/github.com/open-policy-agent/opa/topdown/walk.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/walk.go similarity index 61% rename from vendor/github.com/open-policy-agent/opa/topdown/walk.go rename to vendor/github.com/open-policy-agent/opa/v1/topdown/walk.go index 0f3b3544b5..43aa29c97a 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/walk.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/walk.go @@ -5,18 +5,20 @@ package topdown import ( - "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/v1/ast" ) +var emptyArr = ast.ArrayTerm() + func evalWalk(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { input := operands[0] if pathIsWildcard(operands) { // When the path assignment is a wildcard: walk(input, [_, value]) // we may skip the path construction entirely, and simply return - // same pointer in each iteration. This is a much more efficient + // same pointer in each iteration. This is a *much* more efficient // path when only the values are needed. - return walkNoPath(input, iter) + return walkNoPath(ast.ArrayTerm(emptyArr, input), iter) } filter := getOutputPath(operands) @@ -24,7 +26,6 @@ func evalWalk(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error } func walk(filter, path *ast.Array, input *ast.Term, iter func(*ast.Term) error) error { - if filter == nil || filter.Len() == 0 { if path == nil { path = ast.NewArray() @@ -49,58 +50,63 @@ func walk(filter, path *ast.Array, input *ast.Term, iter func(*ast.Term) error) switch v := input.Value.(type) { case *ast.Array: - for i := 0; i < v.Len(); i++ { - path = pathAppend(path, ast.IntNumberTerm(i)) - if err := walk(filter, path, v.Elem(i), iter); err != nil { + for i := range v.Len() { + if err := walk(filter, pathAppend(path, ast.InternedIntNumberTerm(i)), v.Elem(i), iter); err != nil { return err } - path = path.Slice(0, path.Len()-1) } case ast.Object: - return v.Iter(func(k, v *ast.Term) error { - path = pathAppend(path, k) - if err := walk(filter, path, v, iter); err != nil { + for _, k := range v.Keys() { + if err := walk(filter, pathAppend(path, k), v.Get(k), iter); err != nil { return err } - path = path.Slice(0, path.Len()-1) - return nil - }) + } case ast.Set: - return v.Iter(func(elem *ast.Term) error { - path = pathAppend(path, elem) - if err := walk(filter, path, elem, iter); err != nil { + for _, elem := range v.Slice() { + if err := walk(filter, pathAppend(path, elem), elem, iter); err != nil { return err } - path = path.Slice(0, path.Len()-1) - return nil - }) + } } return nil } -var emptyArr = ast.ArrayTerm() - func walkNoPath(input *ast.Term, iter func(*ast.Term) error) error { - if err := iter(ast.ArrayTerm(emptyArr, input)); err != nil { + // Note: the path array is embedded in the input from the start here + // in order to avoid an extra allocation per iteration. This leads to + // a little convoluted code below in order to extract and set the value, + // but since walk is commonly used to traverse large data structures, + // the performance gain is worth it. + if err := iter(input); err != nil { return err } - switch v := input.Value.(type) { + inputArray := input.Value.(*ast.Array) + value := inputArray.Get(ast.InternedIntNumberTerm(1)).Value + + switch v := value.(type) { case ast.Object: - return v.Iter(func(_, v *ast.Term) error { - return walkNoPath(v, iter) - }) + for _, k := range v.Keys() { + inputArray.Set(1, v.Get(k)) + if err := walkNoPath(input, iter); err != nil { + return err + } + } case *ast.Array: - for i := 0; i < v.Len(); i++ { - if err := walkNoPath(v.Elem(i), iter); err != nil { + for i := range v.Len() { + inputArray.Set(1, v.Elem(i)) + if err := walkNoPath(input, iter); err != nil { return err } } case ast.Set: - return v.Iter(func(elem *ast.Term) error { - return walkNoPath(elem, iter) - }) + for _, elem := range v.Slice() { + inputArray.Set(1, elem) + if err := walkNoPath(input, iter); err != nil { + return err + } + } } return nil diff --git a/vendor/github.com/open-policy-agent/opa/tracing/tracing.go b/vendor/github.com/open-policy-agent/opa/v1/tracing/tracing.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/tracing/tracing.go rename to vendor/github.com/open-policy-agent/opa/v1/tracing/tracing.go diff --git a/vendor/github.com/open-policy-agent/opa/types/decode.go b/vendor/github.com/open-policy-agent/opa/v1/types/decode.go similarity index 96% rename from vendor/github.com/open-policy-agent/opa/types/decode.go rename to vendor/github.com/open-policy-agent/opa/v1/types/decode.go index a6bd9ea030..e3e1e98370 100644 --- a/vendor/github.com/open-policy-agent/opa/types/decode.go +++ b/vendor/github.com/open-policy-agent/opa/v1/types/decode.go @@ -8,7 +8,7 @@ import ( "encoding/json" "fmt" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/util" ) const ( @@ -31,13 +31,13 @@ func Unmarshal(bs []byte) (result Type, err error) { if err = util.UnmarshalJSON(bs, &hint); err == nil { switch hint.Type { case typeNull: - result = NewNull() + result = Nl case typeBoolean: - result = NewBoolean() + result = B case typeNumber: - result = NewNumber() + result = N case typeString: - result = NewString() + result = S case typeArray: var arr rawarray if err = util.UnmarshalJSON(bs, &arr); err == nil { diff --git a/vendor/github.com/open-policy-agent/opa/types/types.go b/vendor/github.com/open-policy-agent/opa/v1/types/types.go similarity index 96% rename from vendor/github.com/open-policy-agent/opa/types/types.go rename to vendor/github.com/open-policy-agent/opa/v1/types/types.go index 2a050927dd..c661e96666 100644 --- a/vendor/github.com/open-policy-agent/opa/types/types.go +++ b/vendor/github.com/open-policy-agent/opa/v1/types/types.go @@ -8,11 +8,13 @@ package types import ( "encoding/json" + "errors" "fmt" + "slices" "sort" "strings" - "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/v1/util" ) // Sprint returns the string representation of the type. @@ -48,6 +50,8 @@ func NewNull() Null { return Null{} } +var Nl Type = NewNull() + // NamedType represents a type alias with an arbitrary name and description. // This is useful for generating documentation for built-in functions. type NamedType struct { @@ -105,7 +109,7 @@ func unwrap(t Type) Type { } } -func (t Null) String() string { +func (Null) String() string { return typeNull } @@ -113,7 +117,7 @@ func (t Null) String() string { type Boolean struct{} // B represents an instance of the boolean type. -var B = NewBoolean() +var B Type = NewBoolean() // NewBoolean returns a new Boolean type. func NewBoolean() Boolean { @@ -136,7 +140,7 @@ func (t Boolean) String() string { type String struct{} // S represents an instance of the string type. -var S = NewString() +var S Type = NewString() // NewString returns a new String type. func NewString() String { @@ -158,7 +162,7 @@ func (String) String() string { type Number struct{} // N represents an instance of the number type. -var N = NewNumber() +var N Type = NewNumber() // NewNumber returns a new Number type. func NewNumber() Number { @@ -252,6 +256,13 @@ type Set struct { of Type } +// Boxed set types. +var ( + SetOfAny Type = NewSet(A) + SetOfStr Type = NewSet(S) + SetOfNum Type = NewSet(N) +) + // NewSet returns a new Set type. func NewSet(of Type) *Set { return &Set{ @@ -339,9 +350,8 @@ type Object struct { // NewObject returns a new Object type. func NewObject(static []*StaticProperty, dynamic *DynamicProperty) *Object { - sort.Slice(static, func(i, j int) bool { - cmp := util.Compare(static[i].Key, static[j].Key) - return cmp == -1 + slices.SortFunc(static, func(a, b *StaticProperty) int { + return util.Compare(a.Key, b.Key) }) return &Object{ static: static, @@ -504,7 +514,7 @@ func mergeObjects(a, b *Object) *Object { type Any []Type // A represents the superset of all types. -var A = NewAny() +var A Type = NewAny() // NewAny returns a new Any type. func NewAny(of ...Type) Any { @@ -675,7 +685,7 @@ func Arity(x Type) int { if !ok { return 0 } - return len(f.FuncArgs().Args) + return f.Arity() } // NewFunction returns a new Function object of the given argument and result types. @@ -723,6 +733,11 @@ func (t *Function) Args() []Type { return cpy } +// Arity returns the number of arguments in the function signature. +func (t *Function) Arity() int { + return len(t.args) +} + // Result returns the function's result type. func (t *Function) Result() Type { return unwrap(t.result) @@ -763,7 +778,7 @@ func (t *Function) UnmarshalJSON(bs []byte) error { f, ok := tpe.(*Function) if !ok { - return fmt.Errorf("invalid type") + return errors.New("invalid type") } *t = *f @@ -780,14 +795,15 @@ func (t *Function) Union(other *Function) *Function { return other } - a := t.Args() - b := other.Args() - if len(a) != len(b) { + if t.Arity() != other.Arity() { return nil } - aIsVariadic := t.FuncArgs().Variadic != nil - bIsVariadic := other.FuncArgs().Variadic != nil + tfa := t.FuncArgs() + ofa := other.FuncArgs() + + aIsVariadic := tfa.Variadic != nil + bIsVariadic := ofa.Variadic != nil if aIsVariadic && !bIsVariadic { return nil @@ -795,13 +811,16 @@ func (t *Function) Union(other *Function) *Function { return nil } + a := t.Args() + b := other.Args() + args := make([]Type, len(a)) for i := range a { args[i] = Or(a[i], b[i]) } result := NewFunction(args, Or(t.Result(), other.Result())) - result.variadic = Or(t.FuncArgs().Variadic, other.FuncArgs().Variadic) + result.variadic = Or(tfa.Variadic, ofa.Variadic) return result } @@ -841,7 +860,7 @@ func Compare(a, b Type) int { } else if x < y { return -1 } - switch a.(type) { + switch a.(type) { //nolint:gocritic case nil, Null, Boolean, Number, String: return 0 case *Array: @@ -883,7 +902,7 @@ func Compare(a, b Type) int { minLen = lenStaticB } - for i := 0; i < minLen; i++ { + for i := range minLen { if cmp := util.Compare(objA.static[i].Key, objB.static[i].Key); cmp != 0 { return cmp } @@ -922,7 +941,7 @@ func Compare(a, b Type) int { } else if len(fA.args) > len(fB.args) { return 1 } - for i := 0; i < len(fA.args); i++ { + for i := range len(fA.args) { if cmp := Compare(fA.args[i], fB.args[i]); cmp != 0 { return cmp } @@ -1120,7 +1139,7 @@ func Nil(a Type) bool { func TypeOf(x interface{}) Type { switch x := x.(type) { case nil: - return NewNull() + return Nl case bool: return B case string: @@ -1155,7 +1174,7 @@ func TypeOf(x interface{}) Type { type typeSlice []Type func (s typeSlice) Less(i, j int) bool { return Compare(s[i], s[j]) < 0 } -func (s typeSlice) Swap(i, j int) { x := s[i]; s[i] = s[j]; s[j] = x } +func (s typeSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s typeSlice) Len() int { return len(s) } func typeSliceCompare(a, b []Type) int { @@ -1163,7 +1182,7 @@ func typeSliceCompare(a, b []Type) int { if len(b) < minLen { minLen = len(b) } - for i := 0; i < minLen; i++ { + for i := range minLen { if cmp := Compare(a[i], b[i]); cmp != 0 { return cmp } diff --git a/vendor/github.com/open-policy-agent/opa/v1/util/backoff.go b/vendor/github.com/open-policy-agent/opa/v1/util/backoff.go new file mode 100644 index 0000000000..1558f0cff8 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/util/backoff.go @@ -0,0 +1,42 @@ +// Copyright 2018 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 util + +import ( + "math/rand" + "time" +) + +// DefaultBackoff returns a delay with an exponential backoff based on the +// number of retries. +func DefaultBackoff(base, maxNS float64, retries int) time.Duration { + return Backoff(base, maxNS, .2, 1.6, retries) +} + +// Backoff returns a delay with an exponential backoff based on the number of +// retries. Same algorithm used in gRPC. +func Backoff(base, maxNS, jitter, factor float64, retries int) time.Duration { + if retries == 0 { + return 0 + } + + backoff, maxNS := base, maxNS + for backoff < maxNS && retries > 0 { + backoff *= factor + retries-- + } + if backoff > maxNS { + backoff = maxNS + } + + // Randomize backoff delays so that if a cluster of requests start at + // the same time, they won't operate in lockstep. + backoff *= 1 + jitter*(rand.Float64()*2-1) + if backoff < 0 { + return 0 + } + + return time.Duration(backoff) +} diff --git a/vendor/github.com/open-policy-agent/opa/v1/util/channel.go b/vendor/github.com/open-policy-agent/opa/v1/util/channel.go new file mode 100644 index 0000000000..e2653ac7fd --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/util/channel.go @@ -0,0 +1,32 @@ +package util + +import ( + "github.com/open-policy-agent/opa/v1/metrics" +) + +// This prevents getting blocked forever writing to a full buffer, in case another routine fills the last space. +// Retrying maxEventRetry times to drop the oldest event. Dropping the incoming event if there still isn't room. +const maxEventRetry = 1000 + +// PushFIFO pushes data into a buffered channel without blocking when full, making room by dropping the oldest data. +// An optional metric can be recorded when data is dropped. +func PushFIFO[T any](buffer chan T, data T, metrics metrics.Metrics, metricName string) { + + for range maxEventRetry { + // non-blocking send to the buffer, to prevent blocking if buffer is full so room can be made. + select { + case buffer <- data: + return + default: + } + + // non-blocking drop from the buffer to make room for incoming event + select { + case <-buffer: + if metrics != nil && metricName != "" { + metrics.Counter(metricName).Incr() + } + default: + } + } +} diff --git a/vendor/github.com/open-policy-agent/opa/util/close.go b/vendor/github.com/open-policy-agent/opa/v1/util/close.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/util/close.go rename to vendor/github.com/open-policy-agent/opa/v1/util/close.go diff --git a/vendor/github.com/open-policy-agent/opa/util/compare.go b/vendor/github.com/open-policy-agent/opa/v1/util/compare.go similarity index 92% rename from vendor/github.com/open-policy-agent/opa/util/compare.go rename to vendor/github.com/open-policy-agent/opa/v1/util/compare.go index 8ae7753690..2569375b19 100644 --- a/vendor/github.com/open-policy-agent/opa/util/compare.go +++ b/vendor/github.com/open-policy-agent/opa/v1/util/compare.go @@ -8,7 +8,6 @@ import ( "encoding/json" "fmt" "math/big" - "sort" ) // Compare returns 0 if a equals b, -1 if a is less than b, and 1 if b is than a. @@ -83,7 +82,7 @@ func Compare(a, b interface{}) int { if bLen < minLen { minLen = bLen } - for i := 0; i < minLen; i++ { + for i := range minLen { cmp := Compare(a[i], b[i]) if cmp != 0 { return cmp @@ -99,23 +98,15 @@ func Compare(a, b interface{}) int { case map[string]interface{}: switch b := b.(type) { case map[string]interface{}: - var aKeys []string - for k := range a { - aKeys = append(aKeys, k) - } - var bKeys []string - for k := range b { - bKeys = append(bKeys, k) - } - sort.Strings(aKeys) - sort.Strings(bKeys) + aKeys := KeysSorted(a) + bKeys := KeysSorted(b) aLen := len(aKeys) bLen := len(bKeys) minLen := aLen if bLen < minLen { minLen = bLen } - for i := 0; i < minLen; i++ { + for i := range minLen { if aKeys[i] < bKeys[i] { return -1 } else if bKeys[i] < aKeys[i] { diff --git a/vendor/github.com/open-policy-agent/opa/util/decoding/context.go b/vendor/github.com/open-policy-agent/opa/v1/util/decoding/context.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/util/decoding/context.go rename to vendor/github.com/open-policy-agent/opa/v1/util/decoding/context.go diff --git a/vendor/github.com/open-policy-agent/opa/util/doc.go b/vendor/github.com/open-policy-agent/opa/v1/util/doc.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/util/doc.go rename to vendor/github.com/open-policy-agent/opa/v1/util/doc.go diff --git a/vendor/github.com/open-policy-agent/opa/util/enumflag.go b/vendor/github.com/open-policy-agent/opa/v1/util/enumflag.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/util/enumflag.go rename to vendor/github.com/open-policy-agent/opa/v1/util/enumflag.go diff --git a/vendor/github.com/open-policy-agent/opa/util/graph.go b/vendor/github.com/open-policy-agent/opa/v1/util/graph.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/util/graph.go rename to vendor/github.com/open-policy-agent/opa/v1/util/graph.go diff --git a/vendor/github.com/open-policy-agent/opa/v1/util/hashmap.go b/vendor/github.com/open-policy-agent/opa/v1/util/hashmap.go new file mode 100644 index 0000000000..cf6a385f41 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/util/hashmap.go @@ -0,0 +1,271 @@ +// Copyright 2016 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 util + +import ( + "fmt" + "strings" +) + +// T is a concise way to refer to T. +type T interface{} + +type Hasher interface { + Hash() int +} + +type hashEntry[K any, V any] struct { + k K + v V + next *hashEntry[K, V] +} + +// TypedHashMap represents a key/value map. +type TypedHashMap[K any, V any] struct { + keq func(K, K) bool + veq func(V, V) bool + khash func(K) int + vhash func(V) int + def V + table map[int]*hashEntry[K, V] + size int +} + +// NewTypedHashMap returns a new empty TypedHashMap. +func NewTypedHashMap[K any, V any](keq func(K, K) bool, veq func(V, V) bool, khash func(K) int, vhash func(V) int, def V) *TypedHashMap[K, V] { + return &TypedHashMap[K, V]{ + keq: keq, + veq: veq, + khash: khash, + vhash: vhash, + def: def, + table: make(map[int]*hashEntry[K, V]), + size: 0, + } +} + +// HashMap represents a key/value map. +type HashMap = TypedHashMap[T, T] + +// NewHashMap returns a new empty HashMap. +func NewHashMap(eq func(T, T) bool, hash func(T) int) *HashMap { + return &HashMap{ + keq: eq, + veq: eq, + khash: hash, + vhash: hash, + def: nil, + table: make(map[int]*hashEntry[T, T]), + size: 0, + } +} + +// Copy returns a shallow copy of this HashMap. +func (h *TypedHashMap[K, V]) Copy() *TypedHashMap[K, V] { + cpy := NewTypedHashMap[K, V](h.keq, h.veq, h.khash, h.vhash, h.def) + h.Iter(func(k K, v V) bool { + cpy.Put(k, v) + return false + }) + return cpy +} + +// Equal returns true if this HashMap equals the other HashMap. +// Two hash maps are equal if they contain the same key/value pairs. +func (h *TypedHashMap[K, V]) Equal(other *TypedHashMap[K, V]) bool { + if h.Len() != other.Len() { + return false + } + return !h.Iter(func(k K, v V) bool { + ov, ok := other.Get(k) + if !ok { + return true + } + return !h.veq(v, ov) + }) +} + +// Get returns the value for k. +func (h *TypedHashMap[K, V]) Get(k K) (V, bool) { + hash := h.khash(k) + for entry := h.table[hash]; entry != nil; entry = entry.next { + if h.keq(entry.k, k) { + return entry.v, true + } + } + return h.def, false +} + +// Delete removes the key k. +func (h *TypedHashMap[K, V]) Delete(k K) { + hash := h.khash(k) + var prev *hashEntry[K, V] + for entry := h.table[hash]; entry != nil; entry = entry.next { + if h.keq(entry.k, k) { + if prev != nil { + prev.next = entry.next + } else { + h.table[hash] = entry.next + } + h.size-- + return + } + prev = entry + } +} + +// Hash returns the hash code for this hash map. +func (h *TypedHashMap[K, V]) Hash() int { + var hash int + h.Iter(func(k K, v V) bool { + hash += h.khash(k) + h.vhash(v) + return false + }) + return hash +} + +// Iter invokes the iter function for each element in the HashMap. +// If the iter function returns true, iteration stops and the return value is true. +// If the iter function never returns true, iteration proceeds through all elements +// and the return value is false. +func (h *TypedHashMap[K, V]) Iter(iter func(K, V) bool) bool { + for _, entry := range h.table { + for ; entry != nil; entry = entry.next { + if iter(entry.k, entry.v) { + return true + } + } + } + return false +} + +// Len returns the current size of this HashMap. +func (h *TypedHashMap[K, V]) Len() int { + return h.size +} + +// Put inserts a key/value pair into this HashMap. If the key is already present, the existing +// value is overwritten. +func (h *TypedHashMap[K, V]) Put(k K, v V) { + hash := h.khash(k) + head := h.table[hash] + for entry := head; entry != nil; entry = entry.next { + if h.keq(entry.k, k) { + entry.v = v + return + } + } + h.table[hash] = &hashEntry[K, V]{k: k, v: v, next: head} + h.size++ +} + +func (h *TypedHashMap[K, V]) String() string { + var buf []string + h.Iter(func(k K, v V) bool { + buf = append(buf, fmt.Sprintf("%v: %v", k, v)) + return false + }) + return "{" + strings.Join(buf, ", ") + "}" +} + +// Update returns a new HashMap with elements from the other HashMap put into this HashMap. +// If the other HashMap contains elements with the same key as this HashMap, the value +// from the other HashMap overwrites the value from this HashMap. +func (h *TypedHashMap[K, V]) Update(other *TypedHashMap[K, V]) *TypedHashMap[K, V] { + updated := h.Copy() + other.Iter(func(k K, v V) bool { + updated.Put(k, v) + return false + }) + return updated +} + +type hasherEntry[K Hasher, V any] struct { + k K + v V + next *hasherEntry[K, V] +} + +// HasherMap represents a simpler version of TypedHashMap that uses Hasher's +// for keys, and requires only an equality function for keys. Ideally we'd have +// and Equal method for all key types too, and we could get rid of that requirement. +type HasherMap[K Hasher, V any] struct { + keq func(K, K) bool + table map[int]*hasherEntry[K, V] + size int +} + +// NewHasherMap returns a new empty HasherMap. +func NewHasherMap[K Hasher, V any](keq func(K, K) bool) *HasherMap[K, V] { + return &HasherMap[K, V]{ + keq: keq, + table: make(map[int]*hasherEntry[K, V]), + size: 0, + } +} + +// Get returns the value for k. +func (h *HasherMap[K, V]) Get(k K) (V, bool) { + for entry := h.table[k.Hash()]; entry != nil; entry = entry.next { + if h.keq(entry.k, k) { + return entry.v, true + } + } + var zero V + return zero, false +} + +// Put inserts a key/value pair into this HashMap. If the key is already present, the existing +// value is overwritten. +func (h *HasherMap[K, V]) Put(k K, v V) { + hash := k.Hash() + head := h.table[hash] + for entry := head; entry != nil; entry = entry.next { + if h.keq(entry.k, k) { + entry.v = v + return + } + } + h.table[hash] = &hasherEntry[K, V]{k: k, v: v, next: head} + h.size++ +} + +// Delete removes the key k. +func (h *HasherMap[K, V]) Delete(k K) { + hash := k.Hash() + var prev *hasherEntry[K, V] + for entry := h.table[hash]; entry != nil; entry = entry.next { + if h.keq(entry.k, k) { + if prev != nil { + prev.next = entry.next + } else { + h.table[hash] = entry.next + } + h.size-- + return + } + prev = entry + } +} + +// Iter invokes the iter function for each element in the HasherMap. +// If the iter function returns true, iteration stops and the return value is true. +// If the iter function never returns true, iteration proceeds through all elements +// and the return value is false. +func (h *HasherMap[K, V]) Iter(iter func(K, V) bool) bool { + for _, entry := range h.table { + for ; entry != nil; entry = entry.next { + if iter(entry.k, entry.v) { + return true + } + } + } + return false +} + +// Len returns the current size of this HashMap. +func (h *HasherMap[K, V]) Len() int { + return h.size +} diff --git a/vendor/github.com/open-policy-agent/opa/util/json.go b/vendor/github.com/open-policy-agent/opa/v1/util/json.go similarity index 98% rename from vendor/github.com/open-policy-agent/opa/util/json.go rename to vendor/github.com/open-policy-agent/opa/v1/util/json.go index 0b7fd2ed64..5a4e460b61 100644 --- a/vendor/github.com/open-policy-agent/opa/util/json.go +++ b/vendor/github.com/open-policy-agent/opa/v1/util/json.go @@ -13,7 +13,7 @@ import ( "sigs.k8s.io/yaml" - "github.com/open-policy-agent/opa/loader/extension" + "github.com/open-policy-agent/opa/v1/loader/extension" ) // UnmarshalJSON parses the JSON encoded data and stores the result in the value diff --git a/vendor/github.com/open-policy-agent/opa/v1/util/maps.go b/vendor/github.com/open-policy-agent/opa/v1/util/maps.go new file mode 100644 index 0000000000..c56fbe98ac --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/util/maps.go @@ -0,0 +1,34 @@ +package util + +import ( + "cmp" + "slices" +) + +// Keys returns a slice of keys from any map. +func Keys[M ~map[K]V, K comparable, V any](m M) []K { + r := make([]K, 0, len(m)) + for k := range m { + r = append(r, k) + } + return r +} + +// KeysSorted returns a slice of keys from any map, sorted in ascending order. +func KeysSorted[M ~map[K]V, K cmp.Ordered, V any](m M) []K { + r := make([]K, 0, len(m)) + for k := range m { + r = append(r, k) + } + slices.Sort(r) + return r +} + +// Values returns a slice of values from any map. Copied from golang.org/x/exp/maps. +func Values[M ~map[K]V, K comparable, V any](m M) []V { + r := make([]V, 0, len(m)) + for _, v := range m { + r = append(r, v) + } + return r +} diff --git a/vendor/github.com/open-policy-agent/opa/v1/util/performance.go b/vendor/github.com/open-policy-agent/opa/v1/util/performance.go new file mode 100644 index 0000000000..467fe766bb --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/util/performance.go @@ -0,0 +1,64 @@ +package util + +import ( + "math" + "slices" + "unsafe" +) + +// NewPtrSlice returns a slice of pointers to T with length n, +// with only 2 allocations performed no matter the size of n. +// See: +// https://gist.github.com/CAFxX/e96e8a5c3841d152f16d266a1fe7f8bd#slices-of-pointers +func NewPtrSlice[T any](n int) []*T { + return GrowPtrSlice[T](nil, n) +} + +// GrowPtrSlice appends n elements to the slice, each pointing to +// a newly-allocated T. The resulting slice has length equal to len(s)+n. +// +// It performs at most 2 allocations, regardless of n. +func GrowPtrSlice[T any](s []*T, n int) []*T { + s = slices.Grow(s, n) + p := make([]T, n) + for i := range n { + s = append(s, &p[i]) + } + return s +} + +// Allocation free conversion from []byte to string (unsafe) +// Note that the byte slice must not be modified after conversion +func ByteSliceToString(bs []byte) string { + return unsafe.String(unsafe.SliceData(bs), len(bs)) +} + +// Allocation free conversion from ~string to []byte (unsafe) +// Note that the byte slice must not be modified after conversion +func StringToByteSlice[T ~string](s T) []byte { + return unsafe.Slice(unsafe.StringData(string(s)), len(s)) +} + +// NumDigitsInt returns the number of digits in n. +// This is useful for pre-allocating buffers for string conversion. +func NumDigitsInt(n int) int { + if n == 0 { + return 1 + } + + if n < 0 { + n = -n + } + + return int(math.Log10(float64(n))) + 1 +} + +// NumDigitsUint returns the number of digits in n. +// This is useful for pre-allocating buffers for string conversion. +func NumDigitsUint(n uint64) int { + if n == 0 { + return 1 + } + + return int(math.Log10(float64(n))) + 1 +} diff --git a/vendor/github.com/open-policy-agent/opa/util/queue.go b/vendor/github.com/open-policy-agent/opa/v1/util/queue.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/util/queue.go rename to vendor/github.com/open-policy-agent/opa/v1/util/queue.go diff --git a/vendor/github.com/open-policy-agent/opa/util/read_gzip_body.go b/vendor/github.com/open-policy-agent/opa/v1/util/read_gzip_body.go similarity index 95% rename from vendor/github.com/open-policy-agent/opa/util/read_gzip_body.go rename to vendor/github.com/open-policy-agent/opa/v1/util/read_gzip_body.go index 217638b363..b979d0bd0f 100644 --- a/vendor/github.com/open-policy-agent/opa/util/read_gzip_body.go +++ b/vendor/github.com/open-policy-agent/opa/v1/util/read_gzip_body.go @@ -4,13 +4,13 @@ import ( "bytes" "compress/gzip" "encoding/binary" - "fmt" + "errors" "io" "net/http" "strings" "sync" - "github.com/open-policy-agent/opa/util/decoding" + "github.com/open-policy-agent/opa/v1/util/decoding" ) var gzipReaderPool = sync.Pool{ @@ -58,7 +58,7 @@ func ReadMaybeCompressedBody(r *http.Request) ([]byte, error) { // earlier in DecodingLimitHandler. sizeTrailerField := binary.LittleEndian.Uint32(content.Bytes()[content.Len()-4:]) if sizeTrailerField > uint32(gzipMaxLength) { - return content.Bytes(), fmt.Errorf("gzip payload too large") + return content.Bytes(), errors.New("gzip payload too large") } // Pull a gzip decompressor from the pool, and assign it to the current // buffer, using Reset(). Later, return it back to the pool for another diff --git a/vendor/github.com/open-policy-agent/opa/util/time.go b/vendor/github.com/open-policy-agent/opa/v1/util/time.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/util/time.go rename to vendor/github.com/open-policy-agent/opa/v1/util/time.go diff --git a/vendor/github.com/open-policy-agent/opa/util/wait.go b/vendor/github.com/open-policy-agent/opa/v1/util/wait.go similarity index 94% rename from vendor/github.com/open-policy-agent/opa/util/wait.go rename to vendor/github.com/open-policy-agent/opa/v1/util/wait.go index b70ab6fcf9..b1ea84fd53 100644 --- a/vendor/github.com/open-policy-agent/opa/util/wait.go +++ b/vendor/github.com/open-policy-agent/opa/v1/util/wait.go @@ -5,7 +5,7 @@ package util import ( - "fmt" + "errors" "time" ) @@ -24,7 +24,7 @@ func WaitFunc(fun func() bool, interval, timeout time.Duration) error { for { select { case <-timer.C: - return fmt.Errorf("timeout") + return errors.New("timeout") case <-ticker.C: if fun() { return nil diff --git a/vendor/github.com/open-policy-agent/opa/version/version.go b/vendor/github.com/open-policy-agent/opa/v1/version/version.go similarity index 95% rename from vendor/github.com/open-policy-agent/opa/version/version.go rename to vendor/github.com/open-policy-agent/opa/v1/version/version.go index 862556bce0..3af111395e 100644 --- a/vendor/github.com/open-policy-agent/opa/version/version.go +++ b/vendor/github.com/open-policy-agent/opa/v1/version/version.go @@ -11,7 +11,7 @@ import ( ) // Version is the canonical version of OPA. -var Version = "0.70.0" +var Version = "1.4.0" // GoVersion is the version of Go this was built with var GoVersion = runtime.Version() @@ -44,6 +44,6 @@ func init() { } } if dirty { - Vcs = Vcs + "-dirty" + Vcs += "-dirty" } } diff --git a/vendor/github.com/open-policy-agent/opa/version/wasm.go b/vendor/github.com/open-policy-agent/opa/v1/version/wasm.go similarity index 100% rename from vendor/github.com/open-policy-agent/opa/version/wasm.go rename to vendor/github.com/open-policy-agent/opa/v1/version/wasm.go diff --git a/vendor/modules.txt b/vendor/modules.txt index e5ca565862..955fe125a5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -25,10 +25,7 @@ github.com/Microsoft/go-winio/pkg/guid github.com/Microsoft/go-winio/pkg/process github.com/Microsoft/go-winio/tools/mkwinsyscall github.com/Microsoft/go-winio/vhd -# github.com/OneOfOne/xxhash v1.2.8 -## explicit; go 1.11 -github.com/OneOfOne/xxhash -# github.com/agnivade/levenshtein v1.2.0 +# github.com/agnivade/levenshtein v1.2.1 ## explicit; go 1.21 github.com/agnivade/levenshtein # github.com/beorn7/perks v1.0.1 @@ -330,18 +327,9 @@ github.com/mrunalp/fileutils # github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 ## explicit github.com/munnerz/goautoneg -# github.com/open-policy-agent/opa v0.70.0 -## explicit; go 1.21 -github.com/open-policy-agent/opa/ast -github.com/open-policy-agent/opa/ast/internal/scanner -github.com/open-policy-agent/opa/ast/internal/tokens -github.com/open-policy-agent/opa/ast/json -github.com/open-policy-agent/opa/ast/location -github.com/open-policy-agent/opa/bundle +# github.com/open-policy-agent/opa v1.4.0 +## explicit; go 1.23.8 github.com/open-policy-agent/opa/capabilities -github.com/open-policy-agent/opa/config -github.com/open-policy-agent/opa/format -github.com/open-policy-agent/opa/hooks github.com/open-policy-agent/opa/internal/bundle github.com/open-policy-agent/opa/internal/cidr/merge github.com/open-policy-agent/opa/internal/compiler @@ -393,33 +381,43 @@ github.com/open-policy-agent/opa/internal/wasm/opcode github.com/open-policy-agent/opa/internal/wasm/sdk/opa/capabilities github.com/open-policy-agent/opa/internal/wasm/types github.com/open-policy-agent/opa/internal/wasm/util -github.com/open-policy-agent/opa/ir -github.com/open-policy-agent/opa/keys -github.com/open-policy-agent/opa/loader -github.com/open-policy-agent/opa/loader/extension -github.com/open-policy-agent/opa/loader/filter -github.com/open-policy-agent/opa/logging -github.com/open-policy-agent/opa/metrics -github.com/open-policy-agent/opa/plugins -github.com/open-policy-agent/opa/plugins/rest -github.com/open-policy-agent/opa/rego -github.com/open-policy-agent/opa/resolver -github.com/open-policy-agent/opa/resolver/wasm -github.com/open-policy-agent/opa/schemas -github.com/open-policy-agent/opa/storage -github.com/open-policy-agent/opa/storage/inmem -github.com/open-policy-agent/opa/storage/internal/errors -github.com/open-policy-agent/opa/storage/internal/ptr -github.com/open-policy-agent/opa/topdown -github.com/open-policy-agent/opa/topdown/builtins -github.com/open-policy-agent/opa/topdown/cache -github.com/open-policy-agent/opa/topdown/copypropagation -github.com/open-policy-agent/opa/topdown/print -github.com/open-policy-agent/opa/tracing -github.com/open-policy-agent/opa/types -github.com/open-policy-agent/opa/util -github.com/open-policy-agent/opa/util/decoding -github.com/open-policy-agent/opa/version +github.com/open-policy-agent/opa/v1/ast +github.com/open-policy-agent/opa/v1/ast/internal/scanner +github.com/open-policy-agent/opa/v1/ast/internal/tokens +github.com/open-policy-agent/opa/v1/ast/json +github.com/open-policy-agent/opa/v1/ast/location +github.com/open-policy-agent/opa/v1/bundle +github.com/open-policy-agent/opa/v1/capabilities +github.com/open-policy-agent/opa/v1/config +github.com/open-policy-agent/opa/v1/format +github.com/open-policy-agent/opa/v1/hooks +github.com/open-policy-agent/opa/v1/ir +github.com/open-policy-agent/opa/v1/keys +github.com/open-policy-agent/opa/v1/loader +github.com/open-policy-agent/opa/v1/loader/extension +github.com/open-policy-agent/opa/v1/loader/filter +github.com/open-policy-agent/opa/v1/logging +github.com/open-policy-agent/opa/v1/metrics +github.com/open-policy-agent/opa/v1/plugins +github.com/open-policy-agent/opa/v1/plugins/rest +github.com/open-policy-agent/opa/v1/rego +github.com/open-policy-agent/opa/v1/resolver +github.com/open-policy-agent/opa/v1/resolver/wasm +github.com/open-policy-agent/opa/v1/schemas +github.com/open-policy-agent/opa/v1/storage +github.com/open-policy-agent/opa/v1/storage/inmem +github.com/open-policy-agent/opa/v1/storage/internal/errors +github.com/open-policy-agent/opa/v1/storage/internal/ptr +github.com/open-policy-agent/opa/v1/topdown +github.com/open-policy-agent/opa/v1/topdown/builtins +github.com/open-policy-agent/opa/v1/topdown/cache +github.com/open-policy-agent/opa/v1/topdown/copypropagation +github.com/open-policy-agent/opa/v1/topdown/print +github.com/open-policy-agent/opa/v1/tracing +github.com/open-policy-agent/opa/v1/types +github.com/open-policy-agent/opa/v1/util +github.com/open-policy-agent/opa/v1/util/decoding +github.com/open-policy-agent/opa/v1/version # github.com/opencontainers/cgroups v0.0.6 ## explicit; go 1.23.0 github.com/opencontainers/cgroups